sending sms to stop a pump using atmega32 and sim300 - microcontroller

I'm working on a project that has to turn a pump off upon sending an sms to the microcontroller. This code below has to be able to read and download the message so it can turn the pump off but it is not working. Can someone please check the code and let me know the problem. The microcontroller used is atmega32 and the software to program it is atmel studio 6.1.
while(1)
{
//check_sensor();
/*uint8_t x=0;
while(GSMWaitForMsg(&id)!=GSM_OK)
{
if(x)
{
LCDWriteStringXY(10,3,"%3"); //LOVE SYMBOL TILL MSG COMES CHECK MYUTILS.H
x=0;
}
else
{
LCDWriteStringXY(10,3,"%4"); //ARROW TO SHOW MESSAGE DOWNLOAD
x=1;
}
}
LCDWriteStringXY(10,3,"%2");
_delay_ms(1000);
//function to read message
char msg[300];
int8_t r=GSMReadMsg(id,msg); //ID=NUMBER MSg=MESSAGE OA=THE REPLY
if(r==GSM_OK)
{
if(strcasecmp(msg,"STOP")==0) // checking if message read is stop
{
PORTC|=(1<<PC7);
LCDClear();
LCDWriteStringXY(0,1,"PUMP TURNED OFF"); // displaying on the lcd screen
RelayOff(); // turning the relay off
_delay_ms(2000);
goto comehomeboy; // going back to home
}
}
}

The message received for GSM module (on UART of controller) are merely ASCII characters.Mostly there is no NULL(\0) appended to the data.
For strcasecmp() function you need NULL terminated strings as Input.
Please make sure 'msg' array is terminated with NULL.

Related

esp8266 http client example

Hi I have used esp8266 module http client example and my code is exactly like the sample code.
This is a part of my code:
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = http.getString();
if(payload=="text") {
digitalWrite(LED_BUILTIN, HIGH);
} else {
digitalWrite(LED_BUILTIN, LOW);
}
}
}
I can't compare my variable with my text and the LED_BUILTIN is always on. I am sure it can get the text of the http client page because I can send it to Arduino nano with softwareserial.
Actually when i want to send it to arduino nano it gives me an error : no matching function for call to HardwareSerial::write(String&)
i could fix the error with this sample code
String mystring= http.getString();
char* buf = (char*) malloc(sizeof(char)*myString.length()+1);
myString.toCharArray(buf, myString.length()+1);
Serial.write(buf);
free(buf);
but esp8266 module can't compare payload with my text
If the LED was turned on, then the compare method was definitely work. Try to send different String from the server, your LED should be turned off. And also, when you got problems like this, try to print the "payload" to the serial monitor. At least, you could figure it out where the faulty is.
hope this help.

Sending AT commands to a GSM/GPRS and displaying the reply on a Serial Monitor

I am quite rusty when it comes to Serial ports. I want to send an AT command to a GSM/ GPRS shield connected to my Arduino UNO. The AT command I want to pass in particular is the command to get a networks signal strength.
I am using the SIM900 and SoftwareSerial library to send the command as the GSM library does not compile correctly for me. Meaning I have to use the SoftwareSerial library.
I have this example code from the SIM900 library working that relies on reading inputs from the serial monitor to carry out commands but I need it to be automated and the command to be passed in hardcoded. In this example code, the place of interest is the simplehwread() method.
#include "SIM900.h"
#include <SoftwareSerial.h>
int numdata;
char inSerial[40];
int i=0;
void setup()
{
//Serial connection.
Serial.begin(9600);
Serial.println("GSM Shield testing.");
//Start configuration of shield with baudrate.
//For http uses is raccomanded to use 4800 or slower.
if (gsm.begin(9600))
Serial.println("\nstatus=READY");
else Serial.println("\nstatus=IDLE");
};
void loop()
{
//Read for new byte on serial hardware,
//and write them on NewSoftSerial.
serialhwread();
//Read for new byte on NewSoftSerial.
serialswread();
};
void serialhwread()
{
i=0;
if (Serial.available() > 0) {
while (Serial.available() > 0) {
inSerial[i]=(Serial.read());
delay(10);
i++;
}
inSerial[i]='\0';
if(!strcmp(inSerial,"/END")) {
Serial.println("_");
inSerial[0]=0x1a;
inSerial[1]='\0';
gsm.SimpleWriteln(inSerial);
}
//Send a saved AT command using serial port.
if(!strcmp(inSerial,"TEST")) {
Serial.println("SIGNAL QUALITY");
gsm.SimpleWriteln("AT+CSQ");
} else {
Serial.println(inSerial);
gsm.SimpleWriteln(inSerial);
}
inSerial[0]='\0';
}
}
void serialswread()
{
gsm.SimpleRead();
}
No matter how I modify this code, the command does not get passed in and response displayed while the method here does it but not the way I want it to be done. i.e Direct input. Could anyone assist here?
i have dealt with exactly this scenario at a company with a cellular radio on board. there are many status signals that come over and if not dealt with appropriately these status flags from the cell modem will be lost
you need to look at the data sheets associated with your cell modem and its protocol so you know what flags to watch for at the various steps taken along the way from configuration, to eventual connection to cellular service.
multi-threaded coding techniques must be followed as well.
keep in mind that the comm channel is not ideal and there WILL be failures. provided your coding techniques are sound and you follow protocol requirements, then it should work.
Ron
Boise, ID

Trouble in reading from Serial port using QSerialPort

I have to develop a C++ program for an embedded FriendlyARM-based processor system.
I use Qt Creator 3.0.0 (based on Qt 5.2.0) for desktop computer. My program should be able to read from serial port at Mini2440 FriendlyARM processor.
Before going to target system (embedded system), I tried to read and write from/to a serial port on my Laptop. My main problem is how to read from serial port. As you know, new computers and laptops don't have serial port so I try to simulate serial port programming using hand-made USB-to-serial adapter cable. When the USB serial cable is plugged in, it is recognized as "/dev/ttyUSB0" on Ubuntu. It seems to work well.
Please note, the other end of cable (the serial port) isn't connected to anything.
My first question is: Is it OK to configure cable like this, or I have to connect it to other device?
I try to wrote to /dev/ttyUSB0 each 10 seconds and read the data. I ended up the following code:
void MainWindow::refreshNotificationArea()
{
generateNotifAreaData(); // a typical random data-generator
QList<QSerialPortInfo> L = QSerialPortInfo::availablePorts();
for (auto e : L)
qDebug() << e.portName() << '\n'; // it prints 1 serial port: :ttyUSB0
// write to the port
QSerialPort notifAreaPort;
// 1. set properties
notifAreaPort.setBaudRate(QSerialPort::Baud9600);
notifAreaPort.setStopBits(QSerialPort::OneStop);
notifAreaPort.setParity(QSerialPort::NoParity);
notifAreaPort.setDataBits(QSerialPort::Data8);
notifAreaPort.setFlowControl(QSerialPort::NoFlowControl);
QObject::connect(&notifAreaPort,SIGNAL(error(QSerialPort::SerialPortError)),
this, SLOT(errorReport(QSerialPort::SerialPortError)));
notifAreaPort.setPortName(serial_device.c_str());
// 2. open port
notifAreaPort.open(QIODevice::ReadWrite);
if (!notifAreaPort.isOpen())
qDebug() << "Open failed"; // open is OK, no error message printed
string s = convertNotifAreadData2Str();
qDebug() << "Generated data " << s.c_str(); // OK
int a = notifAreaPort.write(s.c_str()); // write done
qDebug() << "Write count" << a; // OK
// now read the info
QByteArray ba = notifAreaPort.readLine(3); // read failed
QSerialPort::SerialPortError err = notifAreaPort.error();
qDebug() << "Error code" << err;
qDebug() << "What? " << notifAreaPort.errorString();
qDebug() << "Read count " << ba.size(); // 0
notifAreaPort.close();
}
void MainWindow::errorReport(QSerialPort::SerialPortError error)
{
if(error!=0)
qDebug()<<"ERROR:"<<endl<<error; // nothing printed
}
Writing to serial port is OK. but Reading issues sometimes "No such file or directory"!
sometimes "File temporarily unavalable!
The strange thing is notifAreaPort.error() returns 0, and it means no error
occured!
Thoughts?
-- Saeed Amrollahi Boyouki
You cannot (well, SHOULD not) write then read from a QSerialPort in the same function.
There are two methods which I use for QSerialPort processing:
METHOD ONE
Create and open your QSerialPort object.
Set up a QTimer with a timeout of around 50 ms or so (depends on hardware).
Connect the readyRead() signal to a slot which basically just reads all data into your buffer (QByteArray is ideal for this). The slot stops the QTimer, reads all data available with readAll() and then restarts the QTimer and returns.
Connect the timeout signal of the QTimer to a function to process the read bytes of input.
The premise here is that eventually all data will have arrived and the QTimer will timeout, at which point you will have had all of your data in the buffer to process.
METHOD TWO
The slot which handles readyRead() signal can check all data in the buffer for some "marker" which denotes that some chunk of data has fully arrived. Many devices use 0x0D or 0x0d0x0A as the delmiter. Others use NULL 0x00 or some other byte.
Evaluate the buffer at each iteration of the readyRead() handler slot.
This example shows the second choice and it works well for small reads.
r_port = new QSerialPort(this);
r_port->setPortName("COM3");
r_port->setBaudRate(QSerialPort::Baud9600);
r_port->setDataBits(QSerialPort::Data8);
r_port->setParity(QSerialPort::NoParity);
r_port->setStopBits(QSerialPort::OneStop);
r_port->setFlowControl(QSerialPort::NoFlowControl);
if (r_port->open(QSerialPort::ReadWrite))
{
connect(r_port, &QSerialPort::readyRead, this, &MYPROG::on_readyRead);
connect(r_port, &QSerialPort::errorOccurred, this, &MYPROG::breakCaught);
}
else
{
QMessageBox::critical(this, "SERIAL PORT NOT CONNECTED", "Unable to connect to the radio.\n\nPlease check your connections\nand configuration and try again.");
return;
}
void MYPROG::on_readyRead()
{
// keep reading until we get a \r\n delimiter
rxBytes.append(r_port->readAll());
qDebug()<<"raw rxBtes"<<rxBytes;
if(!rxBytes.contains("\r\n"))
{
return;
}
int end = rxBytes.lastIndexOf("\r\n") + 2;
QStringList cmds = QString(rxBytes.mid(0, end)).split("\r\n", QString::SkipEmptyParts);
rxBytes = rxBytes.mid(end);
foreach(QString cmd, cmds){
qDebug()<<"serial read"<<cmd;
}
}
This allows the QSerialPort to be read when data arrives and then the program can return to the event loop in order to keep a GUI from becoming unresponsive. Typical serial reads are small and of short time duration so UI freezing rarely happens using these methods.
There are a couple of issues in your code, but I will highlight the most important of those:
You are setting the parameters before opening. This should happen after opening. That is how the API was sadly designed, but we are in the process of revamping it.
You should command line examples for reading that I added in 5.2? It seems that you do not know how to read and those would give you a simple example. In short: you are basically trying to read before the write potentially even finished.
„Hand-made USB to serial adapter“ - sounds interesting. Are you sure that this works correctly?. I think it’s a good idea to connect PIN 2(Rx) and 3(Tx), so you getting data. Now you can test your device with any other terminal software.
I use for serial ports always the readyRead() signal and I check before reading with port->bytesAvailable().
And I open my port with port->open(QIODevice::ReadWrite | QIODevice::Unbuffered).

unable to send call from Arduino to a specific number

I Am using Arduino UNO and SIM900A module for GSM + ARDUINO based communication.I used following code to call a specific number but nothing happens,
void setup()
{
Serial.begin(9600);
delay(10000);
}
void loop()
{
Serial.println("ATDTxxxxxxxxxx;"); //where xxxxxxxxxx is a 10 digit mobile number
delay(30000); // wait 20 seconds.
Serial.println("ATH"); // end call
do // remove this loop at your peril
{
delay(1);
}
while (1>0);
}
whereas when i used ATDTxxxxxxxxxx; in minicom while communicating with SIM900A module, i was able to call(AS ATDxxxxxxxxxx was giving No carrier error, so i used " ; ").Similr is the case with Sending message. I am getting "+CMS ERROR: 302" while i am using
AT+ CMGF=1
AT+CMGS="Mobno." //after this i get the error.
I am not able to send the message through minicom + SIM900A GSM module and i want to test it with Arduino.I think i am having some problem with settings of SIM or either module.I even tried to reset the settings of SIM , but nothing worked out.
First of all: never, never ever use delay instead of proper waiting by parsing the actual response given by the modem. And you must read back the responses given by the modem and wait for the final result code before proceeding to the next command. See this answer and this answer for more details (especially regarding proper AT+CMGS handling).
A list of all the CMS ERRORs are defined in 27.005 in the section 3.2.5 Message Service Failure Result Code +CMS ERROR. Does your subscription allow sending SMS (most likely, but just to be sure check this. Test sending an sms using this sim inserted into another mobile phone)? What message storage are you using? Are you sure the gsm module supports text mode?
I solve the problem just use this code:
void setup()
{
Serial.begin(9600);
delay(10000);
}
void loop()
{
Serial.println("ATD+60148266823;"); //where xxxxxxxxxx is a 10 digit mobile number
delay(30000); // wait 20 seconds.
Serial.println("ATH"); // end call
do // remove this loop at your peril
{
delay(1);
} while (1>0);
}
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println("AT");
delay(500);
Serial.print("ATD");
Serial.println("99XXXXXXX8;");
delay(20000);
Serial.println("ATH");
}

Arduino WiFly - ad hoc network setup

I'm currently working with an Arduino trying to build an ad hoc network to which a device can connect to and send web requests to. The problem I am currently having is that I can only set up one connection and then when that connection is terminated (with client.stop()), all subsequent connections are not picked up by the server, even a cURL command just sits there spinning. The first connection I start when I reset the server works fine, and I am able to talk to the server; but after that, the Arduino can no longer find new clients (even though it's trying with the library given).
I`m using the SparkFun library for the WiFly shield cloned from GitHub, along with an Arduino Uno.
My current code is based off their default example 'WiFly_AdHoc_Example', but I had to remove a few things to get the network to start up which might be the cause of this problem.
Here is the .ino file that I am running.
#include <SPI.h>
#include <WiFly.h>
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial( 5, 4); //Part from example not used (see below)
WiFlyServer server(80); //Use telnet port instead, if debugging with telnet
void setup()
{
Serial.begin(9600);
//The code below is from the example, but when I run it the WiFly will hang
// on Wifly.begin(). Without it, the WiFly starts up fine.
//mySerial.begin(9600);
//WiFly.setUart(&mySerial); // Tell the WiFly library that we are not
// using the SPIUart
Serial.println("**************Starting WiFly**************");
// Enable Adhoc mod
WiFly.begin(true);
Serial.println("WiFly started, creating network.");
if (!WiFly.createAdHocNetwork("wifly"))
{
Serial.print("Failed to create ad hoc network.");
while (1)
{
// Hang on failure.
}
}
Serial.println("Network created");
Serial.print("IP: ");
Serial.println(WiFly.ip());
Serial.println("Starting Server...");
server.begin();
Serial.print("Server started, waiting for client.");
}
void loop()
{
delay(200);
WiFlyClient client = server.available();
if (client)
{
Serial.println("Client Found.");
// A string to store received commands
String current_command = "";
while (client.connected())
{
if (client.available())
{
//Gets a character from the sent request.
char c = client.read();
if (c=='#' || c=='\n') //End of extraneous output
{
current_command = "";
}
else if(c!= '\n')
{
current_command+=c;
}
if (current_command== "get")
{
// output the value of each analog input pin
for (int i = 0; i < 6; i++)
{
client.print("analog input ");
client.print(i);
client.print(" is ");
client.print(analogRead(i));
client.println("<br />");
}
}
else if(current_command== "hello")
{
client.println("Hello there, I'm still here.");
}
else if (current_command== "quit")
{
client.println("Goodbye...");
client.stop();
current_command == "";
break;
}
else if (current_command == "*OPEN*")
{
current_command == "";
}
}
}
// Give the web browser time to receive the data
delay(200);
// close the connection
client.stop();
}
}
This script is just a mini protocol I set up to test. Once connected with the wifly module you can send text such as "get" "hello" or "quit" and the wifly module should respond back.
Using Telnet I can successfully connect (the first time) and send commands to the Arduino including "quit" to terminate the connection (calls the client.stop() method). But when I try to reconnect though Telnet, it says the connection was successful, but on the Arduino it's still looping thinking the client is still false. What??
I know right, I'm getting mixed messages from Telnet vs Arduino. None of the commands work obviously since the Ardunio is still looping waiting for a client that evaluates to true. I'm going to take a look at WiFlyServer from the library I imported and see if I can dig up the problem, because somehow that server.available() method isn't finding new clients.
I am noticing a lot of TODO's in the library code....
So I found the reason for the problem. It was in the WiFlyServer.cpp file from the SparkFun library. The code that was causing the reconnect issue was in fact the server.availible() method. Right at the top of the method, there is a check:
// TODO: Ensure no active non-server client connection.
if (!WiFly.serverConnectionActive) {
activeClient._port = 0;
}
For some reason when I comment this out, I can connect and reconnect perfectly fine and everything works as it should. I will now dive into the library and see if I can fix this, I'm not exactly sure what this is doing, but it gets called when the server connection is not active and is somehow blocking subsequent connections. The problem with this solution is that the Arduino always thinks it has found a client since client and client.connected() evaluate to true even if one doesn't exist. Even client.available() evaluates to true right when the connection is terminated and the ghost "client" is found, but after that first run through the if-statement the ghost "client" is no longer available(). Even with this flaw it still picks up a new client when it comes along which is why it works.
How might I get to the root of this problem without using this commenting hack?
Are their any risks or future problems I might run into doing it this way?
What is the purpose of the block that I commented out in the first place?
Well, when you're calling client.stop(); how does the Arduino know whether the client has to start again?
Remember setup() executes only once.
Have you tried to include the following code in your loop to tell the Arduino to create the WiFly AdHoc network again? This may or may not work. I don't have one myself and haven't played with the Wifly shield but it's worth a try.
Remember to only ever execute the code once every time you need to connect again since it's sitting inside a loop that's always going to be running.
WiFly.begin(true);
Serial.println("WiFly started, creating network.");
if (!WiFly.createAdHocNetwork("wifly"))
{
Serial.print("Failed to create ad hoc network.");
while (1)
{
// Hang on failure.
}
}

Resources