Very weird Arduino SetUp issue.

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
Frostz
 
Posts: 19
Joined: Fri Jun 01, 2012 8:35 pm

Very weird Arduino SetUp issue.

Post by Frostz »

Hey guys, I am working on a project to automate the blinds in my house. I have a Uno, Ethernet shield and Motors shield stacked together. My code was working fine, but since I added the SD class to it, it has been having problems. Specifically, the code is hanging on setup. I have a Serial.begin after which there is a Serial.println with ("Serial Starts") but in my Serial moniter, all I see is "SSSSSSSSSS". If I remove all of the code from the void loop{} and then run, the setup finishes without the weird getting stuck. Here is a sample of my code. Just to note, sktech is 25,660 bytes in size. (I didn't include the motors function since commenting it out did not resolve the issue.)

Code: Select all

#include <SPI.h>
#include <Ethernet.h>
#include <Time.h>
#include <AFMotor.h>
#include <stdlib.h>
#include <SD.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x0D, 0xE0 };
IPAddress ip(10,30,20,147); //<<< ENTER YOUR IP ADDRESS HERE!!!

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

File myFile; 
//int change=0; 
int mem0=0;
int mem1=0; //variables to set transition state
int TemPin=0;  //Input Pin for Temperature sensor
int photocellPin=1; //Input Pin for Photocell
int stepperRevolution=200; //number of steps taking for stepper to make on revolution. 
int limitRev=5;//number of revolutions needed to open or close blind. 
int NumberOfRevsFor=0; //Counter for number of revolutions completed by stepper motor going forward.
int NumberOfRevsBack=limitRev; //Counter for number of revolutions completed by stepper motor in reverse.
AF_Stepper motor(200,2); //200 step/rev motor connect to M3 and M4 on motor shield 


void setup()
{  
  Serial.begin(9600);
 delay(1); 
 Serial.println("PSerial Starts");
delay(1); 
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  setTime(17,59,30,10,7,2012); //set current time on arduino 
  motor.setSpeed(250); //set motor 200 rpm. 
  Serial.println("Just server left to start");
  server.begin();  
}



void loop()
{  
  String parameterValue[6]={"variable1","variable2,variable3,variable4,variable5,variable6"};
  int stopreading=0; 
  int loopcounter=0,equalsCount=0;  
  int Mspeed,variablePresent=0,Qcheck=0,storevalue=0; 
  String Mdirection,value;
  String readURL, MotorAction;
  char string_as_char;
 Serial.println("Program is started"); 
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    Serial.println("Client available"); 
    SD.remove("BlindCtl/Settings/Settings.txt");
    while (client.connected()) {
      if (client.available()) {
       
        char c = client.read();
        if(c=='?'&&Qcheck==0)
        {
        variablePresent=1;
        Qcheck=1;
        }        
                
        if (c=='z'){//stops reading into the string once end of header is reached. 
        stopreading=1;}
        else if(c!='z' && stopreading==0&&variablePresent==1)//reads in GET from the HTTP header
        {
        readURL+=c;
        //Serial.println(readURL);        
        }
        
        //delay(1000);
     if(stopreading==1&&variablePresent==1&&storevalue==0)//reads stored GET header to extract variables
     { 
       
      for(int i=0; i<=(readURL.length()-1); i++)
      {
        //Serial.print(readURL[i]);
        //Serial.print(i);
      if(readURL[i]=='=')
       {
         int j=i+1;
         while(readURL[j]!='&'&&readURL[j]!='x')
         {
           value+=readURL[j];
           j++;
         }            
         // Serial.println(value);   
           parameterValue[equalsCount]=value;
          //Serial.println(parameterValue[equalsCount]);
          //Serial.println(equalsCount);
          myFile= SD.open("BlindCtl/Settings/Settings.txt",FILE_WRITE);
          if(equalsCount==0&&MotorAction!="Time")
          MotorAction=parameterValue[0];
          else{          
          myFile.println("Hour'");
          myFile.println(parameterValue[0]); 
          myFile.println("'");  
          }
         if(equalsCount==1)
        {         
         myFile.println("Hour'");
          myFile.println(parameterValue[1]); 
          myFile.println("'");  
        }  
         if(equalsCount==2)
        {          
         myFile.println("Hour'");
          myFile.println(parameterValue[2]); 
          myFile.println("'");  
        }
        if(equalsCount==3)
        { 
        // char string_as_char[parameterValue[3].length()];
         // parameterValue[3].toCharArray(string_as_char,parameterValue[3].length());         
          //closeHour=int(string_as_char); 
          myFile.println("Hour'");
          myFile.println(parameterValue[3]); 
          myFile.println("'"); 
        } 
         myFile.close();     
         equalsCount++;
          value="";                  
       }
      }
      storevalue=1; 
     }
       
       //String MotorAction=parameterValue[1]; 
      // Serial.println(MotorAction);
         
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();         
          //Any variables cannot contain the characters of z or x! Last variable values must end with xz.
           client.println("<div align='center'");
            client.println("<h1>Windows Blinds Client V 1.0</h1>");
            client.println("</div>");
           // client.println("<div align='center'");
          if(MotorAction!="Time")  
         {         
            client.println("<form name='input' action='10.30.20.154' method='get'>");
            client.println("<input type='radio' name='action' value='Openxz' /> Open");
            client.println("<input type='radio' name='action' value='Closexz' /> Close");
            client.println("<input type='radio' name='action' value='Timexz' /> Time");           
           // client.println("</div>");
            client.println("</br>");
            client.println("<input type='submit' value='Submit'/>");
            client.println("</form>");
         }
            if(MotorAction=="Time")
            {
            client.println("<form name='input' action='10.30.20.154' method='get'>");
            client.println("Set current time(Default is 8:30)</br>");
            client.println("Hour:<input type='text' name='Hour' value='8'/>");
            client.println("Minute:<input type='text' name='Minutes' value='30'/>");
            client.println("</br>");            
            client.println("Open*(hour):<input type='text' name='openTime'/>");
            client.println("Close*(hour):<input type='text' name='closeTime'/>");
            client.println("<input type=hidden name='action' value='xz' />");
            client.println("<input type='submit' value='Submit'/>");            
            client.println("</form>");
            client.println("</br>");  
            client.println("Changes will take into effect once connection to arduino is closed.");            
            } 
            //client.println("<input type='submit' value='Submit'/>");
           // client.println("</form>");            
           // client.println("");         
          

          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
      
      
    // if (loopcounter<=readURL.length())
    //loopcounter++;  
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    //Serial.print('Broswer is closed'); 
  }
  //else 
  //{
  ///  motors(openHour, closeHour); 
 // }
   
}

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Very weird Arduino SetUp issue.

Post by adafruit_support_bill »

Sounds like a memory problem. Your program may fit in cache, but it needs RAM for runtime variables. Strings, in particular take up a lot of RAM.

You can save some string space with the "F()" macro as described here: http://arduino.cc/playground/Learning/Memory

Frostz
 
Posts: 19
Joined: Fri Jun 01, 2012 8:35 pm

Re: Very weird Arduino SetUp issue.

Post by Frostz »

I removed the strings that I could (about half of them) and now my serial moniter out puts looks like gibberish symbols, then PStart Serial like I have in the code, and then this repeats forever. Definitely a issue with RAM but majority of my variables are ints. could the SD variable File myFile be taken a large chunk of RAM.

Here is the revised code:

Code: Select all

#include <SPI.h>
#include <Ethernet.h>
#include <Time.h>
#include <AFMotor.h>
#include <stdlib.h>
#include <SD.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x0D, 0xE0 };
IPAddress ip(10,30,20,147); //<<< ENTER YOUR IP ADDRESS HERE!!!

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

File myFile; 
//int change=0; 
int mem0=0;
int mem1=0; //variables to set transition state
int TemPin=0;  //Input Pin for Temperature sensor
int photocellPin=1; //Input Pin for Photocell
int stepperRevolution=200; //number of steps taking for stepper to make on revolution. 
int limitRev=5;//number of revolutions needed to open or close blind. 
int NumberOfRevsFor=0; //Counter for number of revolutions completed by stepper motor going forward.
int NumberOfRevsBack=limitRev; //Counter for number of revolutions completed by stepper motor in reverse.
AF_Stepper motor(200,2); //200 step/rev motor connect to M3 and M4 on motor shield 


void setup()
{  
  Serial.begin(9600);  
 Serial.println("PSerial Starts");
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  setTime(17,59,30,10,7,2012); //set current time on arduino 
  motor.setSpeed(250); //set motor 200 rpm. 
  Serial.println("Just server left to start");
  server.begin();  
}



void loop()
{  
  //String parameterValue[6]={"variable1","variable2,variable3,variable4,variable5,variable6"};
  int stopreading=0; 
  int loopcounter=0,equalsCount=0;  
  int Mspeed,variablePresent=0,Qcheck=0,storevalue=0; 
  String value;
  String readURL, MotorAction;
  //char string_as_char;
 Serial.println("Program is started"); 
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    Serial.println("Client available"); 
    SD.remove("BlindCtl/Settings/Settings.txt");
    while (client.connected()) {
      if (client.available()) {
       
        char c = client.read();
        if(c=='?'&&Qcheck==0)
        {
        variablePresent=1;
        Qcheck=1;
        }        
                
        if (c=='z'){//stops reading into the string once end of header is reached. 
        stopreading=1;}
        else if(c!='z' && stopreading==0&&variablePresent==1)//reads in GET from the HTTP header
        {
        readURL+=c;
        //Serial.println(readURL);        
        }
        
        //delay(1000);
     if(stopreading==1&&variablePresent==1&&storevalue==0)//reads stored GET header to extract variables
     { 
       
      for(int i=0; i<=(readURL.length()-1); i++)
      {
        //Serial.print(readURL[i]);
        //Serial.print(i);
      if(readURL[i]=='=')
       {
         int j=i+1;
         while(readURL[j]!='&'&&readURL[j]!='x')
         {
           value+=readURL[j];
           j++;
         }            
         // Serial.println(value);   
          // parameterValue[equalsCount]=value;
          //Serial.println(parameterValue[equalsCount]);
          //Serial.println(equalsCount);
          myFile= SD.open("BlindCtl/Settings/Settings.txt",FILE_WRITE);
          if(equalsCount==0&&MotorAction!="Time")
          MotorAction=value;
          else{          
          myFile.println("Hour'");
          myFile.println(value); 
          myFile.println("'");  
          }
         if(equalsCount==1)
        {         
         myFile.println("Min'");
          myFile.println(value); 
          myFile.println("'");  
        }  
         if(equalsCount==2)
        {          
         myFile.println("OpenHour'");
          myFile.println(value); 
          myFile.println("'");  
        }
        if(equalsCount==3)
        { 
        // char string_as_char[parameterValue[3].length()];
         // parameterValue[3].toCharArray(string_as_char,parameterValue[3].length());         
          //closeHour=int(string_as_char); 
          myFile.println("CloseHour'");
          myFile.println(value); 
          myFile.println("'"); 
        } 
         myFile.close();     
         equalsCount++;
          value="";                  
       }
      }
      storevalue=1; 
     }
       
       //String MotorAction=parameterValue[1]; 
      // Serial.println(MotorAction);
         
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();         
          //Any variables cannot contain the characters of z or x! Last variable values must end with xz.
           client.println("<div align='center'");
            client.println("<h1>Windows Blinds Client V 1.0</h1>");
            client.println("</div>");
           // client.println("<div align='center'");
          if(MotorAction!="Time")  
         {         
            client.println("<form name='input' action='10.30.20.154' method='get'>");
            client.println("<input type='radio' name='action' value='Openxz' /> Open");
            client.println("<input type='radio' name='action' value='Closexz' /> Close");
            client.println("<input type='radio' name='action' value='Timexz' /> Time");           
           // client.println("</div>");
            client.println("</br>");
            client.println("<input type='submit' value='Submit'/>");
            client.println("</form>");
         }
            if(MotorAction=="Time")
            {
            client.println("<form name='input' action='10.30.20.154' method='get'>");
            client.println("Set current time(Default is 8:30)</br>");
            client.println("Hour:<input type='text' name='Hour' value='8'/>");
            client.println("Minute:<input type='text' name='Minutes' value='30'/>");
            client.println("</br>");            
            client.println("Open*(hour):<input type='text' name='openTime'/>");
            client.println("Close*(hour):<input type='text' name='closeTime'/>");
            client.println("<input type=hidden name='action' value='xz' />");
            client.println("<input type='submit' value='Submit'/>");            
            client.println("</form>");
            client.println("</br>");  
            client.println("Changes will take into effect once connection to arduino is closed.");            
            } 
            //client.println("<input type='submit' value='Submit'/>");
           // client.println("</form>");            
           // client.println("");         
          

          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
      
      
    // if (loopcounter<=readURL.length())
    //loopcounter++;  
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    //Serial.print('Broswer is closed'); 
  }
  //else 
  //{
  ///  motors(openHour, closeHour); 
 // }
   
}

Frostz
 
Posts: 19
Joined: Fri Jun 01, 2012 8:35 pm

Re: Very weird Arduino SetUp issue.

Post by Frostz »

Removing the SD library fixes the issue but I really need this library.

Frostz
 
Posts: 19
Joined: Fri Jun 01, 2012 8:35 pm

Re: Very weird Arduino SetUp issue.

Post by Frostz »

Ok So the moment I add myFile=SD.Open("somefilename"); and myFile.close(); is when I start to see weird behaviour. Just declaring the myFile variable creates no issue.

User avatar
adafruit_support_bill
 
Posts: 88093
Joined: Sat Feb 07, 2009 10:11 am

Re: Very weird Arduino SetUp issue.

Post by adafruit_support_bill »

I removed the strings that I could
Did you use the "F()" macro on the others?
the moment I add myFile=SD.Open("somefilename"); and myFile.close(); is when I start to see weird behaviour.
That is probably when it allocates buffers for the file I/O.

This page has some more advice on managing memory: http://itp.nyu.edu/~gpv206/2008/04/maki ... o_mem.html

Frostz
 
Posts: 19
Joined: Fri Jun 01, 2012 8:35 pm

Re: Very weird Arduino SetUp issue.

Post by Frostz »

That page helped a lot but the SD class is still my main issue. Just simply adding the SD library causes my sketch to go up 8KB and stalls my program. Remove it and I am fine. The reason I need the SD is to save variables that will get pulled from the SD later. My program is essentially two programs, one is a web client and the other runs a motor. The idea is, when it detects a client, then the code from the web app runs, which retrieves the values you enter into it via a website. These values are then saved to the SD card. When you close the client, the program switches over to running the motor which then extracts the values from the SD card and uses them for its logic. (The motor opens and closes a blind based on parameters related to time of day, luminosity outside and the temperature in the room.) With the files on the SD card, it also makes it easy to set values without having to use the web UI.

So does anyone know how to resolves this issue. Is there a better way to extract data from the SD instead of using the File variable.

Here is the updated code.

Code: Select all

#include <SPI.h>
#include <Ethernet.h>
#include <Time.h>
#include <AFMotor.h>
#include <stdlib.h>
//#include <SD.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x0D, 0xE0 };
IPAddress ip(10,30,20,147); //<<< ENTER YOUR IP ADDRESS HERE!!!

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

/* 
byte change=0; 
byte mem0=0;
byte mem1=0; //variables to set transition state
byte TemPin=0;  //Input Pin for Temperature sensor
byte photocellPin=1; //Input Pin for Photocell
byte stepperRevolution=200; //number of steps taking for stepper to make on revolution. 
byte limitRev=5;//number of revolutions needed to open or close blind. 
byte NumberOfRevsFor=0; //Counter for number of revolutions completed by stepper motor going forward.
byte NumberOfRevsBack=limitRev; //Counter for number of revolutions completed by stepper motor in reverse.
AF_Stepper motor(200,2); //200 step/rev motor connect to M3 and M4 on motor shield 
*/

void setup()
{  
  Serial.begin(9600);  
 Serial.println("set");
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  setTime(17,59,30,10,7,2012); //set current time on arduino 
  //motor.setSpeed(250); //set motor 200 rpm.   
  server.begin();  
}



void loop()
{    
  boolean stopreading=0,variablePresent=0,storevalue=0,timeOn=0; //Qcheck=0;
  byte equalsCount=0;    
  String value;
  String readURL;
  //File myFile;
  //char string_as_char;  
  EthernetClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    //Serial.println("Client available"); 
    //SD.remove("BlindCtl/Settings/Settings.txt");
    pinMode(10, OUTPUT);
    //SD.begin(4);
    
    while (client.connected()) {
      if (client.available()) {
       
        char c = client.read();
        if(c=='?')//&&Qcheck==0)
        {
        variablePresent=1;
        //Qcheck=1;
        }        
                
        if (c=='z'){//stops reading into the string once end of header is reached. 
        stopreading=1;}
        else if(c!='z' && stopreading==0&&variablePresent==1)//reads in GET from the HTTP header
        {
        readURL+=c;
        //Serial.println(readURL);        
        }
        
        //delay(1000);
     if(stopreading==1&&variablePresent==1&&storevalue==0)//reads stored GET header to extract variables
     { 
       
      for(int i=0; i<=(readURL.length()-1); i++)
      {
        //Serial.print(readURL[i]);
        //Serial.print(i);
      if(readURL[i]=='=')
       {
         int j=i+1;
         while(readURL[j]!='&'&&readURL[j]!='x')
         {
           value+=readURL[j];
           j++;
         }            
         // Serial.println(value);   
          // parameterValue[equalsCount]=value;
          //Serial.println(parameterValue[equalsCount]);
          //Serial.println(equalsCount);
         
          if(equalsCount==0&&value=="Time"){
          timeOn=1;}
          else if(equalsCount==0&&value!="Open"&&value!="Close"){
          //timeOn=0; 
         //myFile= SD.open("BlindCtl/Settings/Settings.txt",FILE_WRITE);          
        // myFile.println("Hour'");
        // myFile.println(value); 
        // myFile.println("'");
        // myFile.close();   
          }
         if(equalsCount==1)
        {    
      //myFile= SD.open("BlindCtl/Settings/Settings.txt",FILE_WRITE);      
        // myFile.println("Min'");
       // myFile.println(value); 
        //myFile.println("'");
      //  myFile.close(); 
        }  
         if(equalsCount==2)
        {   
          // myFile= SD.open("BlindCtl/Settings/Settings.txt",FILE_WRITE);        
         // myFile.println("OpenHour'");
         // myFile.println(value); 
         // myFile.println("'"); 
         // myFile.close(); 
        }
        if(equalsCount==3)
        { 
        // char string_as_char[parameterValue[3].length()];
         // parameterValue[3].toCharArray(string_as_char,parameterValue[3].length());         
          //closeHour=int(string_as_char);
        // myFile= SD.open("BlindCtl/Settings/Settings.txt",FILE_WRITE);  
         // myFile.println("CloseHour'");
         // myFile.println(value); 
         // myFile.println("'"); 
        // myFile.close();
        } 
             
         equalsCount++;
          value="";                  
       }
      }
      storevalue=1; 
     }
       
       //String MotorAction=parameterValue[1]; 
      // Serial.println(MotorAction);
         
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();         
          //Any variables cannot contain the characters of z or x! Last variable values must end with xz.
           client.println("<div align='center'");
            client.println("<h1>Windows Blinds Client V 1.0</h1>");
            client.println("</div>");
           // client.println("<div align='center'");
          if(timeOn==0)  
         {         
            client.println("<form name='input' action='10.30.20.147' method='get'>");
            client.println("<input type='radio' name='action' value='Openxz' /> Open");
            client.println("<input type='radio' name='action' value='Closexz' /> Close");
            client.println("<input type='radio' name='action' value='Timexz' /> Time");           
           // client.println("</div>");
            client.println("</br>");
            client.println("<input type='submit' value='Submit'/>");
            client.println("</form>");
         }
            else if(timeOn==1)
            {
            client.println("<form name='input' action='10.30.20.147' method='get'>");
            client.println("Set current time(Default is 8:30)</br>");
            client.println("Hour:<input type='text' name='Hour' value='8'/>");
            client.println("Minute:<input type='text' name='Minutes' value='30'/>");
            client.println("</br>");            
            client.println("Open*(hour):<input type='text' name='openTime'/>");
            client.println("Close*(hour):<input type='text' name='closeTime'/>");
            client.println("<input type=hidden name='action' value='xz' />");
            client.println("<input type='submit' value='Submit'/>");            
            client.println("</form>");
            client.println("</br>");  
            //client.println("Changes will take into effect once connection to arduino is closed.");            
            } 
            //client.println("<input type='submit' value='Submit'/>");
           // client.println("</form>");            
           // client.println("");         
          

          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
      
      
    // if (loopcounter<=readURL.length())
    //loopcounter++;  
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    //Serial.print('Broswer is closed'); 
  }
  //else 
  //{
  ///  motors(); 
 // }
   
}

Frostz
 
Posts: 19
Joined: Fri Jun 01, 2012 8:35 pm

Re: Very weird Arduino SetUp issue.

Post by Frostz »

So for anyone in the future, by placing F() around all syntax output (ex client.println, myFile.println and serial.println) extremely helped to free up memory on the SRAM. Program is now running.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”