Israel
Offline
Jr. Member
Karma: 0
Posts: 84
|
 |
« on: July 11, 2012, 10:37:44 pm » |
Hello, Here is my code: #include <SD.h> //http://www.ladyada.net/products/microsd/ #include <Wire.h> #include <SPI.h> #include "floatToString.h" #include "RTClib.h" #include <avr/pgmspace.h> #include <math.h> int CS_pin = 10, SD_led = 8; RTC_DS1307 RTC; float COValue = 0, NO2Value = 0, O3Value = 0; float e_NO2Value = 0, e_NOValue = 0, e_COValue = 0; float celsius = 0; int dust_Vout = 0, ledPower = 5, delayTime = 280, delayTime2 = 40; char date_time[20]; char cel[8]; char e_NO2_Vout[10]; char e_NO_Vout[10]; char e_CO_Vout[10]; char dust[8]; char CO_Vout[10]; char NO2_Vout[10]; char O3_Vout[10]; int _outputserialchar( char c, FILE *t) { Serial.write( c ); return 1; } int pins [3] = {2, 3, 4};
void setup() { for(int i = 2; i<6; i++) pinMode(i, OUTPUT); fdevopen( &_outputserialchar, 0); Wire.begin(); Serial.begin(9600); SPI.begin(); Serial.println("Initializing Card"); pinMode(10, OUTPUT); RTC.begin(); headerW(); }
void loop() { dustsensor(); //Dust sensor http://miscellanea.com/how-to-get-more-arduino-analog-inputs/ E_NO2(); //E_NO2 sensor E_CO(); //E_CO sensor E_NO(); //E_NO sensor MOS(); temperature(); //Temp sensor FtoS(); DnT(); SDWrite(); Serial.flush(); }
void temperature() { //Read Value of 4051 analog-in 5 boolean five [3] = {HIGH, LOW, HIGH}; for(int i=0; i<3; i++) digitalWrite(pins[i], five[i]); delay(1); int readInFive = analogRead(0); float kelvin = readInFive * 0.004882812 * 100; celsius = (kelvin - 273.15) - 5; }
void dustsensor() { //Read Value of 4051 analog-in 1 boolean one [3] = {HIGH, LOW, LOW}; for(int i=0; i<3; i++) digitalWrite(pins[i], one[i]); delay(1); digitalWrite(ledPower,LOW); delayMicroseconds(delayTime); dust_Vout = analogRead(0); delayMicroseconds(delayTime2); digitalWrite(ledPower,HIGH); }
void E_NO2() { //Read Value of 4051 analog-in 2 boolean two [3] = {LOW, HIGH, LOW}; for(int i=0; i<3; i++) digitalWrite(pins[i], two[i]); delay(1); int readInTwo= analogRead(0); e_NO2Value = readInTwo * 0.004882812; }
void E_CO() { //Read Value of 4051 analog-in 3 boolean three [3] = {HIGH, HIGH, LOW}; for(int i=0; i<3; i++) digitalWrite(pins[i], three[i]); delay(1); int readInThree= analogRead(0); e_COValue = readInThree * 0.004882812; }
void E_NO() { //Read Value of 4051 analog-in 4 boolean four [3] = {LOW, LOW, HIGH}; for(int i=0; i<3; i++) digitalWrite(pins[i], four[i]); delay(1); int readInFour= analogRead(0); e_NOValue = readInFour * 0.004882812; }
void MOS() { NO2Value = analogRead(1) * 0.004882812; COValue = analogRead(2) * 0.004882812; O3Value = analogRead(3) * 0.004882812; }
void FtoS() { floatToString(cel, celsius, 0); floatToString(dust, dust_Vout, 0); floatToString(e_NO2_Vout, e_NO2Value, 5); floatToString(e_CO_Vout, e_COValue, 5); floatToString(e_NO_Vout, e_NOValue, 5); floatToString(CO_Vout, COValue, 5); floatToString(NO2_Vout, NO2Value, 5); floatToString(O3_Vout, O3Value, 5); }
void DnT() { DateTime now = RTC.now(); sprintf_P(date_time,PSTR("%d/%d/%d %d:%d:%d"),now.day(),now.month(),now.year(),now.hour(),now.minute(),now.second()); }
void headerW() { if (!SD.begin(CS_pin)) { Serial.println("Card Failure"); return; } Serial.println("Card Ready"); //Write Log File Header File logFile = SD.open("ARD1.csv", FILE_WRITE); if (logFile) { logFile.println(", , , , , , , ,"); //Just a leading blank line, incase there was previous data String header = "Date_Time, Temp, e_NO2_Vout, e_NO_Vout, e_CO_Vout, CO_Vout, NO2_Vout, O3_Vout, Dust_Vout"; logFile.println(header); logFile.close(); Serial.println(header); } else { Serial.println("Couldn't open log file"); } }
void SDWrite() { String dataString = String(date_time) + ", " + String(cel) + ", " + String(e_NO2_Vout) + ", " + String(e_NO_Vout) + ", " + String(e_CO_Vout) + ", " + String(CO_Vout) + ", " + String(NO2_Vout) + ", " + String(O3_Vout) + ", " + String(dust_Vout); File logFile = SD.open("ARD1.csv", FILE_WRITE); if (logFile) { logFile.println(dataString); logFile.close(); //Serial.println(dataString); // testing if the data string is correct printf_P(PSTR("%s, %s, %s, %s, %s, %s, %s, %s, %s\r\n"), date_time, cel, e_NO2_Vout, e_NO_Vout, e_CO_Vout, CO_Vout, NO2_Vout, O3_Vout, dust); pinMode(SD_led, OUTPUT); digitalWrite(SD_led, HIGH); } else { Serial.println("Couldn't open log file"); } delay(29000); digitalWrite(SD_led, LOW); delay(1000); } Here SD_led lights ON when data is getting written on SD card and if there is a problem, it turns off. Based on SD_led, I want to reset Arduino. My idea is: Reset Arduino when SD_led is OFF. Please suggest how is it possible. Thanks. Best, Z
|
|
|
|
|
Logged
|
|
|
|
|
nr Bundaberg, Australia
Online
Tesla Member
Karma: 71
Posts: 6836
Scattered showers my arse -- Noah, 2348BC.
|
 |
« Reply #1 on: July 12, 2012, 03:48:45 am » |
Well the first thing we usually ask is "Why do you need to reset the Arduino?"
That's normally a sign of bad program structure.
______ Rob
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 316
Posts: 35519
Seattle, WA USA
|
 |
« Reply #2 on: July 12, 2012, 04:52:50 am » |
If there is a failure to write to the SD card, what makes you think that a reboot of the Arduino will fix the problem?
|
|
|
|
|
Logged
|
|
|
|
|
Israel
Offline
Jr. Member
Karma: 0
Posts: 84
|
 |
« Reply #3 on: July 12, 2012, 12:34:16 pm » |
Well the first thing we usually ask is "Why do you need to reset the Arduino?"
If there is a failure to write to the SD card, what makes you think that a reboot of the Arduino will fix the problem?
After some hours of operation, a few arduinos get hanged (not all every time, I have 5). This I figure out looking at the SD led. They again start working when I press the reset button and led turns on. That's why I want to soft reset the Arduino based on led activity. Please suggest what needs to be done. Thanks. Best, Z
|
|
|
|
|
Logged
|
|
|
|
|
Gosport, UK
Offline
Faraday Member
Karma: 19
Posts: 3117
|
 |
« Reply #4 on: July 12, 2012, 12:38:17 pm » |
Surely, it's better to find out why it's hanging?
|
|
|
|
|
Logged
|
|
|
|
|
Israel
Offline
Jr. Member
Karma: 0
Posts: 84
|
 |
« Reply #5 on: July 12, 2012, 12:52:02 pm » |
I am not sure why, probably heating? For now, I want to solve this quickly with resetting the board. Do you know what I can do here?
Thanks.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 15
Posts: 1009
Arduino rocks
|
 |
« Reply #6 on: July 12, 2012, 01:35:06 pm » |
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_softresetIf you do go the WDT route, be warned that some arduino bootloaders don't set the WDT off. If it doesn't and you set the WDT on, you could put your arduino in a state only recoverable by an ISP.
|
|
|
|
|
Logged
|
|
|
|
|
Israel
Offline
Jr. Member
Karma: 0
Posts: 84
|
 |
« Reply #7 on: July 12, 2012, 01:54:55 pm » |
Thanks. How would I know that my boards do/don't support WDT off? Or should I connect a digital pin with reset pin? Which way is better? Thanks. Best, Z
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #8 on: July 12, 2012, 05:29:07 pm » |
The pin connection is not recommended, as has been discussed here many times.
The WDT with a long timeout should be fine (eg. 8 seconds). Just "pat the dog" in the main loop, when things are going fine and the watchdog will reset it after 8 seconds if not.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #9 on: July 12, 2012, 05:30:21 pm » |
Besides you can work around the bootloader issue by holding down reset while you power on the board, and letting go when the power is on and the sketch starts to upload.
|
|
|
|
|
Logged
|
|
|
|
|
Israel
Offline
Jr. Member
Karma: 0
Posts: 84
|
 |
« Reply #10 on: July 12, 2012, 05:42:35 pm » |
The WDT with a long timeout should be fine (eg. 8 seconds). Just "pat the dog" in the main loop, when things are going fine and the watchdog will reset it after 8 seconds if not.
Thanks Nick. I have 30 sec of delay in my main loop. Will it affect soft resetting? Probably I don't understand this 8 sec of wait, I am having a doubt that this will reset while Arduino is in waiting loop of 30 sec. Please clarify. Thanks. Best, Z
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #11 on: July 12, 2012, 05:54:43 pm » |
Well, what do you think? Better make the 30 second wait to be 5 x 6 seconds with a "pat the dog" for each one (or 30 x 1 second, as long as you don't get too close to 8 seconds). eg. for (int i = 0; i < 30; i++) { wdt_reset(); // pat the dog delay (1000); }
(edit) Changed delay(1) to delay(1000). Thanks wildbill for pointing it out. 
|
|
|
|
« Last Edit: July 12, 2012, 07:30:23 pm by Nick Gammon »
|
Logged
|
|
|
|
|
Israel
Offline
Jr. Member
Karma: 0
Posts: 84
|
 |
« Reply #12 on: July 12, 2012, 06:17:38 pm » |
Thanks Nick. I think 5x6sec is a better option.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 15
Posts: 1009
Arduino rocks
|
 |
« Reply #13 on: July 12, 2012, 07:58:12 pm » |
Well, what do you think? Better make the 30 second wait to be 5 x 6 seconds with a "pat the dog" for each one (or 30 x 1 second, as long as you don't get too close to 8 seconds). eg. for (int i = 0; i < 30; i++) { wdt_reset(); // pat the dog delay (1000); }
(edit) Changed delay(1) to delay(1000). Thanks wildbill for pointing it out.  If you just want to use the WDT for reset, you should disable it completely in setup (or, ideally, the bootloader) and only enable it when you want to reset. Unless, of course, you want an actual watchdog for your rc car or transformer or whatever.
|
|
|
|
|
Logged
|
|
|
|
|
Israel
Offline
Jr. Member
Karma: 0
Posts: 84
|
 |
« Reply #14 on: July 17, 2012, 01:53:38 am » |
Unfortunately, WDT didn't work in resetting Arduino. Here is the code: #include <SD.h> //http://www.ladyada.net/products/microsd/ #include <Wire.h> //to reset http://www.forums.adafruit.com/viewtopic.php?f=8&t=15435 #include <SPI.h> #include "floatToString.h" #include "RTClib.h" #include <avr/pgmspace.h> #include <avr/wdt.h> #include <math.h> int CS_pin = 10, SD_led = 8; RTC_DS1307 RTC; float COValue = 0, NO2Value = 0, O3Value = 0; float e_NO2Value = 0, e_NOValue = 0, e_COValue = 0; float celsius = 0; int dust_Vout = 0, ledPower = 5, delayTime = 280, delayTime2 = 40; char date_time[20]; char cel[8]; char e_NO2_Vout[10]; char e_NO_Vout[10]; char e_CO_Vout[10]; char dust[8]; char CO_Vout[10]; char NO2_Vout[10]; char O3_Vout[10]; int _outputserialchar( char c, FILE *t) { Serial.write( c ); return 1; } int pins [3] = {2, 3, 4};
void setup() { for(int i = 2; i<6; i++) pinMode(i, OUTPUT); fdevopen( &_outputserialchar, 0); Wire.begin(); wdt_disable(); Serial.begin(9600); SPI.begin(); Serial.println("Initializing Card"); pinMode(10, OUTPUT); RTC.begin(); headerW(); }
void loop() { dustsensor(); //Dust sensor http://miscellanea.com/how-to-get-more-arduino-analog-inputs/ E_NO2(); //E_NO2 sensor E_CO(); //E_CO sensor E_NO(); //E_NO sensor MOS(); temperature(); //Temp sensor FtoS(); DnT(); SDWrite(); Serial.flush(); }
void temperature() { //Read Value of 4051 analog-in 5 boolean five [3] = {HIGH, LOW, HIGH}; for(int i=0; i<3; i++) digitalWrite(pins[i], five[i]); delay(1); int readInFive = analogRead(0); float kelvin = readInFive * 0.004882812 * 100; celsius = (kelvin - 273.15) - 5; }
void dustsensor() { //Read Value of 4051 analog-in 1 boolean one [3] = {HIGH, LOW, LOW}; for(int i=0; i<3; i++) digitalWrite(pins[i], one[i]); delay(1); digitalWrite(ledPower,LOW); delayMicroseconds(delayTime); dust_Vout = analogRead(0); delayMicroseconds(delayTime2); digitalWrite(ledPower,HIGH); }
void E_NO2() { //Read Value of 4051 analog-in 2 boolean two [3] = {LOW, HIGH, LOW}; for(int i=0; i<3; i++) digitalWrite(pins[i], two[i]); delay(1); int readInTwo= analogRead(0); e_NO2Value = readInTwo * 0.004882812; }
void E_CO() { //Read Value of 4051 analog-in 3 boolean three [3] = {HIGH, HIGH, LOW}; for(int i=0; i<3; i++) digitalWrite(pins[i], three[i]); delay(1); int readInThree= analogRead(0); e_COValue = readInThree * 0.004882812; }
void E_NO() { //Read Value of 4051 analog-in 4 boolean four [3] = {LOW, LOW, HIGH}; for(int i=0; i<3; i++) digitalWrite(pins[i], four[i]); delay(1); int readInFour= analogRead(0); e_NOValue = readInFour * 0.004882812; }
void MOS() { NO2Value = analogRead(1) * 0.004882812; COValue = analogRead(2) * 0.004882812; O3Value = analogRead(3) * 0.004882812; }
void FtoS() { floatToString(cel, celsius, 0); floatToString(dust, dust_Vout, 0); floatToString(e_NO2_Vout, e_NO2Value, 5); floatToString(e_CO_Vout, e_COValue, 5); floatToString(e_NO_Vout, e_NOValue, 5); floatToString(CO_Vout, COValue, 5); floatToString(NO2_Vout, NO2Value, 5); floatToString(O3_Vout, O3Value, 5); }
void DnT() { DateTime now = RTC.now(); sprintf_P(date_time,PSTR("%d/%d/%d %d:%d:%d"),now.day(),now.month(),now.year(),now.hour(),now.minute(),now.second()); }
void headerW() { if (!SD.begin(CS_pin)) { Serial.println("Card Failure"); return; } Serial.println("Card Ready"); //Write Log File Header File logFile = SD.open("ARD1.csv", FILE_WRITE); if (logFile) { logFile.println(", , , , , , , ,"); //Just a leading blank line, incase there was previous data String header = "Date_Time, Temp, e_NO2_Vout, e_NO_Vout, e_CO_Vout, CO_Vout, NO2_Vout, O3_Vout, Dust_Vout"; logFile.println(header); logFile.close(); Serial.println(header); } else { Serial.println("Couldn't open log file"); } }
void SDWrite() { String dataString = String(date_time) + ", " + String(cel) + ", " + String(e_NO2_Vout) + ", " + String(e_NO_Vout) + ", " + String(e_CO_Vout) + ", " + String(CO_Vout) + ", " + String(NO2_Vout) + ", " + String(O3_Vout) + ", " + String(dust_Vout); File logFile = SD.open("ARD1.csv", FILE_WRITE); if (logFile) { logFile.println(dataString); logFile.close(); //Serial.println(dataString); // testing if the data string is correct printf_P(PSTR("%s, %s, %s, %s, %s, %s, %s, %s, %s\r\n"), date_time, cel, e_NO2_Vout, e_NO_Vout, e_CO_Vout, CO_Vout, NO2_Vout, O3_Vout, dust); pinMode(SD_led, OUTPUT); digitalWrite(SD_led, HIGH); } else { Serial.println("Couldn't open log file"); } delay(6000); wdt_enable(WDTO_8S); wdt_reset(); delay(6000); wdt_enable(WDTO_8S); wdt_reset(); delay(6000); wdt_enable(WDTO_8S); wdt_reset(); delay(6000); wdt_enable(WDTO_8S); wdt_reset(); delay(6000); wdt_enable(WDTO_8S); wdt_reset(); } But pressing the reset button or re-plugging A/C adopter does restart the device. Please suggest how can I overcome the problem. Thanks. Best, Z
|
|
|
|
|
Logged
|
|
|
|
|
|