Converting arduino code to esphome

I’m confused where to start, converting Arduino code into esphome. The code sends “IR commands”, but hard wired right to the receiver device instead of using an IR led. This allows the ESP to be right inside the device, all nice and neat. It works. Now I’d like to more it over to ESPHome for OTA updates and HA integration.

I just have no idea where to even start, creating my own custom component.

//The message of the NEC protocol is 32-bit long, address (16 bits), command (8 bits), and inverted command (8 bits). Before the previous 32 bits there is 9ms burst and 4.5ms space.
//Logic 1 is represented by 562.5µs burst and 562.5µs space (total of 1125µs)
//Logic 0 is represented by 562.5µs burst and 1687.5µs space (total of 2250µs).
//Keep in mind that the IR receiver output is always inverted.


#define DATA_PIN D2

#define DELAY_LEAD  9000    //9ms burst
#define DELAY_SPACE 4500    //4.5 space
#define DELAY_BURST  560
#define DELAY_0 DELAY_BURST
#define DELAY_1 1690



void send_0()
{
  digitalWrite(DATA_PIN, LOW);
  delayMicroseconds(DELAY_BURST);
  digitalWrite(DATA_PIN, HIGH);
  delayMicroseconds(DELAY_0);
}

void send_1()
{
  digitalWrite(DATA_PIN, LOW);
  delayMicroseconds(DELAY_BURST);
  digitalWrite(DATA_PIN, HIGH);
  delayMicroseconds(DELAY_1);
}


void send(unsigned long data,  int nbits)
{
  digitalWrite(DATA_PIN, LOW);
  delayMicroseconds(DELAY_LEAD);
  digitalWrite(DATA_PIN, HIGH);
  delayMicroseconds(DELAY_SPACE);

  // Data
  for (unsigned long  mask = 1UL << (nbits - 1);  mask;  mask >>= 1) {
      if (data & mask) {
          send_1();
      } else {
          send_0();
      }
  }

  digitalWrite(DATA_PIN, LOW);
  delayMicroseconds(DELAY_BURST);

  digitalWrite(DATA_PIN, HIGH);
  delay(500);
}

void setup()
{
  pinMode(DATA_PIN, OUTPUT);
  digitalWrite(DATA_PIN, HIGH);
  delay(1000); 

}

void loop()
{
  send(0x1FE7887, 32);  // Yellow
  delay(4000);
}

What Nick means is that there is no “conversion”.
You’d better start from scratch in ESPHome, surely with such a simple sketch.

My dunny project works in a similar way (but with pronto).

Maybe some bits are useful to see how you can put it together.

Probably my project has a fair bit more detail than yours. I went with lots of lambdas in a yaml rather than a custom component as I’m allergic to pure c++.

what is this controlling? Is it only controlling On/Off over IR? It looks like it is only using 1 IR command. Is this all the esp board does in there?

Ahh I was a dummy, did use the remote transmitter examples with ESPHome, but I wasn’t inverting the transmitting when I converted the code to ESPHome. Had to bring out the oscilloscope this morning to see what was going on.

# Example configuration entry
remote_transmitter:
  carrier_duty_percent: 100%
  pin:
    number: D2
    inverted: True

**Solved.

1 Like

Great to hear!

Hey, i have found some cool project to use an robotic mawer, but the code is written in Arduino, but i want to use ESPHome, since i use the ESP also for other stuff

here is the sketch below, i think only the http webserver is relevant? Once the webserver is ready, i need to upload a .bin file

Who can help me? thnx!!

source of project:: Mähspitzel - Wi-Fi für Robomow ( in german)

/*
 *  Board: "LOLIN D32 PRO"
 *  Upload Speed: "921600"
 *  Flash Frequency: "80MHz"
 *  Partition Scheme: "Minimal SPIFFS (Large APPS with OTA)"
 *  Core Debug Level: "Keine"
 *  PSRAM: "Enabled"
 *  Port
 */

#define LOGIN_CREDENTIALS_LENGTH_MAX 32

/* Anfang Konfigurationsabschnitt */
const char WLAN_local_SSID[32]     = "meineSSID";       // Geben Sie Ihre bestehende lokale WLAN SSID ein
const char WLAN_local_password[32] = "meinKennwort";    // Geben Sie Ihr bestehendes lokales WLAN-Passwort ein.

const char http_username[LOGIN_CREDENTIALS_LENGTH_MAX] = "Mspitzel";    // HTTP Benutzername, maximum von 31 Zeichen
const char http_password[LOGIN_CREDENTIALS_LENGTH_MAX] = "Mspitzel007"; // HTTP Kennwort, maximum von 31 Zeichen
/* Ende Konfigurationsabschnitt */

#include <WiFi.h>
#include <WebServer.h>
#include <HTTPUpdate.h>
#include <HTTPClient.h>
#include <WiFiClient.h>
#include <EEPROM.h>

const char* host = "mspitzel";
const char* def_ssid = "Mspitzel";
const char* def_pass = "Mspitzel007";

int eeprom_allocated_mem = 4096;
int eeprom_login_credentials_base=64;

  const char* serverIndex = "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>";
  
WebServer httpServer(8080);
HTTPUpdate httpUpdater;
WiFiClient WLAN_Client;
IPAddress local_ip;

