Fix the issue why complete code are not run and nothing are showed in WiFi setting like SSID.
Pin config:
USB to TTL Converter 3v3 - ESP8266 (VCC)
USB to TTL Converter GND - ESP8266 (GND)
Arduino pin 10 - ESP8266 (RX)
Arduino pin 11 - ESP8266 (TX)
Arduino GND - ESP8266 (CH_PD)
Now this is my code I want to connect the Android application to ESP module using WiFi after that I will be able to control relay on and off.
The code is here:
#include <SoftwareSerial.h>
#define DEBUG true
#define LED 40
#define two 42
#define three 44
#define four 46
SoftwareSerial esp8266(10,11); // make RX Arduino line is pin 2, make TX Arduino line is pin 3.
// This means that you need to connect the TX line from the esp to the Arduino's pin 2
// and the RX line from the esp to the Arduino's pin 3
void setup()
{
pinMode(LED,OUTPUT);
pinMode(two,OUTPUT);
pinMode(three,OUTPUT);
pinMode(four,OUTPUT);
Serial.begin(9600);
esp8266.begin(9600); // your esp's baud rate might be different
sendData("AT+RST\r\n",2000,DEBUG); // reset module
sendData("AT+CWMODE=2\r\n",1000,DEBUG); // configure as access point
sendData("AT+CIFSR\r\n",1000,DEBUG); // get ip address
sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
Serial.println("server started running on socket # 192.168.4.1:80");
}
void loop()
{
if(esp8266.available()) // check if the esp is sending a message
{
String cc="";
while(esp8266.available()){
// The esp has data so display its output to the serial window
char c = esp8266.read(); // read the next character.
Serial.write(c);
cc+=c;
}
Serial.print(cc);
delay(1000);
if(esp8266.find("+IPD,"))
{
delay(100);
int connectionId = esp8266.read()-48; // subtract 48 because the read() function returns
// the ASCII decimal value and 0 (the first decimal number) starts at 48
Serial.print("conn id = ");
Serial.println(connectionId);
String msg="";
while(esp8266.available()){
char c=esp8266.read();
msg+=c;
}
Serial.print("msg = ");
Serial.println(msg);
String vv=msg.substring(10,16);
Serial.print("vv = ");
Serial.println(vv);
vv.trim();
/////////////////////////////////////////////////////////
if(vv.length()>0){
if(vv=="sw1:on"){
Serial.println("switch 1 is turned on");
digitalWrite(LED,HIGH);
}
if(vv=="sw1:of"){
Serial.println("switch 1 is turned off");
digitalWrite(LED,LOW);
}
if(vv=="sw2:on"){
Serial.println("switch 2 is turned on");
digitalWrite(two,HIGH);
}
if(vv=="sw2:of"){
Serial.println("switch 2 is turned off");
digitalWrite(two,LOW);
}
if(vv=="sw3:on"){
Serial.println("switch 3 is turned on");
digitalWrite(three,HIGH);
}
if(vv=="sw3:of"){
Serial.println("switch 3 is turned off");
digitalWrite(three,LOW);
}
if(vv=="sw4:on"){
Serial.println("switch 4 is turned on");
digitalWrite(four,HIGH);
}
if(vv=="sw4:of"){
Serial.println("switch 4 is turned off");
digitalWrite(four,LOW);
}
if(vv=="sw_:on"){
Serial.println("all switches are turned on");
digitalWrite(LED,HIGH);
digitalWrite(two,HIGH);
digitalWrite(three,HIGH);
digitalWrite(four,HIGH);
}
if(vv=="sw_:of"){
Serial.println("all switches are turned off");
digitalWrite(LED,LOW);
digitalWrite(two,LOW);
digitalWrite(three,LOW);
digitalWrite(four,LOW);
}
}
///////////////////////////////////////////////////////////
String closeCommand = "AT+CIPCLOSE=";
closeCommand+=connectionId; // append connection id
closeCommand+="\r\n";
sendData(closeCommand,3000,DEBUG);
}
}
}
String sendData(String command, const int timeout, boolean debug)
{
String response = "";
Serial.print("command => ");
esp8266.print(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(esp8266.available())
{
// The esp has data so display its output to the serial window
char c = esp8266.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.print("response => ");
Serial.print(response);
}
return response;
}
You can try setting the baud rate to 115200 of the esp8266 since I have found that is what is mostly used. You have not specified if you can communicate at all.
You may try these...
Connect CH_PD with VCC then 3.3v
Serial.begin(115200);
ESP RESET to Arduino RESET
Related
I have an AI Thinker A9G module connected to an ESP8266 D1 mini. I have the following script to send and receive AT commands to/from the module. The idea is to get a SMS with the Google maps GPS location of the module onto my mobile phone.
// GPS tracker with AI Thinker A9G module and AZ Delivery D1 Mini ESP8266 module
#include <SoftwareSerial.h>
#define rxPin D7
#define txPin D8
SoftwareSerial A9modem(rxPin, txPin); // Pins D7 Rx and D8 Tx are used as used as software serial pins
String incomingData; // For storing incoming serial data
String gpsData; // For storing location data
char msg;
char call;
void setup()
{
Serial.begin(115200); // Baud rate for serial monitor
A9modem.begin(115200); // Baud rate for GSM shield
Serial.println("GPS/GSM A9G BEGIN");
Serial.println("Enter character for control option: ");
Serial.println("h : to disconnect a call");
Serial.println("s : to send a message");
Serial.println("r : to receive a message");
Serial.println("c : to make a call");
Serial.println("l : to read location");
Serial.println("d : to disconnect gps");
Serial.println();
delay(100);
// Set SMS mode to text mode
A9modem.print("AT+CMGF=1\r");
delay(100);
// Set GSM module to TP show the output on serial out
A9modem.print("AT+CNMI=2,2,0,0,0\r");
delay(100);
}
void loop()
{
ReceiveMessage();
gpsData = incomingData.substring(33, 52);
Serial.print("Location: ");
Serial.println(gpsData);
delay(2000);
if (Serial.available() > 0)
switch(Serial.read())
{
case 's':
SendMessage();
break;
case 'r':
ReceiveMessage();
break;
case 'c':
MakeCall();
break;
case 'h':
HangupCall();
break;
case 'l':
ReadLocation();
break;
case 'd':
DisconnectGps();
break;
}
}
void ReceiveMessage()
{
if (A9modem.available() > 0)
{
incomingData = A9modem.readString(); // Get the data from the serial port
Serial.print(incomingData);
delay(100);
}
}
void SendMessage()
{
A9modem.println("AT+CMGF=1"); // Sets the GSM Module into text mode
delay(1000); // Delay of one second
A9modem.println("AT+CMGS=\"xxxxxxxxxxxxx\"\r"); // Replace your mobile number here
delay(1000);
String sms = "http://maps.google.com/maps?q=" + gpsData; // Create the SMS location string
A9modem.println(sms);
delay(100);
A9modem.println((char)26); // ASCII code of CTRL+Z
delay(1000);
}
void MakeCall()
{
A9modem.println("ATD+xxxxxxxxxxxxx;"); // Replace your mobile number here
Serial.println("Calling "); // Print response over serial port
delay(1000);
}
void HangupCall()
{
A9modem.println("ATH");
Serial.println("Hangup Call");
delay(1000);
}
void DisconnectGps()
{
A9modem.println("AT+GPS=0");
Serial.println("Disconnect GPS");
delay(1000);
}
void ReadLocation()
{
A9modem.println("AT+GPS=1");
delay(1000);
A9modem.println("AT+LOCATION=2"); // Check location every two seconds
delay(2000);
}
So if I use the commands "l" and "s" in Arduino IDE serial monitor everything is working well but I don't know how to change the code in a way that I get a fully automated GPS tracker. The idea is the following: Power on starts the tracker. When gpsData string is not empty the first SMS will be send to my mobile phone. The next SMS follows 20 minutes later and so on until power is switched off. Could you help please?
Thanks in advance!
Finally I came up with this solution but I'm not very happy with it (it is working but I have to restart the module from time to time because there are no GPS data). There are 3 reasons for this: There is no error handling for the GPS function, I set the delays in a more ore less random way to get everything working but I don't know if the values make sense and I don't know if the substring() function is the best way to get the location from the serial response.
// GPS tracker with AI Thinker A9G module and AZ Delivery D1 Mini
ESP8266 module
#include <SoftwareSerial.h>
#define rxPin D7
#define txPin D8
SoftwareSerial A9modem(rxPin, txPin); // Pins D7 Rx and D8 Tx are used as used as software serial pins
String incomingData; // For storing incoming serial data
String gpsData; // For storing location data
int runGps = 1;
int sendSms = 0;
void setup()
{
pinMode(LED_BUILTIN, OUTPUT); // Use builtin LED for correct GPS status
Serial.begin(115200); // Baud rate for serial monitor
A9modem.begin(115200); // Baud rate for GSM shield
// Set SMS mode to text mode
A9modem.print("AT+CMGF=1\r");
delay(300);
// Set GSM module to TP show the output on serial out
A9modem.print("AT+CNMI=2,2,0,0,0\r");
delay(1000);
Serial.end();
delay(500);
}
void loop()
{
Serial.begin(115200);
ReceiveMessage(); // Start a new serial stream
gpsData = incomingData.substring(33, 52); // Strip all unnessesary data from the stream
Serial.print("Location: "); // Check if the location data are correct
Serial.println(gpsData);
delay(1000);
if(runGps == 1) { // Start GPS
ReadLocation();
delay(20000); // Wait for GPS to be ready
}
if(gpsData.length() == 19 && sendSms == 0) { // If the location string is correct send SMS
if (isdigit(gpsData.charAt(0))) { // Check if the stream starts with a number
SendMessage();
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
delay(300);
digitalWrite(LED_BUILTIN, HIGH);
delay(300);
digitalWrite(LED_BUILTIN, LOW);
delay(300);
digitalWrite(LED_BUILTIN, HIGH);
}
}
if(runGps == 0 && sendSms == 1) {
runGps = 1;
sendSms = 0;
delay(6000); // Make sure that all SMS serial communication is over
while (A9modem.available()) {
A9modem.read(); // Delete all data from serial buffer
}
delay(300000); // If SMS was sent wait 5 minutes before running the main loop again
Serial.end();
delay(500);
}
}
void ReceiveMessage()
{
if (A9modem.available() > 0)
{
incomingData = A9modem.readString(); // Get the data from the serial port
Serial.print(incomingData);
delay(500);
}
}
void SendMessage()
{
sendSms = 1; // Stop starting the SendMessage function
A9modem.println("AT+CMGF=1"); // Sets the GSM Module into text mode
delay(1000);
A9modem.println("AT+CMGS=\"xxxxxxxxxx\"\r"); // Replace your mobile number here
delay(1000);
String sms = "http://maps.google.com/maps?q=" + gpsData; // Create the SMS string
A9modem.println(sms);
delay(500);
A9modem.println((char)26); // ASCII code of CTRL+Z
delay(500);
}
void ReadLocation()
{
runGps = 0; // Stop starting the ReadLocation function
A9modem.println("AT+GPS=1");
delay(1000);
A9modem.println("AT+LOCATION=2"); // Check location every two seconds
delay(2000);
}
Try turning ON the NMEA stream from the A9G. Say you want to get the NMEA data every t seconds, you can add and then call the following function once in the void setup()
void TurnOnNMEA(int t)
{
if(t > 3600)
t = 3600; // Because the max time is 3600s
A9modem.print("AT+GPSRD=");
A9modem.println(t);
while(!A9modem.available()); // wait till the A9G sends a response
char c;
while(A9modem.available())
{
c = A9modem.read();
Serial.print(c);
delay(2); // Time needed for the next character
}
}
This will start the NMEA data stream every t seconds which you can print using the following function,
void ReadNMEA()
{
char c; // Read each character from the stream as it comes
if(A9modem.available())
{
c = A9modem.read();
Serial.print(c);
delay(2); // Time needed for the next character
}
}
Parsing and decoding the NMEA is a bit tricky thing to do. There is a lot of information inside it and the decoding depends on what you want to do with it. If you just want the location, you can parse the $GNGGA line.
When parsing the data, DO NOT USE Arduino String() class. It is a very bad idea when handling this kind of stream. Instead, use char array.
I need to send orders from Arduino to ESP32.
I have one joystick button to test.
Arduino nano is sender
Esp32 is receiver
Esp32 receives the joystick button information from Arduino (each time I push the button).
I need the Esp32 to Serial.write according to the data, for example:
If I press the button in Arduino: Send the data to Esp32 and turn bluetooth on (or turn a led on).
These are my codes:
//Arduino NANO sender
byte j = 45;
#define boton_joystick A1
void setup() {
Serial.begin(9600);
pinMode(boton_joystick, INPUT_PULLUP);
}
int boton_joystick_state;
void loop() {
//Serial.println("100");
//Serial.write("BOTON EN GRANDE");
//delay(1500);
if(!digitalRead(boton_joystick)) {
boton_joystick_state = 1;
delay(170);
} else {
boton_joystick_state = 0;
}
if (boton_joystick_state) {
Serial.println(j);
Serial.print(" ");
Serial.write(j);
Serial.println();
}
//ESP-32 receiver
#define RXD2 16
#define TXD2 17
byte j = 45;
int comdata;
void setup() {
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
}
void loop() {
//Serial.print("LEYENDO ARDUINO");
Serial.println(Serial2.readString());
if (Serial2.available() >0) {
char comdata = char(Serial2.read());
if (comdata == 'j') {
Serial.println("joystick activado");
}
}
}
am not sure
but am using Nano 33 BLE with UART and Nano has also Serial1 no need to serial2 no need to Softwearserial. Sensd on serial 1 and recive in Serial 1 but also you have to connect it Via USB. so your serial is USB and your serial 1 is TX RX.
for me it work so you can try it.
I have an ATTiny85 connected to an NRF24L01+ module using this wiring diagram: diagram. The ATTiny85 periodically goes in and out of sleep to send some value to a receiver, an Arduino Uno. If the ATTiny is running off the Arduino power supply (3.3v), everything works correctly. When I run the ATTiny off of a separate CR2032 coin cell that delivers around 3v, the Arduino never receives any data. I have a status LED hooked up to the ATTiny to ensure that the ATTiny is waking correctly, which it is. Here's the code for both:
EDIT:
Connecting it to an external 3.3v not from the Uno makes everything work - why wouldn't the coin cell's voltage work? I think everything is rated below 2.8v, the CR2032 minimum.
ATTiny Code
#include <avr/sleep.h>
#include <avr/interrupt.h>
// Routines to set and claer bits (used in the sleep code)
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define CE_PIN 3
#define CSN_PIN 3 //Since we are using 3 pin configuration we will use same pin for both CE and CSN
#include "RF24.h"
RF24 radio(CE_PIN, CSN_PIN);
byte address[11] = "SimpleNode";
unsigned long payload = 0;
void setup() {
radio.begin(); // Start up the radio
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.setRetries(15,15); // Max delay between retries & number of retries
radio.openWritingPipe(address); // Write to device address 'SimpleNode'
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(4, LOW);
delay(500);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(4, LOW);
delay(500);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(4, LOW);
delay(1000);
setup_watchdog(6);
}
volatile int watchdog_counter = 0;
ISR(WDT_vect) {
watchdog_counter++;
}
void loop()
{
sleep_mode(); //Go to sleep!
if(watchdog_counter >= 5)
{
digitalWrite(4, HIGH);
watchdog_counter = 0;
payload = 123456;
radio.write( &payload, sizeof(unsigned long) ); //Send data to 'Receiver' ever second
delay(1000);
digitalWrite(4, LOW);
}
}
//Sleep ATTiny85
void system_sleep() {
cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // System actually sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON
}
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
byte bb;
int ww;
if (ii > 9 ) ii=9;
bb=ii & 7;
if (ii > 7) bb|= (1<<5);
bb|= (1<<WDCE);
ww=bb;
MCUSR &= ~(1<<WDRF);
// start timed sequence
WDTCR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCR = bb;
WDTCR |= _BV(WDIE);
}
Receiver Code
#define CE_PIN 7
#define CSN_PIN 8
#include <SPI.h>
#include "RF24.h"
RF24 radio(CE_PIN, CSN_PIN);
byte address[11] = "SimpleNode";
unsigned long payload = 0;
void setup() {
while (!Serial);
Serial.begin(115200);
radio.begin(); // Start up the radio
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.setRetries(15,15); // Max delay between retries & number of retries
radio.openReadingPipe(1, address); // Write to device address 'SimpleNode'
radio.startListening();
Serial.println("Did Setup");
}
void loop(void){
if (radio.available()) {
radio.read( &payload, sizeof(unsigned long) );
if(payload != 0){
Serial.print("Got Payload ");
Serial.println(payload);
}
}
}
Is the problem here that the ATTiny and Uno need to be turned on at the same time to establish a connection, or is it something to do with the battery, or something else entirely? Any help would be appreciated.
I'm experiencing the same problem when running Arduino Nano from a battery.
Nano has a 3.3V pin that I'm using for powering the NRF24L01+ module.
When the voltage from my battery-pack drops under 3.3V, the 3.3V pin voltage also drops. After few minutes, the RF module is not sending any messages.
I fixed the problem temporarily by routing the battery through a 12V step-up regulator that I bought earlier for a different project. These 12V then go to the "UN" pin on Nano which accepts 6-20V. This setup works nicely but is definitely not optimal.
Therefore I'm planning to use a 3.3V step-up regulator such as Pololu 3.3V Step-Up Voltage Regulator U1V11F3 which, according to the supplier, can efficiently generate 3.3V from input voltages as low as 0.5V.
I think this might be helpful to your project as well.
I am having Issue while connecting ESP8266 with Arduino Mega. It always says "Module have no response."
Please check and correct me if I am wrong anywhere.
I am using below code and and wiring diagram is
My Code:
//#include <SoftwareSerial.h>
//use mega Serial 2 for serial monitor; Serial 1 on pins 19 (RX) and 18 (TX);// Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX).
#define SSID "SopraSteria"
#define PASS "1234567890"
#define DST_IP "220.181.111.85" //baidu.com
//SoftwareSerial dbgSerial(10, 11); // RX, TX
void setup()
{
// Open serial communications and wait for port to open:
//serial 2 is to esp8266
Serial2.begin(9600);//9600 (mine), 57600, 115200
Serial2.setTimeout(2000);
//serial 0 is to usb
Serial.begin(115200);
while(!Serial);
while(!Serial2);
//dbgSerial.begin(9600); //can't be faster than 19200 for softserial
//dbgSerial.println("ESP8266 Demo");
Serial.println("ESP8266 Demo on Mega2560");
while(Serial2.available()>0)
Serial2.read();
delay(1000);
//test if the module is ready
Serial2.println("AT+RST");
//delay(1000);
//delay(1000);
Serial.println("Resetting module");
Serial2.flush();
//if(Serial2.find("ready"))
if(Serial2.find("Ready")||Serial2.find("ready"))
{
//dbgSerial.println("Module is ready");
Serial.println("Module is ready");
}
else
{
//dbgSerial.println("Module have no response.");
Serial.println("Module have no response.");
//while(1);
}
delay(1000);
//connect to the wifi
boolean connected=false;
for(int i=0;i<5;i++)
{
if(connectWiFi())
{
connected = true;
break;
}
}
if (!connected){
//while(1);
Serial.println("Not Connected.");
}
delay(1000);
//print the ip addr
Serial2.println("AT+CIFSR");
Serial.println("ip address:");
while (Serial2.available())
Serial.write(Serial2.read());
//set the single connection mode
Serial2.println("AT+CIPMUX=0");
}
void loop()
{
//connectWiFi();
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += DST_IP;
cmd += "\",80";
Serial2.println(cmd);
Serial.println(cmd);
Serial.println(cmd);
if(Serial2.find("Error")) return;
cmd = "GET / HTTP/1.0\r\n\r\n";
Serial2.print("AT+CIPSEND=");
Serial2.println(cmd.length());
if(Serial2.find(">"))
{
//dbgSerial.print(">");
Serial.print(">");
}else
{
Serial2.println("AT+CIPCLOSE");
//dbgSerial.println("connect timeout");
Serial.println("connect timeout");
delay(1000);
return;
}
Serial2.print(cmd);
delay(2000);
//Serial.find("+IPD");
while (Serial2.available())
{
char c = Serial2.read();
//dbgSerial.write(c);
Serial.write(c);
//if(c=='\r') dbgSerial.print('\n');
if(c=='\r') Serial.print('\n');
}
//dbgSerial.println("====");
Serial.println("====");
delay(1000);
}
boolean connectWiFi()
{
Serial2.println("AT+CWMODE=1");
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
//dbgSerial.println(cmd);
Serial2.println(cmd);
Serial.println(cmd);
delay(2000);
if(Serial2.find("OK"))
{
//dbgSerial.println("OK, Connected to WiFi.");
Serial.println("OK, Connected to WiFi.");
return true;
}else
{
//dbgSerial.println("Can not connect to the WiFi.");
Serial.println("Can not connect to the WiFi.");
return false;
}
}
From the schema I can see, that device uses 3V logic (I guess it from tension divider)? In that case if you communicate with 5V logic, then you should use 5v/3v buffers on Tx and Rx. This is my guess and my advice:
Always debug communication problems with oscilloscope.
Without this you simply cannot know what is happening.
Also make some other debugging. You assume, that device responds with ready or Ready, but try to print this out, what it actually really gave on output. Otherwise it's impossible for us to debug your piece of hardware without your hardware in the hands.
Also please make a note, that this is not appropriate forum for this kind of questions as there is https://arduino.stackexchange.com/.
Sorry #DawidPi thats not completly correct.
Yes it´s right thats not opimal to do it with a voltage divider. But this is not the problem. To solve the problem with the 3.3 TX will work (surely at 9600 baud --> I did it already like this)
Your problem is the power of your Arduino board. The ESP needs much current. Your board will not support this high current. You have to supply your ESP wih an external supply. I can recommend a fix voltage regulator like the LF33CV. Youse it with two condensators and it will work :-)
Wiring like here: .
If you use a LF33CV your UE should be between 4.3 and 40V. For testing I used the 5V of my USB-port. That will also work.
Try starting your ESP like this:
#define pin_reset 2 //Connect to RST pin of ESP8266
bool start()
{
pinMode(PinReset, OUTPUT);
delay(1);
pinMode(PinReset, INPUT);
delay(1000);
if (Serial.find("Ready"))
{
delay(1000);
return true;
}
else
{
return false;
}
}
#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)