Code does not work properly when Arduino is powered with wall plug.

I am trying to make a project using Arduino which sends an sms when electricty is off and sends another when it is on again. Also, when I send an SMS to Arduino, it replies back with "Electricty is on" or "Electricity is off".

I am using SeeedStudio GPRS Shield with Arduino. I have connected an 5.7V adapter to the grid and Arduino is checking if there is voltage coming from that adapter by using analogRead.

Everything works fine when Arduino is powered by the computer via USB. I thought I have accomplished the task. However, when Arduino is powered via 12V wall plug or 5V USB adapter connected to the grid, code does not work properly. This is what I mean by properly:

  • When electricity is off, Arduino sends an SMS and calls me. Good!
  • When electricity is on again, Arduino sends another SMS and calls me. Again this is what I want.
  • However, when I send an SMS, it does not reply back with "Electricty is on or off" which is something Arduino does when it is powered by USB from computer.
  • If I reset the Arduino by pressing the reset button, again everything works properly.

I do not understand why some parts of the code always work and some parts of it work when Arduino is connected to computer. Also, resetting the Arduino seems to solve the problem but I want the code to work properly when I power the Arduino for the first time without it needing a reset.

I am a total newbie with this kind of stuff and any help is much appreciated.

The code can be seen below.

#include <SoftwareSerial.h>

SoftwareSerial gprsSerial(7,8);

int check = 0;
int control = 500;
String myString = "";
char character;

