Back to Smartcitizen.me

Building the firmware

OK: OLED

All that was necessary to check the OLED was to plug the grove connector leading to its mux port into the device. (No firmware was changed to disable it).
This was done with power disconnected. Upon connection of the grove cable the power was reconnected.
The device restarted.

Results: The OLED displays reading values in a cycle of about a couple of seconds for each enabled sensor. Initially the readings are blank or zero; and on the 2nd cycle they begin to show reading values.
Conclusion:
The OLED is evidently operational.
Furthermore the OLED continues to operate for a period of a couple of hours. Looks like this device is not causing lock-up conditions.

I will continue to monitor the device for several more hours (likely overnight) before moving to the next task.

OK. Moving on. I have decided to wait until @victor responds on my proposal to make two different settings for GPS: “dynamic” (current) and “static” (unmoving) which better suits my use-case.

Now I am looking into an issue with the Gas Sensor Voltage readings reported by the ADC.:

10:08:10.993 → ADS1x15 ADC 0x48 Ch0: 1.432812 V
10:08:10.993 → ADS1x15 ADC 0x48 Ch1: 2.047937 V
10:08:10.993 → ADS1x15 ADC 0x48 Ch2: 1.348625 V
10:08:10.993 → ADS1x15 ADC 0x48 Ch3: 2.047937 V
10:08:10.993 → ADS1x15 ADC 0x49 Ch0: 1.361313 V
10:08:11.139 → ADS1x15 ADC 0x49 Ch1: 2.047937 V
10:08:11.139 → ADS1x15 ADC 0x4A Ch0: 1.362062 V
10:08:11.139 → ADS1x15 ADC 0x4A Ch1: 2.047937 V
10:08:11.139 → ADS1x15 ADC 0x4A Ch2: 1.362250 V
10:08:11.139 → ADS1x15 ADC 0x4A Ch3: 2.047937 V

Vgas for each sensor is connected to the Odd numbered channels and Vref is connected to the even numbered channels. Vref ought to be approx 0.5 * Vcc (3.2 volts) = 1.5 volts.
The anomaly that looks suspicious is the fact the Odd numbered channels all show 2.047937 volts exactly. Since the sensors are all different materials having different chemical reactions, I would never expect the voltages to be the same except by random coincidence.

The first thing to check are voltages seen by test instruments on the physical circuit:
I have 3 devices that can measure voltages:
A. Parameters model 7808 B DVM
B. GW Instek MSO2204AE Oscilloscope DVM App.
C. Digitech model QM1551 DVM
D. ADC Reading

These are connected to test pins provided on the 2 x ADC Boards. GND = Negative = Black on each device connects to V- on the board.

Here are the full set of measurements:
__________A__________B.__________C.__________D.(ADC)
A0 _______1.53________1.1 ________1.622________1.432812
A1 ________1.x________1.7x________1.728 _______2.047937
A2 ________1.47________1.05________1.518________1.348625
A3 ________ ~ __________1.6x________1.59 ________2.047937
A4 _______ 1.48 ________1.06 ________1.53________1.361313
A5 _______ 1.55 _________1.6x ________1.616 ______2.047937
A6 _______ 55 mV_______10mV ______ 233 mV______xx (not enabled in firmware)
A7 ________ 55 mV_______10 mV _____ 231 mV ______xx (not enabled in firmware)
B0 _______ 1.46________1.06 ________1.06________1.362062
B1 ________ 1.55________1.6 ________1.624 _______2.047937
B2 ________ 1.45________1.06 ______ 1.06________1.362250
B3 ________ 1.55 _______ 1.6 ________1.6 ________2.047937

I later discovered that when Parameters DVM was connected across test leads when other two devices also connected; that the readings changed (reduced). I conclude that the parameters DVM has low input impedance and loads the circuit. Thus I can dismiss the first column (A) of readings.

The Vraf readings of the Digitech DVM and Oscilloscope kind of agree with one another.
The Vgas readings agree sometimes; other times not so much.

Neither Digitech DVM nor Oscilloscope readings agree with values output by the ADC.

