Humidity sensor on exhaust - other gas sensors ? - Page 5

Discuss roast levels and profiles for espresso, equipment for roasting coffee.

#41: Post by GDM528 »

Esteve wrote:GDM528, have you been able to test the QWIIC sensor ? Curious about your results.
Nicely timed question - just starting collecting data today.

All electronics sourced from Adafruit, who calls QWIIC "STEMMA"... whatever. Used the same ESP32-S3 controller as Esteve, but with a tiny attached display and three built-in buttons - super handy for standalone operation. I use the display to conveniently monitor sensor status, and use the buttons to start/stop data logging. Thanks to all the pre-written code it's very simple to download the log file over Wi-Fi and read into a spreadsheet on my PC.

I attached three sensor boards to the controller:
1) Thermocouple reader for the BT readings in the roast chamber.
2) Temperature and humidity sensor. ... r-breakout
3) TVOC and eCO2 sensor. TVOC is an aggregate readout of all volatiles, and eCO2 is an inferred CO2 readout. ... mox-sensor

They just plug into a string, no soldering for two of the boards, but some soldering was required for the thermocouple reader. I downloaded the curated code examples, and hack-hack-hacked into my own gas-logger code. I started off with Arduino, but <insert nerdy code rant here> ultimately switched to hardware-centric version of Python called "CircuitPython".

I was very anxious to know how the TVOC/eCO2 sensor would behave in this application, but some of the parts for cooling the exhaust were slow to arrive. So, I rigged everything onto a pressboard paddle that I could position in the exhaust stream, far enough away for the exhaust to mix with cooler air. In the photo below, the RH and gas sensors are at the end of the paddle and the thermocouple reader is hidden on the back side of the paddle, out of the way of the heated exhaust. Also not visible in the photo is a LiPo battery pack dangling off the microcontroller to enable fully wireless operation under my fume hood:

The gas-paddle is mounted on a camera tripod to position in the airstream as directed by the copper tubing stuck in the IKAWA exhaust port. I adjusted the location of the sensors such that the humidity sensor temperature peaked at about 60C - about 20C below the spec limit for the sensors.

My initial trust level for the sensors is kinda low, so I set up a sequence of roasts so I could monitor the baseline readings for drift. The sequence was empty chamber / 65g load of greens / empty chamber / 65g load of different greens / empty chamber / 65g load of same greens but different profile / empty chamber.

This first chart is a 'strip' of the entire sequence of relative humidity readings for all seven roasts. It may take a bit of staring to pick out what's happening: red trace is the BT in the chamber, dark blue is the raw RH reading, and the light blue trace is a 'corrected' version of the RH reading. The correction is (sensor temperature - 28) x raw RH reading /20 -7. The correction numbers were arbitrarily chosen to flatten the curve and position it nicely on the graph. The corrected RH curve shows the RH peaking at first crack - when I could hear it. The Brazil greens have been notoriously quiet during first crack, whereas the Mexico greens were audible - and that shows in their more pronounced peak in the curve. And note how the (last) stepped profile makes the RH peak very abrupt:

Diluting the exhaust has significantly reduced the difference between empty chamber and loaded chamber readings compared to Esteve's results, so probably not a good long term solution - but this does shows how robust the technique is, which will cut more slack for the mechanical design.

Next up: TVOC and eCO2 sensor readings. My concerns about overloading the sensors were confirmed - they went nuts when the roasts hit first crack. The TVOC sensor clipped shortly before first crack and the eCO2 sensor came very close to the same limit. The good news is they make it glaringly obvious when first crack starts, like, whoa.

I need to study the datasheet and play around with the code to see if I can keep the TVOC sensor from clipping. FWIW I picked this particular sensor because it appeared to have the greatest dynamic range compared to other sensors. These sensors can detect your breath from a meter away and weren't designed to be treated this way, but are much-much cheaper than lab-grade versions.

Despite the in-yer-face TVOC and eCO2 readings, I've got no guidebook on how to read those tea leaves. Note the difference in the eCO2 curves between different greens and between different roast profiles... what does it mean? Is there such a thing as a 'good' CO2 curve?

