Programming my ESP8266MOD (12 series) in a clone D1 Mini board

Hi

I am having trouble. I am trying to program my ESP8266MOD (12 series) in a clone D1 Mini board. I am putting the D1 Mini on my MateksysF722SE Flight controller connecting the RX/TX on the D1 Mini to TX/RX on the flight controller.

I am confused with what sketches to upload. I tried WifiAccessPoint from examples and but not sure about it talking both ways tot he flight controller. I need to be able to connect to the FC wirelessly with my laptop of mobile using INAV programming software to change settings, access blackbox flight recorder and program autonomous flight plan.

@bartman74

TOPIC SPLIT
PLEASE DO NOT HIJACK

Could you take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

1 Like

Thanks Perry will do

You won't find any ready made example sketches to do this. Not unless, someone has already made exactly the same thing. But it sounds like a serial passthrough, or telnet connection. Is the INAV normally connected to the FC via a serial cable?

thanks all, I was working off an old video tutorial which setup the ESP8266 as an access point and allowed the RX/TX pins ESP8266 D1 mini to talk with the flight controller and allowing wifi connection to the ESP to a mobile or laptop, as to create the same function as you would have when normally connecting the flight controller to the device using usb, but now wireless.

aarg

I am going to try both. I believe serial passthrough is the same as serial loopback? I found this to try:
Note on the ESP8266 D1 mini the pins are TX(1) and RX(3)

#include <SoftwareSerial.h>

// On ESP8266:
// Local SoftwareSerial loopback, connect D5 (rx) and D6 (tx).
// For local hardware loopback, connect D5 to D8 (tx), D6 to D7 (rx).
// For hardware send/sink, connect D7 (rx) and D8 (tx).
// Hint: The logger is run at 9600bps such that enableIntTx(true) can remain unchanged. Blocking
// interrupts severely impacts the ability of the SoftwareSerial devices to operate concurrently
// and/or in duplex mode.
// Operating in software serial full duplex mode, runs at 19200bps and few errors (~2.5%).
// Operating in software serial half duplex mode (both loopback and repeater),
// runs at 57600bps with nearly no errors.
// Operating loopback in full duplex, and repeater in half duplex, runs at 38400bps with nearly no errors.
// On ESP32:
// For SoftwareSerial or hardware send/sink, connect D5 (rx) and D6 (tx).
// Hardware Serial2 defaults to D4 (rx), D3 (tx).
// For local hardware loopback, connect D5 (rx) to D3 (tx), D6 (tx) to D4 (rx).

#ifndef D5
#if defined(ESP8266)
#define D5 (14)
#define D6 (12)
#define D7 (13)
#define D8 (15)
#define TX (1)
#elif defined(ESP32)
#define D5 (18)
#define D6 (19)
#define D7 (23)
#define D8 (5)
#define TX (1)
#endif
#endif

// Pick only one of HWLOOPBACK, HWSOURCESWSINK, or HWSOURCESINK
//#define HWLOOPBACK 1
//#define HWSOURCESWSINK 1
//#define HWSOURCESINK 1
#define HALFDUPLEX 1

#ifdef ESP32
constexpr int IUTBITRATE = 19200;
#else
constexpr int IUTBITRATE = 19200;
#endif

#if defined(ESP8266)
constexpr SoftwareSerialConfig swSerialConfig = SWSERIAL_8E1;
constexpr SerialConfig hwSerialConfig = SERIAL_8E1;
#elif defined(ESP32)
constexpr SoftwareSerialConfig swSerialConfig = SWSERIAL_8E1;
constexpr uint32_t hwSerialConfig = SERIAL_8E1;
#else
constexpr unsigned swSerialConfig = 3;
#endif
constexpr bool invert = false;

constexpr int BLOCKSIZE = 16; // use fractions of 256

unsigned long start;
const char effTxTxt[] PROGMEM = "eff. tx: ";
const char effRxTxt[] PROGMEM = "eff. rx: ";
int txCount;
int rxCount;
int expected;
int rxErrors;
int rxParityErrors;
constexpr int ReportInterval = IUTBITRATE / 8;

