SIM7600CE - How to know when SIM card is registered into network by software - arduino

I am trying to set up the SIM7600CE to have it connect to the internet whenever I turn it on with Arduino Mega. I know how to turn it on with software by set the pin D12 to HIGH but I don't know how to read the signal of the NETLIGHT pin to get to know when the NETLIGHT starts to blink, which means the SIM card is registered into network successfully. Is there any way I can read that signal? Or is there any other way I can acknowledge when SIM card is registered into network successfully by software?
edit: I am trying to get the information that my SIM7600 is connected by using AT command. Even though I can send the AT command, I cannot parse the response. The result of the code below turns out that the Serial keeps printing the string "at+csq" constantly. Can anybody help?
#define mySerial Serial1
#define PWRKEY 12
void setup()
{
digitalWrite(PWRKEY, HIGH); //Press the boot button
Serial.begin(115200);
delay(500);
mySerial.begin(115200);
delay(5000);
while (1)
{
Serial.println("AT+CSQ"); //AT command for Signal quality test
updateSerial();
delay(1500);
}
}
void loop()
{
updateSerial();
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read());
}
while (mySerial.available())
{
Serial.write(mySerial.read());
if (Serial.find("+CSQ: ")) //Find the AT+CSQ response
{
char c = mySerial.read();
if (c != '9') //check the first digit after "+CSQ: ", +CSQ: 99,99 means not detectable,
{
Serial.println("connected");
break;
}
}
}

Checkout the AT manual for the MODEM. Enable all URCs related to network registration, once registered on the network - you will receive a URC that will have information if your SIM was able to register on the network or not.

I have solved the problem with the same logic. However, I tried to just write and read in the SIM7600 serial, with some printing on the monitor to guide/debug. Plus, I used a connection flag as a condition to break the while loop when the MODEM is connected.
#define mySerial Serial1
#define PWRKEY 12
bool connectionFlag = 0; //will be set when connected
void setup()
{
digitalWrite(PWRKEY, HIGH); //Press the boot button
Serial.begin(115200);
delay(500);
mySerial.begin(115200);
delay(5000); //Give it a little time to initialize
while (1)
{
mySerial.println("AT+CSQ"); //AT command for Signal quality test
connectionCheck();
if (connectionFlag ==1) break;
delay(1500);
}
Serial.println("done");
mySerial.println("AT+CSQ"); //Get the CSQ response to confirm.
updateSerial();
}
void loop()
{
updateSerial();
}
void connectionCheck()
{
delay(500);
while (mySerial.available())
{
// Serial.write(mySerial.read());
if (mySerial.find("+CSQ: ")) //Find the AT+CSQ response
{
Serial.print("initializing\t");
char c = mySerial.read();
if (c != '9') //check the first digit after "+CSQ: ", +CSQ: 99,99 means not detectable,
{
Serial.println("connected");
connectionFlag = 1;
break;
}
}
}
}
void updateSerial()
{
delay(500);
if (mySerial.available())
{
Serial.write(mySerial.read());
}
if (Serial.available())
{
mySerial.write(Serial.read());
}
}

Related

Could not find a valid MPU6050 sensor

I am using the below code with arduino-uno, but often getting "Could not find a valid MPU6050 sensor
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
void setup() {
Serial.begin(115200);
Serial.println("Initialize MPU6050");
while (!mpu.begin()) {
Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
delay(500);
}
}
void loop() {
}
My Arduino is working fine,
So, I checked MPU6050 using below code,
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(115200);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
Got Output as expected
Scanning...
I2C device found at address 0x68 !
done
From the above output I hope GPU6050 is working
How can I get values from GPU6050?
Your code is working as expected, it tells you in setup() when it can't connect to the device, until it can.
So when it stops printing the message, it is connected.
Now in loop() you should write your code to negotiate with the device.
Here's an excellent place to start with.

How can I create an automated GPS tracker using A9G AI Thinker module?

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.

Arduino + SIM800A messages get cut-off