Esteve (original poster)
Supporter ♡

#42: Post by Esteve (original poster) »

Wow! Really cool :) the gas reading seems very robust and quite independent of the measurement point. I have recently ordered 2m of 10mm microbore copper piping and will use that instead of the PTFE tubing.

Why do you use:
correction is (sensor temperature - 28) x raw RH reading /20 -7

I have been playing with the formula below lately to convert it to absolute humidity, I think the results are much more consistent, for example independent of the heating up process empty chamber runs return a flat line with about 10g/m3, which is a logical value.
p= pressure_bar * 1e5
AH = (6.112 * math.exp((17.67 * T)/(T+243.5)) * RH * 2.1674)/((273.15+T))
Monitoring closely the sensor temperature after 2 roasts, for example I have a starting humidity sensor temperature of 30ºC and maximum before cooldown of 38.6ºC. Slightly below your readings.

The TVOC eCO2 are quite impressive as a FC indicator! Those could maybe benefit from being further on the exhaust. I wonder if they give you more information.

As per a good CO2 curve, no idea :) the humidity seems more intuitive. I used humidity to tweak some new green where I had no profile. I started with a previous profile I liked and saw a humidity behaviour that was very different, almost loosing all humidity in the drying phase. Then tweaked the profile to have a more flat curve. Maybe Co2 could give similar insights.

First try of new greens, pending cupping... My goal was a light roast, it came ok color wise but humidity was way different from my previous roasts, WL 13.4% DIY color 114 :

Seccond try, came too light DIY meter 120 and WL 12.65%:

Third try (WL 13.7% DIY color 110):

And here some empty chamber runs with just Relative Humidity (right axis %) , Absolute humidity (Right axis g/m3) and sensor temperature (left axis ºC):



#43: Post by GDM528 »

My original correction for RH was a lazy approximation after I saw the complicated fancy-pants science-based formula, with its exponentials and Kelvins and stuff. Nonetheless, I've switched to Esteve's formula and replotted the RoR roast of the Mexican greens (FWIW the curves look identical). The TVOC and eCO2 curves were scaled to fit nicely on the graph:

So, five ways to know when first crack happens:

1) Listen for it, yo.
2) Inflection in BT RoR tracking relative to applied heat (change in specific heat capacity).
3) Moisture release.
4) Release of volatile compounds.
5) Release of CO2.

Surely that's enough. But perhaps there's other side benefits to these gas measurements that can lend yet other insights into the roast results. For example, here's the same Mexican greens, but with a stepped profile:

Area under the moisture release (absolute humidity) curve is about 10% higher for the stepped roast, and the resulting weight loss was a bit under one gram higher than the RoR roast - that difference is about 10% of the available water in the greens pre-roast. So, I can roughly estimate weight loss from the moisture release curve... or I could just weigh it ;)

And yes, I did try misting water into the air intake on my IKAWA, and I did see a small (1-point-ish) bump in the raw RH readings for a few seconds. So, you can manipulate humidity during the roast... now what?

Harder to draw any inferences between the TVOC curves because of the clipping. Don't have any tasting notes between them yet. Depending on the shape of the roasting profile, TVOC release could be an early indicator of first crack, around 30 seconds or so. I wasn't paying close attention at the time, but I do recall seeing the TVOC readings start to ramp up around the time I picked up the signature toasty smells at the early phases of browning - more apparent when plotted on a log scale.

The area under the eCO2 curve is about 11% higher for the stepped profile - again, tasting notes pending. Area under the CO2 curve might be a viable indicator of roast level, so my upcoming set of tests will span a wider range of roast levels to test that theory. I've got no illusions this would be a better indication than roast color, but it might help relate how the roasting profile affects it. The eCO2 curve is nearly flat during development in the RoR profile, but steeply declines in the same period for the stepped profile, curious...

I'm hoping other roasters can chime in with any suggestions for how to exercise this gas-analysis capability. I'd like to think pro roasters are way ahead of the curve on this kind of telemetry, what do they do with it?

Esteve (original poster)
Supporter ♡

#44: Post by Esteve (original poster) »

