My purpose was to send SMS using GSM SIM800L coreboard and Arduino UNO. Here is the code
#include <SoftwareSerial.h>
//Create a software serial object to communicate with SIM800L
SoftwareSerial mySerial(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2
void setup()
{
//Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(115200);
//Begin serial communication with Arduino and SIM800L
mySerial.begin(115200);
Serial.println("Initializing...");
delay(1000);
mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
updateSerial();
mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
mySerial.println("AT+CMGS=\"+ZZxxxxxxxxx\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
updateSerial();
mySerial.print("TEST"); //text content
updateSerial();
mySerial.write(26);
}
void loop()
{
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
And here is the serial monitor output
22:31:19.430 -> Initializing...
However, when I run the code, I get the text message to my mobile phone, but I can't see any AT commands in the serial monitor. It only outputs "Initializing..." .
All the connections and baud rates are okay, checked a thousand times. Has connected 2A, 4.4v power supply to the GSM coreboard and shorten the wires, and sho No bad soldering joints. GSM module red led flash per 3 seconds. And again, I'm getting the text message to my phone. So that means the problem is with the Arduino serial monitor or code, not in the hardware. I need to see AT commands because I need to put more commands through the serial monitor, I tried typing and click send, But it's not showing anything. Any assistance you can provide would be greatly appreciated.
Your logic is reversed in the updateSerial() function.
Actually, you are sending the AT command over mySerial at the setup function, then you need to wait for the answer to come in that object mySerial.
So, you should do the while (!mySerial.available()) ; to be able to read something from it. Once this loop ends, you can read from mySerial.
However, you want to forward it to the serial monitor so, you also need to check if the Serial is available to be written to, that is why you also waits for it, resulting in the while (!mySerial.available() || !Serial.available()) ;.
Once you are sure both serials are available, you can read from one and write what you just read into the other one: Serial.Write(mySerial.read()).
Also, I do not see any need for the mySerial.write(Serial.read()) call, because the Serial is being used just to forward what you are receiving from the SIM800L, thus, you could simply remove that part.
Thus, the correction of your function would result in this:
void updateSerial()
{
delay(500);
while (!mySerial.available() || !Serial.available())
;
Serial.write(mySerial.read());
}
So, with this, everything you receive from the SIM800L is forwarded to the serial monitor.
Related
I'm new to Arduino and I'm having some trouble. I have a 16E TTL GPS module connected to the RX and TX pins on my NodeMCU ESP32 board and have a simple Arduino sketch i wrote to output the data to the serial monitor.
String data = "";
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
data = Serial.read();
Serial.print(data);
delay(500);
}
I am only getting the GPS data in the serial monitor while I am holding down the RST button on the board and an output of "-1" every cycle otherwise.
I have tried looking up the problem but I cant seem to find a solution and I have tried figuring out how to use serial in detail but I'm admittedly confused.
I expected the data to just be printed every loop.
You're using Serial both to output debugging messages and to talk to the GPS.
The RX and TX pins that you connected the GPS to are the same serial port as the USB serial chip connects to. Every time you write something Serial it goes to both the USB port and the GPS. So when you read anything from the GPS, you immediately write it back to it.
You can only use the serial port for one thing at a time. Since it's connected to a USB serial chip, your best bet is to use a second serial port for the GPS.
For instance:
#define RX1_PIN 9
#define TX1_PIN 10
String data = "";
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial1.begin(9600, SERIAL_8N1, RX1_PIN, TX1_PIN);
}
void loop() {
data = Serial1.read();
Serial.print(data);
delay(500);
}
You should set RX_1PIN and TX1_PIN to be whatever pin numbers are convenient for you; just be sure that they're pins that are available on your board and aren't being used for something else.
As an introduction, I bought myself an arduino and a few modules to learn some software stuff. The project is to eventually connect to a bluetooth OBD2 reader on my car to display real time data on a small LCD.
The problem
I am either not able to connect to, or not write to, my HC05 module via software serial. I think I have narrowed this down to a couple possibilities.
I am unable to connect to the module in the first place.
I have a Mega 2560 and HC05.
5V <-> VCC
GND <-> GND
D2 <-> RXD
D3 <-> TXD
Note that I have seen 9600 and 38400 baud rates for connecting but neither worked, so I made this function to try them all for me...
//set up serial relay into HC05.
SoftwareSerial hc05(2,3);
//computer serial baud rate 115200
bool hc05_connect() {
long baud_list[] = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400};
Serial.println("Attempting to connect to HC05 bluetooth module...");
bool success = 0;
for (int i=0; i<(sizeof(baud_list) / sizeof(baud_list[0])); i++) {
Serial.print("Baud rate ");
Serial.print(baud_list[i]);
Serial.print("...");
hc05.begin(baud_list[i]);
hc05.write("AT");
delay(1000);
if (hc05.available()) {
Serial.println(" successful!");
success = 1;
return success;
} else {
Serial.println(" failed");
}
}
return success;
}
Notes:
This has always returned failed for every baud rate.
I have the bluetooth module in command mode, initiated by pressing the button as I supply power.
I have tried unplugging the TX/RX pins while uploading the sketch. No difference noted.
My attempts to send commands to the HC05 are failing.
Below is my function for sending commands to the module.
void loop() {
// listen for communication from the ESP8266 and then write it to the serial monitor
if (hc05.available()) {
Serial.write(hc05.read());
}
// listen for user input and send it to the ESP8266
if (Serial.available() > 0) {
Serial.println("Writing to hc05...");
Serial.println(Serial.available());
Serial.println(Serial.read());
hc05.write(Serial.read());
}
}
I have added in a few lines which write back to Serial so I can see what's being sent, and the monitor returns weird stuff. For example, if I send "AT", this is what the monitor reads:
Writing to hc05...
3
65
Writing to hc05...
1
10
Notes:
Why is it sending 2 different items?
Why is it sending integers rather than the characters I said?
Does this indicate I'm just sending it nonsense commands so it's not responding?
I can provide full code if you want, this is already a huge textwall though. Please help me!
Edit
So I have been able to get communication two ways via the bluetooth module using a modified version of the code in this instructable: https://www.instructables.com/How-to-Set-Up-and-Test-Arduino-Bluetooth-Connectio/
I was able to send from PC only and not receive to an android bluetooth terminal using SoftwareSerial with HC05's RX - TX0 / TX - RX0.
And I was able to receive to PC and not send using hardware serial / Serial1 with HC05's RX - TX1 / TX - RX1.
So now I have RX - TX0 / TX - RX1. It seems to communicate through terminal like this.
void setup() {
Serial.begin(9600); //open the serial port
Serial1.begin(9600);
}
void loop() {
if (Serial1.available()) {
Serial.print("(Received)");
Serial.println(Serial1.readString()); // send from serial to bluetooth
}
if (Serial.available()) {
Serial.print("(Sent)");
Serial.println(Serial.readString());
Serial1.println(Serial.readString()); // send from bluetooth to serial
}
}
But if I apply this to my code, I still can't get it to work.
Before I try to hack this together, why am I getting serial to work across 2 different serial channels? Weird...
Okay, so I figured it out. (I can't say I fully understand, but maybe this will help people in future.)
1. Unable to connect to module
Thanks #ukBaz for suggesting I connect with the terminal app on my phone, this allowed me to debug the connection to the module in the first place. and #Juraj for suggesting that the Mega uses hardware serial.
Serial1 apparently is broken on my board, so I am using Serial3. I bluetoothed to the device with my phone, and was able to send commands back and forth between Serial and Serial3 both on 9600 baud rate. Here is the code I used:
void setup() {
Serial.begin(9600); //open the serial port to PC
Serial3.begin(9600); //open serial port to HC05. TX -> 15, RX -> 14
}
void loop() {
if(Serial3.available()){
Serial.print(Serial3.readString()); // send from serial to bluetooth
}
if(Serial.available()){
Serial3.print(Serial.readString()); // send from bluetooth to serial
}
}
I suspect I was using the wrong read/readString and write/print/println for my purpose initially.
2. Unable to issue commands to the module
Once I got that working, I changed the baud rate to 38400, and tied the STATE pin of the module to VCC (rather than using the button). Uploaded code, disconnected 5V, reconnected 5V, reset arduino.
At that point, I could issue "AT" to the module via Serial Monitor, and receive "OK" back. Woohoo!
I think I understand now that #hlovdal was suggesting that I was issuing a command to the module and never parsing a response I got, so it was.. clogged parhaps? In any case. I can now successfully issue commands and receive responses from the module.
Thanks everyone for your help.
There are some problems with how you are communicating AT command lines to your device. For instance:
hc05.write("AT");
delay(1000);
You do not send an AT command to a modem, you send an AT command line that contains zero or more AT commands, followed by a command line terminating character (that always should be '\r', aka carriage return (or <CR>)).
You are missing that terminating character here, so the modem will never send you a reply, because you have not sent it a command line.
And also, you should never, ever use delay as a substitute for reading and parsing the responses that the modem sends back. See this answer for some more details.
I am trying to run a Processing sketch with my Arduino. I got it a few days ago, so I'm pretty much a noob. I made two similar sketches - one in Arduino and one in Processing. The Arduino one does work, while the Processing sketch doesn't, even though when running the Processing one, the RX lights up on the board.
I have connected an LED into the D9 on the board, with a 220 ohm resistor, and plugged the other leg into the GND. I then proceeded to run the Arduino sketch, which is a simple one, it lights up and down the LED for a second. This one worked.
I then tried running the Processing sketch, exact same code ( adapted for Processing ) using the library for Arduino, and the board seems to communicate with my sketch, as the RX is blinking each second on the board ( I tried different intervals of time and they match with the intervals at which the RX blinks ), but the LED does not turn on and off, like it did with the Arduino sketch.
I tried getting only a serial connection between the Arduino, and it worked - I connected a joystick module to the Arduino and sent the X and Y through the serial port, and the Processing sketch received the information through the serial port, so they are, indeed, communicating.
The port used is COM3 and is running at 9600 baud.
This is the Arduino sketch :
void setup() {
pinMode(9, OUTPUT);
}
void loop() {
digitalWrite(9, HIGH);
delay(1000);
digitalWrite(9, LOW);
delay(1000);
}
and this is the Processing ( version 3.4 ) sketch :
import processing.serial.*;
import cc.arduino.*;
Arduino arduino;
void setup() {
arduino = new Arduino(this, Arduino.list()[0], 9600);
arduino.pinMode(9, Arduino.OUTPUT);
}
void draw() {
arduino.digitalWrite(9, Arduino.HIGH);
delay(1000);
arduino.digitalWrite(9, Arduino.LOW);
delay(1000);
}
Well done on step by step debugging such as double checking the wiring on the electronics side and testing the blink code with the Arduino alone to isolate the issue.
If the Blink sketch is the only Arduino code you have uploaded to your board that won't suffice. Processing does send messages to Arduino (which is why you see the RX LED turn on), but there's nothing in the Arduino code that initialises Serial communication
As you can see in that example, in setup() Serial communication is initialised with 9600 baud rate (communication speed, 9600 bytes/chars per second):
Serial.begin(9600);
Then in draw() if there is data available, each character is read, then printed one at a time with a prefixed message:
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
}
If you upload the example linked, if you've got a single Serial port, you should see both the RX then ever so slightly after the TX LED blinking when you run your Processing sketch. If you close that sketch, open Serial Monitor in Arduino and type something then press enter you'll see the debugging message read back from Arduino.
Using these notions you could write a basic sketch like so:
int incomingByte = 0; // for incoming serial data
void setup() {
pinMode(9, OUTPUT);
Serial.begin(9600);
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
// if we received ASCII character '1', turn LED on
if(incomingByte == '1'){
digitalWrite(9,HIGH);
}
// if we received ASCII character '0', turn LED off
if(incomingByte == '0'){
digitalWrite(9,LOW);
}
}
}
Uploading this sketch to your Arduino should allow you to type 1 into Serial Monitor and press Enter to turn the LED on or 0 to turn it off.
The only thing left is to send the same data from Processing:
import processing.serial.*;
Serial arduino;
void setup(){
try{
arduino = new Serial(this, Serial.list()[0], 9600);
}catch(Exception e){
println("error connecting to serial port, double chek USB connection, serial port and close other programs using Serial");
e.printStackTrace();
}
}
void draw(){
}
void keyPressed(){
if(key == '1'){
if(arduino != null){
arduino.write('1');
}else{
println("arduino serial connection wasn't initialised");
}
background(255);
}
if(key == '0'){
if(arduino != null){
arduino.write('0');
}else{
println("arduino serial connection wasn't initialised");
}
background(0);
}
}
Minor side note: notice I'm not using delay() in Processing, I recommend using millis() instead as it doesn't block the execution of code like delay() does.
So the above looks like quite a bit of code just to blink an LED but the point is to understand the basics of Serial communication which will be useful on the long run:
initialising serial communication with Arduino (understand baud rate)
basic reading/writing of bytes over Serial
initialising serial communication from Processing and sending data
Back to your original question, you've missed an important detail regarding the Arduino library you're using in Processing: it's relying on a special Arduino sketch (firmware) called Firmata. You will be able to read more on that and how to use the library in this Arduino and Processing tutorial.
As the tutorial mentions you need to first upload this sketch from Arduino > Examples > Firmata > StandardFirmata. Also bare in mind baud rate is set to 57600, not 9600 so you need to update your code like so:
arduino = new Arduino(this, Arduino.list()[0], 57600);
To use: are you sure to put the standardfirmata
Using the Arduino software, upload the StandardFirmata example (located
in Examples > Firmata > StandardFirmata) to your Arduino board.
change the line
arduino = new Arduino(this, Arduino.list()[0], 9600);
to:
arduino = new Arduino(this, "COM3", 57600); // in Firmata -> Firmata.begin(57600);
you could add this line to look after your serial port:
println(Arduino.list());
Modify the "arduino = new Arduino(...)" line below, changing the number in Arduino.list()[0] to the number corresponding to the serial port of your Arduino board. Alternatively, you can replace Arduino.list()[0] with the name of the serial port, in double quotes, e.g. "COM3" on Windows or "/dev/tty.usbmodem621" on Mac.
I got it working with Arduino but I had to change some details. My port was "COM3" or Arduino.list()[1] (the 2nd port on the list) which you can check in Windows device manager (Ports COM & LPT: USB-SERIAL) after installing the latest drivers (maybe on the usb port that appears when you connect your Arduino under other devices) using the system update and restarting, then you may need to repeat the system update and restart 2 or 3 times. Or on Linux, you can find which port it's on with:
ls /dev/ttyUSB*
Then unplug it and check it again.
First I had to upload the Arduino IDE program (running it with the serial monitor window from the tools menu ctrl-shft-m after having the same exact baud rate on the lower right menu option as in the program). Then I could close it and compile the processing one as long as I had input that very same baud rate into the Processing program too. All 3 different bauds that I tried, 9600, 57600, 115200, worked requiring their equality between Arduino IDE, Arduino IDE Serial Monitor and Processing. If I uploaded a different project in IDE, then Processing did not even connect to the Arduino, so it had to be that same project running on it for Processing to communicate with Arduino Uno properly. Processing is basicly USING Arduino IDE by sending or receiving messages already programmed for it to do, it doesn't program the Arduino in this case. I have even gone through a big mess, trying to get Visual Micro to work (Arduino on Visual Studio) cross-platform but it still would not allow me to link other libraries and headers because of how picky Arduino's programming is! One of the best ways to learn is to check the actual arduino.cc or Processing manual command parameters after finding out where your problem is.
#include <SoftwareSerial.h>
//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 8
//SIM800 RX is connected to Arduino D7
#define SIM800_RX_PIN 7
//Create software serial object to communicate with SIM800
SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN);
void setup() {
//Begin serial comunication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
while(!Serial);
//Being serial communication with Arduino and SIM800
serialSIM800.begin(9600);
Serial.println("Setup Complete!");
//serialSIM800.println("AT+CSPN?\r\n");
//serialSIM800.println("AT+EXUNSOL=\"SQ\",1\r\n");
//serialSIM800.println("AT");
//delay(1000);
//Send SMS
Serial.println("Sending Text...");
delay(1000);
serialSIM800.print("AT+CMGF=1\r");
serialSIM800.print("AT+CMGS=\"0781xxxxxxx\"\r");
delay(200);
//Send SMS content
serialSIM800.print("TEST");
serialSIM800.print("\r");
delay(500);
//Send Ctrl+Z / ESC to denote SMS message is complete
serialSIM800.print((char)26);
delay(100);
serialSIM800.println();
delay(500);
Serial.println("SMS Sent!");
delay(500);
}
void loop() {
//Read SIM800 output (if available) and print it in Arduino IDE Serial Monitor
if(serialSIM800.available()){
Serial.write(serialSIM800.read());
}
//Read Arduino IDE Serial Monitor inputs (if available) and send them to SIM800
if(Serial.available()){
serialSIM800.write(Serial.read());
}
}
The code above when uploaded runs generate no errors but no SMS received.
serial mode displays the following;-
Setup Complete!
Sending Text...
SMS Sent!
AT+CMGF=1
AT+CMGS="0781xxxxxxx"
OK
TEST
Call Ready
obviously I send the text to my mobile that's available tried the country code option also. I haven't been able to find anything that helps online as yet and was hoping someone can point me in the right direction.
Thanks
Okay, found the answer, the code is fine.
Checked the power at 4.1V which is fine
So with the above code I needed to make sure that I pressed and held the Reset button on the mini board until the sim800L led went from fast flashing to slow flashing, then the text was generated and sent to the number programmed.
As I am new to this, I couldn't find clear guidance anywhere that explained this, so was scratching my head a little.
Now to the next step.
I am a newbie with Arduino Mega 2560 .I have been trying to connect the Arduino and SIM900A module(GSM/GPRS module).I have connected the USB to my PC(Serial instance) and pins 18(Tx) and 19(Rx) to Rx and Tx in the GSM/GPRS module respectively and the GND pin(GSM/GPRS) module's is connected to GND,one near pin 13 in the Arduino.
Power connection:-
I am powering using 12V supplies for each of the boards.
The below is my code.
void setup()
{
Serial.begin(9600);
Serial1.begin(9600);
delay(1000);
Serial.print("Initial Setup !!");
delay(5000);
}
void loop()
{
if(Serial.available())
{
char a=Serial.read();
Serial1.print(a);
//Serial.print(a);
}
if(Serial1.available())
{
char B=Serial1.read();
Serial.print(B);
//Serial.print(a);
}
}
I am able to get the initial response in the "Serial Monitor" like (+CFUN:1,+CPIN:READY)(Once I open the Serial monitor I used to press the reset in the GSM/GPRSmodule).
But when I type some AT commands in the Serial Monitor,I am not able to get the response like "OK" from the GPRS/GSM Module.
Please let me know what I should be doing for getting the responses back from GSM/GPRS module.
Have you tried cutting out the Arduino, for just a moment? Get yourself a UART and wire up TX/RX to the GMS respectively. Then plug it into your PC and launch terminal (Tera Term, etc.).
Try issuing some AT commands and make sure you're getting correct responses/echos. You may also want to try a tool called QNavigator (free download).