void setup(void) {

  /* Serielle Schnittstelle initialisieren */
  Serial.begin(115200);
  Serial.println();

  /* Clear EEPROM */
  Serial.print("Lösche EEPROM-Inhalt...");
  EEPROM.begin(eeprom_allocated_mem);
  
  #define EVENTLOG_ADR 1024
  //for (int i = 0; i < EVENTLOG_ADR; ++i) { // Einsatzprotokoll nicht löschen
  for (int i = 0; i < eeprom_allocated_mem; ++i) { 
      EEPROM.write(i, 0); 
  }
  Serial.println("erledigt");

  /* Speicher http Benutzername / Kennwort in EEPROM */
  EEPROM.put(eeprom_login_credentials_base, http_username);
  EEPROM.put(eeprom_login_credentials_base +  LOGIN_CREDENTIALS_LENGTH_MAX, http_password);

  Serial.println("Einrichten des Firmware-Uploads...");
  
  if (!Local_WLAN_Connect()) {
    /* Standardverhalten - spawn access point */
    WiFi.mode(WIFI_AP);
    WiFi.setHostname(host);
    WiFi.softAP(def_ssid, def_pass);
    Serial.printf("Erstellter WLAN-Zugangspunkt mit WLAN SSID %s\n",def_ssid);
    /* lokale IP */
    local_ip = WiFi.softAPIP();
    Serial.printf("\n>>> Verbindung zum WiFi-Netzwerk \"%s\" mit Kennwort \"%s\"\n\n",def_ssid, def_pass);
  }
  
  EEPROM.commit();
  EEPROM.end();

  httpServer.on("/", HTTP_GET, []() {
  httpServer.sendHeader("Connection", "close");
  httpServer.send(200, "text/html", serverIndex);
  });
  httpServer.on("/update", HTTP_POST, []() {
    httpServer.sendHeader("Connection", "close");
    httpServer.send(200, "text/plain", (Update.hasError()) ? "Fehler" : "In Ordnung");
    delay(1000);
    ESP.restart();
  }, []() {
    HTTPUpload& upload = httpServer.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.setDebugOutput(true);
      Serial.printf("Update: %s\n", upload.filename.c_str());
      if (!Update.begin()) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) { //true, um die Größe an den aktuellen Fortschritt anzupassen
        Serial.printf("Update erfolgreich: %u\nNeustart...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
      Serial.setDebugOutput(false);
    }
    yield();
  });
  httpServer.begin();
  Serial.println("HTTP Server gestartet");
return;
}

void loop(void){
  httpServer.handleClient();
}


boolean Local_WLAN_Connect() {
  /* Versuch lokales WLAN zu benutzen mit den angegebenen Zugangsdaten */
  if ( strlen(WLAN_local_SSID) && strlen(WLAN_local_password)) {
    /* Wifi client mode */
    WiFi.mode(WIFI_STA);
    
    /* mit bestehendem WLAN verbinde */
    Serial.printf("Verbindung mit lokaler WLAN-SSID %s",WLAN_local_SSID);
    WiFi.begin(WLAN_local_SSID, WLAN_local_password);

    /* Warten, bis die Verbindung erfolgreich ist */
    for (int i = 0; i < 20; i++) {  //timeout [s]
      delay(1000);  
      
      int connectionStatus = WiFi.status();
      switch(connectionStatus) {
        case WL_CONNECTED: 
          Serial.println("...verbunden");
          local_ip = WiFi.localIP();
          /* WiFi-Zugangsdaten in EEPROM speichern */
          EEPROM.put(0,WLAN_local_SSID);
          EEPROM.put(32,WLAN_local_password);
          return true; // WLAN-Verbindung erfolgreich
        default:
          Serial.print(".");
      }
    }
  }
  Serial.println("...nicht in der Lage, eine Verbindung herzustellen"); // zum Standardverhalten zurückkehren
  return false;
}

There is a web server component in esphome:

But, at first sight, the only thing the code you show does is updating the firmware.
From the page you mention, it’s unclear whether that project publishes the actual sources of that firmware.

Yeah, indeed, it sends some bin file, it’s indeed a compiled source code, making probably a website

Not sure if I configure the webserver part, how to upload the firmware/bin file?

I don’t see any way you’ll convert that project to ESPHome without the sources.
Just follow their instructions to install their software.

Yeah, bit I was already using an ESP device with ESPhome on it, then I need to use a second device…

The .bin file I have, the one that needs to be uploaded

It’s on the link, you can download it there

This one:

https://www.skyynet.de/ftp/mspitzel_v105.zip

Indeed. Just upload/flash/install it like you would on any ESP.
You have to use the Arduino IDE, here. Converting that sketch to ESPHome just to upload the actual firmware is pointless.

The site describes in decent details what you have to do (translated):

Yeah, I know how Todo it :slight_smile:

But my idea was just to use my current esp32 device with ESPhome and setup a webserver on it to upload that program… Now I need to buy a second device to use this :slight_smile:

As far as I understand, everything is happening on a single ESP:

  1. Install sketch above via Arduino IDE with proper Wifi credentials
  2. Connect to the ESP webserver and upload the (closed source?) “.bin”. That has the effect of updating the ESP firmware
  3. Reboot ESP and enjoy the application.

Yes I know, but then it’s flashed with Arduino, I want to use esphome, not Arduino :slight_smile:

I want to use the Esphome addon and use yaml code to make that webserver and upload the program

I don’t thinks it’s possible to combine arduine sketch code and esphome together on one single device

You don’t seem to quite understand how that works.
Arduino is a framework. ESPHome is another “meta” framework, that actually uses Arduino or ESP-IDF behind the scenes.
ESPHome might use YAML, but it actually translates that YAML in C++ inside the Arduino framework.

At the end of the day, it’s the same machine code running on the ESP.
Coding with ESPHome brings a number of benefits, especially when used together with HA.

You won’t be able to use ESPHome, as you don’t have the source code of the final firmware. If you did, you might have been able to convert the code to ESPHome, but I honestly doubt you currently have the knowledge to do so, anyway.

2 Likes