So Here I can throw in the fact that the Oscilloscope shows that there remains a significant noise component in the Vgas signal. (Despite all the work done to add the LPF) Depending on how the different ADC’s in each device handle AC component on top of DC component, and their input impedance, will affect the readings they deliver.
But it remains clear that the readings from the ADC board differ somewhat from those of the two test instruments.

So, my attention is now directed to the ADC: ADS1115 and the firmware that is driving it.
I first look into the detailed specification for ADS1115 to try to see how it handles noise, and what time window is used to make its measurement;

to be continued…

OK,

I conducted some limited research; and discovered Texas Instruments published a series of well-written papers describing noise sources related to ADC and how to handle it. Their main focus was of course; quantisation noise. Skimming the (very long) article led me to do some further googling concerning how to use FFT to eliminate noise. I even saw some discussion concerning the pro’s and cons of using 3rd order LPF versus using FFT to filter out noise (with the conclusion being FFT is cheaper to deploy).

Furthermore; I find in the existing SCS Firmware code a fine example of the technique applied to the NOISE sensor.

Broadly the steps:

  1. Take a number of samples of the signal. (not just one like we do now)
  2. Convert the voltage values to frequency domain using FFT.
  3. Apply a filter the the FFT to remove unwanted components. HAMMING filter was recommended.
  4. Convert the filtered readings back into the voltage domain using Inverse FFT

Now here’s the thing. Although I learned what is FFT waaay back 40 odd years ago, I have never used it since that time (it was not part of an examination at the time either). Furthermore real time deployment of FFT was not feasible in the days before Microcomputers became available. It could only be applied as a post-processing technique; (think astronomical observations and mainframe computers).
So this is not my area of expertise. I am flying blind; entirely reliant upon example code.

But looking at the overview; I consider the following: The signal of interest in the Gas Sensor output is purely DC (Zero Hertz). any part of the signal above zero Hz needs to be removed; and I just want the DC component. Maybe there is a simpler way. Assuming that the noise is truly statistically random; I am wondering if I just took the average over a number of samples would it produce an accurate enough result to suit the purpose. ? Is the extra computational “effort” to go through FFT calculations worth it ?

@oscgonfer @victor now would be a good time to chip in on this subject if you have the time. I could use some of your expert advice.(!)

Thanks
Bryn

Conducting further thought experiment on the issue….

Decisions needing to be made:

  1. How many voltage samples need to be taken over what time period and what interval between each sample.
    I think:
    a. 10 samples : it’s a trade off because each sample uses I2C bandwidth.
    b. 1 second: again it’s a trade off: time taken to get just one reading. Can slow down the whole system.
    c. Randomised intervals : to eliminate effects of periodic AC signal that potentially can match the sampling interval.

  2. Arithmetic mean or RMS ?
    I think arithmetic mean. I am not interested in the power of the AC signal: only the DC signal; of which RMS and Average are equal.

  3. Eliminate outlier values (highest and lowest samples) ?
    I think: uncertain : I might need to do both and see if it makes a difference.

  4. Include prior sample set average OR include the entire previous sample set ?
    I think it’s the same.
    I think yes. Get average of current sample set then average of last sample set and current sample set. This should help with smoothing.

OK; Finalised de-noising code for ADC (ASB). The code for this is all in Sck_ADS1X15::getReading

Description of the algorithm:
What the previous code did was to take an initial reading and then use that reading to adjust the setting for the Gain Control; and then it took a final reading: converted it to voltage value.
What the revised code does is to
(a) adjust the Gain (as before)
(b) take a configurable number of readings from the ADC over a time period of 1 mS and stores them in a temporary array as voltages.
(c) calculates the average voltage using those readings. Stores the result in a static history array that contains average voltages from past reading requests.
(d) takes the average of the historical readings (including (c)) to arrive at the new reading to be published.

Notes:

  • SCK readings cycle is 30 seconds; so the historical readings are 30 seconds apart.
  • The samples are all taken within a time window of 1000 mS at randomly spaced intervals within that. The idea is to eliminate the effects of any periodic waves contained within the noise signal.

