// Sketch to bridge Serial to esp8266 on Serial3.
// Supports esp8266 flashing.
// For the reset of esp to flashing mode CH_EN and GPIO0 of esp must be connected
// to Atmega pins for pulling them LOW (use diodes to prevent accidental 5V output to esp)
//#define FLASHING // uncomment for use with esptool and Flash Download Tool, if flashing detection always fails
#if !defined(HAVE_HWSERIAL3)
#include <NeoSWSerial.h>
NeoSWSerial Serial3(6, 7);
#ifdef FLASHING
#define BAUD 19200
#else
#define BAUD 38400
#endif
#else
#define BAUD 115200
#endif
#define ESP_ENABLE_PIN 2
#define ESP_GPIO0_PIN 3
void resetESP(boolean toBootloader) {
if (toBootloader) {
pinMode(ESP_GPIO0_PIN, OUTPUT);
digitalWrite(ESP_GPIO0_PIN, LOW);
}
pinMode(ESP_ENABLE_PIN, OUTPUT);
digitalWrite(ESP_ENABLE_PIN, LOW);
delay(5);
pinMode(ESP_ENABLE_PIN, INPUT); // let it to pull-up resistor
if (toBootloader) {
delay(100);
pinMode(ESP_GPIO0_PIN, INPUT); // let it to pull-up resistor
}
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(BAUD);
#ifdef FLASHING
digitalWrite(LED_BUILTIN, HIGH);
Serial3.begin(BAUD * 2); //double speed is necessary for stub upload, but it disturbs frequency test of the 'download tool'
resetESP(true); // reset to bootloader. no need to push the B/L button while connecting to USB
#else
digitalWrite(LED_BUILTIN, LOW);
Serial3.begin(BAUD);
resetESP(false);
#endif
}
void loop() {
while (Serial.available()) {
detectFlashing();
Serial3.write(Serial.read());
}
while (Serial3.available()) {
Serial.write(Serial3.read());
}
}
#ifdef FLASHING
void detectFlashing() {
// empty
}
#else
const byte syncFrame[] = {0xC0, 0x00, 0x08, 0x24, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x07, 0x07, 0x12, 0x20};
const byte checkSumPos = 5; // esptool.py and FDT do not send the checksum for sync frame, IDE does
byte syncFrameIndex = 0;
boolean detectSyncFrame = true;
void detectFlashing() {
if (!detectSyncFrame)
return;
byte b = Serial.peek();
if (!(b == syncFrame[syncFrameIndex] || (syncFrameIndex == checkSumPos && b == 0x00))) {
syncFrameIndex = 0;
} else {
syncFrameIndex++;
if (syncFrameIndex == sizeof(syncFrame)) {
detectSyncFrame = false;
resetESP(true); // reset to bootloader
digitalWrite(LED_BUILTIN, HIGH);
Serial3.write(syncFrame, sizeof(syncFrame) - 1); // last byte was not read, only peek
}
}
}
#endif
This is inspired by how I work with Uno WiFi. On UNO WiFi you can't disconnect the esp8266 from Serial1 and connect it to USB adapter for flashing like you do it with a module. The solution is a software bridge, a sketch ESPProxy in ATmega which copies bytes from USB to esp8266 and back.
On Uno WiFi there are connections to esp8266's CH_EN, GPIO0 and to a mosfet controling the power line to esp8266. It is possible to reset or reset to bootloader the on-board esp8266 from the Atmega sketch.
Flashing tools send DTR signal to USB chip to trigger the reset of the processor to bootloader. The signal causes the reset of the ATmega and restart of the ESPProxy sketch. And ESPProxy calls a reset or a reset to bootloader of esp8266. This way the esp8266 is in bootloader mode if the tool or IDE requires it.
The EspProxy sketch can detect uploading to esp8266 and put the esp into bootloader mode. If you enable DTR in boards.txt and let Serial Monitor open, then after the uploading the EspProxy returns to normal mode and bridges the Serial port of esp to USB for use of Serial Monitor with Serial of the esp.
With EspProxy I upload sketches or firmware to on-board esp8266 or sketches to Atmega, without event looking at the board. No disconnecting from power, pushing of B/L button or changing switches or cabling. Ideal for a lazy man like me. And it is fun experimenting with firmwares and esp sketches co-working with Atmega sketches with quick uploads.
Of course to upload to esp8266, OTA upload can be used in many cases, but sometimes it hangs and flashing over Serial is necessary.
I created this EspProxy sketch for Mega/Uno used with esp8266 module or for boards like the Robotdyn Mega/Uno + WiFi R3.
With Mega the esp8266 can be connected to Serial1, 2 or 3. With Uno only software serial is an option if you want to have Serial Monitor and Atmega flashing on Serial(0). For Uno the SoftwareSerial can handle the flashing from IDE at 38400 baud.
To reset the esp8266 to flashing mode it is necessary to connect the esp's CH_EN and GPIO0 to Mega/Uno pins for pulling them LOW in OUTPUT mode. The EspProxy doesn't set them HIGH to 5V, but some other sketch could do it, so add a guarding diodes to the connections.
EspProxy.ino (2.44 KB)