/* For the Nano logging shield with RTC and SD card. Logs to uSD (every 5 seconds) sensor data from a BME280 and ModernDevice wind sensor (REV C). Displays some data (every 5 seconds) on a 2x16 LCD. LCD module (http://funduino.de/DL/1602LCD.pdf) has a backpack (http://www.ebay.com/itm/281707994237) to make it an I2C device. */ #include #include #include #include #include #include // https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads more: https://arduino-info.wikispaces.com/LCD-Blue-I2C Adafruit_BME280 bme1; // One BME280 will be an I2C device float hgInches = 30.06; // Enter the sealevel barometric pressure here (xx.xx inches Hg) #define SEALEVELPRESSURE_HPA (hgInches/0.02952998751) // hPa=(inches Hg)/0.02952998751 SdFat SD; //SD will be the SdFat object #define MOSIpin 11 #define MISOpin 12 RTC_DS1307 RTC; //RTC will be the RTC_DS1307 object #define DS1307_I2C_ADDRESS 0x68 char TmeStrng[] = "0000/00/00,00:00:00"; //string template for RTC time stamp char TmeStr[] = "00:00:00"; //short string template for LCD LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address and stuff #define analogPinForRV 1 // change to pins you the analog pins are using #define analogPinForTMP 0 // to calibrate your sensor, put a glass over it, but the sensor should not be // touching the desktop surface however. // adjust the zeroWindAdjustment until your sensor reads about zero with the glass over it. const float zeroWindAdjustment = -0.4; // negative numbers yield smaller wind speeds and vice versa. int TMP_Therm_ADunits; //temp termistor value from wind sensor float RV_Wind_ADunits; //RV output from wind sensor float RV_Wind_Volts; unsigned long lastMillis; int TempCtimes100; int WindTemp; float zeroWind_ADunits; float zeroWind_volts; float WindSpeed_MPH; void setup() { Serial.begin(9600); // Open serial communications and wait for port to open: Wire.begin(); // start the i2c interface RTC.begin(); // start the RTC // Set the RTC to the computer time (compile time) when the sketch is loaded. Must comment out for subsequent boots: // RTC.adjust(DateTime((__DATE__), (__TIME__))); lcd.begin(16,2); // initialize the lcd for 16 characters and 2 lines, turn on backlight if (!SD.begin(10)) { // initialize the SD card Serial.println("No SD"); return; } Serial.println(" SD OK"); lcd.setCursor(0,0); // Start at character 0 on line 0 lcd.print("SD card OK"); // Display on LCD so you know data will be logged delay (3000); // Display for 3 seconds File dataFile = SD.open("datalog.txt", FILE_WRITE); if (dataFile) { // if the file is available, write a header to it: dataFile.print("Nano Logger. Sealevel BP "); dataFile.println(hgInches); dataFile.println("Date,Time,UTC,TempC,Humid,hPa,Alt,WindMPH,WindTemp"); dataFile.close(); } // else { // Serial.println("file err 1"); // if the file isn’t open, pop up an error: // } bool status1; status1 = bme1.begin(0x76); // 0x76 is the default I2C address of the clone sensors I have if (!status1) { Serial.println("No BME"); while (1); } } // end of setup void loop() { TMP_Therm_ADunits = analogRead(analogPinForTMP); RV_Wind_ADunits = analogRead(analogPinForRV); RV_Wind_Volts = (RV_Wind_ADunits * 0.0048828125); // these are all derived from regressions from raw data as such they depend on a lot of experimental factors // such as accuracy of temp sensors, and voltage at the actual wind sensor, (wire losses) which were unaccouted for. TempCtimes100 = (0.005 *((float)TMP_Therm_ADunits * (float)TMP_Therm_ADunits)) - (16.862 * (float)TMP_Therm_ADunits) + 9075.4; WindTemp = TempCtimes100/100; zeroWind_ADunits = -0.0006*((float)TMP_Therm_ADunits * (float)TMP_Therm_ADunits) + 1.0727 * (float)TMP_Therm_ADunits + 47.172; // 13.0C 553 482.39 zeroWind_volts = (zeroWind_ADunits * 0.0048828125) - zeroWindAdjustment; // This from a regression from data in the form of // Vraw = V0 + b * WindSpeed ^ c // V0 is zero wind at a particular temperature // The constants b and c were determined by some Excel wrangling with the solver. WindSpeed_MPH = pow(((RV_Wind_Volts - zeroWind_volts) /.2300) , 2.7265); if(isnan(WindSpeed_MPH)) { WindSpeed_MPH = 0; } /* Serial.print("TMP v "); Serial.println(TMP_Therm_ADunits * 0.0048828125); Serial.print("RV volts "); Serial.println((float)RV_Wind_Volts); Serial.print("TempC*100 "); Serial.println(TempCtimes100 ); Serial.print("ZeroWind v "); Serial.println(zeroWind_volts); Serial.print("WindSpeed "); Serial.println(WindSpeed_MPH); */ // read the sensors: float BMEt = (bme1.readTemperature()); float BMEh = (bme1.readHumidity()); float BMEp = (bme1.readPressure() / 100.0F); float BMEa = (bme1.readAltitude(SEALEVELPRESSURE_HPA)); float BMEf = (BMEt*1.8)+32; DateTime now = RTC.now(); // read the time from the RTC, then construct two data strings: sprintf(TmeStrng, "%04d/%02d/%02d,%02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second()); // [added seconds] sprintf(TmeStr, "%02d:%02d:%02d", now.hour(), now.minute(), now.second()); lcd.clear(); lcd.setCursor(0,0); //Start at character 0 on line 0 lcd.print("Temp"); lcd.setCursor(5,0); //Start at character 0 on line 1 lcd.print(BMEf); lcd.setCursor(14,0); //Start at character 7 on line 1 lcd.print("F"); lcd.setCursor(0,1); //Start at character 0 on line 0 lcd.print("Wind"); lcd.setCursor(6,1); //Start at character 0 on line 1 lcd.print(WindSpeed_MPH); lcd.setCursor(13,1); //Start at character 7 on line 1 lcd.print("mph"); // The lines below are handy for troubleshooting but might use too much memory for operation Serial.print("RTC utc Time: "); Serial.print(now.unixtime()); Serial.println(); Serial.print("RTC: "); Serial.println(TmeStrng); Serial.print("Temp: "); Serial.print(BMEt); Serial.println(" C"); /* Serial.print("Humid: "); Serial.print(BMEh); Serial.println(" %"); Serial.print("Press: "); Serial.print(BMEp); Serial.println(" hPa"); Serial.print("Alt: "); Serial.print(BMEa); Serial.println(" m"); */ Serial.print("Wind: "); Serial.print(WindSpeed_MPH); Serial.println(" mph"); Serial.print("WindTemp: "); Serial.print(WindTemp); Serial.println(" C"); Serial.println(); float utc = (now.unixtime()); // write the data to the SD card: File dataFile = SD.open("datalog.txt", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(TmeStrng);dataFile.print(",");dataFile.print(utc);dataFile.print(",");dataFile.print(BMEt);dataFile.print(","); dataFile.print(BMEh);dataFile.print(",");dataFile.print(BMEp);dataFile.print(",");dataFile.print(BMEa);dataFile.print(","); dataFile.print((float)WindSpeed_MPH);dataFile.print(",");dataFile.println(WindTemp); dataFile.close(); } // else { // Serial.println("file err 2"); // if the file isn’t open, display an error: // } delay(5000); // update every 5 seconds } // end of the MAIN LOOP