2

I've written a user library for the Pi Pico that uses the TaskScheduler library to abstract timing away from the user. The user provides a function in their sketch which the library calls periodically via function pointer passed in the constructor.

When I stick to standard Arduino or functions from my library, everything works fine. If I include a function from the ADC library I'm using, core1 hangs while the comms on core0 continue to respond. If I run the same ADC operation from a non-callback function on the same core it works as expected. What is happening?

The relevant code snippets follow:

Library:

class Card {
public:
  typedef void (*ExtCbPtr)();  //pointer type to call sketch code from library
  ExtCbPtr _readCB;            //function pointer, points at user routine in sketch
  ExtCbPtr _writeCB;

  Card(ExtCbPtr readFunc, ExtCbPtr writeFunc); //constructor
private:
  Task readInputs;
  Task writeOutputs;
  Scheduler ts1;
};

Card::Card(ExtCbPtr readFunc, ExtCbPtr writeFunc) {
  this->_readCB = readFunc;    //use to call user's sketch code
  this->_writeCB = writeFunc;
}

void Card::begin() {
  //init scheduler tasks
  ts1.init();
  ts1.addTask(readInputs);
  ts1.addTask(writeOutputs);

  readInputs.setInterval(100);
  readInputs.setIterations(10);
  readInputs.setCallback(_readCB);
  writeOutputs.setInterval(100);
  writeOutputs.setIterations(10);
  writeOutputs.setCallback(_writeCB);
}

void Card::core1Loop() {
  ts1.execute();
}

Sketch:

static void writeOut();
static void readIn();
Card card(readIn, writeOut);
Adafruit_ADS1115 ads;  //ADC

void setup(){

rp2040.idleOtherCore();

//setup ADC
  if (!ads.begin()) {
    Serial.println("Failed to initialize ADS.");
  }
  ads.setDataRate(0x00E0);  //860 samples per second, every conversion takes ~1.2mS
  ads.setGain(GAIN_ONE);    //0.125mV/LSB

  card.begin();  //initialise
  rp2040.resumeOtherCore();
  Serial.println("Ready 0");
}

void setup1(){
  delay(1);
  Serial.println("Ready 1");
}


void loop1();
  card.core1Loop();
}

void readIn() {
  Serial.println("Read start");
  uint16_t adc =  ads.readADC_SingleEnded(0);  //problematic line
  Serial.println("Read end");
}


void writeOut(){
   //Doesn't matter, task not reached if read fails
}
3
  • Are interrupts involved? Try taking out the serial prints from the callback function. Commented Jun 28, 2023 at 21:52
  • Did you try a simpler sketch to verify the compatibility of the Adafruit_ADS1115 readADC_SingleEnded(0) method with Scheduler? Commented Jun 29, 2023 at 4:03
  • 2
    I spent three hours on this yesterday. Come in today, turn the system on, and everything works. PEBKAC? Commented Jun 29, 2023 at 9:25

0

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.