Methane and Carbon Dioxide sensor
Jump to navigation
Jump to search
References
More References
Circuit Diagram
Pinout for Methane Sensor
- NGM2611-E13 - pre-calibrated module for Methane (Figaro)
- Methane Sensor Specifications RS Electrical
- Methane sensor RS
Pinout for CO2 Sensor
- SenseAir K33 LP T/RH CO2 Sensor
- SenseAir K33 LP T/RH CO2 Sensor Specification document
Pinout DHT22 Temperature and Humidity sensor
- DHT22 temperature and humidity sensor
- DHT22 datasheet
Arduino code
// A simple CH4, CO2, RH, T data logger for the Arduino analog pins
// By David Bastviken and Nguyen Thanh Duc, Linkoping University, Sweden.
//Thanks to cactus.io and Adafruit for code components. For setup of RTC, see separate logger shield documentation.
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
//#include "RTClib.h" //RTC library
#include <cactus_io_DHT22.h>
//#include "cactus_io_DHT22.h" //RH_Temp library
#define LOG_INTERVAL 2000 // mills between logging entries (reduce to take more/faster data)
// milliseconds before writing the logged data permanently to disk
// LOG_INTERVAL write each time (safest)
#define SYNC_INTERVAL 5000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
#define DHT22_PIN 7 // DHT22 (RH_T) data pin
DHT22 dht(DHT22_PIN); // Initialize DHT sensor for normal 16mhz Arduino.
// The analog pins that connect to the sensors
#define CH4sens A1 //CH4 sensor Vout
#define CH4ref A2 //CH4 sensor Vref
#define Vb A0 //Battery voltage
int CH4s = 0;
int CH4r = 0;
int Vbat = 0;
float CH4smV = 0;
float CH4rmV = 0;
float VbatmV = 0;
float mV = 5000;
float steps = 1024;
//RTC_PCF8523 RTC; // define the Real Time Clock object
RTC_DS1307 RTC;
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str) //Halt if error
{
Serial.print("error: ");
Serial.println(str);
//digitalWrite(redLEDpin, HIGH); // red LED indicates error
while(1); //halt command
}
double RHValue = 0;
double TempValue = 0;
double CO2Value = 0;
// This is the modified address of the CO2 sensor, 7bits shifted left (defaul 0x68, but collide with RTC chip)
int co2Addr = 0x7F;
///////////////////////////////////////////////////////////////////
// Function : void initPoll()
// Executes : Tells sensor to take a measurement.
// Notes : A fuller implementation would read the register back and
// ensure the flag was set, but in our case we ensure the poll
// period is >25s and life is generally good.
///////////////////////////////////////////////////////////////////
void initPoll() {
Wire.beginTransmission(co2Addr);
Wire.write(0x11);
Wire.write(0x00);
Wire.write(0x60);
Wire.write(0x35);
Wire.write(0xA6);
Wire.endTransmission();
delay(20);
Wire.requestFrom(co2Addr, 2);
byte i = 0;
byte buffer[2] = {0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
}
///////////////////////////////////////////////////////////////////
// Function : double readRH()
// Returns : The current RH Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readRH() {
int RH_value = 0; // We will store the RH value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr);
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x14); //Two bytes starting from 0x14 (high byte) and 0x15 (low byte)
Wire.write(0x36); //Checksum
Wire.endTransmission();
delay(20);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
RH_value = 0;
RH_value |= buffer[1] & 0xFF;
RH_value = RH_value << 8;
RH_value |= buffer[2] & 0xFF;
Serial.print("RH Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)RH_value / (double) 100);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
///////////////////////////////////////////////////////////////////
// Function : double readTemp()
// Returns : The current Temperature Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readTemp() {
int Temp_value = 0; // We will store the temperature value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr); //int K33 == 0x68
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x12); //Two bytes starting from 0x12 (high byte) and 0x13 (low byte)
Wire.write(0x34); //Checksum
Wire.endTransmission();
delay(20);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
Temp_value = 0;
Temp_value |= buffer[1] & 0xFF;
Temp_value = Temp_value << 8;
Temp_value |= buffer[2] & 0xFF;
Serial.print("T Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)Temp_value / (double) 100);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
///////////////////////////////////////////////////////////////////
// Function : double readCO2()
// Returns : The current CO2 Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readCO2() {
int CO2_value = 0; // We will store the temperature value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr); //int K33 == 0x68
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x08); //Two bytes starting from 0x08 (high byte) and 0x09 (low byte). They contain the CO2 data
Wire.write(0x2A); //Checksum
Wire.endTransmission();
delay(50);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
CO2_value = 0;
CO2_value |= buffer[1] & 0xFF;
CO2_value = CO2_value << 8;
CO2_value |= buffer[2] & 0xFF;
Serial.print("CO2 Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)CO2_value * (double) 1);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
void setup(void)
{
Serial.begin(9600);
Serial.println();
dht.begin(); //start RH_T_sensor
//#if WAIT_TO_START
// Serial.println("Type any character to start");
// while (!Serial.available());
//#endif //WAIT_TO_START
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
error("Card failed, or not present");
}
Serial.println("card initialized.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
// connect to RTC
Wire.begin();
if (!RTC.begin()) {
logfile.println("RTC failed");
#if ECHO_TO_SERIAL
Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
}
//if (! RTC.initialized()) {
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//RTC.adjust(DateTime(2024, 5, 5, 20, 33, 0));
}
logfile.println("millis,stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2");
#if ECHO_TO_SERIAL
Serial.println("millis,stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2");
#endif //ECHO_TO_SERIAL
}
char time_to_read_CO2 = 1;
char n_delay_wait = 0;
void loop(){
DateTime now;
if (time_to_read_CO2 == 1) {
initPoll();
delay(50);
CO2Value = readCO2();
delay(20);
RHValue = readRH();
delay(20);
TempValue = readTemp();
// if(RHValue >= 0) {
// Serial.print("RH: ");
// Serial.print(RHValue);
// Serial.print("% | Temp: ");
// Serial.print(TempValue);
// Serial.print("C | CO2: ");
// Serial.print(CO2Value, 0);
// Serial.println("ppm");
// Serial.println();
// }
// else {
// Serial.println(" | Checksum failed / Communication failure");
// }
time_to_read_CO2 = 0;
}
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(", ");
#if ECHO_TO_SERIAL
Serial.print(m); // milliseconds since start
Serial.print(", ");
#endif
// fetch the time
now = RTC.now();
Serial.println(now.unixtime());
// log time
logfile.print(now.unixtime()); // seconds since 1/1/1970
logfile.print(", ");
//logfile.print('"');
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
//logfile.print('"');
#if ECHO_TO_SERIAL
Serial.print(now.unixtime()); // seconds since 1/1/1970
Serial.print(", ");
//Serial.print('"');
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
//Serial.print('"');
#endif //ECHO_TO_SERIAL
// Reading temperature or humidity takes about 250 milliseconds.
// Sensor readings may also be up to 2 seconds 'old' (its a slow sensor)
dht.readHumidity();
dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(dht.humidity) || isnan(dht.temperature_C)) {
Serial.print("DHT sensor read failure!");
return;
}
CH4s = analogRead(CH4sens); //read CH4 Vout
CH4smV = CH4s*(mV/steps); //convert pin reading to mV
delay(10); //delay between reading of different analogue pins adviced.
CH4r = analogRead(CH4ref); //read CH4 Vref
CH4rmV = CH4r*(mV/steps); //convert pin reading to mV
delay(10); //delay between reading of different analogue pins adviced.
Vbat = analogRead(Vb); //read CH4 Vref
VbatmV = Vbat *(mV/steps); //convert pin reading to mV, NOT YET correcting for the voltage divider.
delay(10); //delay between reading of different analogue pins adviced.
logfile.print(", ");
logfile.print(dht.humidity);
logfile.print(", ");
logfile.print(dht.temperature_C);
logfile.print(", ");
logfile.print(CH4smV);
logfile.print(", ");
logfile.print(CH4rmV);
logfile.print(", ");
logfile.print(VbatmV);
logfile.print(", ");
logfile.print(RHValue);
logfile.print(", ");
logfile.print(TempValue);
logfile.print(", ");
logfile.print(CO2Value);
#if ECHO_TO_SERIAL
Serial.print(", ");
Serial.print(dht.humidity);
Serial.print(", ");
Serial.print(dht.temperature_C);
Serial.print(", ");
Serial.print(CH4smV);
Serial.print(", ");
Serial.print(CH4rmV);
Serial.print(", ");
Serial.print(VbatmV);
Serial.print(", ");
Serial.print(RHValue);
Serial.print(", ");
Serial.print(TempValue);
Serial.print(", ");
Serial.print(CO2Value);
#endif //ECHO_TO_SERIAL
logfile.println();
#if ECHO_TO_SERIAL
Serial.println();
#endif // ECHO_TO_SERIAL
if (time_to_read_CO2 == 0 ) {
if (n_delay_wait < 29)
n_delay_wait += 1;
else {
time_to_read_CO2 = 1;
Serial.print("Time to read K33 sensor: ");
n_delay_wait = 0;
}
}
// Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
// which uses power and takes time
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();
logfile.flush();
}
Timestamp example for RTC - Real Time Clock
/* Timestamp functions using a DS1307 RTC connected via I2C and Wire lib
**
** Useful for file name
** ` SD.open(time.timestamp()+".log", FILE_WRITE) `
**
**
** Created: 2015-06-01 by AxelTB
** Last Edit:
*/
#include "RTClib.h"
RTC_DS1307 rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}
void loop() {
DateTime time = rtc.now();
//Full Timestamp
Serial.println(String("DateTime::TIMESTAMP_FULL:\t")+time.timestamp(DateTime::TIMESTAMP_FULL));
//Date Only
Serial.println(String("DateTime::TIMESTAMP_DATE:\t")+time.timestamp(DateTime::TIMESTAMP_DATE));
//Full Timestamp
Serial.println(String("DateTime::TIMESTAMP_TIME:\t")+time.timestamp(DateTime::TIMESTAMP_TIME));
Serial.println("\n");
//Delay 5s
delay(5000);
}
Methane and Carbon dioxide sensor sending data to Pi
// A simple CH4, CO2, RH, T data logger for the Arduino analog pins
// By David Bastviken and Nguyen Thanh Duc, Linkoping University, Sweden.
//Thanks to cactus.io and Adafruit for code components. For setup of RTC, see separate logger shield documentation.
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
//#include "RTClib.h" //RTC library
#include <cactus_io_DHT22.h>
//#include "cactus_io_DHT22.h" //RH_Temp library
#define LOG_INTERVAL 2000 // mills between logging entries (reduce to take more/faster data)
// milliseconds before writing the logged data permanently to disk
// LOG_INTERVAL write each time (safest)
#define SYNC_INTERVAL 5000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
#define DHT22_PIN 7 // DHT22 (RH_T) data pin
DHT22 dht(DHT22_PIN); // Initialize DHT sensor for normal 16mhz Arduino.
// The analog pins that connect to the sensors
#define CH4sens A1 //CH4 sensor Vout
#define CH4ref A2 //CH4 sensor Vref
#define Vb A0 //Battery voltage
int CH4s = 0;
int CH4r = 0;
int Vbat = 0;
float CH4smV = 0;
float CH4rmV = 0;
float VbatmV = 0;
float mV = 5000;
float steps = 1024;
//RTC_PCF8523 RTC; // define the Real Time Clock object
RTC_DS1307 RTC;
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str) //Halt if error
{
Serial.print("error: ");
Serial.println(str);
//digitalWrite(redLEDpin, HIGH); // red LED indicates error
while(1); //halt command
}
double RHValue = 0;
double TempValue = 0;
double CO2Value = 0;
// This is the modified address of the CO2 sensor, 7bits shifted left (defaul 0x68, but collide with RTC chip)
int co2Addr = 0x7F;
///////////////////////////////////////////////////////////////////
// Function : void initPoll()
// Executes : Tells sensor to take a measurement.
// Notes : A fuller implementation would read the register back and
// ensure the flag was set, but in our case we ensure the poll
// period is >25s and life is generally good.
///////////////////////////////////////////////////////////////////
void initPoll() {
Wire.beginTransmission(co2Addr);
Wire.write(0x11);
Wire.write(0x00);
Wire.write(0x60);
Wire.write(0x35);
Wire.write(0xA6);
Wire.endTransmission();
delay(20);
Wire.requestFrom(co2Addr, 2);
byte i = 0;
byte buffer[2] = {0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
}
///////////////////////////////////////////////////////////////////
// Function : double readRH()
// Returns : The current RH Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readRH() {
int RH_value = 0; // We will store the RH value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr);
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x14); //Two bytes starting from 0x14 (high byte) and 0x15 (low byte)
Wire.write(0x36); //Checksum
Wire.endTransmission();
delay(20);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
RH_value = 0;
RH_value |= buffer[1] & 0xFF;
RH_value = RH_value << 8;
RH_value |= buffer[2] & 0xFF;
/*
Serial.print("RH Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
*/
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)RH_value / (double) 100);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
///////////////////////////////////////////////////////////////////
// Function : double readTemp()
// Returns : The current Temperature Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readTemp() {
int Temp_value = 0; // We will store the temperature value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr); //int K33 == 0x68
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x12); //Two bytes starting from 0x12 (high byte) and 0x13 (low byte)
Wire.write(0x34); //Checksum
Wire.endTransmission();
delay(20);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
Temp_value = 0;
Temp_value |= buffer[1] & 0xFF;
Temp_value = Temp_value << 8;
Temp_value |= buffer[2] & 0xFF;
/*
Serial.print("T Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
*/
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)Temp_value / (double) 100);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
///////////////////////////////////////////////////////////////////
// Function : double readCO2()
// Returns : The current CO2 Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readCO2() {
int CO2_value = 0; // We will store the temperature value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr); //int K33 == 0x68
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x08); //Two bytes starting from 0x08 (high byte) and 0x09 (low byte). They contain the CO2 data
Wire.write(0x2A); //Checksum
Wire.endTransmission();
delay(50);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
CO2_value = 0;
CO2_value |= buffer[1] & 0xFF;
CO2_value = CO2_value << 8;
CO2_value |= buffer[2] & 0xFF;
/*
Serial.print("CO2 Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
*/
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)CO2_value * (double) 1);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
void setup(void)
{
Serial.begin(9600);
Serial.println();
dht.begin(); //start RH_T_sensor
//#if WAIT_TO_START
// Serial.println("Type any character to start");
// while (!Serial.available());
//#endif //WAIT_TO_START
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
error("Card failed, or not present");
}
Serial.println("card initialized.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
// connect to RTC
Wire.begin();
if (!RTC.begin()) {
logfile.println("RTC failed");
#if ECHO_TO_SERIAL
Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
}
//if (! RTC.initialized()) {
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//RTC.adjust(DateTime(2024, 5, 5, 20, 33, 0));
}
//Edmond 31 May 2024
//logfile.println("millis,stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2");
#if ECHO_TO_SERIAL
Serial.println("millis,stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2");
#endif //ECHO_TO_SERIAL
}
char time_to_read_CO2 = 1;
char n_delay_wait = 0;
void loop(){
DateTime now;
if (time_to_read_CO2 == 1) {
initPoll();
delay(50);
CO2Value = readCO2();
delay(20);
RHValue = readRH();
delay(20);
TempValue = readTemp();
// if(RHValue >= 0) {
// Serial.print("RH: ");
// Serial.print(RHValue);
// Serial.print("% | Temp: ");
// Serial.print(TempValue);
// Serial.print("C | CO2: ");
// Serial.print(CO2Value, 0);
// Serial.println("ppm");
// Serial.println();
// }
// else {
// Serial.println(" | Checksum failed / Communication failure");
// }
time_to_read_CO2 = 0;
}
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(", ");
#if ECHO_TO_SERIAL
//Serial.print(m); // milliseconds since start
//Serial.print(", ");
#endif
// fetch the time
now = RTC.now();
//Serial.println(now.unixtime());
// log time
/*
logfile.print(now.unixtime()); // seconds since 1/1/1970
logfile.print(", ");
//logfile.print('"');
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
//logfile.print('"');
*/
#if ECHO_TO_SERIAL
Serial.print(now.unixtime()); // seconds since 1/1/1970
Serial.print(",");
//Serial.print('"');
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
//Serial.print('"');
#endif //ECHO_TO_SERIAL
// Reading temperature or humidity takes about 250 milliseconds.
// Sensor readings may also be up to 2 seconds 'old' (its a slow sensor)
dht.readHumidity();
dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(dht.humidity) || isnan(dht.temperature_C)) {
Serial.print("DHT sensor read failure!");
return;
}
CH4s = analogRead(CH4sens); //read CH4 Vout
CH4smV = CH4s*(mV/steps); //convert pin reading to mV
delay(10); //delay between reading of different analogue pins adviced.
CH4r = analogRead(CH4ref); //read CH4 Vref
CH4rmV = CH4r*(mV/steps); //convert pin reading to mV
delay(10); //delay between reading of different analogue pins adviced.
Vbat = analogRead(Vb); //read CH4 Vref
VbatmV = Vbat *(mV/steps); //convert pin reading to mV, NOT YET correcting for the voltage divider.
delay(10); //delay between reading of different analogue pins adviced.
/*
logfile.print(", ");
logfile.print(dht.humidity);
logfile.print(", ");
logfile.print(dht.temperature_C);
logfile.print(", ");
logfile.print(CH4smV);
logfile.print(", ");
logfile.print(CH4rmV);
logfile.print(", ");
logfile.print(VbatmV);
logfile.print(", ");
logfile.print(RHValue);
logfile.print(", ");
logfile.print(TempValue);
logfile.print(", ");
logfile.print(CO2Value);
*/
#if ECHO_TO_SERIAL
Serial.print(",");
Serial.print(dht.humidity);
Serial.print(",");
Serial.print(dht.temperature_C);
Serial.print(",");
Serial.print(CH4smV);
Serial.print(",");
Serial.print(CH4rmV);
Serial.print(",");
Serial.print(VbatmV);
Serial.print(",");
Serial.print(RHValue);
Serial.print(",");
Serial.print(TempValue);
Serial.print(",");
Serial.print(CO2Value);
#endif //ECHO_TO_SERIAL
/*
logfile.println();
*/
#if ECHO_TO_SERIAL
Serial.println();
#endif // ECHO_TO_SERIAL
if (time_to_read_CO2 == 0 ) {
if (n_delay_wait < 29)
n_delay_wait += 1;
else {
time_to_read_CO2 = 1;
/*
Serial.print("Time to read K33 sensor: ");
*/
n_delay_wait = 0;
}
}
// Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
// which uses power and takes time
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();
/*
logfile.flush();
*/
}
Methane and Carbon dioxide sensor sending data to Pi
Python code
#!/usr/bin/env python3
# dweet data
import serial
import datetime
import time
import requests
import pandas as pd
import plotly.express as px
from water_variables import *
count = 0
if __name__ == '__main__':
# methane
ser = serial.Serial('/dev/ttyUSB1', 9600, timeout=1)
ser.reset_input_buffer()
while True:
count = count + 1
time.sleep(0.1)
if ser.in_waiting > 0:
time.sleep(0.1)
try:
line = ser.readline().decode('utf-8').rstrip()
print(line)
except:
line = "0,0,0,0,0,0,0,0,0,0"
#print(f"Data separated using commas {line.split(',')}")
mylist = line.split(',')
print(f'My list {mylist}')
try:
# stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2
stampunix = str(mylist[0])
date_time_not_used = str(mylist[1])
RH1 = str(mylist[2])
temp1 = str(mylist[3])
CH4smV = str(mylist[4])
CH4rmV = str(mylist[5])
VbatmV = str(mylist[6])
K33_RH = str(mylist[7])
K33_Temp = str(mylist[8])
K33_CO2 = str(mylist[9])
print("data extracted")
except:
stampunix = "0.0"
date_time_not_used = "0.0"
RH1 = "0.0"
temp1 = "0.0"
CH4smV = "0.0"
CH4rmV = "0"
VbatmV = "0.0"
K33_RH = "0.0"
K33_Temp = "0.0"
K33_CO2 = "0.0"
now = datetime.datetime.now()
date_stamp = now.strftime("%Y-%m-%d %H:%M:%S")
print(f'CH4smV - {CH4smV}, K33_CO2 - {K33_CO2}, time - {date_stamp}')
print(count)
print()
time.sleep(0.1)
data = ""
data = date_stamp + "," + str(RH1) + "," + str(temp1) + "," + str(CH4smV) + "," +\
str(CH4rmV) + "," + str(VbatmV) + "," + str(K33_RH) + "," + \
str(K33_Temp) + "," + str(K33_CO2) + '\n'
#print(f'The data is = {data}')
if count > 3000:
#print(count)
f = open('/home/pi/Aquarium/aquarium_methane.txt','a')
f.write(data)
f.close()
print("Data saved")
try:
print("Preparing dweet")
dweet_dict = {}
dweet_dict.update({"RH1": str(RH1)})
dweet_dict.update({"temp1": str(temp1)})
dweet_dict.update({"CH4smV": str(CH4smV)})
dweet_dict.update({"CH4rmV": str(CH4rmV)})
dweet_dict.update({"VbatmV": str(VbatmV)})
dweet_dict.update({"K33_RH": str(K33_RH)})
dweet_dict.update({"K33_Temp": str(K33_Temp)})
dweet_dict.update({"K33_CO2": str(K33_CO2)})
dweet_dict.update({"time": str(date_stamp)})
url = "https://dweet.io/dweet/for/3083-Bundoora-aquarium_methane1?"
#https://dweet.io/get/latest/dweet/for/3083-Bundoora-aquarium_methane1?
x = requests.post(url, json=dweet_dict)
print(x.text)
except:
print("Dweet failed")
count = 0
# check dweet with - https://dweet.io/get/latest/dweet/for/3083-Bundoora-aquarium1
# Step 2: Read the data from the text file into a Pandas DataFrame
#data = pd.read_csv('/home/pi/Aquarium/aquarium_methane.txt')
# Step 3: Create a Plotly figure with two scatter plots
#fig = px.scatter(data, x='datetime', y=['temperature','dissolvedOxygen'],
#labels={'datetime': 'Date and Time', 'value': 'Temperature (°C)'},
#title='Aquarium temperature and DO')
# Step 4: Customize the plot layout
#fig.update_layout(xaxis_title='Date and Time', yaxis_title='Temperature (°C)')
# Step 5: Save the plot as an HTML file
#fig.write_html('/home/pi/Aquarium/temperature_plot_DO_EC_chem_aquarium.html')
#print("Aquarium plot saved as temperature_plot.html")
Working Arduino Code 6 June 2024
// A simple CH4, CO2, RH, T data logger for the Arduino analog pins
// By David Bastviken and Nguyen Thanh Duc, Linkoping University, Sweden.
//Thanks to cactus.io and Adafruit for code components. For setup of RTC, see separate logger shield documentation.
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
//#include "RTClib.h" //RTC library
#include <cactus_io_DHT22.h>
//#include "cactus_io_DHT22.h" //RH_Temp library
#define LOG_INTERVAL 2000 // mills between logging entries (reduce to take more/faster data)
// milliseconds before writing the logged data permanently to disk
// LOG_INTERVAL write each time (safest)
#define SYNC_INTERVAL 5000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
#define DHT22_PIN 7 // DHT22 (RH_T) data pin
DHT22 dht(DHT22_PIN); // Initialize DHT sensor for normal 16mhz Arduino.
// The analog pins that connect to the sensors
#define CH4sens A1 //CH4 sensor Vout
#define CH4ref A2 //CH4 sensor Vref
#define Vb A0 //Battery voltage
int CH4s = 0;
int CH4r = 0;
int Vbat = 0;
float CH4smV = 0;
float CH4rmV = 0;
float VbatmV = 0;
float mV = 5000;
float steps = 1024;
//RTC_PCF8523 RTC; // define the Real Time Clock object
RTC_DS1307 RTC;
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str) //Halt if error
{
Serial.print("error: ");
Serial.println(str);
//digitalWrite(redLEDpin, HIGH); // red LED indicates error
while(1); //halt command
}
double RHValue = 0;
double TempValue = 0;
double CO2Value = 0;
// This is the modified address of the CO2 sensor, 7bits shifted left (defaul 0x68, but collide with RTC chip)
int co2Addr = 0x7F;
///////////////////////////////////////////////////////////////////
// Function : void initPoll()
// Executes : Tells sensor to take a measurement.
// Notes : A fuller implementation would read the register back and
// ensure the flag was set, but in our case we ensure the poll
// period is >25s and life is generally good.
///////////////////////////////////////////////////////////////////
void initPoll() {
Wire.beginTransmission(co2Addr);
Wire.write(0x11);
Wire.write(0x00);
Wire.write(0x60);
Wire.write(0x35);
Wire.write(0xA6);
Wire.endTransmission();
delay(20);
Wire.requestFrom(co2Addr, 2);
byte i = 0;
byte buffer[2] = {0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
}
///////////////////////////////////////////////////////////////////
// Function : double readRH()
// Returns : The current RH Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readRH() {
int RH_value = 0; // We will store the RH value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr);
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x14); //Two bytes starting from 0x14 (high byte) and 0x15 (low byte)
Wire.write(0x36); //Checksum
Wire.endTransmission();
delay(20);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
RH_value = 0;
RH_value |= buffer[1] & 0xFF;
RH_value = RH_value << 8;
RH_value |= buffer[2] & 0xFF;
/*
Serial.print("RH Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
*/
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)RH_value / (double) 100);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
///////////////////////////////////////////////////////////////////
// Function : double readTemp()
// Returns : The current Temperature Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readTemp() {
int Temp_value = 0; // We will store the temperature value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr); //int K33 == 0x68
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x12); //Two bytes starting from 0x12 (high byte) and 0x13 (low byte)
Wire.write(0x34); //Checksum
Wire.endTransmission();
delay(20);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
Temp_value = 0;
Temp_value |= buffer[1] & 0xFF;
Temp_value = Temp_value << 8;
Temp_value |= buffer[2] & 0xFF;
/*
Serial.print("T Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
*/
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)Temp_value / (double) 100);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
///////////////////////////////////////////////////////////////////
// Function : double readCO2()
// Returns : The current CO2 Value, ?1 if error has occured
///////////////////////////////////////////////////////////////////
double readCO2() {
int CO2_value = 0; // We will store the temperature value inside this variable.
digitalWrite(13, HIGH);
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr); //int K33 == 0x68
Wire.write(0x22); //Command number 2 (Read Ram, 2 bytes)
Wire.write(0x00); //Sensor address in ?? EEPROM ??
Wire.write(0x08); //Two bytes starting from 0x08 (high byte) and 0x09 (low byte). They contain the CO2 data
Wire.write(0x2A); //Checksum
Wire.endTransmission();
delay(50);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
while(Wire.available()) {
buffer[i] = Wire.read();
i++;
}
CO2_value = 0;
CO2_value |= buffer[1] & 0xFF;
CO2_value = CO2_value << 8;
CO2_value |= buffer[2] & 0xFF;
/*
Serial.print("CO2 Data ");
Serial.print(buffer[0], HEX);
Serial.print("|");
Serial.print(buffer[1], HEX);
Serial.print("|");
Serial.print(buffer[2], HEX);
Serial.print("|");
Serial.println(buffer[3], HEX);
*/
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if(sum == buffer[3]) {
// Success!
digitalWrite(13, LOW);
delay(10);
return ((double)CO2_value * (double) 1);
}
else {
// Failure!
digitalWrite(13, LOW);
delay(10);
return ((double) -1);
}
}
void setup(void)
{
Serial.begin(9600);
Serial.println();
dht.begin(); //start RH_T_sensor
//#if WAIT_TO_START
// Serial.println("Type any character to start");
// while (!Serial.available());
//#endif //WAIT_TO_START
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
error("Card failed, or not present");
}
Serial.println("card initialized.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
// connect to RTC
Wire.begin();
if (!RTC.begin()) {
logfile.println("RTC failed");
#if ECHO_TO_SERIAL
Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
}
//if (! RTC.initialized()) {
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//RTC.adjust(DateTime(2024, 5, 5, 20, 33, 0));
}
//Edmond 31 May 2024
//logfile.println("millis,stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2");
#if ECHO_TO_SERIAL
Serial.println("millis,stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2");
#endif //ECHO_TO_SERIAL
}
char time_to_read_CO2 = 1;
char n_delay_wait = 0;
void loop(){
DateTime now;
if (time_to_read_CO2 == 1) {
initPoll();
delay(50);
CO2Value = readCO2();
delay(20);
RHValue = readRH();
delay(20);
TempValue = readTemp();
// if(RHValue >= 0) {
// Serial.print("RH: ");
// Serial.print(RHValue);
// Serial.print("% | Temp: ");
// Serial.print(TempValue);
// Serial.print("C | CO2: ");
// Serial.print(CO2Value, 0);
// Serial.println("ppm");
// Serial.println();
// }
// else {
// Serial.println(" | Checksum failed / Communication failure");
// }
time_to_read_CO2 = 0;
}
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(", ");
#if ECHO_TO_SERIAL
//Serial.print(m); // milliseconds since start
//Serial.print(", ");
#endif
// fetch the time
now = RTC.now();
//Serial.println(now.unixtime());
// log time
/*
logfile.print(now.unixtime()); // seconds since 1/1/1970
logfile.print(", ");
//logfile.print('"');
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
//logfile.print('"');
*/
#if ECHO_TO_SERIAL
Serial.print(now.unixtime()); // seconds since 1/1/1970
Serial.print(",");
//Serial.print('"');
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
//Serial.print('"');
#endif //ECHO_TO_SERIAL
// Reading temperature or humidity takes about 250 milliseconds.
// Sensor readings may also be up to 2 seconds 'old' (its a slow sensor)
dht.readHumidity();
dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(dht.humidity) || isnan(dht.temperature_C)) {
Serial.print("DHT sensor read failure!");
return;
}
CH4s = analogRead(CH4sens); //read CH4 Vout
CH4smV = CH4s*(mV/steps); //convert pin reading to mV
delay(10); //delay between reading of different analogue pins adviced.
CH4r = analogRead(CH4ref); //read CH4 Vref
CH4rmV = CH4r*(mV/steps); //convert pin reading to mV
delay(10); //delay between reading of different analogue pins adviced.
Vbat = analogRead(Vb); //read CH4 Vref
VbatmV = Vbat *(mV/steps); //convert pin reading to mV, NOT YET correcting for the voltage divider.
delay(10); //delay between reading of different analogue pins adviced.
/*
logfile.print(", ");
logfile.print(dht.humidity);
logfile.print(", ");
logfile.print(dht.temperature_C);
logfile.print(", ");
logfile.print(CH4smV);
logfile.print(", ");
logfile.print(CH4rmV);
logfile.print(", ");
logfile.print(VbatmV);
logfile.print(", ");
logfile.print(RHValue);
logfile.print(", ");
logfile.print(TempValue);
logfile.print(", ");
logfile.print(CO2Value);
*/
#if ECHO_TO_SERIAL
Serial.print(",");
Serial.print(dht.humidity);
Serial.print(",");
Serial.print(dht.temperature_C);
Serial.print(",");
Serial.print(CH4smV);
Serial.print(",");
Serial.print(CH4rmV);
Serial.print(",");
Serial.print(VbatmV);
Serial.print(",");
Serial.print(RHValue);
Serial.print(",");
Serial.print(TempValue);
Serial.print(",");
Serial.print(CO2Value);
#endif //ECHO_TO_SERIAL
/*
logfile.println();
*/
#if ECHO_TO_SERIAL
Serial.println();
#endif // ECHO_TO_SERIAL
if (time_to_read_CO2 == 0 ) {
if (n_delay_wait < 29)
n_delay_wait += 1;
else {
time_to_read_CO2 = 1;
/*
Serial.print("Time to read K33 sensor: ");
*/
n_delay_wait = 0;
}
}
// Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
// which uses power and takes time
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();
/*
logfile.flush();
*/
}
Working Python Code 6 June 2024
#!/usr/bin/env python3
# dweet data
import serial
import datetime
import time
import requests
import pandas as pd
import plotly.express as px
from water_variables import *
count = 0
if __name__ == '__main__':
# methane
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
ser.reset_input_buffer()
while True:
count = count + 1
time.sleep(0.1)
if ser.in_waiting > 0:
time.sleep(0.1)
try:
line = ser.readline().decode('utf-8').rstrip()
print(line)
except:
line = "0,0,0,0,0,0,0,0,0,0"
#print(f"Data separated using commas {line.split(',')}")
mylist = line.split(',')
print(f'My list {mylist}')
try:
# stampunix,datetime,RH%,tempC,CH4smV, CH4rmV, VbatmV, K33_RH, K33_Temp, K33_CO2
stampunix = str(mylist[0])
date_time_not_used = str(mylist[1])
RH1 = str(mylist[2])
temp1 = str(mylist[3])
CH4smV = str(mylist[4])
CH4rmV = str(mylist[5])
VbatmV = str(mylist[6])
K33_RH = str(mylist[7])
K33_Temp = str(mylist[8])
K33_CO2 = str(mylist[9])
print("data extracted")
except:
stampunix = "0.0"
date_time_not_used = "0.0"
RH1 = "0.0"
temp1 = "0.0"
CH4smV = "0.0"
CH4rmV = "0"
VbatmV = "0.0"
K33_RH = "0.0"
K33_Temp = "0.0"
K33_CO2 = "0.0"
now = datetime.datetime.now()
date_stamp = now.strftime("%Y-%m-%d %H:%M:%S")
print(f'CH4smV - {CH4smV}, K33_CO2 - {K33_CO2}, time - {date_stamp}')
print(count)
print()
time.sleep(0.1)
data = ""
data = date_stamp + "," + str(RH1) + "," + str(temp1) + "," + str(CH4smV) + "," +\
str(CH4rmV) + "," + str(VbatmV) + "," + str(K33_RH) + "," + \
str(K33_Temp) + "," + str(K33_CO2) + '\n'
#print(f'The data is = {data}')
if count > 3000 and K33_CO2 != "0.00":
#print(count)
f = open('/home/pi/Aquarium/aquarium_methane.txt','a')
f.write(data)
f.close()
print("Data saved")
try:
print("Preparing dweet")
dweet_dict = {}
dweet_dict.update({"RH1": str(RH1)})
dweet_dict.update({"temp1": str(temp1)})
dweet_dict.update({"CH4smV": str(CH4smV)})
dweet_dict.update({"CH4rmV": str(CH4rmV)})
dweet_dict.update({"VbatmV": str(VbatmV)})
dweet_dict.update({"K33_RH": str(K33_RH)})
dweet_dict.update({"K33_Temp": str(K33_Temp)})
dweet_dict.update({"K33_CO2": str(K33_CO2)})
dweet_dict.update({"time": str(date_stamp)})
url = "https://dweet.io/dweet/for/3083-Bundoora-aquarium_methane1?"
#https://dweet.io/get/latest/dweet/for/3083-Bundoora-aquarium_methane1?
x = requests.post(url, json=dweet_dict)
print(x.text)
except:
print("Dweet failed")
count = 0
# check dweet with - https://dweet.io/get/latest/dweet/for/3083-Bundoora-aquarium1
# Step 2: Read the data from the text file into a Pandas DataFrame
data = pd.read_csv('/home/pi/Aquarium/aquarium_methane.txt')
# Step 3: Create a Plotly figure with two scatter plots
fig = px.scatter(data, x='date_stamp', y=['CH4rmV','K33_CO2'],
labels={'date_stamp': 'Date and Time', 'value': 'Gas quantity'},
title='Aquarium methane and CO2')
# Step 4: Customize the plot layout
fig.update_layout(xaxis_title='Date and Time', yaxis_title='Gas quantity')
# Step 5: Save the plot as an HTML file
fig.write_html('/home/pi/Aquarium/methane_aquarium.html')
print("Aquarium plot saved as methane_aquarium.html")