Air Quality Egg: Firmware/Software Update

Here’s the quickie summary. I reorganized the software on the Air Quality Egg to do the conversion math on the Nanode. Good news is this seems to be giving better results. The downside is it was a fairly broad impact, and I believe every board needs to be reprogrammed to get the system running at the latest baseline. I haven’t yet pushed the updated software and binaries up to Git Hub, but I’m running it and observing this feed, so far so good.

I’ve previously published instructions on how to reprogram the Nanodes using an FTDI-compatible programming cable in videos that are linked on the FAQ. I also plan to make a video that shows how to re-program the Sensor Shield and add-on modules, though that is admittedly not as easy as I’d like it to be for the average user.

I really want the fielded Eggs to get to latest version of the software though, so I’m willing to  reprogram units personally, at no additional cost, if you send them back to us and just pay for the round trip shipping. I know this is a real hassle for our international community members, with customs and all. If there are community members that are willing to be “local experts” for reproramming Eggs that would ease the process. If you are willing to be a volunteer in this capacity please let me know at support AT wickeddevice DOT com. It would be really great to have some local people help support Europe, Asia, and Australia.

Technical Details

Math Code Refactoring

The sensor shield code now responds with a record containing the following information in response to the EGG_BUS_SENSOR_BLOCK_RAW_VALUE request:

   uint32_t adc_value     :: the analog-to-digital conversion (ADC) count
   uint32_t low_side_r    :: the low side resistance associated with the ADC count
   uint32_t sensor_vcc    :: the high side voltage applied to the sensor divider circuit
   uint32_t adc_vcc       :: the reference voltage of the ADC
   uint32_t max_adc_value :: 2^(ADC # of bits), e.g. 2^10 = 1024 for a 10-bit ADC

Given this information, the Nanode computes the measured resistance as follows (using floating point math):

   vx = (adc_value / max_adc_value) * adc_vcc; // this is the voltage divider output voltage
   sensor_resistance = (sensor_vcc - vx) * low_side_r / vx;

And the value of the independent variable used for computing the interpolated response is calculated as sensor_resistance / R0, where the (mutable) calibration value R0 and the piece-wise linear response function table is retrieved from the sensor shield and applied as previously.

A few side note here:

  • This refactoring effectively deprecates the EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT field, as that quantity is now computed on the Nanode as a derived value. This is all obviously “hidden” in the EggBus library, but I did want to make that clear.
  • I tried to keep enough information on the endpoint to allow for future flexibility. I could have included less information in the EGG_BUS_SENSOR_BLOCK_RAW_VALUE response, but it would be less generic. With the interface defined as above, a sensor endpoint could for example use a 24-bit ADC, or a different voltage reference, and so forth, without loss of generality.
  • The terms may mean different things to different sensor endpoints, but they can rely on the Nanode to use them in downstream calculations as described above. The dust sensor, for example, has “occupancy” in “hundredths of a percent” as it’s raw value. To respect the calculation stream, the dust sensor now reports adc_value = 1, max_adc_value=1, adc_vcc=1, low_side_r=1, sensor_vcc=(occupancy + 1), and r0=100.

Data Refactoring

In the updated software, for each sensor there are three values reported to Cosm on every sample interval:

  • Raw Value := the result of the sensor_resistance calculation above. Tagged with “aqe:data_origin=raw”
  • Computed Value := the result of the interpolation calculation derived from the Raw Value, R0, and the piece-wise linear transfer function. Tagged with “aqe:data_origin=computed”
  • R0 := reporting this to Cosm once calibration enters the picture we’ll need to recognize that this value may vary over time, but this should be a mostly constant. Tagged with “aqe:data_origin=r0”

One thing to note, I’m changing the meaning of the raw value feed here. Where previously it reflected the “independent variable” (i.e. the quantity resistance / r0), it now reflects the sensor resistance.

Library Updates

There have been some updates to the Ethercard library in recent months. I’m not sure, but perhaps the latest library baseline addresses the issue causing some Air Quality Eggs to freeze up in the field, requiring a restart to resume publishing data to the web.