The following is a development notebook for constructing a DIY CO2 monitor.
2021-02-05 10:07:42
TODOS:
2021-01-30 08:54:11
Bayou-CO2 up and running.
Feedmaps prototyped. Backend needs work.
Pi set up as Bridge. Can store data locally on Pi without internet connection.
Heltec version, REV_F working.
MicroSD seen as most reliable and accessible way to set up wifi + Bayou credentials on device. Heltec difficult to set up this way. Pivoting to FeatherESP32 in next PCB design.
Next design: Feather ESP32-based, and designed as 'bottom plate' for a clear plastic enclosure (1591BT). Right-angle USB pointing down and buttons on bottom. (MicroSD on bottom too? Would allow for header to use Adafruit board if useful / option). Stand-offs for mounting on wall. If doing this, could also put LoRa on bottom, too. That way the SMT parts get soldered on one side, and can conserve space on other side.)
Lending library design is main focus. System that can collect data on-site. Can also think about 'sync', with replication of feeds into the cloud.
Pi as bridge allows for local data storage, and optional sync to cloud. Can use hotspot with ethernet jack (widely avail).
Same design could accomodate a Feather M0 LoRA as a remote node, with different firmware, taking credentials from microSD. Or the codebase could use ESP32 + LoRa. Might be easier to do that, with a software 'switch'. Not sure. Can prototype both ways.
(Updated: 2020-12-09 08:31:32)
Key to assessment of work items:
Latest accomplishments:
Next steps:
Latest accomplishments:
Next steps:
Latest accomplishments:
Next steps:
2021-01-16 21:19:52
More or less random bookmarks into the notes file, for reference:
2020 SEPT 29
Needs 5V power minimum (actually, looks like it's best run at 6-9V); meanwhile, Logic levels for the UART are at 3.3V.
Useful info on logic levels / etc from the datasheet:
Table 1 from the K30 datasheet. |
Meanwhile, though -- good advice on connecting to signals that run at higher voltage from JeeLab, here. Punchline -- can add a 1K resistor in series with signal as protection.
Figure 2 from the K30 datasheet. |
Datasheet says: should avoid connecting analog and digital ground pins externally in order to avoid ground loops
Analog outputs. |
Calibration. |
Connecting a K30 to an Arduino via I2C
This suggests using 6 to 9V input. (Might be good to upgrade the spec on the MCP1702 voltage reg so we can take > 6V input on the Mothbot). Needs to be able to provide 500mA. So: direct from battery power is likely best.
Schematic of the Feather M0 Lora.
Datasheet for the AP2112-3.3 voltage regulator used on the feather is here.
From the AP2112K datasheet -- 6V max allowed on Feather:
UART connection. |
Note: Logic levels for the UART are at 3.3V.
Connecting a K30 to an Arduino via UART
UART connection. |
First readings. |
Blowing on the sensor and then letting it recover. |
Edge Collective copy of the library for UART connection is here (replica of that provided by CO2 Monitor here).
Guide here for hookup to Arduino UNO.
Example code here.
Using a Mothbot to connect to the K30 sensor over UART and send via LoRa to a Heltec Wifi-LoRa gateway, posting to FarmOS.
Code for remote and gateway is here.
Mothbot remote node connected to K30 CO2 sensor. |
Closeup of Mothbot. |
Closeup of K30 CO2 sensor. |
Heltec Wifi-LoRa gateway |
Graphing on FarmOS |
Would be nice to develop useful ways of connecting to some standard hardware (e.g. Feathers, etc).
Article on measuring CO2 in greenhouses:
Until recently, the vast majority of growers in the U.S. did not measure CO2 or use it to enrich their greenhouses. However, during the winter, CO2 levels can quickly become limiting in unventilated greenhouses full of plants on cold and sunny days. Over the past 10 years, we have also seen greenhouse growers seal up their greenhouses in an effort to control their heating bills during the winter. Other growers, especially in northern latitudes, have invested in supplemental lighting because of the numerous benefits, from improved quality and yields to reduced production time. An apparent result of tightly sealing the greenhouse is increased humidity and condensation. A not-so-apparent result of reducing air infiltration is a reduction of CO2 levels within the greenhouse below ambient levels found outdoors.
Oct 9 2020:
Maybe a good configuraiton is to have the sensor powered via a 7.4V rechargeable lith-ion, while the micro attached has its separate battery voltage?
oct 13 2020:
Recreating the prototype but using a Feather M0 instead ...
now we want to use Hardware Serial instead of Software Serial ...
We noticed a Twitter thread by Linsey Marr on Oct 8 2020 that references using a CO2 monitor to assess activity in a space re: COVID-19; they use the HOBO CO2 monitor pictured in Fig C below.
Fig C. HOBO CO2 Logger used to assess activity level / air turnover in a college gym. |
Note: some power options (if plugging into the wall): use a 9V power wall wart, and drop down voltage to 5V; or use a 5V wall wart (more commong), and boost up to 9V.
If the latter, probably need to check on current (mA) requirements of the K30.
Offhand, seems like drop down is easier; boosting to 6V / 9V is a bit odd.
Fig A2. Feather M0 connected to a K30 sensor. |
Feather firmware is here.
Wiring for test:
Fig A. UART connection on the K30. When connecting to the Feather, connect TXD (K30) to RX0 (Feather) and RXD (K30) to TX1 (Feather). |
Fig B. Data from Feather, plotted in Arduino plotter utility. Data shows breathing on sensor at a particular time and and watching decay. Time interval unit is 2 seconds. |
UPDATE: looks like the K30 can be powered by up to 14V. So a 12V boost, or power supply, could be an option.
Started by closing door, sitting next to sensor. At 150 time mark, opened door and left room. Then At 250 time mark, reentered room and closed door. At 280 time mark, started a conversation.
Cf. 'room_test.png'.
'room_test_later.png' -- had a phone call
'room_test_later_2.png' -- left room for a bit with door open, then emilie came back and worked with the door open.
Nice discussion here, thanks to Laura P.
Specifically mentions NDIR.
For sale on Banggood. Another option
Mentions infrared. This is the one that Craig used / that I have in my possession now.
For sale on Banggood for $20.
Goal as of 13 OCT 2020: get this up and running in parallel to the K30 and see how they compare with the 'ambient' test.
Nice article on testing out the Z19 on a Raspberry Pi.
Update 15 OCT 2020: Just found a fairly official-looking Arduino library for the MH-Z19 here by WifWaf.
In that repo they have some nice notes about calibration. The Z19 allows us to turn autocalibration off (which seems useful -- otherwise it is using the lowest reading in a 24 hour period as '400 ppm'). Would be good to experiment with this.
Also, here's another library for the MH-19 -- looks a bit older. Going to try the WifWaf one above for now.
Note that the WifWaf github MH-Z19 lib is already in the Arduino online Lib repo, can just install via Library Manager in IDE.
Update 15 OCT 2020: was able to get the WifWaf lib running on the MothbotV3. Radiohead + the library ends up generating a 'low memory' warning. This is fine; we'll likely end up using the Feather; also, we can pare down the full library to just generate raw values, likely.
Guide to using ESP32 in Arduino IDE
Add this to Boards Manager:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Select 'Heltec Wifi Lora (v2)'
Add this to Boards Manager:
https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
Oct 14 2020
Posting CO2 PPM data from a K30 to FarmOS, measuring overnight from 14 OCT to 15 OCT 2020. |
This article mentions a technique, using their library.
(TODO: set up using chappy-server as a model?)
15 OCT 2020 10:42 AM
K30 is autocalibrating, Z19 is not.
Ah -- looks like the K30 also can give temp, and RH! Cf the example here.
How to read the K30 via I2c app note here.
Ahhh here is a library for multiple params by CO2meter for the K30 -- boom.
need to modify their library so that it doesn't rely on SoftwareSerial (necessarily)
-- but first check whether we can even disable autocalibration?
Reading the K30 datasheet
Useful CO2meter guide to K30 ABC here.
i2c communication guide to K series sensors
-- looks like it can be disabled in EEPROM via I2C, at least ...
Nice reference on connecting a Teensy to a K30 here
Reference to a key application note re: K-Series eeprom setup here
-- need to email them, UART command lib is missing ...
15 OCT 14:00 -- Interesting link to the Yoctopuce V2, which uses a 'better sensor' than the K30, they claim ...
The K30-based yoctopuce-c02 is here
More about the yp-co2-v2 is here
Yp-co2 (K30) user's guide
this is the serious guide, here
simple i2c example here
The yocto uses the SCD30 -- listed for $54 on digikey
Here's the SCD30 datasheet
Arduino library here
And on github
annnnd the Sparkfun library has a 'disable calibration' settting here
K30 seems outdated; won't trust it until we figure out how to turn off the autocalibration ... waiting to hear back from CO2 meter
MH-Z19 is also a bit older; can at least control the autocal ...
The calibration assumption with these meters seems to be that they use the lowest ppm value over some period and consider it to be 400 ppm -- assumes that all spaces end up getting 'fresh air' at some point in that period. For the K30, this is et to 7 days. Not sure for the other sensors.
Also: readings for NDIR are temp, humidity, and pressure dependent. My sense is that all the sensors measure these variables and compensate; the SCD30 also allows for feeding it the current ambient pressure and using it for calibration.
My current thought is the SCD30 would be a good one to get, along with an ambient pressure sensor.
OCT 16 2020
Example of an electrochemical CO2 sensor.
Really nice collection of references from co2meter.com
OCT 21 2020
Looks like the SCD30 can run off 3.3V, requiring max current of 80mA -- that's well within range of Feather LDO I believe!
SCD30 datasheet has the following table:
SCD30 handling and assembly guide
Electrical characeristics of SCD30. |
Listing for th SCD30 on Amazon, here.
And on Digikey, here.
Note: should likely pair with a precision pressure sensor like the BME280 or better.
OCT 22 2020
CO2Meter note on calibration here
Calibration for the SCD30 sensor document here p. 7 / 10.
Calibration of the SCD30, via this document |
Upshot: seems as though with the ABC algorithm, sensor needs to see at least 1 hour of fresh air daily.
With the 'manual' mode, can run it for 2 minutes outdoors and press button saying 'calibrate' and set it to '400ppm'.
Seems like this latter mode would work best.
Assembly of SCD30 PCB, via this doc |
OCT 23 2020
Field calibration guide for SCD30
Effect of 'forced recalibration' (FRC) of SCD30 as described in the SCD30 ield calibration guide |
Effect of automatic self-calibration (ASC) algorithm used in SCD30 as described in the SCD30 ield calibration guide. |
OCT 24 2020
Might consider adding a high-precision pressure sensor to any SCD30 breakout board; the SCD30 can compensate for pressure if sent values directly. E.g. the BMP388 breakout from Adafruit.
NOV 12 2020
Quick task: Feather-based breakout for SCD30 + BMP388 or equiv.
Any other useful things to add?
Should we use the ESP32?
If we use Heltec, it could be a remote node or a gateway ...
That's an argument for using the Heltec ...
Looks like SCD30 can use i2c ... ... other sensors can use i2c (break it out!) or UART ...
which library does Sparkfun use?
Sparkfun SCD30 library Ah, here's the Sparkfun SCD30 CO2 Library. They use i2c, great!
SCD30 pinout From the SCD30 datasheet:
Pinout for BMP388, precision temp + pressure ...
Current thinking: make a place for the i2c oled displays, both the thin and the larger versions.
Ahhh ... BM390 has even greater precision, why not go for that. Looks like same pinout, in fact.
(Same as BMP380)
Question -- do we need the INT pin assigned to a feather pin?
Looks like it might only be for SPI -- see Adafruit description of pinout. In any case, not used in their libraries, so don't assign for now.
Guide is here
They give an example with D10 as TX and D11 as RX. So, break out those pins.
[Small i2c display] is 38x12mm.
Large i2c display is 27mm x 27mm.
Current breakout board is here.
2020 NOV 13
Lithium Ion battery that fits nicely inside of feather, here.
Sizing logos in Kicad, article here.
2020 NOV 14
Nice guide to trace width here.
Trace width calculator link here, and here.
Based on this link at OSHPark, the typical copper thickness for a 2-layer board is 2oz.
Then,
I think the CO2 board won't source more than 0.2 Amps.
Ah! Note that JLCPCB uses 1 oz copper by default. This means:
Idea: develop footprint for K30 and Z19, to co-deploy the sensors and test them out.
On the other hand: nice to have a board that is smaller, that can connect to these other boards, but is ready to start deploying as its own sensor.
Here's a version (REV_A) that does the latter.
Now, need to ask again: can we turn off the autocalibration for the Z19 and the K30?
Z19, I believe it's straightforward -- need to review.
K30 -- here are the links sent via email from CO2Meter:
Screenshot of gaslab software from CO2Meter, showing serial interface to turn ABC off:
Turning off ABC in K30 via i2c (found in 'Communications Protocols Manuals', in the i2c folder. Specific document stored in our archives here.
Communicating with K30 via I2C + Arduino guide, here. Example below:
// CO2 Meter K-series Example Interface
// Revised by Marv Kausch, 7/2016 at CO2 Meter <co2meter.com>
// Talks via I2C to K30/K22/K33/Logger sensors and displays CO2 values
// 12/31/09
#include <Wire.h>
// We will be using the I2C hardware interface on the Arduino in
// combination with the built-in Wire library to interface.
// Arduino analog input 5 - I2C SCL
// Arduino analog input 4 - I2C SDA
/*
In this example we will do a basic read of the CO2 value and checksum verification.
For more advanced applications please see the I2C Comm guide.
*/
int co2Addr = 0x68;
// This is the default address of the CO2 sensor, 7bits shifted left.
void setup() {
Serial.begin(9600);
Wire.begin ();
pinMode(13, OUTPUT); // address of the Arduino LED indicator
Serial.println("Application Note AN-102: Interface Arduino to K-30");
}
///////////////////////////////////////////////////////////////////
// Function : int readCO2()
// Returns : CO2 Value upon success, 0 upon checksum failure
// Assumes : - Wire library has been imported successfully.
// - LED is connected to IO pin 13
// - CO2 sensor address is defined in co2_addr
///////////////////////////////////////////////////////////////////
int readCO2()
{
int co2_value = 0; // We will store the CO2 value inside this variable.
digitalWrite(13, HIGH); // turn on LED
// On most Arduino platforms this pin is used as an indicator light.
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr);
Wire.write(0x22);
Wire.write(0x00);
Wire.write(0x08);
Wire.write(0x2A);
Wire.endTransmission();
/////////////////////////
/* End Write Sequence. */
/////////////////////////
/*
We wait 10ms for the sensor to process our command.
The sensors's primary duties are to accurately
measure CO2 values. Waiting 10ms will ensure the
data is properly written to RAM
*/
delay(10);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
/*
Since we requested 2 bytes from the sensor we must
read in 4 bytes. This includes the payload, checksum,
and command status byte.
*/
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
/*
Wire.available() is not nessessary. Implementation is obscure but we leave
it in here for portability and to future proof our code
*/
while (Wire.available())
{
buffer[i] = Wire.read();
i++;
}
///////////////////////
/* End Read Sequence */
///////////////////////
/*
Using some bitwise manipulation we will shift our buffer
into an integer for general consumption
*/
co2_value = 0;
co2_value |= buffer[1] & 0xFF;
co2_value = co2_value << 8;
co2_value |= buffer[2] & 0xFF;
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if (sum == buffer[3])
{
// Success!
digitalWrite(13, LOW);
return co2_value;
}
else
{
// Failure!
/*
Checksum failure can be due to a number of factors,
fuzzy electrons, sensor busy, etc.
*/
digitalWrite(13, LOW);
return 0;
}
}
void loop() {
int co2Value = readCO2();
if (co2Value > 0)
{
Serial.print("CO2 Value: ");
Serial.println(co2Value);
}
else
{
Serial.println("Checksum failed / Communication failure");
}
delay(2000);
}
'Final' REV_A version (ordered on JLCPCB on 14 NOV) is here:
Repo for REV_A schematic and board file is here.
2020 NOV 16
Really nice research paper by Peng and Jimenez that yields CO2 thresholds for indoor activity, with thresholds based on activity / mask use / etc -- linked here.
Abstract from Peng and Jimenez 2020. |
This is the key figure (Fig 2) to understand from the paper:
Figure 2. from Peng and Jimenez 2020. |
An online aersol transmission calculator based on the paper is here.
The tweet broadcasting the tool is here.
The lead author on the paper, an expert on aerosol transmission, is here.
Some of the feedback on the paper & tool was from Linsey Marr, the NYTimes-quoted air expert on COVID transmission. Her Twitter profile is here.
TODO:
Need to add buttons!! For calibration, and other navigation.
Sensiron SCD30 available on Amazon UK
NRF52 + LoRa wing setup --
2020 NOV 17
REVB board 3D rendering:
REV_B KiCAD design files are here.
2020 NOV 18
Heltec version of CO2 board ... 'REV_C' ...
Aside -- interesting 'hiveyes' project using the Heltec, might have interesting code associated with it, here. Nice collection of github code here, including weight scales!
Interesting radio protocol here.
Radio protocols -- another way in which efficiency might be in tradeoff with legibility.
Kicad design files are here.
Thread here on the battery connector type for the Heltec -- "Micro JST 1.25 mm".
Example of 1000 ppm cylinder here
Product here
Manual here
Product page here
Product guide here
Link on Amazon here.
Link on Amazon here.
2020 NOV 23
REV_A Boards have arrived in the mail. Assembly and initial code tests!
Sparkfun SCD30 i2c library is here.
First version with display, lora, screen, scd30 is here.
Associated gateway code is here.
Online data is currently posting here.
Quick indoor test of REV_A board. |
Also took sensor outside for a few minutes. It fluctuated a lot. Seems like we're going to want to average readings over a minute or or more to get some stable value when the CO2 is low. Might have been due to wind. Might need to suggest that people get out of wind if they calibrate outside. Or, to tell folks to wait til the reading stabilizes before hitting calibrate. Or even have this happen automatically.
2020 NOV 24
Results of overnight test on NOV 23. Out of three people in apartment, two went to bed at around 8 PM, the final person at around 10:30 PM. One person (me) woke up and started using computer right next to CO2 sensor at 4:30 AM. Collecting data in this Bayou feed, generated these graphs as of 4:30 AM:
CO2 concentration in PPM, 2020 NOV 23 overnight. |
Temperature in C, 2020 NOV 23 overnight. |
Comment. Note the correlation between temperature and CO2, with co-occurring peaks around 12 AM and 1:30 AM. The temperature pattern likely due to the HVAC system. (The spike in CO2 and temperature at 4:30 AM are likely simply due to my presence near the sensor.) Unless the HVAC is in fact bringing in air with higher concentration of CO2, perhaps this indicates the range of fluctuation in CO2 reading due to temperature. Do we expect CO2 to rise with temperature for this NDIR sensor type?
Found nice reference for effect of temperature and pressure on CO2, here.
Key passage:
The size of the NDIR sampling chamber is fixed and is open to the atmosphere so that air can move in and out. As explained above, the number of air molecules in a given volume is affected by temperature and air pressure but not the concentration of CO2. At low pressures or high temperatures, there will be fewer air molecules in the sample chamber, so there will also be fewer CO2 molecules, even though the ppm of CO2 hasn’t changed. Fewer CO2 molecules “fools” the sensor into thinking that the CO2 concentration is lower than it really is. At high pressures or low temperatures, there are more air molecules in the sample chamber and more CO2 molecules, even though the CO2 concentration hasn’t changed. More CO2 molecules “fools” the sensor into thinking that the CO2 concentration is higher than it really is. Therefore a CO2 sensor calibration will only be accurate at one temperature and one air pressure.
This would suggest:
This fluctuation is due to pressure inside the apartment, when the HVAC system turns on? Now worth attempting to compensate with external pressure sensor.
Addendum. I've now replaced the above graphs so that we can see the readings from 0430 to 0530, during which time I sat close to sensor. Note that the temperature rose less than during some of the nightly spikes, but CO2 rose more, as one might expect given my proximity to the sensor. This perhaps leads to more confidence in the temperature-compensation of the SCD30.
Thoughts on calibration, and baselines. The key metric in the 2020 paper by Peng et al is 'PPM above baseline'. So, perhaps absolute calibration isn't really an important metric, here; more useful and interesting might be to establish a 'baseline', algorithmically; display it graphically; and allow the user to adjust based on their interpretation.
Key passage from page one of Peng et al:
Indoor CO2 has been suggested as a practical proxy of respiratory infectious disease transmission risk (8), as pathogen-containing aerosols and CO2 are co-exhaled by those infected (Fig. 1). Since background (ambient) CO2 level is stable and indoor excess CO2 is usually only from human exhalation, measurements of indoor CO2 concentration by low-cost CO2 sensors can often be good indicators of infection risk and suitable for mass deployment (9, 10).
Nice tutorial on measuring sound levels using the MAX4466. This might be the way to go if we're going to use ambient audio data to determine in-room activity.
Tutorial on using the auto-gain mic, which might be even better ...
This fancy microphone amplifier module is a step above the rest, with built in automatic gain control. The AGC in the amplifier means that nearby 'loud' sounds will be quieted so they don't overwhelm & 'clip' the amplifier, and even quiet, far-away sounds will be amplified. This amplifier is great for when you want to record or detect audio in a setting where levels change and you don't want to have to tweak the amplifier gain all the time.
Design. Using a simple, auto-amplified microphone in this context seems useful. The raw data can be presented online, and used in an attempt to discern baseline thresholds. No algorithm needs to be applied at first; or, the user community can supply the algorithm.
This leads to an instrument in the following Designer PCB configuration:
Total: $72
This can also be accomplished by a more DIY Version:
Total: $98
Likely best to produce this latter version immediately, and then take time, if available, to make the inexpensive version.
Philosophy.
This is an open hardware project in the realm of home-based IOT; a highly-contested area around privacy. In this case, for example, a microphone levels can probably serve a useful proxy for indoor occupancy status. Usually, this would lead to anxieties about privacy. But because we can produce this device in an open hardware manner, we can avoid an entire class of such concerns. (Not all such concerns: there's still the possibility that other surveillance software made it onto the device).
By making this a FOSS/H project, we allow more eyes onto the design to evaluate.
Switch on microphone.
Ability to deploy mic without CO2, if just want to monitor activity levels in an area.
Ability to deploy CO2 without mic, in order to secure privacy.
Listing for product is here.
Schematic is here.
From page 2 of Peng 2020:
If there are no other significant CO2 sources/sinks (e.g., gas/coal stove and pets/plants), i.e., if indoor excess CO2 (relative to the background outdoor level) production is only due to human exhalation and its loss is ventilation, similar quantities for CO2 can be expressed as follows (see Materials and Methods for the derivation)
Gas stove or pets can be a source; plants can be a sink.
Indeed, looks like I may have seen this effect using a propane stove on Nov 24 2020, as per experiment above.
24 NOV 2020 Update @ 14:30
CO2 (PPM). Note: made lunch around noon on Nov 24 (gas stove). Left house around 12:30 / 12:45 on Nov 24. |
MAX9814 Auto-gain audio board from Adafruit. |
MAX4466 adjustible audio board from Adafruit. |
2020 NOV 24 Update 22:10
Arrived back home at 5:30 PM Nov 24th. Interesting that the ambient CO2 decreased in our absence to a value lower than overnight in the apartment with us sleeping there. |
2020 NOV 25
2020-11-27 17:20:40
Snapshot from the Bayou feed. Left house around 9 AM on Nov 26th. Visitors likely in house, late morning of Nov 27th. Returned home a little before 5 PM, and started using gas stove. |
Vishay light sensor here.
Simple, cheap analog light sensor breakout here.
BH1750 here,seemed to be recommended for ambient light sensing ... but difficult to solder. Note though that this seems widely available on Amazon as breakout boards. This description also indicates that it's a good candidate for this application; and in fact, the leads don't look too small.
MEMS mic from Adafruit, the SPW2430
Looks like: use the electret verison for the DIY solderable verison; use the SPW2430 or similar for custom PCB.
Nice post on comparing MEMS and Electret microphones.
Tutorial on measuring sound levels with the MAX4466 by Adafruit here.
2020-11-27 20:18:07
Microphones:
Light sensors:
REV_B appears to work!
Now testing microphone ...
Connecting analog out of mic to A0 on REV_B (one of the button pins) ...
Running overnight on Nov 27th with mic sampling of 10 sec ...
Test code is [here](
Data will appear here.
2020-11-28 04:22:39
My impression is that this mic will require additional signal conditioning to pick up ambient noise; perhaps this can be done with an op-amp and a potentiometer that allows experimentation; or maybe a light sensor is the best next step. Or maybe auto-gain is best, the idea being that it will attempt to acquire any signal. That said, I'd think that 'max gain' on this system would do the trick, if that would work. All depends on the circuit and the mic.
Data from the Bayou feed, overnight Nov 27th -- Nov 28th in CSV format has a snapshot here. This analysis is necessary because the current graphical display in Bayou is configured to who only every 10th data point; we'd like to see the higher-density data.
Snapshot of mic data from the Bayou feed. Woke up at 5 AM. Note that pattern of sampling shown is a bit odd. Need to dive back in an look at how data is captured and how it should be averaged. |
Higher sampling rate of mic data from the Bayou feed. Working to convert this to proper dates (see below) ... |
Formula for converting unix timestamp to date in Excel / Sheets is discussed here; if the timestamp is in cell 'A1', the formula for the date is:
=(((A1/60)/60/24)+DATE(1970,1,1)
CO2 and Mic data from the Bayou feed. Microphone data is "highest p-p amplitude over 10 sec interval". Note -- entered room with sensor around 4:30 AM. Generally mic data seems to precipitate rise in CO2 level. At some point gas stove was used; from this data, I would surmise around 6:40 AM, but unsure. Need to track this next round. |
115 x 90 x 55mm for $10 w/ transparent screw cover here.
Popular 200 x120 x56 mm for $15 w/ transparent screw cover here
5.9 x 3.9 x 2.8inch w latching cover here
Would be nice to have 'wings' for mounting ...
This one has wings, here.
In fact, seems to be part of a pretty standard and well-rated series, here
In particular, the 4.5"x3.3"x1.4"(115x85x35mm) size looks good, for $10. But: maybe too flat to drill holes for cables. And will require fairly large PCB.
From comments, the comparison is between Awclub and LeMotech on Amazon, favoring LeMotech for quality. Likely to find some analysis of sizes and design in hobby projects online (or better: datasheets) given how popular the brands are.
Plan: first assess how large the project will likely be by laying out some PCBs, and order an enclosure.
Review of best projecte enclosures here
Apparently the 'wings' I'm referring to are termed 'ears'.
E.g.: for the 4.5 x 3.5 x 2.68 inch(115 x 90 x 68 mm) 'ear' Lemotech version, the PCB is essentially 84 mm by 89 mm.
This might be a good case size to shoot for. I think I can accommodate it. A larger PCB might be expensive, anyway.
Datasheet for this enclosure is here.
Need to accommodate a USB cable.
Alright: let's lay out a PCB for testing, and if it looks plausible, order one of these.
Note that the 6.2"x3.5"x1.8" version of LeMotech has a nice drawing by a user. Also has same price as smallest version.
Suggestion to make panel mounting oneself.
This is in keeping with previous ideas.
From what I can tell online, the most effective & inexpensive / adaptable approach to enclosures might be:
The reason given online for this is that the inexpensive enclosures are often made from 'recycled molds' that have poor tolerances. So it really isn't a great idea to design a custom PCB for them. Rather, lasercut inexpensive (ideally, drillable, as backup) mounting plates.
Outside Size (approx.): 6.2"x3.5"x1.8"(158mmx90mmx46mm)/(LWH); Inner size (approx.): 5.9"x3.3"x1.6"(151mmx84mmx42mm)/(LWH)- - (Allowable Error: 2mm); Screw Thread Size: M4
Lemotech enclosure, 6.2 x 3.5 x 1.8 inch (158 x 90 x 46 mm). |
Customer-provided CAD drawings for Lemotech enclosure, 6.2 x 3.5 x 1.8 inch (158 x 90 x 46 mm). |
Outside Size (approx.): 4.5"x3.5"x2.68"/(115mmx90mmx68mm)(LWH); Inner size (approx.): 4.3"x3.3"x2.44"/(111mmx86mmx62mm) (LWH)- -(Allowable Error: 2mm); Screw Thread Dia.: 4mm/0.16"
Lemotech enclosure, 4.5"x3.5"x2.68"/(115mmx90mmx68mm). |
2020-11-28 15:37:00
Overall framing / todos.
2020-11-29 21:52:45
Jupyter dashboard via voila -- gallery of examples
gesis notebooks, here
guide to voila, here
Dashboarding options in Jupyter discussed here
2020-12-01 13:41:41
2020-12-01 16:17:24
Continuing research for REV_D ...
Some changes that need to be made to the circuit:
Misjudged the header spaceings on the Heltec -- too far apart by one row!
MMBT2222 NPN Mosfet datasheet -- it's 'BEC' -- 1: BASE, 2: EMITTER, 3: COLLECTOR
Adafruit guide to BMP388 is here.
Breakout schematic:
2020-12-01 20:45:59
2020-12-02 20:41:42
Upshot -- the SPW2430 mic is weak w/out an amplifier -- should check out tutorial for how to add it when doing SMT version ...
Meanwhile, light sensor BH1750 tutorial is here
Install hp_BH1750 library via Arduino IDE ...
firmware that adds the light sensor is here
Resultant data feed here
For reference, Eagle CAD for max4466 is here -- can likely use the amp setup they have ...
2020-12-03 08:25:40
co2 sensor seems to have stopped last night? and reset on m0 didn't reset it -- needed to power cycle -- do we need a mosfet on it?
if we use esp32 for mic, do we need to worry about analog performance / drift?
Should SEL be floating to ground (or tied to ground) on SCD30? https://forum.sparkfun.com/viewtopic.php?t=48325
issue where bh1750 library hangs here.
tried co2 + bh1750 -- co2 freezes
can't reset, co2 still 'frozen'
changed firmware to remove bh1750, but kept bh1750 on board, co2 freezes
then removed wires of bh1750, no freezing yet
I wonder if it's an 'address' issue with the bh1750? can check. info on the module i'm using is here
BUT: light sensor is of questionable use for now. better perhaps to have breakout for i2c.
real next steps:
Seems like the max4466 board avail on amazon (here) is fairly identical to that sold by Adafruit. wonder if the op-amp is similarly set up.
So, design:
i like how explicit the mic on the co2 sensor is ... and it's an analog reading -- if it's removed, just get 'zero' for analog measurement.
that might be the place to start. simplify the design. part is avail on amazon, alternative to adafruit.
don't even need a switch -- just remove the part.
Nice feature: basic board that can be produced with SMT parts; then, add adafruit boards for pressure and/or mic as one likes.
Tutorial on Adafruit here.
Actually, confusing way to do the i2c / spi ... not sure how to hook up to Feather's i2c ...
Shifting to Sparkfun library here ....
which leads to the library here
Nice feature: allows for use with ESP32, has special code for that ... (maybe just picks particular pins?)
2020-12-03 10:10:13
Looks like BMP388 code is working (using the lib from MartinL1, 'BMP388_DEV', here).
Also: having the device on a Feather LoRa, using a gateway, is a nice system -- can deploy several all over a building, or across a campus, even if no wifi available.
University systems have issues using wifi. This way, can use where there is wifi. Also: get one device registered on wifi network, rather than several. (Typically, for IT on campus, would need to register every one).
Also note: might be useful to have a PC with a heltec and a python script. That way the PC can be registered on the network, the heltec can be placed at a height.
Also: might be good to have a microsd on the heltec.
Need to test soon in a university / high school class setting.
Can we get serial input to a chromebook this way?
2020-12-03 15:58:47
Features to add:
Another reason to do esp32 + rfm95 is to allow for access point configuration of device
2020-12-04 22:21:45
Red is mic data, blue is CO2. Spreadsheet is here, based on feed here (pulled on eve of Dec 4). |
2020-12-06 09:54:24
All systems go!
Feather ESP32 scd30 code for "rev_b" is here
SSD1306 with the u8x8 library tutorial here
List of u8x8 fonts here
Arduino code for heltec-based "rev_c" with bmp388 is here
Adafruit tutorial on Max4466
2020-12-06 14:42:04
Fixed the microphone issue with the Feather ESP32 -- seems to be necessary to refer to A0 by its gpio number for feather esp32 -- i.e., "26" for A0.
Updated code for REV_B Feather ESP32 is here
Posting data from REV_B with Feather esp32 ('wifi sensor' mode) here.
2020-12-06 15:08:54
Parallel tests:
REV_C board (heltec) feed here
REV_B board (with Feather ESP32) feed here
2020-12-06 19:05:45
Jupyter plotting csv file tutorial here
Another nice guide here
plotting two data traces on the same graph:
ax = df1.plot()
df2.plot(ax=ax)
2020-12-06 20:02:10
Procedure: Sensors were placed side-by-side. No effort was made to calibrate manually. They had been operating for only a few seconds before data was collected; so the automatic calibration algorithm (which begins at 7 days) had not been in operation. Next attempt will involve manually calibrating both in same fresh air conditions, and looking at resulting behavior.
Using two SCD30 sensors, side-by-side. Left: "REV_C" board using Heltec 32 Wifi LoRa v2 as micro. Right: "REV_B" board using Feather ESP32 as micro. |
Comparison of two side-by-side SCD30 CO2 sensors for a given time range. Jupyter notebook used in the analysis is here. |
Tweet about aerosol transmission here.
Sparkfun SCD30 library is here, and has several relevant examples:
See 1.3.7 (p. 7) of document:
For implementation, look at Sparkfun library and follow procedure for temperature / altitude compensation.
E.g. altitude compensation code begins here
//Set the altitude compenstation. See 1.3.9.
bool SCD30::setAltitudeCompensation(uint16_t altitude)
{
return sendCommand(COMMAND_SET_ALTITUDE_COMPENSATION, altitude);
}
Can we set this up with a button? Would be nice if it works mid-loop ... test with ESP32?
ESP32 GPIO interrupts guide here
Fork of Sparkfun library here
Experimental feed is here
Update: the library already includes the functionality!
setForcedRecalibrationFactor(int co2_concentration_ppm)
the 'calibrate' button on rev_c is pin 36
ESP32 debouncing a button w/ interrupts, here
The ultimate debouncer from Hackaday
Following debounce here
2020-12-06 21:37:07
Meanwhile, verify that the forced calibration works. Expectation: if we do it after a few loops, the current CO2 value will suddenly appear to be whatever we force it to be.
Force calibrate seems to work!
Code (still working out a button debounce routine) here
overnight feeds as of 2020-12-06 22:13:47:
2020-12-07 09:35:29
2020-12-07 10:23:27
Further reading on temperature / other compensation for the SCD30, "Low Power Mode for the SCD30"
Observation: when force calibrating the sensor outdoors in much lower temperature and assuming 410 ppm, it recovered inside to < 400 ppm. This may be because of temperature effects. There is a temperature compensation function for the sensor. It requires an external temperature reading for calibration. This might be done with a 1-wire temp sensor attached to the device.
So, advantages of the pvos device:
2020-12-07 10:37:03
Blog on use of SCD30 here
TODO: need to find field calibration guide for SCD30.
I believe the airflow isolation issue is the reason for seeing such strong fluctuations of measurements when outdoors in wind, and is a strong argument for designing an enclosure:
2020-12-07 11:53:18
Resurrecting the React code ...
React sparkines library here
How to trigger a popup in Leaflet, here
Stack overflow for interacting with leaflet in React here -- with associated fiddle
pswoodworth's code for poll / leaflet
Using Leaflet for non-map images
Nice tutorial on using leaflet to zoom into images -- has some nice tiling programs!
Using leaflet to pan and zoom a big image
Based on: "using leaflet with non-geographical imagery" tutorial.
Code in 'trial.html' here
leaflet map in a flexbox layout here
See 'side.html' here:
Leaflet guide to non-geographic maps here
Using CRS in React-Leaflet here
Example with imageoverlay and react-leaflet here
Note: "reg-leaf" branch of spark-leaf repo is a working example.
Jamming on inserting code from here into my current setup
hmm, this approach seems simple here
support for non-geographical maps here
2020-12-07 21:23:59
'clicknav' is a working branch.
fetching data in react using hooks here
another article here
much nicer guide here
working with 'livedata' branch of spark-map currently ...
using react and fetch here
2020-12-08 10:58:47
nice leaflet grid layer code for displaying lat / long here
Nice leaflet grid layer here
2020-12-08 12:39:52
running p2p-farm-server locally, branch: 'mappin'
http://localhost:3050/drives/94dc05a75bc3ac9b064cbe1c2ae3264e96ca753ff05aef28303d1c5b752a1f4b/console
reference putscript_local.sh for the appropriate keys and to add more data
SVG sparklines here
keeping popups open in leaflet here
intro to leaflet here
add and remove leaflet circle on click here
assigning ids to markers in leaflet here
adding horizontal lines in chartjs here
above is 'mappin' branch of p2p-farm-server on gitlab
2020-12-09 17:39:11
modfiying leaflet icon on mouseover here
nice working example of buttons and overlap and highlighting here.
https://www.providencejournal.com/story/news/coronavirus/2020/08/14/umass-professor-expands-on-risks-of-covid-19-and-how-to-avoid-them-in-schools/113968580/
https://twitter.com/ErinBromage
https://twitter.com/ErinBromage/status/1336769111922241539
great writings collected here: https://twitter.com/JuliaLMarcus
battery-powered datalogging, for use on e.g. planes? export to csv ...
2020-12-10 11:08:32
Link here
Key organizing tweet by Jose-Luis Jimenez, here and here. Jimenez group here.
Jimenez group listing here
Aranet4 listing here
Article covering Jimenez int'l org around air quality and covid here
Online presentation here
2020-12-10 13:42:11
note on next steps:
2020-12-10 17:44:16
Note on experimental setup. Code is set up to broadcast every 90 seconds; on third round, it force calibrates to 410 ppm; there is a parameter named 'forced' that is '0' initially and then '1' after forced calibration. Both devices were reset simultaneously, hopefully they will be relatively in sync when force calibrated. need to check difference.
Update: no, better to force calibrate in beginning. Send value right after force calibration, then reset to 0.
2020-12-10 20:21:52
2020-12-10 22:03:01
Note that the orange line is the FeatherESP2, and tracking the 'forced' parameter indicates that the device rebooted and then re-force calibrated to 410 ppm. Not sure why it rebooted -- perhaps the power supply on the Feather is insufficient to handle the SCD30, or the memory? Note that the readings were more variable for the Feather prior to the reboot.
2020-12-10 22:12:26
Added legend, and the 'forced' parameter, to make it all more explicit. Here, the red line is the Feather32 data, the blue is the Heltec. The accompanying 'forced' data are shown, multiplied and shifted to show on scale.
New experiment: restart code, but swap the SCD30 modules.
2020-12-10 22:18:31
Update: swapped the scd30. heltec didn't start up at first. realized that i placed the scd30, was shorting something. so there may be some odd data out of the heltec now. if there was something wrong with the scd30 module associated with the feather, it's on the heltec now.
Note -- if this immediate divergence is 'real', it could indicate that small variations in air flow are very important / and/or that one oughtn't to worry about fluctuations on order of approx 50 ppm.
Reasons it might not be 'real' -- one of the sensors is underpowered b/c of a different micro ... the scd30 sampling rate is too high, or we're force calibrating too soon ... others?
2020-12-10 22:45:58
Ah -- after careful readjustment inside enclosure, looks like they did coincide more closely (or could be fluke) on restart (last restart / force calibration before the '80000' mark.) Will now monitor to see whether one of the devices exhibits odd behavior.
Now that I've switched scd30 modules ... if the data from the Feather32 still exhibits odd behavior, then my guess would be that the problem is the power supply / memory of the Feather32. If the data from the heltec exhibits odd behavior, then the problem may lie with that particular scd30 module.
2020-12-10 22:53:13
Last two resets are after readjusted enclosure.
2020-12-11 06:14:27
Results from overnight, after initial force calibration on both sensors (as per above description):
Systematic difference (red climbs faster) is perhaps due to placement in box / closer to airflow opening.
Plot of difference between the two traces above:
SCD30 Field Calibration Guide here
Effects of forced recalibration (from guide):
Effects of automatic calibration (from guide):
2020-12-11 08:03:52
Updated scd30 comparison:
Differences:
2020-12-11 09:25:16
Notebook for above analysis is here
2020-12-11 13:54:30
2020-12-11 22:33:39
p2p-farm-server/public/console.html is the latest code connected to the p2p-farm-server, which does floorplan side by side with the charts.
the route to visit is here.
It's determined in p2p-farm-server/routes/index.js
meanwhile, the code that connects buttons and highlights leaflet markers is here.
2020-12-12 10:50:11
Video of attempt at interactive code here, and below:
Relevant code is in 'console.html', here; the routes portion of the server that handles that page is index.js, here.
Note: was able to resolve CORS errors when prototyping locally by simply referencing the '0.0.0.0' address rather than 'localhost'.
Inspirational map flood network viz here (link to actual viz seems to be broken).
2020-12-12 14:04:25
Adafruit max4466 is here.
Typical Amazon cheaper product is here
Dimensions of board seem to be about (width x height) (15 mm x 22 mm).
listed on adafruit here. "JST SH 4-pin" -- 'micro' / 'vertical' version.
amazon listing here
For now: break out A0 and A1 pins to do the button measurement separately on a breakout if need be (to externalize the control, avoid interacting with scd30).
Aside: nice neobit project
micro li-ion board on Amazon here -- 'jst 1.25 connector 2 pin'
Size: 8.52540(mm)
2020-12-13 09:55:51
mini pushbutton switch -- tall via sparkfun
10 mm tall.
How tall is a typical header?
Assortment of pushbuttons here
Omron B3F datasheet here
need to swap out 'dual' switch for a single ..
Discussion here
Connectors_JST:JST_SH_SM04B-SRSS-TB_04x1.00mm_Angled
Redo for easier hand soldering?
2020-12-14 13:27:09
Datasheet for smaller enclosure is here
2020-12-14 21:52:32
Github repo for REV_E is here
Zipped Gerber files for REV_E are here
2020-12-19 08:07:40
JST SH 4 pin micro -- vertical, here
horizontal (as placed on rev_e) here
or as listed on sparkfun (horizontal) here
2020-12-19 13:18:40
adafruit uFL connector here
looking at feather m0 lora pcb for uFL connector reference here
BMP3XX adafruit firmware on github here
BMP3XX adafruit hardware design files on github here
BMP390 datasheet here
Adafruit BMP390 schematic:
BMP388 datasheet here
Adafruit BMP388 schematic:
Question: do we need to add a power supply to board? Seems to be a common way of keeping the power supply clean for the pressure sensor chip.
Reference: here
Looks like we should add a regulator. Default to using the Adafruit part, change if something else seems better.
Adafruit uses AP2112K-3.3 for the BMP390 breakout (more recent breakout). This also seems to be used for the feather.
Look to see if it's also used for the Feather ESP32 -- and what its specs are -- if it can source sufficient current for the full CO2 board (which are ...?)
Q:
AP2112K-3.3 on Digikey and associated datasheet
Looks like it can provide 600 mA.
max input 6V
Assume SOT-23-5 package on Adafruit
Also add MCP73831.
Feather M0 MCP7831:
Do FTDI board separately? yes b/c DTR might be needed
TODO: Need also to break out the reset and other button, in case ftdi cable someone uses doesn't expose dtr ...
Buttons -- use SW_Push symbol ... with which SMT buttons? use adafruits?
these are the KMR2 buttons from the Feather and etc. datasheet is here
look to see how adafruit did it with the huzzah board
Ah, there we go -- GPIO0 is floating:
TODO: add the side-mounted through-hole buttons that ordered on Amazon, and that were present on REV_E
Add connectors for micro and reg lithium ion? Might be nice for folks used the world of feathers.
Using standard Adafruit one (2-pin JST PH)
as well as a micro one -- JST SH -- SM02B-SRSS-TB(LF)(SN) -- digikey link here
this would simplify things.
Q: Possible to solder? Look at Feather ESP32 schematic / footprint.
Maybe this is a separate project -- make an ftdi header board.
Need to decide on nice microUSB footprint. SMT would be nice, and fine for this context -- don't need through-hole. feather esp32 part should be fine. see if you can source them on digikey (or which smt parts are easy to source).
Adafruit microUSB part is the 4UConn 20329 v2, datasheet here
Link to Adafruit microUSB part here
MicroUSB B with KiCad footprints:
the microUSB device used on the riffle is here; datasheet is here
above left: 10104110; above right: 10104111
some optoins for footprints in kicad:
A recommended Amphenol part is here
TODO Need to add caps from all relevant sub-circuits:
Possible to add footprint for USB chip and allow FTDI?
Adafruit Feather ESP32 eagle files on github
Feather ESP32 schematic:
CP2104 subcircuit:
the microSD card used on the Riffle 0.1.8 is here
2020-12-19 19:00:53
TODO: double check pin order on JST connectors ...
DMG3415U p-mosfet used in power circuit for Feather ESP32 here; datasheet; SOT23;
to check orientation / pin assign for the pmos as part of the power circuit, here's what we see on the feather esp32:
Diode -- MBR120 -- SOD-123FL -- datasheet
Note: used KiCAD 123F rather than 123FL
now I have all of them avail. seems like sod 123FL is the most pop part on digikey. but 123 and 123FL are avail. see here
2020-12-19 20:37:04
latest updates to board design ("REV_D") are here
note: need to review and see if there are any remaining changes.
might try to place a microSD on the board and guess at a CS pin; but also break out SPI + optional CS pins. If SPI conflict, might be able to start by only doing LoRa (SPI) OR microSD (SPI) on bus in any given firmware.
TODO:
if add a smt mic, add a switch otherwise: maybe just make it an optional DIP add-on ...
2020-12-20 08:21:38
rather than replicate the mosfet on the power supply, maybe just have one at the intake?
alright -- emulate feather 32 instead of heltec. we know that the circuit works, and it's the same esp32 module, with same pins avail.
iterate to fancier version of batt meas circuit.
check against tinypico for power circuit
nice reference for esp32 pinouts and which pins to use here
default spi pins on esp32 for lora here
Hog 32 schematic:
using the arduino ide + esp32 + sd card here
update: heltec uses gpio5 for lora sck; feather esp32 uses gpio5 for sck; so that's fine. default to using feather esp32 pinouts.
pins 34,35,36,39 are input only. use these on buttons.
ref for using sd card featherwing with feather esp32 here -- cs is on gpio33
nice reference here
(mimic in rev_d)
Reference here
TODO: Look into changing footprint ...
2020-12-22 09:41:59
for low power tests -- look up tinypico schematic
schematic here
and in our own repo here
key part is the power subcircuit:
This is the regulator they are using on the board here
and this is the mosfet here
analysis: looks like we've got essentially an identical circuit; they make a different choice of mosfet, but we can probably dial that in easily ....
2020-12-22 10:00:06
battery voltage meas reference on jeenode here
TODO: check reset subcircuit -- match feather
2020-12-24 05:04:43
Test of the co2 board "rev_e"!
Used firmware here
bayou data feed is here
2020-12-27 08:57:35
Enclosure arriving today linked to on Amazon here
example enclosure from pac-tec here
free samples here
the OD43 looks good here; drawing here
2020-12-27 15:55:50
Update: small enclsoure arrived. The shape is a bit awkward, and it was anyway broken. If going with plastic enclosure, might be better to find another / a specific manufacturer.
Rev_f was an attempt to re-spin rev_e in order to fit inside New idea: 3d print a nice enclosure, and then also design a cardboard one. Run them side-by-side for a few days to see any differences. Humidity might be a factor; but can line inside with tape, and humidity is supposedly compensated for.
2020-12-27 20:24:24
openscad ...
designing a box with openscad
3d printed enclosures with openscad here
2020-12-28 07:28:38
Test of REV_E system starting here
UPDATE: Looks like it never really went above initial baseline (which started around 8:10 AM on below graph):
Aside: nice info on openscad shapes / language here
2020-12-28 11:52:02
Description of process of making an enclosure for Rev_E (kicad board files for RevE) in the below video:
The associated scad file for this video is:
Some additional files / information:
Dimensions for PVOS CO2 Rev_E (KiCAD board files are here. |
OpenSCAD rendering of an enclosure protype. Scad file is here. |
STL file for cover is here. |
STL file for bottom is here. |
Separately rendered cover and bottom are here:
2020-12-28 19:52:34
Craig has now revamped the scad file considerably, allowing everything to be measured in 'pcb coordinates' much more readily.
Latest branch is "ver1d_holes", and the associated scad file is here.
Latest version ("ver1d") of OpenSCAD enclosure. |
2020-12-28 20:34:24
Meanwhile, working on box enclosure:
Latest version 'box enclosure template' for REV_E. Scad file is here |
2020-12-29 10:59:16
2020-12-29 13:53:04
latest file with holes for screen, mic, buttons is here -- still need to add USB and lora holes
maybe should make cover a bit narrower to accomodate the bend ends ?
2020-12-29 16:59:44
2020-12-29 20:13:52
File is here (note that it's in the 'cardboard' branch)
File is here.
2020-12-30 14:16:53
The current design worked out better with a thinner cardboard box from Amazon, that has 'A3' and 'FLX' printed prominently on it, and which also had some graphics printed on it. Saving that as "a3_flx.scad" in the 'cardboard' branc.
Going to try also to optimize for the thicker (but I think more standard) Amazon box that has "Z12" and "120" printed on it, saving as 'z12_120.scad'.
2020-12-30 14:55:05
Set up 'router-style' connection on rev_e ...
'heltec_router.ino' ...
2020-12-30 15:03:18
TODO: check button status on rev_e -- is "A" connected to LED pin?
Basic button check ...
Buttons check out. Pin "A" is gpio37, Pin "B" is gpio36.
Todo!
Nice tutorial here
Ahh -- this is the code I'd found that worked nicely -- from hieromon, here.
Arduino WiFi module description here
captive portal here
wifimanager for esp32 here
or maybe better library https://diyprojects.io/esp32-test-wifimanager-library-manage-wifi-connections/#.X-99TnVKjVM
this seems powerful -- not sure how to use though!
https://github.com/warmcat/lws-esp32-factory
https://github.com/tonyp7/esp32-wifi-manager/ looks like a great option
back to trying https://diyprojects.io/esp32-test-wifimanager-library-manage-wifi-connections/#.X--CfHVKjVM
documentation for wifi manager here
note: seems that we want the 'development' branch of wifimanger for esp32 -- as per instructions here
tutorial on using wifimanager (with esp8266, but should work here) -- https://diyprojects.io/esp32-test-wifimanager-library-manage-wifi-connections/#.X--CfHVKjVM
2021-01-01 15:48:48
OKAY! working wifi configuration (basic) at https://github.com/edgecollective/co2-remote-and-gateway/tree/rev_e_wifi_config/rev_e/firmware/wifi_sensor/wifi_config_basic_scd30
2021-01-01 18:13:05
migrating from arduinojson5 to 6 article here
2021-01-01 19:17:36
okay, current candidates are: wifimanager (dev branch), and hieromon.
latest attempt at getting it to work (which req'd upgrading the ArduinoJSON code) was here: AutoConnectWithFSParameters_bayou
customization on wifimanager looks a bit hairy.
l
hieromon might work better re: customization.
trying more with hieromon now ...
for autoconnect, looks like we want to consider autoreconnect to determine behavior if device needs to connect to wifi again. link here: https://hieromon.github.io/AutoConnect/adconnection.html
2021-01-01 19:49:31
Here's a thread on how to delete credentials --
https://github.com/Hieromon/AutoConnect/issues/175
2021-01-01 20:31:46
This code is working fairly nicely!
Document this tomorrow first thing.
It displays the AP to visit, then once connected, displays the IP.
Need to collect custom paramters ...
2021-01-02 10:45:37
autocnnect wifi connect sending to bayou -- sort of an mvp -- https://github.com/edgecollective/co2-remote-and-gateway/tree/rev_e_wifi_config/rev_e/firmware/wifi_sensor/AutoConnect_Elements_display_scd30
2021-01-02 11:16:49
basic landing page functionality here: https://github.com/edgecollective/co2-remote-and-gateway/tree/rev_e_wifi_config/rev_e/firmware/wifi_sensor/AutoConnect_Elements_display_scd30_landing_page
2021-01-02 12:26:43
Getting data form AutoConnect -- https://hieromon.github.io/AutoConnect/achandling.html
2021-01-02 13:40:42
use of snprintf: https://joequery.me/code/snprintf-c/
2021-01-02 14:45:33
A nice basic MVP, here:
It allows for configuring wifi. The Bayou credentials are set via 'credentials.h' (requires Arduino IDE). There's an informative landing page.
This would work for a version where the Bayou feed is flashed before the device is shipped, or by the user.
For a user-config version, a nice starting point might be the code here:
... where one might use the '/elements' page to capture Bayou feed credentials (and maybe set the measurement interval).
TODO: set the measurement interval in the config file.
Some more todos:
Initial rollout:
Does the SMT need to be part of the rollout?
Add an opencollective tier for:
2021-01-02 18:35:56
u8x8 fonts here: https://github.com/olikraus/u8g2/wiki/fntlist8x8
2021-01-02 19:17:19
Two button interface video demo here
NOTE: LED D1 doesn't seem to work -- perhaps value of resistor?
2021-01-02 21:01:25
Idea: measure every X seconds; average these values; PUT every Y*X seconds so that the PUT interval is 5 or 10 min or more. The averaging will help smooth out the noise. Every measurement, can blink the LED (optionally) and update the screen. Indicate on screen when have sent data online.
Also: can embed videos & other 'heavy' material in the ESP32 landing page by pulling it from online such that it only shows up once there's an internet connection to the outside world ...
2021-01-03 10:54:43
cap_params seems to work alright ...
working on cap_params_load ...
retrieving files from SPIFFS -- https://techexplorations.com/blog/esp32/blog-esp32-how-to-retrieve-a-file-from-the-spiffs/
2021-01-03 11:55:47
arduinojson read file -- https://arduinojson.org/v6/example/config/
arduinojson read array -- https://arduinojson.org/v6/api/jsonarray/
SPIFFS read and write examples https://www.esp8266.com/viewtopic.php?f=29&t=8194
this is how i want to reference an element of the array i think https://arduinojson.org/v6/api/jsonarray/subscript/
2021-01-03 13:12:57
Okay, this version of the code uses a file, elements.json, on the SPIFFS filesystem of the esp32 to configure things; and it can be modified by the esp32 as well.
2021-01-03 13:29:44
Getting closer to capturing parameters data:
2021-01-03 16:51:47
params_fuller_FS is where it's at!
warning regarding dynamic memory usage in micros here: https://arduino.stackexchange.com/questions/1013/how-do-i-split-an-incoming-string
2021-01-03 19:02:50
This is getting really close now:
Need to get it to make some measurements; but basic interface seems to be in place now.
2021-01-04 08:52:08
setting the AutConnect menu items https://hieromon.github.io/AutoConnect/apiconfig.html#menuitems
Captive portal IP address if captive doesn't work: 192.168.10.1
configuration of autoconnect portal here
customizing menu further here
IDEA: be able to modify 'force calibrate co2 value' from AutoConnect
this is what I ended up using to customize the menu
resulting in this commit for param_fuller_FS
TODO:
combine cap_params_load code (measuring CO2) into params_fuller_FS
change /mqqt endpoint settings to e.g. 'data'
force calibration setting in autconnect
mic on/off in autoconnect
average co2 readings
use pressure values to compensate for co2
redesign through-hole board to match existing case on amazon
look at specs on amazon case
redesign SMT board -- with advantages (longer on battery, say, lower cost to produce)
2021-01-04 13:30:08
enclosure
free enclosure from pac-tec:
interesting free enclosure option:
PCB size (from design drawing above):
Some nice options
https://www.digikey.com/en/products/detail/serpac/032CBK/2286005
Serpac 032C
detachable wall mount! https://www.serpac.com/accessories/wall-mounts.aspx
https://serpac.com/wm-series/wm072rc.aspx
This could actually be cool -- 'main board' on left, 'proto board' on right
--- but it's $20 :)
https://www.digikey.com/en/products/detail/serpac/232CBK/2286017
hammond tiny enclosure -- https://vetco.net/products/hammond-1551ltbu-translucent-blue-plastic-enclosure-3-15-in-x-1-58-in-x-0-59-in?gclid=Cj0KCQiAlsv_BRDtARIsAHMGVSbv12vGAESWYlcDZyyMR1AF3k45esmKYOVDSHDajJhLA6uLqX9A1j0aAqqiEALw_wcB
octopart enclosure listing here
bud industries BT-2723 here
hammond 1551LTBU here
multipurpose translucent hammond boxes here
accessory plastic flanges avail!!
hammond 1591S --
hammond economical enclosures here
hammond 1591STCL on digikey here
really cool series, with accessories! here
allows mounting of pc boards horizontally within enclosure here
shenzen enclosure here
this is worth ordering for testing -- enclosures for $4 ea here -- https://www.alibaba.com/product-detail/IP65-plastic-transparent-electronic-enclosure_60787051803.html
top candidates:
hammond 1591STCL / 1591BTCL serpac 032C
listing for that whole hammond line is here
avail on amazon!! here
1591BTCL avail via amazon here
1591BTCL datasheet is here
hammond page for 1591btcl is here
the whole 1591 series is listed here
1591BTCL is avail for $5.10 ea at Hawk Electronics here
1591STCL here
1591DTCL -- would fit the REV_E board!
meanwhile I think I can probably redesign and fit the 1591STCL or 1591BTCL (whichever is cheaper)
1591STCL -- $10.50 1591BTCL -- $7.80 1591DTCL -- $12.02
conclusion:
1591BTCL (datasheet) -- this is the target to design for.
1591DTCL (datasheet) (octopart) (digikey) -- this is what I can buy to house the REV_E enclosure.
1591DTCL avail via Powell electronics here
DTCL arrives on jan 25 - ish here
If I do the BTCL, I'll need to find a clever way to include the battery ... maybe on top somehow.
--
$10 aluminum enclosure bud insdustries -- https://www.digikey.com/en/products/detail/bud-industries/AN-1302-A/5804534?utm_adgroup=Boxes&utm_source=google&utm_medium=cpc&utm_campaign=Shopping_Boxes%2C%20Enclosures%2C%20Racks&utm_term=&utm_content=Boxes&gclid=Cj0KCQiAlsv_BRDtARIsAHMGVSZDrdL__T4EZEguqhJTtaaFs6oxlLmh0ItZ9ZZeMTFqdDHsmJ5U4goaAiZJEALw_wcB
1591STCL here
2021-01-04 22:12:14
accessory flanges for 1591 series here --
digikey listing for the flange for the 1591DTCL here
1591BSFLBK on newark here
adapter card pcb for 1591 series:
1591DTCL enclosure diagram here
associated slot pcb mountings diagram here
associated plastic flanges listed here
Likely should order some on Digikey tomorrow.
Interesting that it gives us some room for prototyping
Epidemiologist around rapid testing here
TODO: add the flange to the digikey order and order tomorrow
flange for the DTCL seems to be the 1591FDBK (digikey drawing)
Aside: gorgeous hammond enclosure 1590B die-cast aluminum (amazon)
2021-01-05 11:46:04
to get:
update: gray is on backorder. going with black.
2021-01-05 18:37:37
this seems to be key -- how to set up the captive portal IP address -- need to check whether this works on a laptop https://hieromon.github.io/AutoConnect/apiconfig.html#gateway
2021-01-05 19:07:15
Finished the AutoConnect switch-over of endpoint names -- now use 'bayou_settings' instead of 'mqtt_setting'.
Resultant working code is here (note branch): https://github.com/edgecollective/co2-remote-and-gateway/tree/cap_params/rev_e/firmware/wifi_sensor/params_fuller_FS_endpoint
2021-01-06 16:27:47
1591 enclosure guide for pcb here
might use a clear lid with a pre-flanged enclosure -- look here
2021-01-06 16:33:46
Black 'B' enclosure with a flange here
direct link for pc board adapter here
and dimensions for pcb board adapter here
catalog page for 1591 series here
looks here as though the 'C' enclosures come between 'B' and 'D' (surprise) -- hammond
also: C is just slightly larger than B, it seems
here are the C dimensions pdf -- and on amazon and digikey
2021-01-07 11:36:19
Document from Hammond re: the proper PCB size for the 1591B series here: pdf | dxf file | dxf file with dim
heltec dimensions
2021-01-07 14:08:27
https://github.com/edgecollective/co2-remote-and-gateway/tree/cap_params/rev_f/atkins
particular commit here:
2021-01-07 15:07:44
Update: Pin 34-39 on the ESP32 are not capable of output -- that's why pin 39 wasn't working as an LED control.
looks like scd30 could use a 2.5 mm screw, ish; the height of the screw would be about 8 mm. so can guess at a standoff size perhaps.
nice material heltec here
full heltec tech specs here
does look in the schematic that there's a battery divider already in place -- see discussion here
interesting code for heltec from a lot of perspectives re: optimal use of esp32, includes battery measurement here: https://github.com/HelTecAutomation/Heltec_ESP32/blob/master/examples/ESP32/ADC_Read_Voltage/Battery_power/Battery_power.ino
pin 21 is external battery control -- low, ON --
special pins on esp32 here
pin 12 must be low during boot
2021-01-07 20:33:35
PIR sensor here
just need 3V, GND, and an input pin ... maybe add a screw terminal?
"sh1.25" is perhaps the search term for relevant batteries on aliexpress here
2021-01-08 11:54:39
Rev_F board submitted to JLCPCB, order Order #: Y12-2489114A // W202101090100951
board files github commit here
zipped gerber files in particular here
2021-01-12 14:40:22
2021-01-14 12:54:10
2021-01-15 11:25:38
Feed Name: "asdfasdf" Feed Public Key: 9816e2df7cc14d64698d7012859080757780c73f22213bd1 Feed Private Key: 7e633222f381a99170e370ea7476b43662507a5352077ade Feed Home Page: http://data.pvos.org/co2/data/9816e2df7cc14d64698d7012859080757780c73f22213bd1
TODO: add a download from the feed page (CSV?)
2021-01-15 12:26:46
Hammond flanged enclosures here
Main plastic enclosure page for Hammond here
Vented sensor enclosure! here
2021-01-15 21:52:47
Latest firmware attempt is here. Acquires actual CO2 values & uploads them to Bayou-CO2
Test feed on Bayou-CO2 'loft' is at http://data.pvos.org/co2/data/09b3f0239025e03c386b3f3ccfeba5501f95b8eff0ec9358
2021-01-17 05:04:02
Loft test feed continues: http://data.pvos.org/co2/data/09b3f0239025e03c386b3f3ccfeba5501f95b8eff0ec9358
Notes on feed above:
jan 16
jan 17
Note that it seems that when I walk around a bit and go upstairs to loft huffing and puffing, there's an initial spike; the co2 calms down when i start to settle and work at computer quietly. then level decays further when I leave.
UPDATE: after refreshing feed, not sure this is true; the 'spike' isn't that much higher than what is perhaps 'noise'; the CO2 level does seem to be fairly stably higher when I'm up in loft.
Question: I wonder why there's an apparent dip below 'baseline' 6 PM to 830 PM on Jan 16? Maybe the doors to house were open a bit? interesting if we can show that baseline shifts considerably when crack open doors (experiment to be done)
2021-01-17 08:12:24
Just re-entered loft w/ coleman now ...
went back down, then camb back around 8:30 ...
2021-01-18 11:59:52
Working on pulling in parameters ... looks like this is how I did it here:
2021-01-18 12:06:20
Requirements in Arduino IDE for CO2 monitor based on ESP32 ...
IDE setup:
Libraries:
2021-01-18 12:49:59
Test feed here: http://data.pvos.org/co2/data/cbb8d444591def61d4e59f9b53d3193dd7724a9d8599c6ee
2021-01-18 13:54:57
Now reading in parameter file and displaying CO2 value with this commit: https://github.com/p-v-o-s/co2-monitor/commit/39c589e08763c8f280da3e49c05ae70d059a7791
Feed is here: http://data.pvos.org/co2/data/cbb8d444591def61d4e59f9b53d3193dd7724a9d8599c6ee
2021-01-18 14:10:36
Now show network config on button press https://github.com/p-v-o-s/co2-monitor/commit/5f05b084ba1b026370a0f2adb9492b0d187b2205
NOTE: should try to do everything with non-blocking code. This button approach currently delays for 3 sec. Could instead check every loop for whether enough time has passed, and whether should display which info.
TODO: implement this; also factor out display functions.
2021-01-19 04:57:51
Got weird error message -- result seemed to be no wifi connection, but loop still ran and measurement was made / screen updated every measurement interval:
E (52119735) wifi: esf_buf: t=2 l=76 max:32, alloc:32 no eb, TXQ_BLOCK=0
Really useful post on strings and esp32 and memory here
Looks like free heap is okay.
New test feed is here: http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
The current version of the code is here: https://github.com/p-v-o-s/co2-monitor/commit/af6c57182ef2486cf87aedc404f5fca257c330d0.
TODO: Reading in measurement interval from param file initially still not working (fix).
TODO: We should implement a watchdog that looks to see if successful post and/or connection and resets if not -- the error message I was seeing might be related to the wifi, apparently
TODO: Should also change the plotting style in Bayou-CO2 to not use bezier ...
2021-01-19 09:26:43
More TODOS:
ESP32 power req's ...
Observation -- looks like heap stabilizes ...
getFreeHeap(): 250128
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":331,"tempC":22.7,"humidity":23.25,"mic":0,"auxPressure":1008.91,"auxTempC":19.61,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
200
Measurement recorded
getFreeHeap(): 250128
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":328,"tempC":22.52,"humidity":23.64,"mic":0,"auxPressure":1008.86,"auxTempC":19.56,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
200
Measurement recorded
getFreeHeap(): 250128
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":332,"tempC":22.65,"humidity":23.66,"mic":0,"auxPressure":1008.85,"auxTempC":19.59,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
200
Measurement recorded
getFreeHeap(): 250128
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":348,"tempC":22.55,"humidity":24.13,"mic":0,"auxPressure":1008.89,"auxTempC":19.58,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
200
Measurement recorded
2021-01-19 09:34:25
Get calibration code working ...
TODO: add force calibration value to the Bayou settings
TODO: add field to database indicating whether force calibrated in the last round ...
TODO: pull out configuration values as 'config' file (or put in json param file)
2021-01-19 10:40:54
Looks like by default, SCD30 sensor measurement interval is 2 seconds ... and can't go lower.
SCD30 datasheet reference p 10 of https://media.digikey.com/pdf/Data%20Sheets/Sensirion%20PDFs/CD_AN_SCD30_Interface_Description_D1.pdf
Just checked -- in fact, it does work to ask if there is new CO2 data available -- that gives us a delay of about 2 sec.
2021-01-19 10:49:03
Added calibration procedure with this commit: https://github.com/p-v-o-s/co2-monitor/commit/68c467baa1c6b8c20b4b76a5eb5f6a89d55c9508
2021-01-19 10:56:50
Fixed an interface bug with canceling forced calibration ...
Now, after pressing the calibrate button, in any case we drop into a 'firstLoop' meausurement, so that we make a measurement, display it, and send it. Probably a good feature anyway to have a way to send a value immediately. Might want to indicate graphically that data has been sent ("200" on top right of screen or something)
Also looks like the sensor needs at least a few seconds to warm up (check datasheet) ... maybe we should check for startup and display 'warming up' and show measurement every few seconds ..
2021-01-20 05:48:45
Stopped working overnight:
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":383,"tempC":18.98,"humidity":25.85,"mic":0,"auxPressure":1004.71,"auxTempC":19.74,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
[HTTP] GET... failed, error: connection refused
getFreeHeap(): 250108
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":376,"tempC":18.9,"humidity":25.87,"mic":0,"auxPressure":1004.66,"auxTempC":19.57,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
[HTTP] GET... failed, error: connection refused
getFreeHeap(): 250108
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":368,"tempC":19.02,"humidity":25.47,"mic":0,"auxPressure":1004.64,"auxTempC":19.62,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
[HTTP] GET... failed, error: connection refused
getFreeHeap(): 250108
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":363,"tempC":19.18,"humidity":25.34,"mic":0,"auxPressure":1004.58,"auxTempC":19.96,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
[HTTP] GET... failed, error: connection refused
getFreeHeap(): 250108
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":372,"tempC":19,"humidity":25.77,"mic":0,"auxPressure":1004.47,"auxTempC":19.8,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
[HTTP] GET... failed, error: connection refused
getFreeHeap(): 250108
http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
{"private_key":"13adcd2e8704165a62aea86bee0a3abe2fd3be4d62427a35","co2":377,"tempC":18.9,"humidity":25.87,"mic":0,"auxPressure":1004.4,"auxTempC":19.66,"aux001":0,"aux002":0}http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
[HTTP] GET... failed, error: connection refused
-- is this Bayou, or the monitor?
UPDATE: answer -- it wasn't Bayou.
Pressed reset, and it just worked. Need to look into this as a bug; but this is another reason to set up a 'reset' if we don't a good connection to the server.
Ah -- it could be that the IP address changes overnight.
Good thread on watchdog style approach here: https://github.com/espressif/arduino-esp32/issues/653
More on this here: https://github.com/Hieromon/AutoConnect/issues/292
This might be the approach to take: https://github.com/Hieromon/AutoConnect/issues/292#issuecomment-757340418.
Skeleton code here: https://github.com/Hieromon/AutoConnect/issues/292#issuecomment-756634645
There is a patched release here: https://github.com/Hieromon/AutoConnect/issues/292#issuecomment-759202689 that might address the issue, and apparently release v1.2.3 will fix it?
Another nice post about dropping the wifi here: https://rntlab.com/question/wifi-connection-drops-auto-reconnect/
oooh -- and it offers some auto-restart code ... will try that ...
implemented in the 'restart' branch here: https://github.com/p-v-o-s/co2-monitor/tree/restart/co2monitor
2021-01-20 10:47:23
CORS and associated issues explained here
2021-01-20 11:00:02
Ideas discussed w/ Mike:
Bayou / deployment ideas:
Firmware ideas:
Hardware ideas:
Documentation:
2021-01-20 11:08:20
How to upload and display an image in NodeJS here: https://stackoverflow.com/questions/15772394/how-to-upload-display-and-save-images-using-node-js-and-express
General impression I'm getting: store image files on file system; store their filenames / references in the relational database.
Oh nice -- can use ImageMagic in NodeJs -- see this link here: https://stackoverflow.com/questions/12539918/get-the-width-and-height-of-an-image-in-node-js
Or you can probe the image size without a full download here: https://gitehub.com/nodeca/probe-image-size
One interim solution is: host your own image somewhere, and we can display feed data on top of it via URL ...
How to start a nodejs project here: https://philna.sh/blog/2019/01/10/how-to-start-a-node-js-project/
2021-01-20 11:40:26
Trying to work in this repo here: https://github.com/edgecollective/floorplan
This is the file that seems to have been the demo file I was playing with around mapping: https://gitlab.com/dwblair/p2p-farm-server/-/blob/mappin/public/console.html
Handling CORS here -- good guide; and:
good guide here, which leads to:
2021-01-20 15:24:42
Follwing this example here
Guide to pug here: https://www.sitepoint.com/a-beginners-guide-to-pug/
2021-01-20 16:57:33
Good start on plotting data in separate Node server here: https://github.com/edgecollective/floorplan/commit/607816a05848093a471966e0b9dd00c1cab90733
2021-01-20 20:38:45
Latest: try this link: http://192.168.1.163:4000/map/cbb8d444591def61d4e59f9b53d3193dd7724a9d8599c6ee?key=co2
Some layout details here: https://coder-coder.com/display-divs-side-by-side/
Latest attempt is at this commit of floorplan in the url-load branch, here: https://github.com/edgecollective/floorplan/commit/4972382b4982f34b75a60b5f8026a180a1591daf
2021-01-20 20:59:49
Ongoing test feed is here: http://data.pvos.org/co2/data/3897755c6379d00bbb1d622827b1ffd1ba6a0579802044c9
2021-01-22 11:22:08
May be very similar to one used in SCD30 ...
"Complete Gas Sensor Circuit Using Nondispersive Infrared (NDIR)": link: https://www.analog.com/media/en/analog-dialogue/volume-50/number-4/articles/complete-gas-sensor-circuit.pdf
Mike B. comments on the SCD30:
Looks like a lamp at one end, and two legs are the two wavelengths - sensing, and reference; 75mA when measuring implies about 70 Ohms for that lamp.
Link here: http://www.alphasense.com/WEB1213/wp-content/uploads/2016/01/AAN_202-04.pdfe
-- 2021-01-22 14:28:56
2021-01-23 11:52:42
Current case for REV_E ... 1591BTCL
2021-01-25 11:25:35
v0.1-alpha release of the firmware for REV_F!
https://github.com/p-v-o-s/co2-monitor/releases
2021-01-25 19:14:15
Added more info to the screen!
2021-01-27 07:46:09
Two devices:
ESP-1cfe posting to: http://data.pvos.org/co2/data/a00aed3265bf99e1784168ac9b1b509f30adfe9d00a2918d
and
ESP-2c7e posting to: http://data.pvos.org/co2/data/e9d7a2df343e8e6d0bf6c169011be8721ee9c24707ad7347
2021-01-27 09:24:36
2021-01-27 19:57:10
2021-01-28 08:21:57
TODOS:
2021-01-28 14:59:42
Article on airborne covid and CO2 montoring https://www.aol.com/article/lifestyle/2020/08/12/the-best-ways-to-reduce-the-risk-of-covid-19-indoors/24589315/
2021-01-28 15:28:17
2021-01-28 17:49:17
Adding microSD functionality to the Heltec ...
https://randomnerdtutorials.com/esp32-data-logging-temperature-to-microsd-card/
First get the libraries ...
Maybe it's possible to talk to SCD30 i2c over OLED i2c (as did on Quahog)? see https://github.com/HelTecAutomation/Heltec_ESP32/blob/master/examples/SD/SD_Time/SD_Time.ino
Ah, SD card might require resistors! See answer here: https://stackoverflow.com/questions/57454066/how-to-use-2-spi-devices-lora-and-sd-card-on-esp32
Also this info here -- looks like it can get dug out! http://ldsrc.blogspot.com/2018/02/micro-sd-card-for-esp32.html
2021-01-29 11:19:51
Switching over to Feather ESP32 ...
Arduino SD Card library + Feather breakout ... https://learn.adafruit.com/adafruit-adalogger-featherwing/using-the-sd-card
Adafruit microsd breakout board
Trying Examples > SD > Cardinfo
Note: important code for multiple SPI buses (for use later when doing microSD + lora): https://github.com/jonashoechst/ttgo-lora-sd
works ...
1591 Page on Hammond 1591BTCL Listing on Digikey Enclosure datasheet with screw positions
horizontal cover inside lip: 107.7 horizontal screw distance: 98.3 horizonal span (screw, inside lip): (107.7-98.3)/2 =
vertical screw distance: 48.4 vertical cover inside lip: 57.8 vertical span (screw, inside lip): (57.8-48.4)/2 =
horizontal span: 106 mm horiz screw dist: 98.3 horiz screw center to edge: (106-98.3)/2 = 3.85
vertical span: 56 mm vert screw dist: 48.4 vert screw center to edge: (56-48.4)/2 = 3.8
x,y:
top left: 3.85,3.8 top right: 3.85+98.3, 3.8 = 102.15,3.8 bottom left: 3.85, 3.8+48.4 = 3.85, 52.2 bottom right: 102.15, 52.2
https://www.raspberrypi.org/documentation/configuration/wireless/access-point-bridged.md
https://www.balena.io/blog/turn-a-raspberry-pi-into-a-wi-fi-access-point-or-repeater/
https://gist.github.com/Lewiscowles1986/fecd4de0b45b2029c390
2021-01-29 17:12:36
https://www.pidramble.com/wiki/benchmarks/external-usb-drives
This worked nicely: https://www.nayab.xyz/linux-tools/partitioning-using-fdisk.html
Showing progress while zipping: https://unix.stackexchange.com/questions/179563/when-i-use-zip-how-can-i-display-the-overall-progress-without-flooding-the-comm
Back up raspberry pi image:
sudo dd bs=4M if=/dev/sdb of=pvosPi.img status=progress
Zipping it afterwards:
zip -qr - pvosPi.img | pv -bep -s $(du -bs pvosPi.img | awk '{print $1}') > pvosPi.img.zip
2021-01-30 10:20:43
2021-01-30 16:30:53
https://randomnerdtutorials.com/esp32-lora-rfm95-transceiver-arduino-ide/
Adding additional SPI buses https://github.com/espressif/arduino-esp32/issues/1219
https://forum.arduino.cc/index.php?topic=637121.0
2021-01-30 21:24:20
Working setup!
2021-01-31 09:13:44
Converting a board to a footprint https://forum.kicad.info/t/converting-board-to-footprint/2781/5
2021-01-31 17:08:28
M3 nylon standoffs amazon here
2021-01-31 17:50:52
Initial version of REV_G!
2021-01-31 19:55:55
Wiring up a microSD https://components101.com/misc/microsd-card-pinout-datasheet
Featherwing microsd https://cdn-learn.adafruit.com/assets/assets/000/044/116/original/feather_schem.png?1500667618
Feather schematic & pintouts https://cdn-learn.adafruit.com/assets/assets/000/041/630/original/feather_schem.png?1494449413
2021-01-31 20:15:51
The code that worked! (?) https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/blob/master/v0.1-alpha/feather_esp32/feather_esp32_lora_sd_u8x8_scd30/feather_esp32_lora_sd_u8x8_scd30.ino
// SD uses 'regular' SPI pins on Feather ESP32:
#define SD_CS 33
#define SD_SCK 5
#define SD_MOSI 18
#define SD_MISO 19
// LoRa uses a newly-created SPI bus:
#define LORA_IRQ 15
#define LORA_CS 14
#define LORA_SCK 26 //A0
#define LORA_MOSI 21
#define LORA_MISO 25 //A1
#define LORA_RST 27
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=/ 16, / data=/ 17, / reset=*/ 39);
SCD30 on 'regular' i2c for feather esp32: SCL: 22, SDA: 23
display on SCL: 16, SDA: 17
maybe add qwiik for both?
2021-01-31 20:29:41
First pass at pin assignments; double check!
Test button functionality ...
Add DIO1 for LoRaWAN ability?
Button pin assignments?
RESET pin choice for display (no wiring to do for library ... maybe U8X8 can avoid a reset pin? Or what pin do we assign in order to avoid conflicts?)
Add label / pinout / description for Adafruit microSD card on back
Hirose microSD part DM3D-SF on Digikey: https://www.digikey.com/en/products/detail/DM3D-SF/HR1941CT-ND/1786515
2021-02-02 17:08:26
Jupyterlab on a Raspberry Pi https://medium.com/analytics-vidhya/jupyter-lab-on-raspberry-pi-22876591b227#:~:text=Install%20Jupyter%20Lab,to%20install%20jupyter%20lab%20later.&text=Install%20jupyter%20using%20pip3.
Jupyer Hub on an RPi https://towardsdatascience.com/setup-your-home-jupyterhub-on-a-raspberry-pi-7ad32e20eed?gi=b0e66a9b10f7
The script-based approach to installing Jupyter! https://github.com/kleinee/jns
Another nice approach: https://morioh.com/p/93349454d65a
2021-02-03 05:18:10
2021-02-03 05:08:58
ESP32 and wifi access point https://www.google.com/search?q=esp32+can%27t+connect+to+pi+as+access+point&oq=esp32+can%27t+connect+to+pi+as+access+point&aqs=chrome..69i57.8176j0j7&sourceid=chrome&ie=UTF-8
ESP32 and wifi access point 2 https://www.esp32.com/viewtopic.php?t=18928
ESP32 and RPi connection without internet connection https://raspberrypi.stackexchange.com/questions/107647/esp-8266-and-raspberry-pi-communication-without-an-internet-connection
Update: just tried connecting my Heltec to my Pi using the identical image, without having the ethernet connected, and: "wifi?" but as soon as I plugged the ethernet back in, it connected. Googling now, this is a known problem: ESP32 doesn't like to connect to Pi as isolated AP. I think people have found a fix.
Suggestion to use MQTT here https://github.com/nhonchu/mqttspooler
Setting up a Raspberry Pi as an access point https://learn.sparkfun.com/tutorials/setting-up-a-raspberry-pi-3-as-an-access-point/all
Setting up a Pi as an access point in a standalone network -- solid instructions, here: https://github.com/SurferTim/documentation/blob/6bc583965254fa292a470990c40b145f553f6b34/configuration/wireless/access-point.md
Todo: follow instructions here on fresh Pi image install.
2021-02-04 09:04:21
M.B.'s data from overnight, using a REV_E and a Pi w/ Bayou-CO2 installed locally!
2021-02-04 12:57:13
looks like syntax is:
var sql = "select * from user order by id desc LIMIT "
2021-02-04 15:11:18
comparing timestamps in postgresql
https://stackoverflow.com/questions/19469154/how-to-compare-dates-in-datetime-fields-in-postgresql
https://popsql.com/learn-sql/postgresql/how-to-query-date-and-time-in-postgresql
2021-02-05 10:43:17
Radiohead LoRa on ESP32 Heltec here:
http://community.heltec.cn/t/lora-32-v2-radio-head-library-sovled/129/2
Adafruit Radiohead example https://learn.adafruit.com/adafruit-rfm69hcw-and-rfm96-rfm95-rfm98-lora-packet-padio-breakouts/rfm9x-test
Arduino array length https://www.arduino.cc/reference/en/language/variables/data-types/array/
2021-02-05 13:12:57
Basic lora receive and parse (not yet POST) here:
2021-02-07 11:04:31
low power mode of scd30 https://www.mouser.com/pdfdocs/CD_AN_SCD30_Low_Power_Mode_D2.pdf
2021-02-09 12:26:06
Rev G BOM here: https://docs.google.com/spreadsheets/d/1lVheEod6zCzNCYa6XvAfB3fSmFhtaZ6GWjAGM3Qgw9o/edit#gid=970277542
Rev_G gerbers on Oshpark here: https://oshpark.com/shared_projects/B5Xvlckj
2021-02-09 19:58:22
Create the feed online here: http://co2data.pvos.org/
Arduino firmware is here: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/blob/master/releases/v0.4-alpha.zip
Examples (of individual feeds):
http://co2data.pvos.org/data/rk8gt2ig7atv
http://co2data.pvos.org/data/kmwfezd45adn
2021-02-11 17:31:12
1591 btcl http://www.hammondmfg.com/pdf/1591B.pdf
good thread on pcb hole sizes / placement https://www.eevblog.com/forum/eda/m3-screw-drill-diameter/
Depends how accurate are the hole positions are in what you are mounting it to.
You want accurate size on one side and oversize on the other to allow for tolerance.
3.5mm would be a generally normal size for an M3 mount, but M3.5 on both pieces may get too sloppy, so you'd normally do 3.2mm on one and 3.5 on the other.
If it's just a general purpose mount hole with no specifiiic 'other bit', use 3.5mm
2021-02-11 19:58:23
2021-02-12 09:58:30
2021-02-12 20:38:52
common hole / tap sizes:
M2 spacers on amazon
2021-02-12 21:25:40
Submitted to jlcpcb! Order: Y15-2489114A
2021-02-12 21:30:58
Updated code for REV_E and REV_F (Heltec) to show public key on screen here: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/b0f7bae152fd3fedaaca335b2e49ac72dcf17830/v0.4-alpha/pvos_co2_wifi_pubkey
Test code for REV_G (Feather ESP32; should work on REV_H too) here: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/40179ca69b689f22f4f3d207cea9c0f9568a5edf/v0.4-alpha/rev_g
2021-02-13 10:23:28
QR codes:
https://github.com/soldair/node-qrcode
Added to feedmaps:
https://gitlab.com/p-v-o-s/co2/feedmap/-/tree/182e091f08e907bae7640dbb3cbb344c7f8f1961
Added to bayou-co2:
https://gitlab.com/p-v-o-s/co2/bayou-co2/-/tree/f288bec254317eab2deab5af808de973bf5c4d1e
download canvas https://www.purplesquirrels.com.au/2019/10/saving-a-canvas-element-as-an-image/
2021-02-14 11:14:43
canvas to pdf https://stackoverflow.com/questions/23681325/convert-canvas-to-pdf
2021-02-25 10:52:39
Code for watchdog timer for esp32 here: https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino
2021-02-27 14:23:17
Going to resurrect the 'lora mesh' idea ...
nootropic design lora mesh: https://nootropicdesign.com/projectlab/2018/10/20/lora-mesh-networking/
q: can we make radiohead lib work with sd card on same spi bus?
can the feather m0 work on a rev_h board?
simple radio control of stuff remotely as per nu vu ?
2021-02-27 19:53:43
basic lora mesh working on both heltecs and a feather: https://github.com/edgecollective/lora-mesh/tree/master/co2/simple_a
one specifies the 'target' node, and one's node id ...
would be nice to have a switch on the remote nodes to change node id
might use feather based board as gateway for now ...
As of Feb 27, here's what we see at A2:
The story is that there is a heater that turned off on Feb 24th, and turned back on around 3 PM Feb 25th ...
2021-02-28 12:07:50
blog post on mesh networking: https://nootropicdesign.com/projectlab/2018/10/20/lora-mesh-networking/
Idea: we can have the nodes mesh, and use a 'test network' to visualize. We can add a 'next hop' field to the database, as well as a 'last rssi' value, and a 'node id' field. so then we'll have:
node id next hop id rssi to the next hop
we can then start to visualize these networks using a similar approach
2021-02-28 13:08:51
RH_TEST_NETWORK
////////////////////////////////////////////////////////////////////
bool RHRouter::recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* source, uint8_t* dest, uint8_t* id, uint8_t* flags)
{
uint8_t tmpMessageLen = sizeof(_tmpMessage);
uint8_t _from;
uint8_t _to;
uint8_t _id;
uint8_t _flags;
if (RHReliableDatagram::recvfromAck((uint8_t*)&_tmpMessage, &tmpMessageLen, &_from, &_to, &_id, &_flags))
{
// Here we simulate networks with limited visibility between nodes
// so we can test routing
#ifdef RH_TEST_NETWORK
if (
#if RH_TEST_NETWORK==1
// This network looks like 1-2-3-4
(_thisAddress == 1 && _from == 2)
|| (_thisAddress == 2 && (_from == 1 || _from == 3))
|| (_thisAddress == 3 && (_from == 2 || _from == 4))
|| (_thisAddress == 4 && _from == 3)
#elif RH_TEST_NETWORK==2
// This network looks like 1-2-4
// | | |
// --3--
(_thisAddress == 1 && (_from == 2 || _from == 3))
|| _thisAddress == 2
|| _thisAddress == 3
|| (_thisAddress == 4 && (_from == 2 || _from == 3))
#elif RH_TEST_NETWORK==3
// This network looks like 1-2-4
// | |
// --3--
(_thisAddress == 1 && (_from == 2 || _from == 3))
|| (_thisAddress == 2 && (_from == 1 || _from == 4))
|| (_thisAddress == 3 && (_from == 1 || _from == 4))
|| (_thisAddress == 4 && (_from == 2 || _from == 3))
#elif RH_TEST_NETWORK==4
// This network looks like 1-2-3
// |
// 4
(_thisAddress == 1 && _from == 2)
|| _thisAddress == 2
|| (_thisAddress == 3 && _from == 2)
|| (_thisAddress == 4 && _from == 2)
#endif
#if defined(__AVR)
//mothbot
#define RFM95_CS 8
#define RFM95_RST 7
#define RFM95_INT 2
#define LED 4
RH_RF95 rf95(RFM95_CS, RFM95_INT);
#elif defined(HELTEC_WIFI_LORA_32_V2)
// heltec wifi lora 32 v2
#define RFM95_CS 18
#define RFM95_RST 14
#define RFM95_INT 26
#define LED 25
RH_RF95 rf95(RFM95_CS, RFM95_INT);
#elif defined(FEATHER_ESP32)
// feather esp32
#define RFM95_CS 14
#define RFM95_RST 27
#define RFM95_INT 15
#define LED 13
RHSoftwareSPI sx1278_spi;
RH_RF95 rf95(RFM95_CS, RFM95_INT, sx1278_spi);
#endif
2021-02-28 19:46:46
working!
Only the feather m0 and the heltec code works for now I think (easy to make the feather esp32 code work I believe)
NOTE: in order to generate the 'test networks', it has to be done in the RHROUTER.h file in the library itself.
See below, displaying RH_TEST_NETWORK==3:
Documentation on RHMesh here
2021-02-28 20:23:29
Nice LoRa tracker project here
Great thread on using CO2 for indoor ventilation assessment here
2021-03-01 13:55:42
from https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/fatal-errors.html:
LoadProhibited, StoreProhibited This CPU exception happens when application attempts to read from or write to an invalid memory location. The address which was written/read is found in EXCVADDR register in the register dump. If this address is zero, it usually means that application attempted to dereference a NULL pointer. If this address is close to zero, it usually means that application attempted to access member of a structure, but the pointer to the structure was NULL. If this address is something else (garbage value, not in 0x3fxxxxxx - 0x6xxxxxxx range), it likely means that the pointer used to access the data was either not initialized or was corrupted.
Indeed, this is what we're seeing from the stack trace:
Rebooting...
RFM95_CS:18
initializing node done
RF95 ready
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d0dfa PS : 0x00060d30 A0 : 0x800d37cc A1 : 0x3ffb1f60
A2 : 0x3ffc0214 A3 : 0x00000004 A4 : 0x3ffc0224 A5 : 0x3ffc08b8
A6 : 0x00000000 A7 : 0x3ffba264 A8 : 0x800d0dee A9 : 0x3ffb1f40
A10 : 0x00000000 A11 : 0x00000001 A12 : 0x00000000 A13 : 0x00000003
A14 : 0x00000001 A15 : 0x00000000 SAR : 0x0000000e EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000001 LBEG : 0x400eb508 LEND : 0x400eb525 LCOUNT : 0x00000000
Backtrace: 0x400d0dfa:0x3ffb1f60 0x400d37c9:0x3ffb1fb0 0x40088249:0x3ffb1fd0
Is there a way to check whether a pointer is null or not before attempting?
Null pointer material here
Checking for null status in Arduino: https://forum.arduino.cc/index.php?topic=128622.0
Checked for null pointer first, now it works!
Going to implement in other versions, too ...
2021-03-01 14:35:37
Fixed trio! https://github.com/edgecollective/lora-mesh/tree/50f2046267c6fdc4c8f0d68c1d225a53ddbb854c/co2/simple_e
Working basic lora mesh relay code.
Now set up to send CO2 data.
2021-03-01 15:15:49
Mesh healing:
Simple mesh + co2 reading code: https://github.com/edgecollective/lora-mesh/tree/fb1f5d3abc81c1c32d06cecbc9205877d048cef3/co2/simple_f/mesh_featheresp32_hardcoded
Now need to:
the remote nodes should be mostly listening and relaying, then periodically sending their data
the gateway should be mostly listening and relaying the value via wifi whenever something comes in
i guess the only difference is that if the gateway sees that it is the target node then it is never broadcasting, only wifi sending ...
for now we'll http POST every incoming data point, see if that can handle the random lora messages; otherwise we can store N incoming messages, then POST
2021-03-01 15:26:46
testing gateway setup -- adding wifi to gateway node
Feed Public Key: 7zqjzktfq997 Feed Private Key: 4g5xf5xzzhr8 Feed Home Page: http://co2.pvos.org/data/7zqjzktfq997
(on local database)
Ah -- I might want to use 'recvfromAck' (non-blocking) instead of 'recvfromAckTimeout' on the remote nodes.
sequence:
set up the recvfromAck in the loop (or start it running in setup?)
in remote nodes, periodically send co2 data ...
in the gateway, periodically send the data that has been collected thus far ...
some relevant posts:
https://forum.arduino.cc/index.php?topic=413182.0
https://forum.arduino.cc/index.php?topic=381973.msg2638162#msg2638162
example using recvfromAck: https://github.com/adafruit/RadioHead/blob/master/examples/serial/serial_reliable_datagram_server/serial_reliable_datagram_server.pde
2021-03-01 20:45:29
lora-mesh/co2/simple_g/basic_mesh_system/mesh_heltec seems to work as a basic mesh gateway.
will need to test code for other nodes.
need to think through how to handle; seems like each node sends its pubkey, its privkey, and identifies its network by gateway's pubkey.
somehow we have to identify nodes in the network by simple integers, it seems. need to think that through.
note that the gateway should send its own data via http every X seconds ...
... so maybe there's a millis() loop, where if you're the remote node, when it triggers, you send your data via lora; if you're the gateway, you send your data to the cloud via wifi.
the gateway is then set up so that it is listening for chunks of time; if it ever hears anything, it does an http POST of that data; and if it is then also past its own interval, it posts data.
every listen-receive-post re-loops the system
in the limit of many receipts, it simply loops back into another receipt again; but it will always measure itself and send via wifi if it's past time to do so
i.e. something like:
if (millis() > wait interval) {
if we're the gateway, measure our own CO2 and send via wifi;
if we're a remote node, measure our own CO2 and send via lora;
}
if recvfromAckTimeout(wait interval) { // running this function means that we are relaying any mesh messages // if it returns true, then we were the intended recipient // in our network, this is only true if we're the gateway; so in that case, post the resultant data to the proper feed. }
this means that the data struct has to include the pubkey and privkey of the remote node that is sending the data. the node id would ideally be set in hardware, but we'll do it in the config file in this round. i don't think there's any need to have an upper limit on # nodes; but each nodeid needs to be unique
we should rename nodeId to node_id
2021-03-02 10:41:51
Heating events ...
Exponential decay here
fitting using python here
get slopes of data here
adding fields to bayou:
2021-03-02 18:20:59
Plan:
ALTER TABLE measurements ADD COLUMN node_id INT;
ALTER TABLE measurements ADD COLUMN next_hop INT;
ALTER TABLE measurements ADD COLUMN next_rssi FLOAT;
ALTER TABLE measurements ADD COLUMN light FLOAT;
need to remember to optimize strings!
need to add lux to database
string args and string cat -- https://forum.arduino.cc/index.php?topic=120233.0
strlcat() -- truncates string if necessary rather than writing outside bounds
2021-03-02 21:31:36
Replaced use of strings with chars; put stuff into functions: https://github.com/edgecollective/lora-mesh/tree/bdec49aedecffb83f29723c3f0fcfdf924c9e2fe/co2/simple_h/mesh_heltec -- basic gateway is working.
Now need to:
2021-03-03 12:43:22
Basic working version for Heltec!
Also includes code for a 'dummy' featherm0 node.
Next priorities:
2021-03-03 17:08:56
sorting javascript objects by key https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key
sorting javascript objects by value https://stackoverflow.com/questions/1069666/sorting-object-property-by-values
2021-03-03 17:38:11
working! the "simple_k" arduino version, with associated commits on bayou and feedmap ...
bayou code: https://gitlab.com/p-v-o-s/co2/bayou-co2/-/tree/d738bfcbbd1f4b934a11add33852f7f00267e0fc
feedmap code: https://gitlab.com/p-v-o-s/co2/feedmap/-/tree/52820c9e0cdbdb02808a239cf75fe65ff7360391
arduino firmware: https://github.com/edgecollective/lora-mesh/tree/731e5e392831f657b3cb9bdfb01c6fe3691d9187/co2/simple_k
2021-03-04 09:10:42
Data analysis repo here: https://github.com/p-v-o-s/co2data-analysis/tree/a4879538a447a920785b4d9182a0b38e4830baab/jupyter/heating_mar_04_2020
2021-03-04 13:13:30
Repeaters working!
Arduino firmware is 'simple_l' version: https://github.com/edgecollective/lora-mesh/tree/32dbf22e74e37e31f55ce6855fca599a2c0105f9/co2/simple_l
Feedmap version is in the 'mesh' branch: https://gitlab.com/p-v-o-s/co2/feedmap/-/tree/817f69f4ab2012de69c9be0644be988d19e879e8
Bayou-feed version is https://gitlab.com/p-v-o-s/co2/bayou-co2/-/tree/d738bfcbbd1f4b934a11add33852f7f00267e0fc
2021-03-05 10:15:35
Pandas series to numpy array https://pandas.pydata.org/pandas-docs/version/0.24.0rc1/api/generated/pandas.Series.to_numpy.html
polyfit: https://numpy.org/doc/stable/reference/generated/numpy.polyfit.html
https://stackoverflow.com/questions/54313463/pandas-datetime-to-unix-timestamp-seconds
https://stackoverflow.com/questions/35495045/exponential-fit-of-the-data-python
https://numpy.org/doc/stable/reference/generated/numpy.exp.html
2021-03-06 08:10:48
Error on the fit in numpy: https://stackoverflow.com/questions/15721053/whats-the-error-of-numpy-polyfit
2021-03-07 13:19:18
New mesh code here: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/raw/master/releases/v0.7-alpha.zip
2021-03-10 16:13:42
error in fit: http://clip.med.yale.edu/courses/brdu/Costa_ODE.pdf
error in slope of linear fit: https://pages.mtu.edu/~fmorriso/cm3215/UncertaintySlopeInterceptOfLeastSquaresFit.pdf
SE of regression slope = sb1 = sqrt [ Σ(yi – ŷi)2 / (n – 2) ] / sqrt [ Σ(xi – x)2 ]
https://people.duke.edu/~rnau/mathreg.htm
https://faculty1.coloradocollege.edu/~sburns/LinearFitting/SimpleDataFitting.html
https://newt.phys.unsw.edu.au/~mcba/mcba12.pdf
https://www.ruf.rice.edu/~bioslabs/tools/data_analysis/errors_curvefits.html
https://statisticsbyjim.com/regression/standard-error-regression-vs-r-squared/
https://astrofrog.github.io/py4sci/_static/15.%20Fitting%20models%20to%20data.html
2021-03-11 18:17:18
Rework of firmware and bayou for mesh networking ...
Bayou software: https://gitlab.com/p-v-o-s/agroeco/bayou/-/tree/08b7b44a7fc53e3e3fd1f61d3eb32aee927503e9
Arduino firmware -- ver 0.8-alpha: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/96f83332bae148ced8d4809c85f2e35f16c18a85/v0.8-alpha
Can now use URL parameters to specify node and parameter to graph:
2021-03-12 10:05:53
Added overlay functionality to Bayou:
Still associated with ver 0.8-alpha of firmware:
2021-03-13 08:42:37
Great presentation on using CO2 for assessing ventilation -- recommends using fans: https://www.ghdonline.org/uploads/Measuring_Air_Changes.pdf
https://en.wikipedia.org/wiki/Exponential_decay
Medrxiv: Ventilation rate assessment by carbon dioxide levels in dental treatment rooms -- note: uses baking soda! Key paper, here.
https://stackoverflow.com/questions/31253468/chart-js-get-point-index-from-chart-getpointsatevente
https://www.npmjs.com/package/chart.js-rangeslider
https://stackoverflow.com/questions/6195335/linear-regression-in-javascript
https://github.com/Tom-Alexander/regression-js
2021-03-13 10:15:09
Updated bayou to find the existing nodes in a feed, and pull JSON and CSV for them:
https://gitlab.com/p-v-o-s/agroeco/bayou/-/tree/731a1e1564680eb8ec48bab12ca204ac5f2534ee
Still compatible with latest (ver0.8-alpha) software
Some useful folks to add to the list: https://twitter.com/rod_escombe/status/1246117208440418304
https://twitter.com/wendyNAIFarbman/status/1246896832363614208?s=20
2021-03-13 13:08:51
"Natural Ventilation for the Prevention of Airborne Contagion" -- another key paper by Enscombe et al.
2021-03-14 09:00:12
Baking soda and vinegar experiment https://www.thoughtco.com/equation-for-the-reaction-of-baking-soda-and-vinegar-604043
How to make carbon dioxide https://sciencing.com/make-carbon-dioxide-6532065.html
Making CO2 w/ DIY bottle system https://www.co2supermarket.co.uk/diy-co2-kit-setup-instructions-guide-6.html
CO2 in grow rooms, increasing ppm: https://www.rollitup.org/t/co2-generated-via-vinegar-and-baking-soda.397247/
CO2 heavier than air, typically we'll need to use a fan to circulate it in the room
https://antoine.frostburg.edu/chem/senese/101-hidden/gases/faq/co2-from-vinegar-and-baking-soda.shtml
2021-03-14 12:09:47
Showing a fit in chartjs https://stackoverflow.com/questions/42841925/mixed-chart-scatter-plot-with-chart-js
2021-03-14 16:32:35
Select range in chartjs: https://stackoverflow.com/questions/42855738/how-do-i-selecting-a-date-range-like-onclick-but-drag-select
Chartjs plugin zoom: [https://github.com/chartjs/chartjs-plugin-zoom]
https://github.com/jjppof/chartjs-plugin-zoom-pan-select
https://stackoverflow.com/questions/30256695/chart-js-drawing-an-arbitrary-vertical-line
https://github.com/chartjs/chartjs-plugin-zoom
2021-03-14 19:44:38
Bayou branch that does curve fitting: https://gitlab.com/p-v-o-s/agroeco/bayou/-/tree/6a97681e2cc36e1e41edc2b6800e00858987fa42
Video demo here
2021-03-16 17:26:51
Added live exponential fit! Bayou commit here: https://gitlab.com/p-v-o-s/agroeco/bayou/-/tree/fe7b5ed71be3ebddf4d0be98c3d1bd88fb758d20
2021-03-17 08:04:41
Nice working prototype of Bayou ACH fit: https://gitlab.com/p-v-o-s/agroeco/bayou/-/tree/1372dc343ec2f9e70449fe0b0628fb26019eac8a
E.g. http://192.168.1.163:5000/data/jy5kv5ybwq5j/ach/2
Video here: https://youtu.be/AfVbtuXU_sA
2021-03-17 09:58:58
Brought back in display of linear fit, along with slope and intercept parameters, in the following commit:
https://gitlab.com/p-v-o-s/agroeco/bayou/-/tree/88f6d5afbd9e33244800946c21719db9db13b627
2021-03-17 10:11:20
Bayou has format-able canvas size now:
https://gitlab.com/p-v-o-s/agroeco/bayou/-/tree/0ed7d425ca237134644ebc88445594b18736baf0
2021-03-17 11:36:09
Nice reference for downloading canvas as a PDF: https://stackoverflow.com/questions/23681325/convert-canvas-to-pdf -- some pretty simple code
2021-03-18 19:00:18
Dataset here: http://bayou.pvos.org/data/6adqqks8f7yb/ach/2
2021-03-18 19:05:04
Dataset here: http://bayou.pvos.org/data/8fs9k3zwjg4w/
2021-03-31 14:51:59
barrel jack connector https://www.sparkfun.com/datasheets/Prototyping/Barrel-Connector-PJ-202A.pdf
pos centerpole on 2.1 mm + USB cable from Amazon ...
extension cable from sparkfun for 2.1 mm jack here
2021-04-17 08:49:02
force calibration event at a2:
![](/img/co2/force_calibration_at _a2.png)
http://bayou.pvos.org/data/8fs9k3zwjg4w
2021-04-17 08:50:02
Current setup idea:
uf2 based board, so we can flash firmware without IDE
microSD card for parameters on gateway; not necessary for remote node, b/c each node can be determined by a switch, and the loranetwork can be set in the firmware -- we can have several options
https://learn.adafruit.com/adafruit-metro-esp32-s2/arduino-ide-setup
2021-04-18 10:23:09
uf2 bootloader on feathers2 is not protected. this means that arduino ide upload will likely erase UF2 (way to mitigate this?) and in fact does in my experience.
But 'advanced' users who use Arduino IDE w/ esp32 setup should also likely be able to handle webserial or other modes of re-flashing the bootloader.
questions:
tempting to use the itsy bitsy, but sticking with the feather ecosystem if possible seems smart.
esp32-s2 feathers2 as main board seems like a good setup if we can swing it. means that gateway and remote node are identical setups.
making uf2s --- https://github.com/blurfl/makeUF2-tool
python /home/dwblair/.arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool.py --chip esp32s2 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0xe000 /home/dwblair/.arduino15/packages/esp32/hardware/esp32/2.0.0-alpha1/tools/partitions/boot_app0.bin 0x1000 /tmp/arduino_build_224941/Blink_S2.ino.bootloader.bin 0x10000 /tmp/arduino_build_224941/Blink_S2.ino.bin 0x8000 /tmp/arduino_build_224941/Blink_S2.ino.partitions.bin
important video to watch: https://www.youtube.com/watch?v=xmB22q2p40g
instructions for loading the uf2 bootloader https://feathers2.io/install_uf2.html
esptool.py --chip esp32s2 -p /dev/cu.usbmodem01 -b 921600 --before=default_reset --after=no_reset write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x1000 bootloader.bin 0x8000 partition-table.bin 0xe000 ota_data_initial.bin 0x410000 tinyuf2.bin
options for setting up system:
option A:
option b:
option A:
----> this is the major thing to test right now
option B:
samd51 in standby mode -- can use sleepdog library -- https://forum.arduino.cc/t/samd51-sleep-mode/591685 -- get 43 uA
2021-04-18 15:14:29
https://learn.adafruit.com/adafruit-hallowing/using-with-arduino-ide
https://github.com/PaulStoffregen/SerialFlash
https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-spi
SPIClass SPI (&PERIPH_SPI, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI, PAD_SPI_TX, PAD_SPI_RX);
2021-04-18 16:14:31
core code for project! M0 + uSD + lora + esp32 wifi breakout (tested on itsybitsy)
2021-04-18 19:14:53
mini ultra -- https://www.rocketscream.com/blog/product/mini-ultra/
mini ultra pro https://github.com/rocketscream/MiniUltraPro
samd51 easier part ot solder https://www.digikey.com/en/products/detail/microchip-technology/ATSAMD51N20A-AUT/7390290
https://twitter.com/marwa_zaatari/status/1383828012022439937?s=20 good thread on hvac
2021-04-20 13:22:50
adding adalogger to feather m0 lora: https://forums.adafruit.com/viewtopic.php?f=31&p=856795
This thread indicates that the original Arduino SD library shouldn't be used with more than one device on the SPI bus; use SdFAT instead https://forum.arduino.cc/t/problem-using-both-spi-library-and-sd-library-in-arduino-uno-program/149775/16, and making sure to set the relevant pins high or low depending on which device you want to talk to
2021-04-24 11:26:44
Ordered CO2 REV_K / REV K from JLCPCB -- git commit is here: https://gitlab.com/p-v-o-s/co2/co2monitor-hardware/-/tree/2f2a087edde58be6938c8b4bdc3f76482e28a35f/REV_K/kicad
2021-04-24 11:37:42
Gateway design:
set up 'all breakout' option, so that the basic soldering req'd is:
going to work on this using 'gateway' file in co2monitor-firmware v0.91-alpha
NOTE: if someone were to use a feather m0 lora, they'd have to load firmware via arduino ide anyway ... so virtual lora connection is fine.
Need to see if hardware uSD and hardware airlift are compatible ...
But: looks like uSD doesn't 'play nice' with other SPI devices. so: let's see if we can do hardware lora and hardware airlift; then virtual uSD.
2021-04-24 12:22:18
feather m0 express + hardware airlift and hardware lora working in this commit: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/b21eeb06612cf2d21b35c77848c71bd4566b9cc5/v0.91-alpha/gateway/featherm0express_hardware_airlift_ScanNetworks_hardware_lora
virtual SPi on m0 reference here: https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports?gclid=CjwKCAjwg4-EBhBwEiwAzYAlsoaFHbvfOeNx0AQbUp4pAbEmXst8Mpb2HCE15YLEejIkYbjp9jlnWRoC4VkQAvD_BwE
....
challenging to create virtual SPI for uSD ... ? can't find in library as yet ...
another option might be to do virtual SPI for lora + airlift ...
quick test of that ...
2021-04-24 14:32:12
basic test of: featherm0express + hardware_airlift + hardware uSD + virtual LoRa here: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/a0e75274df4518dbe081546bc32aacd0a79d6e80/v0.91-alpha/gateway/featherm0express_airlift_test_hardware_uSD_virtual_LoRa
now try writing to uSD, connecting to wifi, and sending lora packet in loop ...
2021-04-24 14:43:32
note: seems like airlift (which includes 3.3V LDO) can do alright on 3.7 lithium ion battery (gets sufficient current)
2021-04-24 15:21:12
was able to read config file and then use wifi -- also lora -- now need to write gateway firmware to test! -- commit is here: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/d7d8ad2ac631a02f62a4df86c8642994a86d8005/v0.91-alpha/gateway/featherm0express_airlift_test_hardware_uSD_virtual_LoRa_readcon
2021-04-26 17:34:57
2021-04-29 11:22:02
design updates:
base around itsy bitsy m0 / m4 diy version can be hand soldered easily microsd breakout option battery power is: cell battery module force calibrate procedure
then next version: cheaper, SMT
samd51 deep sleep mode: https://forum.arduino.cc/t/standby-sleep-mode-on-samd51/576584/4
note: we don't really need to worry about the samd51 sleeping -- we'll probably only use it when doing circuitpython, on the gateway, if we want to do that ... but the gateway usually won't be sleeping ... at least not for many applications ...
2021-04-30 10:20:04
IBM4 + uSD (hardware SPI) + esp32 airlift featherwing (hardware SPI) + LoRa (virtual SPI): https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/95aca8ffeebd98583e0790de480f285ef62d94da/v0.91-alpha/ibm4_hardware_airliftwing_hardware_uSD_virtual_LoRa
above, + OLED + SCD30: https://gitlab.com/p-v-o-s/co2/co2monitor-firmware/-/tree/59575acfdf487dab619edb50be38fe54dbf7a503/v0.91-alpha/ibm4_hard_airliftwing_hard_uSD_soft_LoRa_i2c_oled_i2c_scd30
note: looks like we have another reason for using the IBM4 -- we need the extra pins?
pinouts for esp32 airlift featherwing -- https://learn.adafruit.com/adafruit-airlift-featherwing-esp32-wifi-co-processor-featherwing/pinouts
upgrading firmware https://learn.adafruit.com/adafruit-airlift-featherwing-esp32-wifi-co-processor-featherwing/upgrade-external-esp32-airlift-firmware
okay -- need a pint on GPIO0 ---
"SD-2010"
Part from digikey here: https://www.digikey.com/en/products/detail/nidec-copal-electronics/SD-2010/948380
Datasheet: https://www.nidec-copal-electronics.com/e/catalog/switch/sd-1000&sd-2000.pdf
2021-05-01 12:19:15
https://docs.google.com/spreadsheets/d/1tf-k_AHOju78dKrg6N9kK3bM163Hrda-1mUbevxc0zM/edit?usp=sharing)
2021-05-01 13:43:06
maxim unique id chip https://www.digikey.com/en/products/detail/maxim-integrated/DS2401/956992
https://preshing.com/20110504/hash-collision-probabilities/
So the probability of no collisions is exp(-1/2) or about 60%, which means there’s a 40% chance of at least one collision. As a rule of thumb, a hash function with range of size N can hash on the order of √N values before running into collisions.
https://learn.sparkfun.com/tutorials/cryptographic-co-processor-atecc508a-qwiic-hookup-guide/all
2021-05-01 14:46:31
using spi flash on feather m0 express: https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/using-spi-flash
2021-05-01 17:28:23
airlift featherwing esp32 schematic https://cdn-learn.adafruit.com/assets/assets/000/076/198/original/adafruit_products_AirLift_FeatherWing_Sch.png?1559155254
best practices for neopixels https://learn.adafruit.com/adafruit-neopixel-uberguide/best-practices
2021-05-01 17:45:25
2021-05-01 17:52:23
esp32 wroom antenna placement options https://www.espressif.com/sites/default/files/documentation/esp-wroom-02_pcb_design_and_module_placement_guide_0.pdf
2021-05-01 18:19:20
esp32 add-on for itsy bitsy schematic: https://cdn-learn.adafruit.com/assets/assets/000/080/457/original/adafruit_products_schematic.png?1567623352
ibm4 EXPRESS https://cdn-learn.adafruit.com/assets/assets/000/055/481/original/adafruit_products_schem.png?1529261754
DS2401 -- maxim through-hole serial # chip: https://www.digikey.com/en/products/detail/maxim-integrated/DS2401/956992
maxim additional chip: https://www.digikey.com/en/products/detail/maxim-integrated/DS28CM00R-A00-T/1197555
2021-05-01 19:03:10
incorporated latest changes to REV_L here: https://gitlab.com/p-v-o-s/co2/co2monitor-hardware/-/tree/064aa5c7a90d85fe930543ed271bc1fce1ff6d45/REV_L/kicad
2021-05-02 10:24:28
Board files on github: https://github.com/adafruit/NeoPixel-Sticks
2021-05-02 19:12:47
Latest REV_K is here: https://gitlab.com/p-v-o-s/co2/co2monitor-hardware/-/commit/acc99be30c98ecd960c28571723e39a166e170a5
2021-05-05 11:26:02
motor for dump truck:
https://www.youtube.com/watch?v=XSUyETpCy9M
linear actuator from scratch https://www.hackster.io/news/a-linear-actuator-made-from-scratch-b89c3c389003
2021-05-05 14:32:02
itsy bitsy m4 pinout:
interesting ref on partitioning esp32 here: https://towardsdatascience.com/tensorflow-meet-the-esp32-3ac36d7f32c7
2021-06-26 08:10:10
Working on REV_L with Mike, Craig, and Brett ...
Indoor ACH experiment w/ CO2 (in Spanish)
Working on getting the ACH fitting working again on Bayou ...
Craig's bayou feed: http://bayou.pvos.org/data/sj5ppfn94meh
Mike's bayou feed: http://bayou.pvos.org/data/kurqr92abvua
2021-06-26 09:46:48
Video explaining current interface for assessing ACH using Bayou: https://youtu.be/xXAM4NldULA
Todos:
2021-06-26 13:03:46
Mike's 'box test':
Quick video showing ACH analysis for node #2: https://youtu.be/7Rr_agMS50k
2021-07-22 21:15:55
2021-07-23 10:58:04
Design-in guidelines for SCD30
Seems to argue for larger ventilation holes, smaller inside enclosure.
Might just place holes directly beneath the sensor.
2021-07-25 11:29:17
Sensor inside enclosure, sensor close to 'pcb'; square hole cut out as per build-in guidelines; no tape around sensor.
Ambient CO2 level; brought from inside out to outside in < 5 seconds. Same outside to inside, but ambient CO2 indoors may have been lower; then people entered room.
No enclosure; sensor close to 'pcb'; no tape around board.
Comparison of option A and option B:
Note that when we'd calibrated using the 'slow' enclosure, it looks as though we didn't actually give the sensor enough time to reach ambient; when the enclosure is removed, we dropped down to ambient.
No enclosure; sensor close to 'pcb', tape around sensor to create 'small enclosure'
(graphic shows events for options a, b, c from left to right)
Enclosure; sensor close to 'pcb', tape around sensor to create 'small enclosure'.
Note that there are CO2 intakes on top and bottom of sensor. The top of the sensor is not taped. The below behavior in fact indicates that by having the bottom exposed only to the outside, and the top exposed only to the outside, we are somewhat 'averaging' the measurement (with a slow leak).
(graphic shows events for options a,b,c,d from left to right)
Enclosure; sensor close to 'pcb', tape around sensor to create 'small enclosure'; also covered 'top' of sensor to avoid intake on top.
Note that what appears to be happening is that I've sealed in a slightly higher CO2 env on the top, by putting tape on top of the intakes. Also, the sensor responds a bit slower with only the bottom intakes (perhaps the time constant is 'half' as fast as with top and bottom intakes exposed?).
So: as per Mike's suggestion, let's create the tightest enclosure around the sensor that also allows air to flow up over the intakes ...
(Note: I think spike on far right is me exhaling towards sensor accidentally while writing these notes ...)
(graphic shows events for options b,c,d from left to right; option a is only partially visible on left)
Made a "small box" that has some finite volume but still allows air flow over the top part of the sensor.
Note that the ends of the response (drop down and rise up) seem a bit more rounded / slower ... perhaps because of the small reservoir of gas inside the enclosure ...
(options a,b,c,d,e,f from left to right below:)
Looks like the sensor is about 9 or 10 mm peak off board, with sides around 5 mm; the intakes on the 'top' would still have some breathing room if tape was put over the top; so 8.5 mm headers could work pretty well as 'sides'
2021-07-25 16:51:24
2021-07-27 19:56:53
Summary of PCB ventilation experiment ...
2021-07-28 19:52:05
Final report TU Delft comparing CO2 sensor technologies: https://repository.tudelft.nl/islandora/object/uuid:6957a1c1-6ece-41b9-9802-2674c9365339/datastream/OBJ/download
Crodeon deployment of SCD30 https://www.crodeon.com/products/covid-co2-kit
2021-07-28 19:56:28
SCD40 design-in guidelines https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/9.5_CO2/Sensirion_CO2_Sensors_SCD4x_design-in_guide.pdf
2021-08-08 20:57:45
Notes on Corsi interview:
don't ever get worse results, but might be waste of time ...
keep devices 3ft away from walls / out of corners -- to avoid recirculation
don't want to put e.g. in front of window
look at classroom -- where is air coming in, where is air flowing out -- don't put device close to where air is flowing out
in general -- would try to put two boxes diagonally apart in the classroom
next to each other -- 'short circuiting'
600 700 800 900
Make sure that it's well-sealed around the edges
Remove at 6 months -- bag them in big plastic bag, toss them in dumpster, wash hands after.
sucks in through filters and out through fan
air blow vertically upward -- good -- want circulating flow up and diagonally across
weird fluid flow phenomena -- suck air in corners at filter
pleated merv 13 means greater surface area, less resistance, lower average velocity, reduces resistance on fan
filters as designed are capturing particles on surface of filter -- there's no barrier -- so:
CO2 Monitor notes:
Airboxes are imporant when you can't get better ventilation -- i.e. poor mechanical systems or
36:00 -- The true metric using CO2 is the 'rebreathe fraction' -- how much you're breating other people's breath. If you have a rebreathe fraction of 5% -- really high, bad. Rebreathe fraction of .5% is much better. Rebreathe fraction is: (CO2 concentration in room - CO2 concentration outdoors) / CO2 concentration on typical human breath -- also a function of who is the space -- dynamics are important ...
Building boxes lowers aerosol particle levels in the classroom
2021-08-19 12:54:18
co2 monitor --
feather m4 express, because:
esp32 airlift, because:
add a buzzer
2021-09-07 13:28:29
https://twitter.com/DavidElfstrom/status/1435290656608501765?s=20