Really interesting. And nice to see that the approximated AH formula is the same :) I am also waiting to taste the difference between profiles. A stepped profile releases most moisture at first crack, where a faster plateau or ramp can have most moisture released before FC.

The eCO2 curve is intriguing. It is very interesting that it only registers at around the maillard phase and jumps during FC. Could it be used to determine better when the coffee is fully dried ?

And for a gas burner I guess CO2 and VOC readings might not work as they might get mixed with the combustion gases. I guess you could boil some pasta and see what the sensor registers :roll:

One question, what is your sample rate ? Your RH readings have some sort of hysteresis, more pronounced on the way to higher RH. Do you think this is sampling, the sensor type, or the fact that it is open air ?

Edit: This paper is very inline with your VOC findings :


#45: Post by GDM528 »

My calculated absolute humidity curves have a 'ratcheting' effect that makes the curve noisier than it should have been. I think root cause is the calculation involves two numbers: sensor temperature and sensor humidity. A formatting error when saving the data to a log file rounded the temperature readings to only two significant digits, whereas the humidity readings were four significant digits. So, the humidity readings were changing smoothly with temperature while the sensor temperature readings were jumping in 1-degree steps. Alas, I can't go back and fix the error - but I know to be more careful next run.

The TVOC and eCO2 readings span five decades, so viewing them on a logarithmic scale may be more appropriate:

TVOC does ramp up nicely as the roast transitions into the Mailliard phase. Of course, I can tell the same thing just by looking at and smelling the roast, but the area under the TVOC curve might lend some insights into the amount of Mailliard-ing going on. At least for that 'stepped' roasting profile...

The RoR temperature profile is mind-bending when viewed with a log scale:

When the BT follows a linearly-declining RoR temperature profile, The TVOC curve on a log scale is a perfectly straight line. Put a ruler on the screen and check it yourself, I'll wait...

That is crazy-cool. Don't know what's going on, but it's still fascinating and curious. Could be some sort of clever error, but my mistakes are seldom this orderly. So much for using TVOC to detect the onset of the Mailliard phase.

Esteve (original poster)
Supporter ♡

#46: Post by Esteve (original poster) »

Really cool indeed! Good thought putting it on a log scale :) The second profile TVOC's is crazy.

I ordered the same sensor for eCO2 and TVOC, I'll try to reproduce the results in a couple of weeks.

Yesterday I was able to try the copper tubbing and it works well. Settled at about 1.4m for a temperature at the sensor of a maximum of around 40ºC. I did try a much shorter one 0.6m and was above 60ºC which is fine for the sensor but makes my PLA case suffer more... too lazy to print again with ABS.

Also tried your misting technique on IKAWA's empty run to test that the sensor was working. The delay from misting to seeing on the plot is about 1 second, pretty acceptable, 3 mist runs towards the end of the graph:


#47: Post by GDM528 »

Brazil v Mexico, can you 'smell' the difference during the roast?

Brazil is Klatch Coffee's "Diamond Reserve" from Minas Gerais. A blend of yellow and red Catuai, natural process. Purchased six months ago, but vacuum sealed and frozen until about two months ago.

Mexico is from Oaxaca region, Typica, Caturra, and Mundo Novo, washed process. Borrowed from a friend who held it at room temperature for around 2-3 years. So, 'mature'.

Both were roasted using a linearly-declining RoR roast profile to just barely Full City. The following chart shows BT(red), total volatile organics(orange), equivalent CO2(green), and absolute humidity(blue). Note regardng the TVOC curve: the sensor saturated right around first crack mark, which is why it flattens out (fixing that is TBD). Brazil are the solid lines and Mexico are the dotted lines:

In a typical IKAWA control-loop magic moment, the BT curves are identical. If you're looking to split hairs, the Mexico roast ran no more than one degree cooler after first crack - well within measurement error, or perhaps due to the slightly higher moisture release.

Absolute humidity readings, aka moisture release, were largely identical until first crack (at the six-minute mark), with the Mexico releasing a bit more moisture. Maybe related: the Mexico roast produced clearly audible first crack sounds, whereas the Brazil was largely silent.

