Go Down

Topic: Resetting Arduino (Read 1 time) previous topic - next topic

zeus2kx

Hello,

Here is my code:
Code: [Select]
#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

Graynomad

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
Rob Gray aka the GRAYnomad www.robgray.com

PaulS

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?

zeus2kx


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

dxw00d

Surely, it's better to find out why it's hanging?

zeus2kx

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.

WizenedEE

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_softreset

If 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.

zeus2kx


http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_softreset

If 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.


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

Nick Gammon

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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

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.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

zeus2kx


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

Nick Gammon

#11
Jul 13, 2012, 12:54 am Last Edit: Jul 13, 2012, 02:30 am by Nick Gammon Reason: 1
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.

Code: [Select]
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. :)
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

zeus2kx

Thanks Nick.
I think 5x6sec is a better option.

WizenedEE


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.

Code: [Select]
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.

zeus2kx

Unfortunately, WDT didn't work in resetting Arduino.
Here is the code:

Code: [Select]
#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

Go Up