Pages: [1] 2   Go Down
Author Topic: Resetting Arduino  (Read 1656 times)
0 Members and 1 Guest are viewing this topic.
Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

Here is my code:
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
Offline Offline
Tesla Member
***
Karma: 130
Posts: 8620
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Rob Gray aka the GRAYnomad www.robgray.com

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 654
Posts: 50929
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19356
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19356
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 511
Posts: 19356
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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. smiley
« Last Edit: July 12, 2012, 07:30:23 pm by Nick Gammon » Logged

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

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Israel
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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. smiley

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 Offline
Jr. Member
**
Karma: 0
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Pages: [1] 2   Go Up
Jump to: