adafruit / Adafruit_MAX31865

Arduino Library for Adafruit MAX31865 RTD Sensor
77 stars 79 forks source link

Two delays in readRTD are blocking #10

Open MakeNModify opened 5 years ago

MakeNModify commented 5 years ago

In Adafruit_MAX31865::readRTD two delays are used. This makes it unusable when driving a stepper motor at the same time (motor stops at every reading). Is there an easy way around it?

The way it is it is hard to be used for simultaneous tasks, it would be nice if this could be changed. Thank you :)

ladyada commented 5 years ago

at this time, no - you can use interrupts for other tasks or you could submit a PR for non-blocking reads, but we have no plans to do so.

MakeNModify commented 5 years ago

The project is somewhat like an 3D Printer Extruder/Hotend. So the Stepper has a high priority. If so it would work better to stop measuring temperature while extruding (3sec). But that is an compromise I'm not willing to make. Sure i could transfer the temperature control task to a second arduino but that would be solving software issues with hardware which is most of the time not an efficient concept.

Anyways thank you for your fast feedback. Meanwhile I found an other library that is sufficient for what I need and dose not block here: https://github.com/hallard/arduino-max31865

rvt commented 4 years ago

The library could be easily be written such that we can do both. Keep the readRTD function with the delay. And for people like me andMakeNModify two additional function that are called ´readRTDStart(..)' and 'readRTDread(...)' (open for better names)... Then people can decide if they want the 'async' or 'sync' version. This would allow for code re-use. Interrupts are not to be used for ´tasks´ If you are open for a PR around this, I can get you one.

sylvanoMTL commented 3 years ago

Here are some modifications, sample code is provided here to read multiple RTDs with a single shot.

Here are some results:

1RTD single shot | 76 to 77 ms 8 RTDs single shot | 614 to 616 ms    (77ms 8 = 616 ms) 15 RTDs single shot | 1152 to 1153 ms  (77ms15 = 1555 ms) 8 RTDs single shot but in asynchronous mode | 76 to 77ms 15 RTDs single shot but in asynchronous mode | 76 to 77ms

It would be nice to see a modification of the library to have also continuous measurement. I am sure that such modification combined with asynchronous reading would help to reach the 20ms reading.

frowin commented 3 years ago

I modified the library so that it becomes async. Until now it's a little bit hacky (e.g. it returns a temperature of 0 when the sensor is not yet ready to be read out). For timing I used millis() instead of delay(). With this change, the loop is not blocked for 75ms per sensor but only 160us.

rvt commented 3 years ago

If possible, I would let the temperature return NaN if it's unknown, and?or at least a function you can call to know if a temperature has a valid reading or not.

sylvanoMTL commented 3 years ago

After forking some codes, and taken some piece of code from the link I posted above, I am using this forked library. it could be clean up and pulled but I have very little time for this. As well I have an example on how to use this forked library with the following options: 1) One-shot (typical example) 2) Asynchro one-shot 3) Continuous I will add it if I have some time.

rvt commented 3 years ago

@sylvanoMTL On that library you mentioned this bugs me static t_state state = STATE1; (https://github.com/sylvanoMTL/Adafruit_MAX31865/blob/master/Adafruit_MAX31865.cpp#L357) that means you can only connect to one 31865 device because the static variable is shared between all objects.

sylvanoMTL commented 3 years ago

I think you may be right, but for me it works well The state machine is in reference with the property : uint32_t chrono; line 125 of the .h file. I believe the variable "state" stay internal to the function.

void setup(){
Adafruit_Max31865 RTD1;
Adafruit_Max31865 RTD2;
...
}

void loop(){
 RTD1.readRTDAsynch(); //will create an internal state
 RTD2.readRTDAsynch(); //will create another internal state (tbc)

This is to be confirmed, I had no issue plugin up to 15 RTDs on one arduino micro.

sylvanoMTL commented 3 years ago

Thanks, I would need to pass that variable as a class attribute.

sylvanoMTL commented 3 years ago

I have completed a first correction for the asynchronous mode: https://github.com/sylvanoMTL/Adafruit_MAX31865/tree/asynchronous_mode_fix I haven t written an example yet, but my this library works fine with my project. as discuss above, state and chrono is an attribute of the class, and are modified by the method setState(t_state new_state). this method is called in RTD.begin( ); and readRTDAsync(uint16_t& rtd);

Work to do is to clean up comments in the .h and .cpp, I have writen an example for multiple RTD readings

studi1882 commented 2 years ago

Thank you for your work! With this modification it also works parallel which is pretty amazing! 10 Pt100 in 76 ms instead of 760 ms!

budulinek commented 11 months ago

For a non-blocking version of the library, you can also check my fork:

https://github.com/budulinek/MAX31865_NonBlocking

A state machine is not implemented in the library itself.

OK, I have inserted a state machine into the library itself. Inspired by @sylvanoMTL with some modifications.