// Wind speed, current and voltage logging software (to SD memory) using real time clock. //Software part of the OpenEnergyMonitor.org project // and designed for V3 power (application at Bath University) //Author: Suneil Tagore // Date: 25/2/11 // This sketch logs windspeed, current and voltage // Implements a real time clock DS1302 using DS1302.h library // Writes data (including timestamp) to an SD card using SD.h library, comma separated. // Red LED indicates write operation to SD card // Green LED indicates it is safe to remove SD card (but be quick! the green LED will time out after a short delay)w // pushbutton on analog(2) halts program to allow safe SD removal // wind pulses are counted using an interupt method /* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. see . */ #include #include // rtc lib // Init the DS1302 DS1302 rtc(6, 4, 3); const int chipSelect = 10; // for SD on nuelectronics int redLEDpin=7; int greenLEDpin=9; int yellowLEDpin =8; // not implemented int INTERVAL = 10000; // interval at which sampling takes place over the entire loop double avVoltage, voltage, voltageSum = 0; double avCurrent, current, currentSum = 0; double power; int counter=0; // calibration double CURRENT_OFFSET = 0.5; // the hall probe is offset from zero amps. double CURRENT_SCALER = 0.133; //use multimeter to verify. double VOLTAGE_SCALER = 0.055932203; // R1 = 3.3.K, R2 = 56K, 3.3/59 = 0.055932203. measure accurately with multimeter! double VOLTS_PER_DIV = 0.004882813; // 5/1024 (or is it 1023?) double WIND_CALIB = (2.5)*(0.44704); // 2.5 mph per Hz, and mph to m/s double windPulses; double windSpeed; unsigned long lastMillis; void setup(){ Serial.begin(9600); // ------------------SD card initialise ---------------------------------- 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)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } Serial.println("card initialized."); // RTC stuff --------------------------- // Set the clock to run-mode, and disable the write protection rtc.halt(false); rtc.writeProtect(false); // Setup Serial connection Serial.begin(9600); // The following lines can be commented out to use the values already stored in the DS1302 //rtc.setDOW(SATURDAY); // Set Day-of-Week to FRIDAY //rtc.setTime(15, 00, 0); // Set the time to 12:00:00 (24hr format) //rtc.setDate(26, 2, 2011); // Set the date to August // --------------------------------------- // ----- LED pins pinMode(redLEDpin, OUTPUT); // SD writing warning pinMode(greenLEDpin, OUTPUT); // safe SD card removal pinMode(yellowLEDpin, OUTPUT); // windspeed pulses // do this last in setup, so that pulsecounts are properly initialised with timer millis.. attachInterrupt(0, pulseCount, RISING); // interupt in digital pin2 lastMillis = millis(); } void loop() { if(analogRead(2) > 500) // if.. to halt program to allow safe SD card removal { //Serial.println(analogRead(2)); digitalWrite(greenLEDpin, HIGH); Serial.println("halted"); delay(10000); //Serial.println(analogRead(2)); digitalWrite(greenLEDpin, LOW); //reset all values: avCurrent =0; currentSum =0; avVoltage =0; voltageSum =0; counter =1; // reset lastMillis = millis(); // reset windPulses = 0; //reset } analogRead(0); // creates a delay to prepare analog(0) channel if((millis() - lastMillis) > INTERVAL){ // do wind calc first so that interupt value does not change.. windSpeed = (windPulses/(INTERVAL/1000))*WIND_CALIB; // in metres per second //Serial.println(windSpeed); //Serial.println("here"); //Serial.print(" "); avCurrent = ((avCurrent* VOLTS_PER_DIV) - CURRENT_OFFSET )/ CURRENT_SCALER; // calibrate //Serial.print(avCurrent); //Serial.print(" "); avVoltage = avVoltage * VOLTAGE_SCALER; // calibration //Serial.print(avVoltage); //Serial.print(" "); power = avCurrent*avVoltage; //Serial.println(power); // create datastring and write to SD card.. String dataString = ""; // reset string //dataString += rtc.getDOWStr(); // day of week not necessary //dataString += ","; dataString += rtc.getDateStr(); dataString += ","; dataString += rtc.getTimeStr(); dataString += ","; //dataString += String(int(windSpeed)); // String() does not work in doubles it seems, will int truncate? // .. therefore write doubles directly to file... // file automation, abandoned method due to SD file coruption.. try to implement at later date.. //String dateString; //dateString = rtc.getDateStr(); //char this_char[dateString.length() + 1]; //dateString.toCharArray(this_char, sizeof(this_char)); //int my_integer_data = atoi(this_char); //int filenameSize = sizeof(this_char) -1; // -1 or -2 for less dots.. // char filename[filenameSize]; // int skipdot =0; //for(int x; x