When reading SMS using an Arduino program, the serial monitor shows only the senders (no date or time) and truncates the message. This is may be due to serial overflow, a common problem in Arduino.
Code:
#include <SoftwareSerial.h>
#include <String.h>
SoftwareSerial mySerial(7, 8);
void setup()
{
mySerial.begin(9600);
Serial.begin(9600);
}
void loop()
{
mySerial.print("AT+CMGR=1\r");
delay(100);
while(mySerial.available())
Serial.write(mySerial.read());
delay(1000);
}
Output
AT+CMGR=1
+CMGR: "REC READ","+XXXXX","A Silky Soni","1AT+CMGR=1
+CMGR: "REC READ","+XXXXX","A Silky Soni","1AT+CMGR=1
+CMGR: "REC READ","+XXXXX","A Silky Soni","1AT+CMGR=1
You might need to adjust the baud rate in your code to match the GSM shield.
It's not the baud rate, because the string is legible so all the bits are in the correct position, however the string is truncated.
This happen because the output buffer in mySerial take more time to be filled by the GSM shield than the time to be depleted by the mySerial.read() instruction. That's it: when mySerial.available() is checked and the GSM shield don't have time to put anything in the output buffer, the result is the fail of the while loop. There are some ways to face that problem:
Put a delay() with specific time inside the while:
void loop()
{
mySerial.print("AT+CMGR=1\r");
delay(100);
while(mySerial.available()){
Serial.write(mySerial.read());
delay(100); //fix the time according to how fast the GSM shield
//wrote the data in the serial port.
}
delay(1000);
}
Or use a timeout:
unsigned long init_time, timeout=500;//choose the correct timeout value
void loop()
{
mySerial.print("AT+CMGR=1\r");
//delay(100); //this delay can be omitted
init_time=millis();
do{
while(mySerial.available()){
Serial.write(mySerial.read());
init_time=millis();
}
}while(millis()-init_time < timeout);
delay(1000);
}
The millis()-init_time give the time elapsed since the last time the mySerial.available() return true or before the check if never was available. The code will still checking for availability until reach the timeout limit.
I suggest the last approach. Happy coding!
Related
when I upload the code on arduino mega with sim808 bk-808-v3.1 , I reach the following output on the serial monitor. A NMEA statements appears infinitely. what is the problem and how to solve it?
Note that i connect SMS antenna and GPS antenna with sim808
the code
#include <SoftwareSerial.h>
SoftwareSerial SIM808(10,11); //(RX-Pin,TX-Pin)
void setup() {
Serial.begin(9600);
SIM808.begin(9600);
}
void loop() {
if (SIM808.available())
Serial.write(SIM808.read());
if (Serial.available())
SIM808.write(Serial.read());
}
I actually don't know about SIM808. But the GPS module seems to properly outputing NMEA packets every seconds by reading the GPGGA packet.
If the problem is that messages are printed out too slowly, try using Serial.readStringUntil('\n') and Serial.print functions instead of Serial.read() and Serial.write() functions.
#include <SoftwareSerial.h>
SoftwareSerial SIM808(10,11); //(RX-Pin,TX-Pin)
void setup() {
Serial.begin(9600);
SIM808.begin(9600);
}
void loop() {
if (SIM808.available())
Serial.print(SIM808.readStringUntil('\n'));
if (Serial.available())
SIM808.print(Serial.readStringUntil('\n'));
}
i need to use another serial to send data from arduino teensy to processing because default serial (Serial.begin(9600)) already used for big program
i try to read some reference about how maybe i can change from which serial i want to receive (https://processing.org/reference/libraries/serial/Serial.html), but i dont think it can be change
void setup() {
Serial.begin(115200); // already used
Serial2.begin(9600); // processing
}
void loop() {
Serial.println("...") //big code that i am not allow to change
Serial2.println("hello world");
delay(1000);
}
i expected to get "hello world" in my processing repeatly, but i really dont have any idea how to write the code so i can get value from Serial2 instead from Serial
It depends on what Teensy module you are using and how you're doing the wiring.
Please see the Teensy Using the Hardware Serial Ports article for more details.
If possible I'd try their UART/USB example:
// set this to the hardware serial port you wish to use
#define HWSERIAL Serial1
void setup() {
Serial.begin(9600);
HWSERIAL.begin(9600);
}
void loop() {
int incomingByte;
if (Serial.available() > 0) {
incomingByte = Serial.read();
Serial.print("USB received: ");
Serial.println(incomingByte, DEC);
HWSERIAL.print("USB received:");
HWSERIAL.println(incomingByte, DEC);
}
if (HWSERIAL.available() > 0) {
incomingByte = HWSERIAL.read();
Serial.print("UART received: ");
Serial.println(incomingByte, DEC);
HWSERIAL.print("UART received:");
HWSERIAL.println(incomingByte, DEC);
}
}
If that hows with the same USB connection at the same time, negotiate with your colleague so you get to use the easier one that simply shows up as another Serial port in Processing.
If that is not an option:
double check the pinout the Serial Ports article above but also the logic level voltage (e.g. might be 3.3V, not 5V)
get a USB Serial converter (for the right logic level) - this will show up as a different Serial port using Processing's Serial.list()
connect Serial2's TX pin to the convertor's RX pin and read the data in Processing (similar to process to how you'd read Serial, just a different port name)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(0, 1);
void setup()
{
mySerial.begin(9600); // Setting the baud rate of GSM Module
Serial.begin(9600); // Setting the baud rate of Serial Monitor (Arduino)
delay(100);
}
void loop()
{
if (Serial.available()>0)
SendMessage();
if (mySerial.available()>0)
Serial.write(mySerial.read());
}
void SendMessage()
{
mySerial.println("AT+CMGF=1"); //Sets the GSM Module in Text Mode
delay(1000); // Delay of 1000 milli seconds or 1 second
mySerial.println("AT+CMGS=\"+1876xxxxxxx\"\r"); // Replace x with mobile number
delay(1000);
mySerial.println("I am SMS from GSM Module");// The SMS text you want to send
delay(100);
mySerial.println((char)26);// ASCII code of CTRL+Z
delay(1000);
}
I am trying to send a sms using SIM 800 RPI GSM ADD-on v2.3 module through the arduino platform however everything I try fails. Please assist and explain where i am going wrong. Thank you. My code is above. Thanks
You are missing a carriage return in "AT+CMGF=1".
Change "AT+CMGF=1" to "AT+CMGF=1\r"
Although having delays between command works and suffices the purpose but is not recommended.
It is preferable to catch and analyze the messages returned by the SIM800 especially in case of error has occurred.
I have an Arduino Pro Mini 5v, 16 mhz and it is connected to a digital switch on pin 2. This switch is used to wake the Arduino from sleep using a external digital interrupt. I also have a DHT11 temperature sensor connected to pin 9. What I want to achieve is the when the Arduino is awake for 5 seconds and also when the switch on pin 2 is HIGH, I want to read the temperature sensor and return the temperature. I am using the DHT11 library by Tillart and when I do this, it returns a TIME_OUT error. The only possible explanation I have for this is that somehow the voltage is changed when both the DHT11 and the switch on pin 2 is being read together? Any pointers to a solution will be greatly appreciated. Thank you.
Edit 1: Added code
#include <LowPower.h>
#include <dht.h>
int pin2 = 2;
dht DHT;
#define DHT11_PIN 9
void pin2interrupt(void)
{
// Function called when awoken from sleep
// Detach interrupt to stop it from continuosly firing when in normal mode
}
void enterSleep(void)
{
attachInterrupt(0, pin2interrupt, HIGH);
Serial.println("Sleeping");
delay(100);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
Serial.println("Awake!");
}
void setup()
{
Serial.begin(115200);
pinMode(pin2, INPUT);
pinMode(DHT11_PIN, INPUT);
}
int seconds = 0;
void loop()
{
delay(1000);
seconds++;
Serial.println("Awake in the loop!");
Serial.println(seconds);
if (digitalRead(pin2) == LOW && seconds == 5)
{
seconds = 0;
Serial.println("No child detected, so going to sleep!");
delay(200);
enterSleep();
}
else if (seconds == 5)
{
Serial.print("DHT11, \t");
int chk = DHT.read11(DHT11_PIN);
switch (chk)
{
case DHTLIB_OK:
Serial.print("OK,\t");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.print("Time out error,\t");
break;
default:
Serial.print("Unknown error,\t");
break;
}
// DISPLAY DATA
Serial.println(DHT.temperature, 1);
delay(2000);
seconds = 0;
}
}
Edit 2: I also forgot to to mention that I am using the LowPower library by RocketScream to put the Arduino to sleep. The library can be found here: https://github.com/rocketscream/Low-Power
As discussed in the issues section on the official Github page of the DHT11 library by Rob Tillart, the problem is caused because some DHT11 sensors take longer to transfer data back to the board then the 50ms or so specified on the datasheet. Therefore, if you are encountering this problem try increasing the DHTLIB_TIMEOUT on the dht header file by reducing the the value dividing the F_CPU value to around 400 and try again. This allows the board to wait longer than 50ms for the board to receive data back from the sensor. If this fix doesn't work, you might want to try measuring the response time using an oscilloscope as it seems some DHT11 are built differently.
I have a problem with my brand new Arduino, it seems that
no matter what I print with
Serial.println()
be it numbers, strings or anything else, I get garbage
on the Arduino serial monitor:
Not even the simplest hello world program works.
Could you help me identify the problem and solve it?
I found the solution :)
I wrote a test program and found a working baud-rate at 600.
My test program:
long baudrates[] = {600,1200,2400,4800,9600,14400,19200,28800,38400,56000,57600,115200,128000,256000};
unsigned char baudcounter = 0;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication
Serial.begin(baudrates[baudcounter]);
}
// the loop routine runs over and over again forever:
void loop() {
Serial.println();
Serial.println(baudrates[baudcounter]);
Serial.println(" !\"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");
Serial.println();
baudcounter++;
baudcounter %= sizeof(baudrates)/sizeof(long);
delay(1000); // delay
Serial.begin(baudrates[baudcounter]); // switch baudrate
}