///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void setup()
{
  gprsSerial.begin(19200); // GPRS shield baud rate 
  Serial.begin(19200);   
  delay(100);
  pinMode(9, OUTPUT);
  pinMode(A0, INPUT);
  delay(100);
  digitalWrite(9, HIGH);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void loop()
{
 if (Serial.available()) // if there is incoming serial data
    switch(Serial.read()) // read the character
   {
     case 't': // if the character is 't'
       SendTextMessage(); // send the text message
       break;
       
     case 'd': // if the character is 'd'
       DialVoiceCall(); // dial a number
       break;
       
     case 'r': // if the character is 'r'
       ReadSMS(); // read the text messages
       break;
       
     case 's': // if the character is 's'
       DeleteSMS(); // delete text messages
       break;  
       
     case 'a': // if the character is 'a'
       RecieveCall(); // answer incoming call
       break;      
   } 



 
   
  while(gprsSerial.available()) {
      character = gprsSerial.read();
      delay(10);
      myString.concat(character);
  }





  if (myString.indexOf("CMTI: ") > 0) // Incoming SMS. Read the SMS and if it is from me, reply.
  {
    gprsSerial.println("AT+CMGL=\"ALL\"");
    delay(200);

    while (myString.indexOf("OK") < 0)
    {
      myString = "";
      Oku();  

      if (myString.indexOf("(SOME PART OF MY MOBILE NUMBER") > 0)
      {
        if (control > 200)
        {
          ElectricityOn();    
        }
        else
        {
          ElectricityOff();
        }
        delay(3000);
        DeleteSMS();
      }
      
    }
     
  }
    
  



  if (myString != "") 
  {
    Serial.print(myString);
    myString = "";
  }

  

  if (millis() > 40000)
  {
    control = analogRead(A0);

    if (control == 0 && check == 0)
    {
      Serial.print("control: ");
      Serial.println(control);
      ElectricityOff();
      delay(5000);
      DialVoiceCall();
      delay(15000);
      gprsSerial.println("AT+CHUP");
      check = 1;
    }
   
    if (control > 200 && check == 1)
    {
      Serial.print("control: ");
      Serial.println(control);
      ElectricityBackOn();
      delay(5000);
      DialVoiceCall();
      delay(15000);
      gprsSerial.println("AT+CHUP");
      check = 0;
    }
  }
  
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
void Oku()
{
    while(gprsSerial.available()) 
    {
      character = gprsSerial.read();
      delay(10);
      myString.concat(character);
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void SendTextMessage()
{
  Serial.println("Sending text...");
  
  gprsSerial.println("AT+CMGF=1\r"); // Set the shield to SMS mode
  delay(100);

  gprsSerial.println("AT+CMGS = \"MY PHONE NUMBER\"");
  delay(100);

  gprsSerial.println("myString"); //the content of the message
  delay(100);

  gprsSerial.print((char)26);//the ASCII code of the ctrl+z is 26 (required according to the datasheet)
  delay(100);

  gprsSerial.println();
  Serial.println("SMS sent.");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void DialVoiceCall()
{
  gprsSerial.println("ATD+MY PHONE NUMBER;");//dial the number, must include country code  
  delay(100);
  gprsSerial.println();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void ReadSMS()
{
  gprsSerial.println("AT+CMGL=\"ALL\"");
  delay(100);
  gprsSerial.println();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void DeleteSMS()
{
  gprsSerial.println("AT+CMGD=1,4\r");
  delay(100);
  gprsSerial.println();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void RecieveCall()
{
  gprsSerial.println("ata");
  delay(100);
  gprsSerial.println();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void ElectricityOff()
{
  Serial.println("Electricity is off. Sending SMS.");
  
  gprsSerial.println("AT+CMGF=1\r"); // Set the shield to SMS mode
  delay(100);

  gprsSerial.println("AT+CMGS = \"MY PHONE NUMBER\"");
  delay(100);

  gprsSerial.println("Elektricity is off."); //the content of the message
  delay(100);

  gprsSerial.print((char)26);//the ASCII code of the ctrl+z is 26 (required according to the datasheet)
  delay(100);

  gprsSerial.println();
  Serial.println("SMS sent.");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void ElectricityBackOn()
{
  Serial.println("Electricity is back on. Sending SMS.");
  
  gprsSerial.println("AT+CMGF=1\r"); // Set the shield to SMS mode
  delay(100);

  gprsSerial.println("AT+CMGS = \"MY PHONE NUMBER\"");
  delay(100);

  gprsSerial.println("Elektrik is back on."); //the content of the message
  delay(100);

  gprsSerial.print((char)26);//the ASCII code of the ctrl+z is 26 (required according to the datasheet)
  delay(100);

  gprsSerial.println();
  Serial.println("SMS sent.");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void ElectricityOn()
{
  Serial.println("Electricity is on. Sending SMS.");
  
  gprsSerial.println("AT+CMGF=1\r"); // Set the shield to SMS mode
  delay(100);

  gprsSerial.println("AT+CMGS = \"MY PHONE NUMBER\"");
  delay(100);

  gprsSerial.println("Elektricity is on :)"); //the content of the message
  delay(100);

  gprsSerial.print((char)26);//the ASCII code of the ctrl+z is 26 (required according to the datasheet)
  delay(100);

  gprsSerial.println();
  Serial.println("SMS sent.");
}

There is a lot going on, and the problem could be in many places. Perhaps it is a combination of problems.

Please give a link to your GPRS shield. Does that shield require both 5V and a voltage at VIN ?
Perhaps the 5V external power to the USB connector is weaker than the USB from the computer ?
Is that 12V wall wart a regulated voltage ? The voltage might be too high. Put your finger on the voltage regulator of the Arduino board. If it is too hot to keep your finger on it, then the 12V is too high.
The best is a regulated wall wart of 7.5V.

Do you have a multimeter ? Could you measure the 5V and the VIN with the different ways to power it.

Which Arduino board are you using ?

When using an Arduino Uno, some would say that you can't use a String object. It might require too much memory.
How much sram (dynamic memory) is used according to the compiler ?
The 'F()' macro can be used to put a number of strings in flash memory.

The delay(10) when reading data is probably used to allow new bytes to be received. But it slows down the sketch.

Why do you test if millis() is above 40000 ? That is code that will only runs once ?
The compiler uses integer as default, that means your 40000 is too large. Use 40000L or 40000UL. The 'L' makes it a 'long', and the 'UL' makes it a 'unsigned long'.

Testing if the analogRead() is zero, is dangerous. There might be some noise or a voltage offset. I would test if it is lower than 10 or so.

I have my doubts about the program flow. The program flow depends on clearing the 'myString'. I rather have the program flow defined by the code itself.

So, the arduino when not plugged into a battery backup has enough juice to sent the initial "Uh oh" via SMS, but not enough to just sit there acting like a server.

I mean - am I taking crazy pills here? Is the issue really that it surprises you that your arduino won't work when it has no power?

Koepel:
There is a lot going on, and the problem could be in many places. Perhaps it is a combination of problems.

Please give a link to your GPRS shield.

This is the GPRS shield I am using: GPRS Shield V3.0 | Seeed Studio Wiki

Koepel:
Does that shield require both 5V and a voltage at VIN ?

"5v via 5V pin, 6.5~12v via Vin pin" is written in spec sheet of the shield I am using.

Koepel:
Perhaps the 5V external power to the USB connector is weaker than the USB from the computer ?
Is that 12V wall wart a regulated voltage ? The voltage might be too high. Put your finger on the voltage regulator of the Arduino board. If it is too hot to keep your finger on it, then the 12V is too high.
The best is a regulated wall wart of 7.5V.

You are right. When Arduino is powered with 12V wall plug, it gets too hot. Not hot as I can't keep my finger on it. But still much more hot than the case in which Arduino is powered from computer.

Koepel:
Do you have a multimeter ? Could you measure the 5V and the VIN with the different ways to power it.

I don't have it with me right now.

Koepel:
Which Arduino board are you using ?

Arduino Uno R3

Koepel:
When using an Arduino Uno, some would say that you can't use a String object. It might require too much memory.
How much sram (dynamic memory) is used according to the compiler ?
The 'F()' macro can be used to put a number of strings in flash memory.

Global variables use 638 bytes (31%) of dynamic memory, leaving 1,410 bytes for local variables. Maximum is 2,048 bytes.

Koepel:
The delay(10) when reading data is probably used to allow new bytes to be received. But it slows down the sketch.

Why do you test if millis() is above 40000 ? That is code that will only runs once ?
The compiler uses integer as default, that means your 40000 is too large. Use 40000L or 40000UL. The 'L' makes it a 'long', and the 'UL' makes it a 'unsigned long'.

GPRS shield takes some time before connecting to the network. It takes 20 seconds or so after a reset, so 40 seconds is a safe time to start checking whether the electricity is on or not. After 40 seconds Arduino repeatedly checks the electricity. Therefore, it is just a offset for the checking.

Koepel:
Testing if the analogRead() is zero, is dangerous. There might be some noise or a voltage offset. I would test if it is lower than 10 or so.

I did not have any problem so far with that but you are right. I will set it to 10.

Koepel:
I have my doubts about the program flow. The program flow depends on clearing the 'myString'. I rather have the program flow defined by the code itself.

Clearly this code works when Arduino is reset by the reset button. I have tried it numerous times. The only problem I have is that, below part of the code does not work when Arduino is powered for the first time. The rest works just fine.

  if (myString.indexOf("CMTI: ") > 0) // Incoming SMS. Read the SMS and if it is from me, reply.
  {
    gprsSerial.println("AT+CMGL=\"ALL\"");
    delay(200);

    while (myString.indexOf("OK") < 0)
    {
      myString = "";
      Oku();  

      if (myString.indexOf("(SOME PART OF MY MOBILE NUMBER") > 0)
      {
        if (control > 200)
        {
          ElectricityOn();    
        }
        else
        {
          ElectricityOff();
        }
        delay(3000);
        DeleteSMS();
      }
      
    }
    
  }

PaulMurrayCbr:
So, the arduino when not plugged into a battery backup has enough juice to sent the initial "Uh oh" via SMS, but not enough to just sit there acting like a server.

I mean - am I taking crazy pills here? Is the issue really that it surprises you that your arduino won't work when it has no power?

Arduino is always powered. I made a circuit which gets its power from another plug. Arduino checks the circuit to see if there is voltage. When that plug is not connected Arduino reads no voltage and sends me an sms.

When the project is completed, I am planning to buy an UPS and power the Arduino from it. For now I just unplug the little circuit to simulate a power cut.

When you connect the Arduino to the PC usb port, do you open the serial monitor? That will cause a reset on the Uno. If that is what is required, and what you are doing, then that is what is happening.

I have a Due that requires a reset after power up to get it started. If I don't open the serial monitor, it doesn't start. :frowning:

SurferTim:
When you connect the Arduino to the PC usb port, do you open the serial monitor? That will cause a reset on the Uno. If that is what is required, and what you are doing, then that is what is happening.

I have a Due that requires a reset after power up to get it started. If I don't open the serial monitor, it doesn't start. :frowning:

Well, I open the serial monitor and I guess that resets Arduino like you said. I am new to Arduino & electronics and stuff and I did not notice the fact that openning serial monitor resets Arduino before your post. Then, I guess I should restate my problem: some part of the code does not work without a reset. What can I do to fix this issue? Obviously I can't be there to push the reset button everytime Arduino starts.

The Due has a fix that I have not tried yet. Some users solder a resistor across a FET on the Arduino.
http://forum.arduino.cc/index.php?topic=256771.0
Otherwise, you may need to use an additional IC that does a reset when good, stable power is detected.

SurferTim:
The Due has a fix that I have not tried yet. Some users solder a resistor across a FET on the Arduino.
Due won't start after power off-on, have to reset - Arduino Due - Arduino Forum
Otherwise, you may need to use an additional IC that does a reset when good, stable power is detected.

Ok, I will try this thank you.

However, isn't it very strange that some parts of the sketch work as it should while some don't? What is the reason behind?

My experience has shown me that the String data type is unreliable to put it mildly. It has never failed to disappoint me by crashing my sketches. I prefer using character arrays.

As far as power goes, I use a 7.5v 1000ma wall wart on my Mega 2560/ethernet shield, and it does well. Maybe your current power supply doesn't get to its rated supply voltage fast enough. I've had problems like that with a few underpowered wall warts.

SurferTim:
My experience has shown me that the String data type is unreliable to put it mildly. It has never failed to disappoint me by crashing my sketches. I prefer using character arrays.

As far as power goes, I use a 7.5v 1000ma wall wart on my Mega 2560/ethernet shield, and it does well. Maybe your current power supply doesn't get to its rated supply voltage fast enough. I've had problems like that with a few underpowered wall warts.

I have two adapters. One is 6V 300mA and the other is 12V 500mA. Using one or another seems to change nothing. I also have two Arduino Uno R3. I tried both and they act the same.

Maybe I should find another way to do this besides using String. Thanks for your help.

I have read this whole topic once more. Thank you for the answers in reply #3, that seems to be all okay.
I still get a bad feeling with the power supplies. That is something that is not perfectly done right.

The first thing to do is search your house for bad power supplies and throw them away. Use only good and certified power supplies. The next thing is to really measure what you have. Even a very cheap multimeter of less than 10 dollars is helpful, but it is better to spend a little more money to get an accurate multimeter.
If you can use a usb-oscilloscope from someone, then you could check the noise of the power supply.

The Arduino Uno can be powered via the USB connector. That can be a computer or a power supply of 5V. It can be up to 5.5V but no more.

It can also be powered via the power jack or VIN. The power jack has an extra protection diode (from the power jack to VIN). For safety, the USB power is switched off when a voltage is applied to the power jack or VIN. To activate that switch, the voltage must be at least 7.2V at the power jack or 6.6V at VIN.

Therefor, a regulated power supply of 7.5V is the perfect voltage. The voltage regulator doesn't get very hot, and the switch is activated. But also a power supply of 9V is often used.
Your power supply of 6V does not do that and is the voltage is really 6V ?

Some power supplies leak high voltage into the output. That could cause a ground current glitch, which is very hard to find. Some power supplies have a lot of noise. Some power supplies of 12V output 18V when there is no load. There are many bad power supplies.

Although it does not quite explain the behaviour, I found the datasheet via the seedstudio site. Worst case power consumption seems to be around 440 mA (section 5.3), so you might be living at the edge with your 12V / 500mA. And peak current during TX is 2A (duh?).

If you power the shield from the Arduino, I would change that and feed it independently.

Note 1:
PC power supply is around 500mA and does not go through the regulator.
Your USB power supply can't deliver the 440 mA.
Your 12V can probably (just) deliver the power but it goes through the regulator which will get warm and migt even shutdown.

Note 2:
I might totally misunderstand the datasheet but it might be worth investigating.

Multimeter shows that 12 V adapter gives 12.24 V. I also measured the current going to Arduino and it seems to be 100 mA while making a call and around 77 mA while looping without making a call or sending an sms.

6 V adapter gives 7.85 V according to multimeter. Current is around 72 mA while looping and around 100 mA while calling.

Is there something wrong with these numbers?

No, nothing wrong. However, if there are peak currents and voltage drops, you don't see those with a multimeter.

I think

SurferTim:
My experience has shown me that the String data type is unreliable to put it mildly. It has never failed to disappoint me by crashing my sketches. I prefer using character arrays.

As far as power goes, I use a 7.5v 1000ma wall wart on my Mega 2560/ethernet shield, and it does well. Maybe your current power supply doesn't get to its rated supply voltage fast enough. I've had problems like that with a few underpowered wall warts.

I should mention that the problem is solved. Instead of using String, I used char array and the problem disappeared. However I still don't know the cause behind it. Anyway, thanks a lot.