I am working with Arduino and SIM800A. My goal is to save the sms message received by SIM800A to a string variable to be used later. Yet to my surprise, the message always get cut off and I have no clue why.
I send to SIM:
This is a test message
The Serial Monitor only shows:
+CMT: "+XXXXXXXXXX","","21/02/20,01:52:40+28"
This is a tes
Below is the code
#include <SoftwareSerial.h>
// Configure software serial port
SoftwareSerial Sim(2, 3);
// Variable to store text message
char incomingMessage;
String textMessage;
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
// Initializing serial commmunication
Serial.begin(9600);
Sim.begin(9600);
delay(100);
while (!Sim.available()) {
Sim.println("AT");
delay(200);
Serial.println("Connecting...");
}
Serial.println("Connected!");
Sim.println("AT+CMGF=1"); //Set SMS to Text Mode
delay(200);
// Sim.println("AT+CMGL=\"ALL\"");
// delay(500);
Sim.println("AT+CNMI=1,2,0,0,0"); //Procedure to handle newly arrived messages(command name in text: new message indications to TE)
delay(1000);
Sim.read();
//Sim.println("AT+CMGL=\"REC UNREAD\""); // Read Unread Messages
}
void loop() {
if (Sim.available()>0) {
delay(200);
// Serial Buffer
while (Sim.available()>0) {
incomingMessage = Sim.read();
textMessage += incomingMessage;
}
delay(500);
Serial.println(textMessage);
textMessage = "";
}
}

How would I create a simple Arduino script that allows me to turn on and off LEDBuitIn remotely?

I'm working on a project that includes working with arduino hardware remotely. I would like to learn how to create a simple script that allows me to turn on and off the Led builtin to my MKR1000 wirelessly. I could then use this knowledge in more complicated projects. After doing some research and looking at the arduino library's sample webserver program, I came up with this Frankenstein of code. After working for hours I just keep on making it worse, I could really use some guidance on what I'm doing wrong, why and how to fix it.
My Frankenstein code:
#include <WiFi101.h>
#include <SPI.h>
char ssid[] = "ARROW_015D80";
char pass[] = "KRR3K47XZXM3NYRHV7GX";
int status = WL_IDLE_STATUS;
int LED = LED_BUILTIN;
int LEDState = digitalRead(LED);
WiFiServer server(80);
void setup() {
while (!Serial) {
}
Serial.begin(9600);
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("Yo, where the wifi shield at?");
while(true);
}
while (status !=WL_CONNECTED) {
Serial.print("Connecting to ssid: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000);
}
server.begin();
printWiFiStatus();
}
void loop() {
WiFiClient client = server.available();
if (client) {
Serial.println("+1 Client");
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
if (c == '\n') {
if(currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("Refresh: 1"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("State of button:");
if (LEDState == HIGH){
client.print("ON");
}
if (LEDState == LOW){
client.print("OFF");
}
client.println("<br>");
client.println("</html>");
client.println();
break;
}
else {
currentLine = "";
}
}
else if (c !='\r') {
currentLine += c;
}
if (currentLine.endsWith("GET /H")) {
digitalWrite(LED, HIGH);
}
if (currentLine.endsWith("Get /L")) {
digitalWrite(LED, LOW);
}
if (currentLine.endsWith("Get /stop")){
client.stop();
Serial.println ("Client disconnected");
}
}
}
}
}
void printWiFiStatus() {
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
According to the videos and the mismatch of information, this program should connect the arduino to the internet, print the arduino's ip address in the serial monitor and I should be able to change the state of the built in LED by changing the end of the ip address search.
Instead, after showing the ip address and displaying the page, with the button state on it. When I try to change the url to change the button state it bugs out. It takes me to the "This page can't be reached" and the serialmonitor bug out.
Never mind, I found a video online that explain clearly how to write the code I'm looking for. It is extremely helpful : https://www.youtube.com/watch?v=H0p7GVPdlyU
It also link to a page with all the code for it.

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