Receiving SMS using GSM and controlling LED using Arduino - arduino

Has someone come up with a solution with the above stated problem?
We are using Arduino Duemilanove and SIM 900 GSM module (http://robokits.co.in/shop/index.php?main_page=product_info&products_id=303)
We've tried to work on the similar problem of lightning LEDs from port 9-12 when we send an sms #aibicidi, where i = 0 or 1, 0 =off, 1=on. E.g. #a1b1c1d1 will switch on all the LEDs.
When we upload the code and run it through serial monitor and enter the #a1b1c1d1 in the serial monitor, we can see all the LEDs lighten up. But if we send the sms with having content "#a1b1c1d1", we don't see any function of LEDs.
It would be great if anyone can give some guidance about the same.
char inchar; //Will hold the incoming character from the Serial Port.
int led1 = 9;
int led2 = 10;
int led3 = 11;
int led4 = 12;
void setup()
{
// prepare the digital output pins
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
//Initialize GSM module serial port for communication.
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
Serial.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
Serial.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
delay(200);
}
void loop()
{
//If #a1b1c1d1 comes as sms, all LEDs should light up.
if(Serial.available() >0)
{
inchar=Serial.read();
if (inchar=='#')
{
delay(10);
inchar=Serial.read();
//first led
if (inchar=='a')
{
delay(10);
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led1, LOW);
}
else if (inchar=='1')
{
digitalWrite(led1, HIGH);
}
delay(10);
//Second led
inchar=Serial.read();
if (inchar=='b')
{
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led2, LOW);
}
else if (inchar=='1')
{
digitalWrite(led2, HIGH);
}
delay(10);
// Third led
inchar=Serial.read();
if (inchar=='c')
{
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led3, LOW);
}
else if (inchar=='1')
{
digitalWrite(led3, HIGH);
}
delay(10);
//Fourth led
inchar=Serial.read();
if (inchar=='d')
{
delay(10);
inchar=Serial.read();
if (inchar=='0')
{
digitalWrite(led4, LOW);
}
else if (inchar=='1')
{
digitalWrite(led4, HIGH);
}
delay(10);
}
}
Serial.println("AT+CMGD=1,4"); // delete all SMS
}
}
}
}
}

First do not use delay
Serial.begin(9600);
delay(3000); // give time for GSM module to register on network etc.
This is neither necessary nor reliable. Instead of waiting some random time, you can check the network status with AT+CFUN and/or AT+COPS. If the GSM module is already attached to a network when you open the serial connection, it is a waste of time waiting like that. And if is not attached you should wait explicitly for that to happen (polling CFUN/COPS or enabling AT+CREG), otherwise you risk waiting too short time. See the 27.007 specification for more information for those commands.
Second do not use delay
Serial.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
Please do not write code like this. See this answer on why using delay is such a bad idea, and this answer for suggestion to how to handle properly.

Related

LED not glowing

