2

I am currently making a high bandwidth transmitter spreading ADS1115 data over both a LoRa and NRF24 module, however, I am running into lots of issues with the task scheduler and unstable behaviour of i2c (being used for the ADC, both transmitters use SPI). I am trying to read and process data on one core and transmit it on the other. Both processes work perfectly in isolation but not together when together the ADS1115 returns -1 or ~32k, and sometimes when working together the NRF module stops transmitting. Here is the minimal working code:

// flag to indicate that a packet was received
volatile bool transmittedFlag = true;

void IRAM_ATTR setFlag(void) {
    // packet transmission is finished, set the flag
    transmittedFlag = true;
}

void AttemptTrans() {
    lora.setDio0Action(setFlag);
    while (true) {
        if (transmittedFlag || digitalRead(DIO0)) {
            
            int state = lora.startTransmit((uint8_t*)(&LoRaData), sizeof(Data));

            if (state != ERR_NONE) {
                Serial.print(F("failed, code: "));
                Serial.println(state);
            }
            else {
                data.counter++;
                transmittedFlag = false;

            }
            
        }
        if (nrf.txFIFOEmpty()) { //Custom function: read_register(FIFO_STATUS) & _BV(TX_EMPTY);
            nrf.writeFast(&data, sizeof(Data), 0);
            data.counter++;
        }
    }
}

int ads_counter = 0;
void ADSFunc(){
    while (true) {
        uint32_t input = REG_READ(GPIO_IN_REG);
        if (input && 0x400000) { //Digital read on pin 22
            ads.setMultiplexer(ads_counter + 4);
            ADS_RAW[ads_counter] = ads.getConversion(false);
            ads_counter = (ads_counter + 1) % 4;
        }
    }
}

The tasks have been added in the following snippet:

disableCore1WDT();
xTaskCreatePinnedToCore((TaskFunction_t)ADSFunc, "ads", stackSize2, NULL, 1, &ADSHandle, 0);
xTaskCreatePinnedToCore((TaskFunction_t)AttemptTrans, "LoRaTX", stackSize, NULL, 1, &LoRaHandle, 1);

What works:

  • Disabling either task
  • Concatenating the functions onto one core - giving a bandwidth ~20 lower :(
  • the power lines have minimal noise staying between 3.301-3.302v

What doesn't work:

  • using DigitalRead rather than REG_READ, it causes the task to be permanently blocked, using REG_READ causes the task to be blocked less as time goes by, this was checked by running eTaskGetState(ADSHandle) on the other core
  • Changing i2c pins
  • Disabling the LoRa interrupt
  • moving the LoRa interrupt between cores
  • disabling the watchdog on both cores
  • using the blocking methods of the ADS or the NRF, the ADS blocking method breaks the NRF module too, not sure why but I know the blocking method constantly polls the i2c bus
  • using the adafruit ADS1115 library
  • using small vTaskDelays / TaskYeild
  • using big caps on the 3.3v lines + ceramic for the ADC
  • using AMS1117 3.3 regs for each device
  • using 2 AMS1117 3.3 regs for the ESP
  • using a Li-ion + boost converter as a power source

Current theory: There is a resource conflict between the SPI and i2c bus, this locks a mutex that blocks the ADS thread? When you work around this, the i2c bus spits out random values

I feel like I have tried everything so I am just hoping that this is a resource conflict, and is a known issue with an easy workaround! Any help is much appreciated!

1
  • The easiest way to go about it is not to use their dreadful library for either SPI nor I2C. Do it yourself, based on the datasheet. Been there, done that - their library is trash. The less you use it, the better off you'll be. Commented Sep 2, 2020 at 0:16

2 Answers 2

0

There seems to be some wierd issue with task threads and I2C in the ESP32 I2C library. There is mention of it here but no solution given. I have problems with reading a BME 280 temperature sensor through I2C from different threads, even though I have a mutex to avoid reading the sensor at the same time. What I found was that if I read the sensor twice in a row within each thread, the second read is always reliable, only the first read within the thread tends to give an erroneous reading. So I just do that for now, even though it is just a hack. Not sure if this helps you.

Sign up to request clarification or add additional context in comments.

Comments

0

I got the same issue in the past.

That is due most likely to a drop on the power supply line during the transmission and the correlate malfunction of the microchip logic. Therefore that is an electronic issue and not a programming one.

The reason is the current peak requested by the transmitter that rapidly induce a drop in voltage on the power supply line.

There is an easy fix soldering a 10 µF capacitor between GND and Vcc (take care of the capacitor polarity).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.