Async sensor Libraries (SI7021, APDS-9306)



  • Hello,

    Following the presentation of my project gdomotics : https://forum.mysensors.org/topic/9009/gdomotics

    I write this post to share my work on 2 new libraries :

    AsyncSI7021 : https://github.com/gmarti/AsyncSI7021
    AsyncAPDS9306 : https://github.com/gmarti/AsyncAPDS9306

    During my test of the existing libraries, I was really frustrated the way they were written, especially a lot of unnecessary waiting when measuring with multiple sensors.

    With those new libraries, you can start a measurement, continue any other task you want and get back the result when it is ready.

    Old way of measuring sensors:

    def syncMeasurement() : int{
      Wire.write(requestMeasurementRegister)
      delay(25)
      return Wire.read(resultRegister)
    }
    
    def syncMeasurement() : int{
      Wire.write(requestMeasurementRegister)
      While(Wire.read(mesurementStatusRegister) != terminated){ }
      return Wire.read(resultRegister)
    }
    

    Async measuring of sensors:

    def startMeasurement() : void{
      Wire.write(requestMeasurementRegister)
    }
    
    def isMeasurementReady() : bool{
      return  Wire.read(mesurementStatusRegister) == terminated
    }
    
    def getMeasurement() : int{
      return Wire.read(resultRegister)
    }
    

    With this you can write this:

    AsyncSI7021 si7021;
    AsyncAPDS9306 apds9306;
    
    
    while(!apds9306.begin()){} //Wait for sensor to be ready
    apds9306.startLuminosityMeasurement();
    
    while(!si7021.begin()){} //Wait for sensor to be ready (SI7021 has 18-80ms of powerup time)
    si7021.startHumidityMeasurement();
    
    bool isSi7021Measuring = true;
    bool isApds9306Measuring = true;
    
    do{
      if(isSi7021Measuring && si7021.isMeasurementReady()) {
        send(si7021.getTemperature());
        send(si7021.getHumidityFromTemperatureMeasurement());
        isSi7021Measuring = false;  
      }
      if(isApds9306Measuring && apds9306.isMeasurementReady()) {
        send(apds9306.getLuminosity());
        isApds9306Measuring = false;      
      }
    
       //Another task here !!
    
    while(isSi7021Measuring  || isApds9306Measuring);
    
    

    With this code, you don't know if si7021 or apds9306 will finish measuring first.

    And you don't care! Because the total measurement time will more or less be max(SI7021time, apds9306time, otherSensorTime, otherTaskTime)

    SI7021 max measurement time (12bit RH 14bit Temp) : 12 + 10.8 = 22.8ms
    APDS9306 max measurement time : from 25ms to 400ms

    With async code, you will spare more or less 22.8ms in your sketch with this 2 sensors

    With more sensors, you will spare a lot more! (async battery measurement, async everything !)

    Spare time == less battery use == happy me

    I really hope it will be useful for the community.

    Thanks

    Artix

    PS : This is the first release of those libraries, they have been tested only by me for the moment. Things can go wrong and some functionality (mostly interrupts)
    does not exist.


  • Hardware Contributor

    hi,

    async/SM is a good habit . no delays, code freely running, always makes me happy too 🙂 thx for sharing 👍
    I did the same for si7021 too, and a few others like opt3001 (async + C for mem footprint)

    Keep the good work!



  • @scalz You could share your code too ☺


 

250
Online

7.8k
Users

8.7k
Topics

93.0k
Posts