#if defined(ESP8266)
#if defined(HWLOOPBACK) || defined(HWSOURCESWSINK)
HardwareSerial& hwSerial(Serial);
SoftwareSerial serialIUT;
SoftwareSerial logger;
#elif defined(HWSOURCESINK)
HardwareSerial& serialIUT(Serial);
SoftwareSerial logger;
#else
SoftwareSerial serialIUT;
HardwareSerial& logger(Serial);
#endif
#elif defined(ESP32)
#if defined(HWLOOPBACK) || defined (HWSOURCESWSINK)
HardwareSerial& hwSerial(Serial2);
SoftwareSerial serialIUT;
#elif defined(HWSOURCESINK)
HardwareSerial& serialIUT(Serial2);
#else
SoftwareSerial serialIUT;
#endif
HardwareSerial& logger(Serial);
#else
SoftwareSerial serialIUT(14, 12);
HardwareSerial& logger(Serial);
#endif

void setup() {
#if defined(ESP8266)
#if defined(HWLOOPBACK) || defined(HWSOURCESINK) || defined(HWSOURCESWSINK)
    Serial.begin(IUTBITRATE, hwSerialConfig, SERIAL_FULL, 1, invert);
    Serial.swap();
    Serial.setRxBufferSize(2 * BLOCKSIZE);
    logger.begin(9600, SWSERIAL_8N1, -1, TX);
#else
    logger.begin(9600);
#endif
#if !defined(HWSOURCESINK)
    serialIUT.begin(IUTBITRATE, swSerialConfig, D5, D6, invert, 2 * BLOCKSIZE);
#ifdef HALFDUPLEX
    serialIUT.enableIntTx(false);
#endif
#endif
#elif defined(ESP32)
#if defined(HWLOOPBACK) || defined(HWSOURCESWSINK)
    Serial2.begin(IUTBITRATE, hwSerialConfig, D4, D3, invert);
    Serial2.setRxBufferSize(2 * BLOCKSIZE);
#elif defined(HWSOURCESINK)
    serialIUT.begin(IUTBITRATE, hwSerialConfig, D5, D6, invert);
    serialIUT.setRxBufferSize(2 * BLOCKSIZE);
#endif
#if !defined(HWSOURCESINK)
    serialIUT.begin(IUTBITRATE, swSerialConfig, D5, D6, invert, 2 * BLOCKSIZE);
#ifdef HALFDUPLEX
    serialIUT.enableIntTx(false);
#endif
#endif
    logger.begin(9600);
#else
#if !defined(HWSOURCESINK)
    serialIUT.begin(IUTBITRATE);
#endif
    logger.begin(9600);
#endif

    logger.println(PSTR("Loopback example for EspSoftwareSerial"));

    start = micros();
    txCount = 0;
    rxCount = 0;
    rxErrors = 0;
    rxParityErrors = 0;
    expected = -1;
}

unsigned char c = 0;

void loop() {
#ifdef HALFDUPLEX
    char block[BLOCKSIZE];
#endif
    char inBuf[BLOCKSIZE];
    for (int i = 0; i < BLOCKSIZE; ++i) {
#ifndef HALFDUPLEX
#ifdef HWSOURCESWSINK
        hwSerial.write(c);
#else
        serialIUT.write(c);
#endif
#ifdef HWLOOPBACK
        int avail = hwSerial.available();
        while ((0 == (i % 8)) && avail > 0) {
            int inCnt = hwSerial.read(inBuf, min(avail, min(BLOCKSIZE, hwSerial.availableForWrite())));
            hwSerial.write(inBuf, inCnt);
            avail -= inCnt;
        }
#endif
#else
        block[i] = c;
#endif
        c = (c + 1) % 256;
        ++txCount;
    }
#ifdef HALFDUPLEX
#ifdef HWSOURCESWSINK
    hwSerial.write(block, BLOCKSIZE);
#else
    serialIUT.write(block, BLOCKSIZE);
#endif
#endif
#ifdef HWSOURCESINK
#if defined(ESP8266)
    if (serialIUT.hasOverrun()) { logger.println(PSTR("serialIUT.overrun")); }
#endif
#else
    if (serialIUT.overflow()) { logger.println(PSTR("serialIUT.overflow")); }
#endif

    int inCnt;
    uint32_t deadlineStart;

#ifdef HWLOOPBACK
    // starting deadline for the first bytes to become readable
    deadlineStart = ESP.getCycleCount();
    inCnt = 0;
    while ((ESP.getCycleCount() - deadlineStart) < (1000000UL * 12 * BLOCKSIZE) / IUTBITRATE * 24 * ESP.getCpuFreqMHz()) {
        int avail = hwSerial.available();
        inCnt += hwSerial.read(&inBuf[inCnt], min(avail, min(BLOCKSIZE - inCnt, hwSerial.availableForWrite())));
        if (inCnt >= BLOCKSIZE) { break; }
        // wait for more outstanding bytes to trickle in
        if (avail) deadlineStart = ESP.getCycleCount();
    }
    hwSerial.write(inBuf, inCnt);
#endif

    // starting deadline for the first bytes to come in
    deadlineStart = ESP.getCycleCount();
    inCnt = 0;
    while ((ESP.getCycleCount() - deadlineStart) < (1000000UL * 12 * BLOCKSIZE) / IUTBITRATE * 8 * ESP.getCpuFreqMHz()) {
        int avail;
        if (0 != (swSerialConfig & 070))
            avail = serialIUT.available();
        else
            avail = serialIUT.read(inBuf, BLOCKSIZE);
        for (int i = 0; i < avail; ++i)
        {
            unsigned char r;
            if (0 != (swSerialConfig & 070))
                r = serialIUT.read();
            else
                r = inBuf[i];
            if (expected == -1) { expected = r; }
            else {
                expected = (expected + 1) % (1UL << (5 + swSerialConfig % 4));
            }
            if (r != expected) {
                ++rxErrors;
                expected = -1;
            }
#ifndef HWSOURCESINK
            if (serialIUT.readParity() != (static_cast<bool>(swSerialConfig & 010) ? serialIUT.parityOdd(r) : serialIUT.parityEven(r)))
            {
                ++rxParityErrors;
            }
#elif defined(ESP8266)
            // current ESP8266 API does not flag parity errors separately
            if (serialIUT.hasRxError())
            {
                ++rxParityErrors;
            }
#endif
            ++rxCount;
            ++inCnt;
        }

        if (inCnt >= BLOCKSIZE) { break; }
        // wait for more outstanding bytes to trickle in
        if (avail) deadlineStart = ESP.getCycleCount();
    }

    const uint32_t interval = micros() - start;
    if (txCount >= ReportInterval && interval) {
        uint8_t wordBits = (5 + swSerialConfig % 4) + static_cast<bool>(swSerialConfig & 070) + 1 + ((swSerialConfig & 0300) ? 1 : 0);
        logger.println(String(PSTR("tx/rx: ")) + txCount + PSTR("/") + rxCount);
        const long txCps = txCount * (1000000.0 / interval);
        const long rxCps = rxCount * (1000000.0 / interval);
        logger.print(String(FPSTR(effTxTxt)) + wordBits * txCps + PSTR("bps, ")
            + effRxTxt + wordBits * rxCps + PSTR("bps, ")
            + rxErrors + PSTR(" errors (") + 100.0 * rxErrors / (!rxErrors ? 1 : rxCount) + PSTR("%)"));
        if (0 != (swSerialConfig & 070))
        {
            logger.print(PSTR(" (")); logger.print(rxParityErrors); logger.println(PSTR(" parity errors)"));
        }
        else
        {
            logger.println();
        }
        txCount = 0;
        rxCount = 0;
        rxErrors = 0;
        rxParityErrors = 0;
        expected = -1;
        // resync
        delay(1000UL * 12 * BLOCKSIZE / IUTBITRATE * 16);
        serialIUT.flush();
        start = micros();
    }
}

I tried a few different ways but couldn't get any working.

I found the following which seems to fulfill me needs so far and easy to install

Download - JeeLabs

Thanks all for your help

1 Like

No. Passthrough uses an intermediate device to communicate with another device, by just passing data unmodified, both ways. A loopback sends unmodified data from some one device, back to itself.