Question

I want to read two inputs and right them on SD card and then if condition is met tweet something. The problem is after some iterations I get weird shapes instead of numbers and the program freezes. Worth saying that arduino is away from the source and so is connected via a shielded wire to reject noise.

Any one faced same problem?

I tried the code connecting one leg of a resistor to 5V and the other to A0 and the same for A1 and I didn't face any problem writing them on SD ; and if not connected it generates random numbers which also works fine!.

worth saying last line while (1>0) is due to the need for continuous tweeting.

Source Code

#include <SPI.h> 
#include <WiFi.h>
#include <Twitter.h>
#include <SD.h>

File myFile;
char ssid[] = "...";  
char pass[] = "...";  

Twitter twitter("..."); 

int PV;
int LDR;

char tweetText[140];

int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
    Serial.begin(9600);
    pinMode(10, OUTPUT);
    pinMode(0,INPUT);
    while ( status != WL_CONNECTED) { 
        Serial.print("Attempting to connect to SSID: ");
        Serial.println(ssid);
        status = WiFi.begin(ssid, pass);
        if (!SD.begin(4)) 
        {
            Serial.println("Card failed, or not present");
            return;
        }
        Serial.println("card initialized.");
        delay(10000);
    }
}

void tweet(char msg[]) {
    Serial.println("Connecting to Twitter");
    if(twitter.post(msg))
    {
        int status = twitter.wait(&Serial);
        if (status==200){
            Serial.println("Successful");
        } else {
            Serial.println("Tweet failed.");
            Serial.println(status);
        }
    } else {
        Serial.println("Connection to Twitter failed");
        Serial.println("20 Seconds timeout started");
        delay(20000);
    }
} 

void loop() {
    String dataString="";
    // read PV voltage from A0 and A1 then append to the string
    do {
        for (int analogPin=0; analogPin<2; analogPin++) {
            PV = analogRead(0);
            LDR= analogRead(1);
            int sensor=analogRead(analogPin);
            dataString += String(sensor);
            if (analogPin<1){
                dataString += ",";
            }
        }

        File dataFile = SD.open("datalog.txt", FILE_WRITE);
        if (dataFile) {
            dataFile.println(dataString);
            dataFile.close();
            Serial.println(dataString);
        } else {
            Serial.println("error opening datalog.txt");
        }

        if(PV>=1023) {
            Serial.println(PV);
            sprintf(tweetText,"A0>5volts and reads: %d. @MeghdadiAli." , PV, LDR);
            delay(50000);
            tweet(tweetText);
            Serial.println("A0>5volts");
        } else {
            Serial.println(PV);
            sprintf(tweetText,"A0<5volts and reads: %d. @MeghdadiAli.", PV, LDR);
            delay(50000);
            tweet(tweetText);
            Serial.println("A0 is not 5volts");
        }
    } while(1>0);
}

Expected output

it should write amount of A0 and A1 at each iteration and then write it beside the previous data written on SD

Obtained output

Here is what I got last time:

1023,1011, 1023,1011,1023,1008, 1023,1011023,1008,1023r 1023,
1011023,1008023r 1023r ´z #þ½.D" " _DATALOG TXT 1023,997 - 23,
1011023 ë 10r 1023,997 - 23,1011023 ë 10r

(line breaks added for commodity)

Was it helpful?

Solution

You are createing a do{}while loop inside the loop(), that has no meaning as they do the same things, infact if you look at the .cpp created in the temp folder (activate "verbose compiling" from the menu), you will find something similar to;

int main(){
  setup();
  while(1){
    loop();
  }
}

BUT

String dataString=""; is called only one time, then dataString is modified only ADDING char, so it will grow until it will overflow and do bad things to your ram.

Infact, if you look at the SD file, you should find

read1,
read1, read1, read2,
read1, read1, read2, read1, read1, read2, read3,

and so on

There are 2 solution:

  1. remove the do{}while loop as it is rendoundant, that way dataString will be destroied at the end of the loop, and recreated (empty) at the beginning;

  2. dataString = ""; before the between the do{ and for, that will not destroy and recreate the variable, but just clear its value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top