/* DHT22_BME280_2.ino, David R. Brooks, June 2017 See DHT22_BME280.ino for code that logging at even minute/second intervals. This code increases sleep time by logging at approximate intervals rather than watching the clock for even intervals. This code assumes use of separate clock and SD card modules, as required for use with a SparkFun Pro Mini board (shields don't fit). For the DHT22 sensor: pin 1 (on the left) to +5V, pin 2 to DHTPIN (digital pin 8 in this case), pin 4 (on the right) to GND, 10K resistor from pin 2 (data) to pin 1 (power) of the sensor For clock and BME280, SCL and SDA. For SD module: microSD --> Arduino CLK --> 13 DO --> 12 DI --> 11 CS --> 10 */ #include #include #include #include #include #include #include #include // for DHT11 or DHT22 sensors #define ECHO_TO_SERIAL 0 #define ECHO_TO_FILE 1 #define DHTPIN 8 // digital pin for reading DHT22 #define DHTTYPE DHT22 // change to DHT11 with DHT11 sensor #define SDpin 10 // internally connected pin for SD card RTC_DS1307 rtc; // real time clock Adafruit_BME280 bme; // I2C device DHT dht(DHTPIN,DHTTYPE); float T,RH,P,day_frac,DHT_T,DHT_RH; File logfile; const int msec=29000; void setup() { Serial.begin(9600); Wire.begin(); rtc.begin(); //rtc.adjust(DateTime(__DATE__, __TIME__)); if (!rtc.isrunning()) { Serial.println("RTC not running."); exit; } Serial.println("DHT22-BME280 data"); dht.begin(); bme.begin(); #if ECHO_TO_FILE Serial.print("Initializing SD card..."); pinMode(10,OUTPUT); if (!SD.begin(SDpin)) {Serial.println("Card failed."); delay(50); exit(0);} Serial.println("card initialized."); char filename[] = "LOGGER00.CSV"; for (uint8_t i = 0; i < 100; i++) { filename[6] = i/10 + '0'; filename[7] = i%10 + '0'; // Create a new file LOGGERxx.CSV, xx= 01 to 99, only if it doesn't already exist. if (! SD.exists(filename)) { logfile = SD.open(filename, FILE_WRITE); if (!logfile) {Serial.println("Couldn't create file."); delay(50); exit(0);} break; // Leave the loop once a file is created. } } logfile=SD.open(filename,FILE_WRITE); Serial.print("Logging to: "); Serial.println(filename); logfile.println("yr,mon,day,hr,min,sec,day_frac,DHT_T(*C),DHT_RH(%),BME280_T(*C),BME280_RH(%),BME280_P(mbar)"); logfile.flush(); #endif // ECHO_TO_FILE #if ECHO_TO_SERIAL Serial.println("yr,mon,day,hr,min,sec,DHT_T(*C),DHT_RH(%),BME280_T(*C),BME280_RH(%),BME280_P(mbar)"); #endif // ECHO_TO_SERIAL } void loop() { delay(100); // Wait a little after end of Narcoleptic sleep... DateTime now=rtc.now(); DHT_T = dht.readTemperature(); DHT_RH = dht.readHumidity(); T=bme.readTemperature(); RH=bme.readHumidity(); P=bme.readPressure(); #if ECHO_TO_SERIAL Serial.print(now.year()); Serial.print('/'); Serial.print(now.month()); Serial.print('/'); Serial.print(now.day()); Serial.print(", "); Serial.print(now.hour()); Serial.print(':'); Serial.print(now.minute()); Serial.print(':'); Serial.print(now.second()); Serial.print(", "); Serial.print(DHT_T,1); Serial.print(", "); Serial.print(DHT_RH,1); Serial.print(", "); Serial.print(T,1); Serial.print(", "); Serial.print(RH,1); Serial.print(", "); Serial.print(P/100,1); Serial.println(); delay(100); // Give prints time to finish before Narcoleptic sleep. Narcoleptic.delay(msec); #endif // ECHO_TO_SERIAL #if ECHO_TO_FILE //V_batt=5.*analogRead(batt_pin)/1023; logfile.print(now.year()); logfile.print(','); logfile.print(now.month()); logfile.print(','); logfile.print(now.day()); logfile.print(','); logfile.print(now.hour()); logfile.print(','); logfile.print(now.minute()); logfile.print(','); logfile.print(now.second()); logfile.print(','); delay(10); day_frac=now.day()+now.hour()/24.+now.minute()/1440.+now.second()/86400.; logfile.print(day_frac,6); logfile.print(','); logfile.print(DHT_T,1);logfile.print(','); logfile.print(DHT_RH,1); logfile.print(','); logfile.print(T,2); logfile.print(','); logfile.print(RH,2); logfile.print(','); logfile.print(P/100,2); logfile.println(); logfile.flush(); delay(100); // Give prints time to finish before Narcoleptic sleep. Narcoleptic.delay(msec); Narcoleptic.delay(msec); Narcoleptic.delay(msec); Narcoleptic.delay(msec); // Sleep for a little while. #endif // ECHO_TO_FILE } ------------------------------------------------------ /* RadioHead69_ReceiveTRH_LCD_SD.ino, D. Brooks, September 2017 A modification of the example RX code for the RH-RF69 packet radio module. Receives a text string from the TX module (see RadioHead69_DHT22_LowPower.ino) and formats it for display on a 2-line LCD and saving on an SD card with date/time stamp using datalogging shield, both from adafruit.com. */ #include #include #include #include #include #include #define RF69_FREQ 900.0 #define ON 0x1 #define SDpin 10 #define RFM69_INT 3 #define RFM69_CS 4 #define RFM69_RST 2 #define LED 13 RTC_DS1307 rtc; Adafruit_RGBLCDShield lcd=Adafruit_RGBLCDShield(); RH_RF69 rf69(RFM69_CS, RFM69_INT); char L1_text[6]="T,RH="; int i; File logfile; char filename[]="LOG00000.CSV"; void setup() { Serial.begin(9600); SD.begin(); Wire.begin(); rtc.begin(); logfile=SD.open(filename,FILE_WRITE); lcd.begin(16,2); lcd.setBacklight(ON); pinMode(LED, OUTPUT); pinMode(RFM69_RST, OUTPUT); digitalWrite(RFM69_RST, LOW); // manual reset digitalWrite(RFM69_RST, HIGH); delay(10); digitalWrite(RFM69_RST, LOW); delay(10); if (!rf69.init()) { Serial.println("RFM69 radio init failed"); while (1); } Serial.println("RFM69 radio init OK!"); if (!rf69.setFrequency(RF69_FREQ)) { Serial.println("setFrequency failed"); } rf69.setTxPower(20, true); // range from 14-20 for power, // The encryption key has to be the same as the one in the TX. uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; rf69.setEncryptionKey(key); pinMode(LED, OUTPUT); Serial.print("RFM69 radio @"); Serial.print((int)RF69_FREQ); Serial.println(" MHz"); } void loop() { if (rf69.available()) { // Should be a message for us now uint8_t buf[RH_RF69_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (rf69.recv(buf, &len)) { if (!len) return; buf[len] = 0; Serial.println(); Serial.print(L1_text); lcd.clear(); lcd.print(L1_text); for (i=0; i<4; i++) { Serial.print((char)buf[i]); lcd.print((char)buf[i]); logfile.print((char)buf[i]); } Serial.println(); lcd.print(','); //lcd.setCursor(0,1); lcd.print(L2_text); Serial.print(L2_text); logfile.print(','); for (i=7; i<=10; i++) { Serial.print((char)buf[i]); lcd.print((char)buf[i]); logfile.print((char)buf[i]); } Serial.println(); logfile.print(','); DateTime now=rtc.now(); logfile.print(now.year()); logfile.print(','); logfile.print(now.month()); logfile.print(','); logfile.print(now.day()); logfile.print(','); logfile.print(now.hour()); logfile.print(','); logfile.print(now.minute()); logfile.print(','); logfile.print(now.second()); logfile.print(','); logfile.println(); logfile.flush(); lcd.setCursor(0,1); lcd.print(now.month()); lcd.print('/'); lcd.print(now.day()); lcd.print(' '); lcd.print(now.hour()); lcd.print(':'); lcd.print(now.minute()); lcd.print(':'); lcd.print(now.second()); } else { lcd.print("Receive failed"); } } } ---------------------------------------------------------------- /* RadioHead69_DHT22_BME280_TXLowPower, D. Brooks, November 2017 Puts all the TX code in the setup() function. Turns system on to collect data and send packet, then turns system off upon receipt of "done" signal from Pro Mini Board, using the TPL5110 low power module from adafruit.com. */ #include #include #include #include #include #include /************ Radio Setup ***************/ // Change to 434.0 or other frequency, must match RX's freq! #define RF69_FREQ 900.0 // for UNO #define RFM69_INT 3 // #define RFM69_CS 4 // #define RFM69_RST 2 // #define DHTPIN 8 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); Adafruit_BME280 bme; RH_RF69 rf69(RFM69_CS, RFM69_INT); // Instantiate radio driver. float T, RH,T_BME,RH_BME,P_BME; int i; const int donePIN=5; char RadioPacket[30]; char TString[6],RHString[6]; // DHT22 char T_BMEString[6],RH_BMEString[6],P_BMEString[7]; // BME280 // The encryption key has to be the same as the one in the receiver. uint8_t key[] = { 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; void setup() { pinMode(donePIN,OUTPUT); digitalWrite(donePIN,LOW); Serial.begin(9600); dht.begin(); bme.begin(); pinMode(RFM69_RST, OUTPUT); digitalWrite(RFM69_RST, LOW); // manual reset digitalWrite(RFM69_RST, HIGH); delay(10); digitalWrite(RFM69_RST, LOW); delay(10); if (!rf69.init()) { Serial.println("RFM69 radio init failed"); while (1); } Serial.println("RFM69 radio init OK!"); // Defaults after init are 434.0MHz, // modulation GFSK_Rb250Fd250, // +13dbM (for low power module) // No encryption if (!rf69.setFrequency(RF69_FREQ)) { Serial.println("setFrequency failed"); } rf69.setTxPower(20, true); // range from 14-20 for power rf69.setEncryptionKey(key); Serial.print("RFM69 radio @"); Serial.print((int)RF69_FREQ); Serial.println(" MHz"); // Build text string from T and RH values, comma separated. // read DHT22 delay(2000); T = dht.readTemperature(); delay(20); delay(10); RH = dht.readHumidity(); delay(20); RH-dht.readHumidity(); dtostrf(RH, 5, 1, RHString); dtostrf(T, 5, 1, TString); // read BME280 T_BME=bme.readTemperature(); RH_BME=bme.readHumidity(); P_BME=bme.readPressure(); // Serial.print(T_BME); Serial.print(' '); Serial.print(RH_BME); // Serial.print(' '); //Serial.println(P_BME); dtostrf(RH_BME,5,1,RH_BMEString);dtostrf(T_BME,5,1,T_BMEString); dtostrf(P_BME/100.,6,1,P_BMEString); // DHT22 part of packet string for (i = 0; i <= 4; i++) { RadioPacket[i] = TString[i]; } RadioPacket[5] = ','; for (i = 6; i <= 10; i++) { RadioPacket[i] = RHString[i - 6]; } // BME280 part of packet string RadioPacket[11]=','; for (i=12; i<=16; i++) { RadioPacket[i] = T_BMEString[i-12]; } RadioPacket[17]=','; for (i=18; i<=22; i++) { RadioPacket[i] = RH_BMEString[i-18]; } RadioPacket[23] =','; for (i=24; i<=29; i++) { RadioPacket[i] = P_BMEString[i-24]; } // string terminator RadioPacket[30] = '\0'; // Test contents of RadioPacket string. //for (i=0; i<30; i++) { // Serial.print(RadioPacket[i]); //} //Serial.println(); rf69.send((uint8_t *)RadioPacket, strlen(RadioPacket)); rf69.waitPacketSent(); // Now wait for a reply uint8_t buf[RH_RF69_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (rf69.waitAvailableTimeout(500)) { // Should be a reply message for us now if (rf69.recv(buf, &len)) { Serial.print("Got a reply: "); Serial.println((char*)buf); } else { Serial.println("Receive failed"); } } else { Serial.println("No reply, is another RFM69 listening?"); } delay(50); digitalWrite(donePIN,HIGH); // turn off power } void loop() { } ------------------------------------------------- /* Connections on Pro Mini: "Done" to digital 5 "DRV" to VCC */ #include #include #include #include #include Adafruit_ADS1115 ads(0x48); // default address is 0x48 RTC_DS1307 rtc; float V0,V1; //float V2,V3;; //float DtoA=0.015625/1000.; float DtoA=0.007813/1000; const int donePin=5,SDpin=10; // SDpin fixed for the microSD board. File logfile; char filename[]="LOG00000.CSV"; void setup() { //Serial.begin(9600); // Power is applied... pinMode(donePin,OUTPUT); digitalWrite(donePin,LOW); // power on //Serial.println("low power pin LOW"); //Serial.begin(9600); Wire.begin(); rtc.begin(); if (!rtc.isrunning()) { //Serial.println("RTC not running."); exit; } //rtc.adjust(DateTime(__DATE__, __TIME__)); //Serial.print("Initializing SD card..."); pinMode(10,OUTPUT); if (!SD.begin(SDpin)) { //Serial.println("Card failed."); delay(50);exit(0);} //Serial.println("card initialized."); ads.begin(); //ads.setGain(GAIN_EIGHT); // full scale = 0.512 V ads.setGain(GAIN_SIXTEEN); int16_t adc0,adc1; // ADC reading produces 16-bit integers //int16_t adc2,adc3; adc0 = ads.readADC_SingleEnded(0); adc1 = ads.readADC_SingleEnded(1); //adc2 = ads.readADC_SingleEnded(2); //adc3 = ads.readADC_SingleEnded(3); V0 = adc0 * DtoA; V1 = adc1 * DtoA; //V2 = adc2 * DtoA; //V3 = adc3 * DtoA; //Serial.print(adc0); Serial.print(" V0="); //Serial.print(V0, 4); Serial.print(' '); //Serial.print(adc1); Serial.print(" V1="); //Serial.print(V1, 4); Serial.print(' '); //Serial.print(adc2); Serial.print(" V2="); //Serial.print(V2, 4); Serial.print(' '); //Serial.print(adc3); Serial.print(" V3="); //Serial.print(V3, 4); Serial.print(' '); //Serial.println(); DateTime now=rtc.now(); logfile=SD.open(filename,FILE_WRITE); logfile.print(now.year()); logfile.print(','); logfile.print(now.month()); logfile.print(','); logfile.print(now.day()); logfile.print(','); logfile.print(now.hour()); logfile.print(','); logfile.print(now.minute()); logfile.print(','); logfile.print(now.second()); logfile.print(','); logfile.print(V0,5); logfile.print(','); logfile.print(V1,5); logfile.print(','); //logfile.print(V2,5); logfile.print(','); //logfile.print(V3,5); logfile.println(); logfile.flush(); delay(250); logfile.close(); delay(250); digitalWrite(donePin,HIGH); // power off //Serial.println("low power pin HIGH"); } void loop() {} ------------------------------------ /* LCD1602_I2C_template, D. Brooks, September 2017 Email:support@sunfounder.com Website:www.sunfounder.com */ #include #include LiquidCrystal_I2C lcd(0x27,16,2); /LCD address is 0x27 for 16 char, 2 line display char line1[]="T(C) = "; char line2[]="RH(%) = "; int col1,col2; void setup() { Serial.begin(9600); lcd.init(); //initialize the lcd lcd.backlight(); //turn on the backlight lcd.clear(); lcd.setCursor(0,0); lcd.print(line1); lcd.setCursor(0,1); lcd.print(line2); } void loop() {} /* ADC1115_LowPowerTest.ino, D. Brooks, Nov. 2017 Uses adafruit low power timer board to collect insolation data from two pyranometes. Connections on Pro Mini: "Done" to digital 5 "DRV" to VCC */ #include #include #include #include #include Adafruit_ADS1115 ads(0x48); // default address is 0x48 RTC_DS1307 rtc; float V0,V1; //float V2,V3;; //float DtoA=0.015625/1000.; float DtoA=0.007813/1000; const int donePin=5,SDpin=10; File logfile; char filename[]="LOG00000.CSV"; void setup() { //Serial.begin(9600); // Power is applied... pinMode(donePin,OUTPUT); digitalWrite(donePin,LOW); // power on //Serial.println("low power pin LOW"); //Serial.begin(9600); Wire.begin(); rtc.begin(); if (!rtc.isrunning()) { //Serial.println("RTC not running."); exit; } //rtc.adjust(DateTime(__DATE__, __TIME__)); //Serial.print("Initializing SD card..."); pinMode(10,OUTPUT); if (!SD.begin(SDpin)) { //Serial.println("Card failed."); delay(50);exit(0);} //Serial.println("card initialized."); ads.begin(); //ads.setGain(GAIN_EIGHT); // full scale = 0.512 V ads.setGain(GAIN_SIXTEEN); int16_t adc0,adc1; // ADC reading produces 16-bit integers //int16_t adc2,adc3; adc0 = ads.readADC_SingleEnded(0); adc1 = ads.readADC_SingleEnded(1); //adc2 = ads.readADC_SingleEnded(2); //adc3 = ads.readADC_SingleEnded(3); V0 = adc0 * DtoA; V1 = adc1 * DtoA; //V2 = adc2 * DtoA; //V3 = adc3 * DtoA; //Serial.print(adc0); Serial.print(" V0="); Serial.print(V0, 4); Serial.print(' '); //Serial.print(adc1); Serial.print(" V1="); Serial.print(V1, 4); Serial.print(' '); //Serial.print(adc2); Serial.print(" V2="); Serial.print(V2, 4); Serial.print(' '); //Serial.print(adc3); Serial.print(" V3="); Serial.print(V3, 4); Serial.print(' '); //Serial.println(); DateTime now=rtc.now(); logfile=SD.open(filename,FILE_WRITE); logfile.print(now.year()); logfile.print(','); logfile.print(now.month()); logfile.print(','); logfile.print(now.day()); logfile.print(','); logfile.print(now.hour()); logfile.print(','); logfile.print(now.minute()); logfile.print(','); logfile.print(now.second()); logfile.print(','); logfile.print(V0,5); logfile.print(','); logfile.print(V1,5); logfile.print(','); //logfile.print(V2,5); logfile.print(','); //logfile.print(V3,5); logfile.println(); logfile.flush(); delay(250); logfile.close(); delay(250); digitalWrite(donePin,HIGH); // power off //Serial.println("low power pin HIGH"); } void loop() {}