I a beginner to IoT. I want to glow LED connected to arduino for this I have made connections as described below, also see the image of breadboard attached here.
LED Connections
Connected
Arduino GND to one leg of LED and 3.3V to another leg of LED.
My Arduino program is-
void setup() {
Serial.begin(9600);
// connect to wifi.
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("connecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.print("connected: ");
Serial.println(WiFi.localIP());
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.set("LED_STATUS",0);
}
int n = 0;
void loop() {
// get value
n = Firebase.getInt("LED_STATIS");
if (n == 1) {
Serial.print("LED IS ON");
digitalWrite(D1,HIGH);
return;
}else{
Serial.print("LED IS OFF");
digitalWrite(D1,LOW);
return;
}
delay(1000);
}
Serial monitor shows LED is ON as shown in screenshot.
Serial Monitor
i think you should declare pinMode in setup, and you put LED in D0
#define LED D0 // Led in NodeMCU at pin GPIO16 (D0).
void setup() {
pinMode(LED, OUTPUT); // LED pin as output.
}
void loop() {
if (n == 1) {
Serial.print("LED IS ON");
digitalWrite(LED ,HIGH);
return;
}else{
Serial.print("LED IS OFF");
digitalWrite(LED ,LOW);
return;
}
}
note that it has built-in LED, but its active low, it should glow when logic is 0
and you should using pull-up resistor, because you can't depend current supply from GPIO pin since its only provide 12mA

Arduino http request LED

Forgive me I am very new c/Arduino, for my first project I have placed a php file on my server. When the page returns "ON" I would like the built in LED to be turned on and conversely when the response is "OFF" then the LED should be off.
At the moment the LED remains on despite the response being returned as off.
I cannot figure out why this could be
Any help much appreciated.
#include <Bridge.h>
#include <HttpClient.h>
void setup() {
// Bridge takes about two seconds to start up
// it can be helpful to use the on-board LED
// as an indicator for when it has initialized
pinMode(13, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
SerialUSB.begin(9600);
while (!SerialUSB); // wait for a serial connection
}
void loop() {
// Initialize the client library
HttpClient client;
// Make a HTTP request:
client.get("http://www.***.co.uk/arduino.php");
// if there are incoming bytes available
// from the server, read them and print them:
while (client.available()) {
char c = client.read();
String response = String(c);
Serial.print(response);
if(c == 'OFF'){
digitalWrite(LED_BUILTIN, LOW);
}else{
digitalWrite(LED_BUILTIN, HIGH);
}
}
SerialUSB.flush();
delay(5000);
}

Serial.read() - XBee - not firing 'else if'

I am currently trying to do some communication test between a PC and Arduino Uno using an XBee in AT mode.
My test is to send characters from the computer to the XBee and process through conditional statements.
I don't believe this issue is with configuration of the XBees, for I am able to communicate successfully when I watch the Serial monitors.
Here is the code I am running on the Arduino:
#include <SoftwareSerial.h>
SoftwareSerial xBee = SoftwareSerial(1, 0);
int Led = 9;
void setup()
{
pinMode(Led, OUTPUT);
xBee.begin(9600);
}
void loop()
{
if (xBee.available()> 0)
{
if (xBee.read() == 'r')
{
digitalWrite(Led, HIGH);
xBee.write("Led On");
delay(10);
}
else if (xBee.read() == 'o')
{
digitalWrite(Led, LOW);
xBee.write("Led Off");
delay(10);
}
else
{
xBee.write("NR"); // Testing for not recognized characters
}
delay(10);
}
delay(10);
}
I can turn on the LED when sending the character 'r' from the PC to the XBee. The intended result is received back as well. When I try to send the character 'o' from the PC the LED stays on, and I get the response of "NR".
This same result happens with different characters in the else if statement, sending character 'o' as the first character, changing to just if statements, and changing the initial condition to - while xBee.available().
How can I fix this problem?
You need to store the input value of xBee.read() and then use it in the if condition.
You can try this
#include <SoftwareSerial.h>
SoftwareSerial xBee = SoftwareSerial(1, 0);
int Led = 9;
void setup()
{
pinMode(Led, OUTPUT);
xBee.begin(9600);
}
void loop()
{
char read_value = xBee.read();
if(xBee.available()> 0)
{
if ( read_value == 'r')
{
digitalWrite(Led, HIGH);
xBee.write("Led On");
delay(10);
}
else if ( read_value == 'o')
{
digitalWrite(Led, LOW);
xBee.write("Led Off");
delay(10);
}
else
{
xBee.write("NR"); // Testing for not recognized characters
}
delay(10);
}
delay(10);
}
The problem is that you are taking the input with xBee.read() but not storing it.
Only your first if works ie,
if ( read_value == 'r')
{
digitalWrite(Led, HIGH);
xBee.write("Led On");
delay(10);
}
The control is not even going in the else if hence condition for o is not tested.

Arduino Code LED failure to alternate

Traffic light just stays on red rather than alternating.
Wanted it to stay on for 10s then off for 10s, continuing ad infinitum.
Dont want to use the delay function cos need to do other stuff while the LED continues to alternate.
Thanks
int red = 10; // red traffic light LED on pin 10
int redcounter;
// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.
pinMode(red, OUTPUT);
digitalWrite(red, LOW);
redcounter = 0;
}
// the loop routine runs over and over again forever:
void loop()
{
redcounter = redcounter +1;
if(redcounter==1000)
{
redcounter=0;
if(digitalRead(red)==HIGH)
{
digitalWrite(red, LOW);
}
if(digitalRead(red)==LOW)
{
digitalWrite(red, HIGH);
}
}
You try to read a port which is configured as an OUTPUT. I don't know if this is supposed to work, but it would be more clear if you simply use another port as INPUT and feedback the signal you want to check in that port. I'm not sure however if it makes much sense to check the state of a signal you generate yourself (?). Moreover your redcounter is just "Active waiting", and arduino provides a delay function which does exactly that.
int red=10;
int signal=11;
void setup()
{
pinMode(red, OUTPUT);
pinMode(signal, INPUT);
digitalWrite(red, LOW);
}
void loop()
{
delay(1000);
if(digitalRead(signal)==HIGH)
{
digitalWrite(red, LOW);
}
if(digitalRead(signal)==LOW)
{
digitalWrite(red, HIGH);
}
}
Use elseif instead of if here:
if(digitalRead(red)==HIGH)
{
digitalWrite(red, LOW);
}
else if(digitalRead(red)==LOW)
{
digitalWrite(red, HIGH);
}
In your old solution every time red turned low, it was turned high a moment later.
Two issues in your code are that digitalread will not read an output pin and if you use an increment counter you won't be able to accurately denote time. Sorry if I missed a bracket or something I was doing this on the mobile app.
Use this:
int red = 10; // red traffic light LED on pin 10
int redcounter;
boolean pinState = false;
int delayTime = 10000;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(red, OUTPUT);
digitalWrite(red, LOW);
redcounter = millis();
}
// the loop routine runs over and over again forever:
void loop() {
if((millis() - red counter) > delayTime) {
redcounter=millis();
if(pinState) {
digitalWrite(red, LOW);
pinState = false;
}
else {
digitalWrite(red, HIGH);
pinState = true;
}
}
}

How to read an SMS from Arduino and get LED to switch on or off

#include <SoftwareSerial.h>
char inchar; //Will hold the incoming character from the serial port.
SoftwareSerial cell(2,3); //Create a 'fake' serial port. Pin 2 is the Rx pin, pin 3 is the Tx pin.
int led1 = A2;
void setup()
{
// Prepare the digital output pins
pinMode(led1, OUTPUT);
digitalWrite(led1, HIGH);
//Initialize GSM module serial port for communication.
cell.begin(19200);
delay(30000); // Give time for GSM module to register on network, etc.
cell.println("AT+CMGF=1"); // Set SMS mode to text
delay(200);
cell.println("AT+CNMI=3,3,0,0"); // Set module to send SMS data to serial out upon receipt
delay(200);
}
void loop()
{
//If a character comes in from the cellular module...
if(cell.available() >0)
{
delay(10);
inchar=cell.read();
if (inchar=='a')
{
delay(10);
inchar=cell.read();
if (inchar=='0')
{
digitalWrite(led1, LOW);
}
else if (inchar=='1')
{
digitalWrite(led1, HIGH);
}
delay(10);
delay(10);
}
cell.println("AT+CMGD=1,4"); // Delete all SMS
}
}
This is the code for receiving SMSes from the cellular network. I am using the Arduino Gboard with SIM900. There is no error in the code, but the LED on the board doesn't switch on or off in response to an SMS.
Why?
Here's a fully functional code for sending a command thru SMS using Arduino and GSM, it will also reply the state of the light.
#include <SoftwareSerial.h>
SoftwareSerial GPRS(10, 11);
String textMessage;
String lampState;
const int relay = 12; //If you're using a relay to switch, if not reverse all HIGH and LOW on the code
void setup() {
pinMode(relay, OUTPUT);
digitalWrite(relay, HIGH); // The current state of the light is ON
Serial.begin(9600);
GPRS.begin(9600);
delay(5000);
Serial.print("GPRS ready...\r\n");
GPRS.print("AT+CMGF=1\r\n");
delay(1000);
GPRS.print("AT+CNMI=2,2,0,0,0\r\n");
delay(1000);
}
void loop(){
if(GPRS.available()>0){
textMessage = GPRS.readString();
Serial.print(textMessage);
delay(10);
}
if(textMessage.indexOf("ON")>=0){ //If you sent "ON" the lights will turn on
// Turn on relay and save current state
digitalWrite(relay, HIGH);
lampState = "ON";
Serial.println("Lamp set to ON\r\n");
textMessage = "";
GPRS.println("AT+CMGS=\"+631234567890\""); // RECEIVER: change the phone number here with international code
delay(500);
GPRS.print("Lamp was finally switched ON.\r");
GPRS.write( 0x1a );
delay(1000);
}
if(textMessage.indexOf("OFF")>=0){
// Turn off relay and save current state
digitalWrite(relay, LOW);
lampState = "OFF";
Serial.println("Lamp set to OFF\r\n");
textMessage = "";
GPRS.println("AT+CMGS=\"+631234567890\""); /// RECEIVER: change the phone number here with international code
delay(500);
GPRS.print("Lamp was finally switched OFF.\r");
GPRS.write( 0x1a );
delay(1000);
}
if(textMessage.indexOf("STATUS")>=0){
String message = "Lamp is " + lampState;
GPRS.print("AT+CMGF=1");
delay(1000);
Serial.println("Lamp state resquest");
textMessage = "";
GPRS.println("AT+CMGS=\"+631234567890\""); // RECEIVER: change the phone number here with international code
delay(500);
GPRS.print("Lamp is currently ");
GPRS.println(lampState ? "ON" : "OFF"); // This is to show if the light is currently switched on or off
GPRS.write( 0x1a );
delay(1000);
}
}
Change
AT+CNMI=3,3,0,0
to:
AT+CNMI=2,2,0,0,0
The simplest way is the best way.
// if You use SoftwareSerial lib, declare object for GSM
SoftwareSerial gsm(8,9); // TX, RX
void setup(){
// initialise UART and GSM communication between Arduino and modem
Serial.begin(115200);
gsm.begin(115200);
// wait 5-10sec. for modem whitch must connect to the network
delay(5000);
// configure modem - remember! modem didn't remeber Your's configuration!
gsm.print("at+cmgf=1\r"); // use full functionality (calls, sms, gprs) - see app note
gsm.print("at+clip=1\r"); // enable presentation number
gsm.print("at+cscs=\"GSM\"\r"); // configure sms as standard text messages
gsm.print("at+cnmi=1,2,0,0,0\r"); // show received sms and store in sim (probobly, I don't compre this settings with app note but it's working :)
}
void loop(){
String response = gsmAnswer();
if(response.indexOf("+CMT:") > 0 ) { // SMS arrived
// Now You can parse Your Message, if You wont controll only LED, just write
if(response.indexOf("LED ON") > 0) {
digitalWrite(LED_PIN, HIGH); // enable it
}else if(response.indexOf("LED OFF") > 0) {
digitalWrite(LED_PIN, LOW); // turn off
}
delay(1000);
}
}
String gsmAnswer(){
String answer;
while(!gsm.available());
while(gsm.available()){
delay(5);
if(Serial.available() > 0){
char s = (char)gsm.read();
answer += s;
}
}
return answer;
}
One think more, incomming sms has the following format:
+CMT: "+48xxxxxxxxx","","17/07/07,21:57:04+08"
Test of arrived messages
You should first know exactly what the response is before attempting to parse it.
Try something simple like the following code (note: untested!) to get a feeling of what you should look for:
void loop() {
if(cell.available() > 0) {
char ch = cell.read();
Serial.print(ch);
}
}
My guess is you'll see more than just a '0' or a '1' :)
void loop() {
while(cell.available() > 0) {inchar = cell.read(); readString+=c;delay(1);} ///can be a delay up to (10) so you can get a clear reading
Serial.print(readString); /// Declare a string " String readString; "
for (i=0; i<200; i++){ /// Serch for the txt you sent up to (200) times it depends how long your ""readString" is
if(readString.substring(i,i+4)=="RING"){ //// I am looking for the word RING sent from my phone
digitalWrite(13,HIGH);
break;
}
}
}
this will help you find the specific word ir your reading (text message)

Resources