TVOC and eCO2 are the only readings that show a clear difference between the origins. The curves for Mexico sit completely inside the curves for Brazil, so that implies the Brazil greens were 'gassier'. My wild guess is the difference in gas output is because the Brazil greens were (probably) fresher - although that doesn't explain the opposite effect with the moisture release. I encourage other readers to offer up opinions on why the curves are different.

The answer to the original question does appear to be "yes", however it may hinge on being very rigorous when comparing. Gas sensors drift over time and the humidity readings can shift from environmental influences, so I ran the different greens consecutively in one roasting session. And big-picture, even though I can see a difference in the sensor data between different greens, it's still much simpler to just look at the labels on the bags ;)


#48: Post by GDM528 »

Made some coding tweaks to keep the TVOC readings from clipping, and corrected the mixed-precision math error in the humidity calculation. Ran another batch of Klatch's Brazil Diamond Reserve:

So, the TVOC readings level off similar to the eCO2 readings. Plotted on a linear scale to emphasize the degree to which these readings constitute a "ding!" indication for reaching first crack. The VOC, CO2, and humidity curves all inflect right at the first crack mark, to the point where I might trust the gas readings over whatever I might hear in the roasting chamber. About $65 in components that just clip together. Listening for audible crack sounds is so 2022...

My physical setup is sloppy, with the sensors just grazing the exhaust gas from my IKAWA, so the readings from one roasting session to the next will vary. Next up for me is to stabilize the gas collection and cooling system - that should enable exploration of using the gas analysis for more than just first-crack detection.

Appendix: extending the TVOC measurement range (going into the weeds here):
The gas sensor chip has a calibration system to improve sensitivity for low-level readings. It varies from chip to chip and each chip will have its own calibration settings. That calibration setting can be manipulated to increase the dynamic range as it gets close to saturating. This is kind of a hack, but I took 2% of the previous TVOC reading and subtracted it from the calibration setting. Essentially a small gain reduction as the readings ramp up. However, this method can cause the readings to oscillate if the correction is too aggressive, so I'm hoping for a better solution longer term.

Esteve (original poster)
Supporter ♡

#49: Post by Esteve (original poster) »

Really interesting data :) I hope we can gather more to compare it to flavor with different humidity/TVOC/eCO2. I got my SGP30 sensor and I have it ready to acquire data on my next roast. I've done a few roasts with the copper cooling tube and it is been quite consistent on humidity readings.

One quick question, I had it running for 24h to get a baseline. What correction did you do ? What function are you using ?

Here is my current design. I was able to remove the pullup resistors and convert the humidity+air quality into a single QWIIC module.

PS: I need to get a new solder tip...


#50: Post by GDM528 »

Esteve wrote:One quick question, I had it running for 24h to get a baseline. What correction did you do ? What function are you using ?
Looking forward to your new data. In your setup the sensors will see 100% roast exhaust, so I'm concerned they may saturate as you approach first crack.

As for the baseline, below I'll be using references to the Python code supplied by Adafruit. The Arduino syntax will read a bit differently. Also, the H-B text processing algorithms inconveniently removes line indents, so pasting in code snippets will look kinda off.

I've essentially taken manual control of the sensor baseline settings with:

sgp30.set_iaq_baseline(eCO2, BaseTVOC)

For my sensor eCO2=0x92C3 BaseTVOC=9C40, determined after letting it run overnight. While the data logging is running I keep resetting the baseline after every reading, and subtract 2% of the last reading from the baseline to turn down the response as the concentrations increase.
with open("/Log.csv", "a") as Log:
   while True:
      T = sensor.temperature
      RH = sensor.relative_humidity
      TVOC = sgp30.TVOC
      eCO2 = sgp30.eCO2
      sgp30.set_iaq_relative_humidity(celsius=T, relative_humidity=RH)
      sgp30.set_iaq_baseline(0x92c3, int(hex(int(BaseTVOC - .02 * TVOC))))
      TC = mcp.temperature
I'm not making any adjustments to eCO2, but it does come really close to saturating. If it was clipping I would've applied the same sort of correction I'm using for TVOC.