The number of sample readings can be configured; default is 5. Its a tradeoff between the I2C traffic that comes from taking readings + time taken for the readings against the accuracy of the average. More samples = greater accuracy.
The number of historical readings to draw into the calculation is also configurable. A greater number of historical readings means the output will react more slowly to a change in environmental gas concentration.

The ‘Average’ calculation is a basic arithmetic average. If an RMS mean were used instead this would mean we are interested in the power spectrum of the noise signal; which is not the case; we are interested only in the underlying DC value.
I thought long and hard as to whether outlier values (largest sample and least sample) should be eliminated and decided it wasn’t worth the extra coding effort required; and it would be uncertain if there is any benefit. If the final result still shows wavering readings it will be due to a bias in outlier values (spikes) in the input signal.

I used the calculated average of past averages rather than storing the readings themselves; because it is more efficient and storage of the values would have no beneficial effect.

I made it possible to alter the number of samples taken and the number of historical readings to take into account; by way of the UI control. the user can change parameters and see the effect on the output.

The results of all of this ?

17:38:35.397 → ADS1x15 ADC 0x48 Ch0: 1.511806 V
17:38:35.458 → ADS1x15 ADC 0x48 Ch1: 1.679325 V
17:38:35.530 → ADS1x15 ADC 0x48 Ch2: 1.419256 V
17:38:35.603 → ADS1x15 ADC 0x48 Ch3: 1.990025 V
17:38:35.678 → ADS1x15 ADC 0x49 Ch0: 1.433150 V
17:38:35.711 → ADS1x15 ADC 0x49 Ch1: 1.908175 V
17:38:35.786 → ADS1x15 ADC 0x4A Ch0: 1.431981 V
17:38:35.861 → ADS1x15 ADC 0x4A Ch1: 1.920469 V
17:38:35.933 → ADS1x15 ADC 0x4A Ch2: 1.433381 V
17:38:35.971 → ADS1x15 ADC 0x4A Ch3: 1.955119 V

So, no longer are the Odd numbered channels showing identical unmoving voltages. There are some small voltage changes; indicating (I think) that the gas sensors are alive. I will need to somehow find a way to test the responsiveness to noxious gases. The only means available to me are Car Exhaust Gases; which should yield CO, NO2 and SO2 values. some-where above the baseline. Not sure how I can test H2S and O3.

1 Like

Ok

With the big issue of Has Sensor noise behind; now it’s time for a review to decide next things to do.

  1. Other sensors with Issues:
    1.a. ENS160 vs CCS811.
    The CCS811 sensor does not deliver results on every set of readings. Sometimes it seems to sleep; perhaps it’s old like me. The ENS160 was supplied to me by ScioSense for evaluation some time ago. Initially it seemed not to be working very well, but now after a few days of continuous operation it is delivering results on every reading. It delivers not only eCO2 and TVOC but also a calculated AQI value. The values are somewhat different than CCS811. I have no independent calibrated source to verify which one is closest to reality. But ….
    I am inclined to trust the veracity of ENS160 More than CCS811 because it’s based on 4 hot plates at different temperature rather than just one in the CCS811. It also has the companion ENS210 temp and humidity sensor that feeds direct into the ENS160 providing calibration services. It’s easy to get them working with each other.
    My vote is for ENS160 + ENS210 combo ahead of the CCS811.

  2. Noise sensor. This has previously been covered and it’s found to be deficient mainly due to lockup issues with I2S on the Samd21 MCU library. Thus for now it is disabled because of the lockups.

  3. GPS it runs ok but uses a lot of power and appears to cause lockups. At present it’s configured for frequent readings on a constantly mobile use-case. My system needs operation to be less frequent based on a static location use-case. I need to study it carefully to change the operation characteristic for my use-case but still have it capable of the mobile use-case. I asked @victor for collaboration on this but no quick response received so far. I am forced to go it alone as so many times before.

  4. SCD41 CO2 sensor. It started out delivering very high 1700 ppm readings. I changed it for another unit with the same result. Now after a week of continuous operation reading values are less than 1000 ppm. So there is hope that over time it will continue to settle down and slowly come to a credible value.

  5. INA219 was disabled when I ceased using the supplied power distribution board. Now I have no capability to measure power consumption thus no way to estimate battery life. It’s not the end of the world. I will repurpose the mounting of the power distribution board to hold the new buck boost power board.

  6. This review should not be complete without mention of temperature and humidity sensors. There is no shortage of them in the system.(and that is the issue). Not only do we have the original temp/rh sensor on the urban board but with the expansion in this SCS we see the following:
    a) SCD4x sensor has both temp and RH but less useful because they suffer from temperature rise from the CO2 device.
    b) the Dallas probe attached to PM board is exposed to clear air outside the enclosure and it also has a high degree of accuracy. It’s not mounted nearby any of the sensors that produce heat.
    c) the ENS160 has ENS210 associated. It too may be affected by the high temperatures used to measure VOC gases.
    d) each of 5 Spec Sensor ASB devices has a thermistor device onboard. It’s intended to be used to offset temperature effects on the electrochemical reactions of the Gas sensors. But the voltage to temperature conversion parameters is not specified so less useful. It also requires a connection to ADC in order to be read.
    So, that’s 9.

So, out of all these the Dallas probe should produce the most useful results. It will be used to calibrate Spec Sensor gas readings and also be the primary published temperature reading.

  1. Finally we come to interfacing with the central
    Platform. This depends on:
    a. Firmware configuration of device Id numbers used to tag readings sent to the platform.
    b. Several json files residing on the platform that are used to identify the incoming data stream and allow it to be displayed on the map.

At the moment 7 (a) and 7 (b) do not agree with one another. FablabsBCN need to supply me with Device ID’s that are unique for the new sensors.

I have done my best to supply information but I have to say that the collaboration with FablabsBCN team is a vacuum black hole with little or nothing coming back to me in a timely fashion. They are busy doing something else and I know not what it is.
The Fablabs team need to do their part in joining of the data flow particularly voltages from gas sensors to a calculation system to make gas concentration values. It would be similar to, or even identical calculations to those used for the alphasense gas sensors given it’s the same mathematical problem for similar type of sensors. It should be quick and easy for them.

I have the necessary mathematical formulas and algorithm to make this calculation within the SCS system but the architecture of the smart citizen system is to make this calculation on the platform. I prefer to keep my version of the system compatible so far as possible.
But, if I am forced to wait too long I will just proceed to implement that calculation locally. Too much time has passed for me to allow my pace of development to be held up much further. And I want to see the results delivered by the Spec Sensors given the amount of trouble and effort they have cost me personally with all this noise susceptibility BS. I want to find out if it’s worth the effort I put in or was it just a learning thing with no useful result.
I note we have now gone past the 12 month anniversary date of when I started this project. It’s long enough and I want to move forward. There are other interesting projects that are growing in my mind.

1 Like

So The results of the review (after overnight thought).

  1. CCS811 will be disabled. ENS160/ENS210 combo will work in its place. Mounting of this little board is problematic. It may need to wait until I have ordered and obtained Prusa 3D printer. I envisage a board holder and a protective cover that allows air entry; and thiswill be mounted on the exterior of the SCS enclosure. Its a very small 3D project that should serve as a good introduction for me (I have no prior experience with 3D printing or design.).

  2. x

  3. GPS: The antenna currently exits the enclosure via a hole in the base and the cable is clamped by the same clamp used for the Dallas Probe. Not completely satisfactory. So, I will drill a hole in the enclosure nearby the GPS board (must be within 100 mm) and there install the cable for the antenna plug/socket.

  4. Buck/Boost power conversion. Needs to receive power by the USB cable so it can be powered either by standard SCS PSU OR the Solar Battery. It will be mounted on top of the power distribution board but all of the existing USB cable connections will be removed and the power districution will feed only to the buck/boost; and power then feeds into the Grove Aux line via I2C mux.

  5. Urban Temp will be disabled. To be replaced by readings from Dallas Probe. there will be a disparity between Temp and HUM, but the error introduced will be quite small.

  6. x

  7. Gas concentrations. Presently the SCS sends individual voltages from each ADC port to the platform for conversion. There are two ports for each Gas Sensor; Vref and Vgas. The plan is to convert the voltages into Gas concentrations within the SCS and send only the calculated concentration values to the platform for display. Here is the sketch plan:
    7.a A new ‘virtual’ Class object that takes the voltage readings and converts to concentrations. ‘Virtual’ in the sense that it is not based directly on one sensor; it is made by calculations: several sensors together. It will look to the system like any of the sensor classes, and there will be 5 sensors defined in sensors.h. The existing ADC ports will remain enabled; but ID values removed so as NOT to send the raw voltages to the platform. The new virtual class will be artfully configured to be read AFTER the ADC voltages are read on each reading cycle. There will be just one instance of the virtual class. It will have defined a data structure that stores configuration data for each of 5 gas sensors. It comprises an array of struct. Data comprising config is:
    (a) identify the virtual sensor (ie SENSOR_CO_CONC)
    (a) sensor ID that has readings of Vgas for that sensor…
    (b) sensor ID that has readings of Vref
    (c) sensor ID that has readings of temperature. (ie Dallas Probe).
    (d) sensitivity M value for the specific gas sensor. The information is sourced from a barcode on each sensor.
    (e) array comprising lookup table for temperature coefficient adjustments (available from Manufacturer data sheets).

7.b. The algorithm for calculation has been provided to me a long time ago from the manufacturer. Their example code will need to be inserted as a class method and adjusted as necessary. It will write the reading result of its calculation to the standard place for handling by the base>aux code and ultimately written to the platform and displayed on the OLED or stored on Flash memory.

  1. Dust sensors. The regular SCK2.1 has one PM5003 dust sensor; the SCS V3 has 2. It helps to get greater confidence in the result. The two sensors A and B are alternately read during each reading cycle. Presently readings from each of the sensors is sent to the host separately. so you get two sets of PM values that can be (should be) compared with one another. Ya ok. (Seems like its BS to me); I am just not interested in such comparison. I need just one set of PM1, 2.5 and 10 dust readings. The focus must be on the result; and not the mechanism. So the plan is to add code that will calculate an arithmetic average of the two sets of readings and send to the platform just one set comprising the average values.

  2. The combined work on (5) (7) and (8) above will reduce the total number of sensor readings sent to the platform by 7; which is useful. It also results in the platform having to do very little work to display the data.

  3. The above work will take me a few days to put together. There is a risk of using too much text memory and/or RAM. I will need to be careful and write efficient code. We will see how that pans out.

Today I am part the way through development of the new set of 5 sensor comprising a calculation engine to convert Gas Sensor voltages into ppm readings.

It’s a significant amount of work therefore taking several days. I need to do all of it together as all the parts are linked. Therefore some risks : in the end I might find I do not have enough resources or I have messed up with the math. Of course I am trying to make certain the code is as efficient as I can do.

OK…
In the past couple of weeks I have spent a lot of time working through the problems associated with calculating usable gas concentrations for the 5 Spec Sensors that I have : H2S, CO, O3, SO2, NO2

The problem comes in several parts:
1/. Calculation of gas concentrations directly using voltages measured by the 16 bit ADC Board.
2/. Adjustment of the Gas readings for temperature effect. The gas sensors are calibrated for 20 degC but the real time temperature might be anything between -20C and +50C. The electro chemical sensors become generally more sensitive as temperature increases.
3/. Adjustment of the sensor readings to take into account cross sensitivity with other non-target gases. The idea being to get readings focussed on the target gas on the sensor label.

The first two calculations I found to be relatively straightforward. Temperature compensation has two parts:
(a) offset of the reading against the Zero value for the sensor. The zero value is taken as the voltage at the calibration temperature when the target gas concentration is zero ppm. Of course it’s a different value when the temperature is different from the calibration temperature.
(b) offset of the reading due to change in sensitivity of the sensor caused by temperature. The simplest way to make the adjustment is to calculate the change using a set of linear equations that approximate to curve of sensitivity change. The most accurate method however is to try to fit the curve y=b+ e^x. I chose the linear approximation method because its easiest to implement in firmware.

I ran into significant problems when attempting to calculate the cross sensitivity offsets. Firstly I fabricated a set of 5 simultaneous equations using the mfr-supplied cross sensitivity values; and found that I could not get a usable solution using standard matrix math. When I subsequently tried manual method to solve the equations using gaussian elimination I found the problem: two of the 5 sensors react to cross-sensitive gases to about the same amount as the target gas, and thus could not be eliminated. In fact the sensors are about equally sensitive to each of two gases.

I had some discussion with support engineers from the manufacturer; but could not come up with a usable work-around. If I continue to use these sensors then I will be forced to accept a compromise; and it is not an easy thing to do.

There is another way, I need to re-think whats going on here and in the next post I will run through a review of my gas sensor strategy;

OK; so I need to review the choices I have made for gas sensors for the custom SCS V3 I’ve been building for the past year.

Firstly: The initial decision to include noxious gases within the suite of sensors for the system. I wanted the system to have as comprehensive set of sensor readings as possible to deliver a broad picture of the environment in which the system is placed. To this end I added the wind and rain sensors and included GPS (to set the location) and a broad set of gas sensors for noxious gases commonly found in urban environments. The gases include those emanating from motor vehicles and factories and all of them can cause adverse heath effects when present at high enough concentrations.

Secondly what gas sensors to use ? The FablabsBCN team have selected Alphasense brand sensors but I found that this brand of sensors to be extraordinarily expensive when compared to the rest of the system. Adding them would more than double the overall cost. I searched for alternatives, and found that Spec Sensors (US) brand offered alternative sensors, manufactured using different, cheaper technology. The specification for these sensors appeared on the surface to be comparable; and at the time I did not have the experience to delve deeper into the specifications to discover hidden issues lurking within.
And so, on cost criteria alone, I selected Spec Sensors ahead of Alphasense.
Secondarily I was unimpressed with customer service provided by Alphasense when I requested cost information. They responded slowly and their attitude seemed arrogant. Whereas the attitude provided by Spec Sensors appeared to be helpful; and pricing is publicly accessible, the sensors themselves can be readily purchased from several sources including both Digikey and Mouser.

NOW: upon review I find that information provided by Spec Sensors regarding noise sensitivity, temperature compensation and cross sensitivity to be opaque and I find myself doubting the accuracy of readings and specificity of the gas concentrations.
Alphasense documentation shows that they have investigated the issue of noise sensitivity and documentation and the design of their analog interface boards helps to mitigate this important issue. The Spec Sensors analog interface boards broadly amplify the noise signal found on single ended power supplies; where as the double ended design of the Alphasense ISB serves to minimise noise pickup. I am unable to establish how well this works because I do not have any examples of the Alphasense available to test.
I have been able to mitigate the noise sensitivity to some extent using the Spec Sensors; but in overview I have to say that the eagle eye view of my design, comprising a 3rd order passive filter on the single ended power lead plus an averaging design for the firmware is not particularly impressive. It is clearly a compromise, inelegant solution that should not have been necessary if the Spec Sensors ASB design had recognised the potential of noise to wreck the veracity of readings and worked to mitigate its effects.
The physical design of the 3rd Order LPF in particular is mechanically weak; and will need to be revisited at some later stage when I acquire the means to fabricate my own PCBA’s (not using veroboard.)

Can I swap gas sensors to Alphasense ?
Spec Sensors have a different physical shape to those from Alphasense. The SCS V3 enclosure gas sensor portals are now customised to suit Spec Sensors and it would be a major effort to now change horses mid-stream; even if I could find the cash to commit to a new set of alphasense sensors.

[ Putins phoney war against Ukraine has crashed the share market; making it more difficult for me to commit extra cash at this time…]

So, the logical decision of this review is to continue with the Spec Sensors; despite the issues; and despite that fact I will only be able to trust the readings for a couple of the gas sensors.