This is my first question to the forum , Therefore, sorry for any mis-understanding.
In fact, I'm doing a simple project of turning on a light if I send an SMS "LIGHT ON" and turn it off with "LIGHT OFF"
With my code, everything is working as expected. However, when removing the serial monitor and only putting an external voltage input (either 5V / 12V, with sufficient voltage...), the received message is just garbage... I used the EEPROM to put the message within for investigation purposes : The obtained message is the following "⸮v⸮⸮⸮⸮⸮⸮⸮⸮⸮P⸮⸮Z&⸮⸮⸮"
I'm sure that the message is well received.
The code is the following:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8); // Tx, Rx
const int relaisPin = 10;
String smsContent = "";
const int sensorPin = A0; // Analog input pin
float voltage = 0.0;
float old_voltage = 0.0;
float factor = 5.0 / 1024.0; // Scaling factor for 5V Arduino
const float Max_Volt = (100.0 / 220.0) * 5.0; // Correct calculation of max voltage
const float Min_Volt = (10.0 / 220.0) * 5.0; // Correct calculation of min voltage
bool isLampOn = false;
bool DBG = true;
bool processing = false;
bool first = true;
void setup() {
pinMode(relaisPin, OUTPUT);
digitalWrite(relaisPin, LOW); // Ensure the relay is initially off
if (DBG) Serial.begin(9600);
mySerial.begin(9600);
if (DBG) Serial.println("Initialisation...");
delay(1000);
mySerial.println("AT");
delay(2000);
if (DBG) updateSerial();
mySerial.println("AT+CMGF=1"); // Set SMS mode to text
delay(2000);
if (DBG) updateSerial();
mySerial.println("AT+CNMI=1,2,0,0,0"); // Configure to send SMS data to the serial out
delay(2000);
if (DBG) updateSerial();
digitalWrite(relaisPin, HIGH);
}
void loop() {
if (first) {
setup();
first = false;
}
if (mySerial.available()) {
processing = true;
smsContent = read_sms();
if (DBG) Serial.println("The full buffer is: " + smsContent);
processMessage(smsContent);
} else if (!processing){
checkVoltage(); // Check voltage and send SMS if conditions are met
}
//delay(1000);
if (DBG) updateSerial();
}
String read_sms() {
String sms = ""; // Initialize
while (mySerial.available()) {
char c = mySerial.read();
sms += c;
delay(2); // Allow time for buffer to fill
}
return sms;
}
void processMessage(String message) {
if (DBG) Serial.print("Received SMS: ");
if (DBG) Serial.println(message);
// Find +CMT line and extract phone number
int cmtIndex = message.indexOf("+CMT:");
if (cmtIndex != -1) {
int phoneNumberStart = message.indexOf("\"", cmtIndex);
int phoneNumberEnd = message.indexOf("\"", phoneNumberStart + 1);
String phoneNumber = message.substring(phoneNumberStart + 1, phoneNumberEnd);
// Debug print for extracted phone number
if (DBG) Serial.print("Extracted phone number: ");
if (DBG) Serial.println(phoneNumber);
// Check if the phone number is allowed
if (phoneNumber == "+xyz" || phoneNumber == "+sev") {
// Extract message body
int messageStart = message.indexOf("\n", phoneNumberEnd) + 1;
String messageBody = message.substring(messageStart);
// Debug print for message body
if (DBG) Serial.print("Extracted message body: ");
if (DBG) Serial.println(messageBody);
// Process message
if (messageBody.indexOf("LIGHT ON") != -1) {
digitalWrite(relaisPin, HIGH); // Turn the relay on
if (DBG) Serial.println("Turning lamp on.");
//sendConfirmation("Lampe allumee");
}
else if (messageBody.indexOf("LIGHT OFF") != -1) {
digitalWrite(relaisPin, LOW); // Turn the relay off
if (DBG) Serial.println("Turning lamp off.");
//sendConfirmation("Lampe eteinte");
} else {
if (DBG) Serial.println("Received an unrelated message.");
}
// Debug relay pin state
if (DBG) Serial.print("Relay pin state: ");
if (DBG) Serial.println(digitalRead(relaisPin));
} else {
if (DBG) Serial.println("Unauthorized phone number.");
}
}
processing = false;
//delay(10000); // Delay for data processing
if (DBG) Serial.println("end processing....");
}
void updateSerial() {
while (Serial.available()) {
mySerial.write(Serial.read());
}
while (mySerial.available()) {
Serial.write(mySerial.read());
}
}
void sendConfirmation(String message) {
if (DBG) Serial.println("Sending confirmation: " + message);
mySerial.print("AT+CMGS=\"+phone number -_-\"\r"); // Replace with your phone number
delay(1000);
mySerial.print(message);
delay(1000);
mySerial.write(26); // ASCII code for CTRL+Z to send the SMS
delay(1000);
if (DBG) Serial.println("Confirmation sent: " + message);
}
void checkVoltage() {
int sensorValue = analogRead(sensorPin);
voltage = sensorValue * factor; // Convert to voltage
if (((voltage > (old_voltage * 1.1)) || (voltage < (old_voltage *0.9))) && DBG) {
Serial.print("AC Voltage: ");
Serial.print(voltage);
Serial.println(" V");
old_voltage = voltage;
}
if (voltage > Max_Volt && !isLampOn) {
if (DBG) Serial.println("Voltage > 100V and lamp is off. Sending confirmation...");
sendConfirmation("Lampe allumee");
isLampOn = true;
}
else if (voltage < Min_Volt && isLampOn) {
if (DBG) Serial.println("Voltage < 10V and lamp is on. Sending confirmation...");
sendConfirmation("Lampe eteinte");
isLampOn = false;
}
}
The used hardware are Arduino Uno , GSM/GPRS A6 module and 5v/220v relay
...but maybe not sufficient current.
Anyway if you don't present your hardware, it's impossible to help. We only know that there is some A6 and some 5v relay
Pins 7 and 8 connected to Rx and Tx
Pin 10 connected to the relay In
I'll do a schematic and I'll send it, howe er, since it's working with the PC , I don't think it's a schematic problem
The answer of thr second question: I'm sending an SMS from my phone to the Arduino Sim card, and saving it in the EEPROM
If you power arduino with 5V/3A power supply to usb or 5V pin you are fine.
So confirm, when connected to computer your message is saved to eeprom correctly?
When powered to 5V/3A, the same issue is present, same as 12V/3A
When connected to computer, the message is properly saved to EEPROM, when doing the same with the power supply, I got the garbage message
the code with further modifications, including the eeprom method, and having the same results is below
#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial mySerial(7, 8); // Tx, Rx
const int relaisPin = 10;
String smsContent = "";
const int sensorPin = A0; // Analog input pin
float voltage = 0.0;
float old_voltage = 0.0;
float factor = 5.0 / 1024.0; // Scaling factor for 5V Arduino
const float Max_Volt = (100.0 / 220.0) * 5.0; // Correct calculation of max voltage
const float Min_Volt = (10.0 / 220.0) * 5.0; // Correct calculation of min voltage
bool isLampOn = false;
bool DBG = true; // Enable debug
bool processing = false;
void setup() {
pinMode(relaisPin, OUTPUT);
digitalWrite(relaisPin, LOW); // Ensure the relay is initially off
if (DBG) Serial.begin(9600);
mySerial.begin(9600);
if (DBG) Serial.println("Initialisation...");
delay(5000); // Longer delay for stability
// Send initialization commands to GSM module
mySerial.println("AT");
delay(1000);
if (DBG) updateSerial();
mySerial.println("AT+CMGF=1"); // Set SMS mode to text
delay(1000);
if (DBG) updateSerial();
mySerial.println("AT+CNMI=1,2,0,0,0"); // Configure to send SMS data to the serial out
delay(1000);
if (DBG) updateSerial();
digitalWrite(relaisPin, HIGH);
// Clear initial response from GSM module
clearSerialBuffer();
}
void loop() {
if (mySerial.available()) {
processing = true;
smsContent = read_sms();
if (DBG) Serial.println("The full buffer is: " + smsContent);
processMessage(smsContent);
} else if (!processing) {
checkVoltage(); // Check voltage and send SMS if conditions are met
}
// Read and display stored SMS content from EEPROM if "Ilyes" is typed in the console
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
if (command.equals("Ilyes")) {
String storedMessage = readFromEEPROM();
Serial.println("Stored SMS from EEPROM: " + storedMessage);
}
}
if (DBG) updateSerial();
}
String read_sms() {
String sms = "";
long startTime = millis();
char c;
// Wait for SMS message or timeout after 5 seconds
while (millis() - startTime < 5000) {
if (mySerial.available()) {
c = mySerial.read();
sms += c;
// Check for end of SMS message
if (sms.endsWith("OK\r\n")) {
break;
}
}
}
return sms;
}
void processMessage(String message) {
if (DBG) Serial.print("Received SMS: ");
if (DBG) Serial.println(message);
// Find +CMT line and extract phone number
int cmtIndex = message.indexOf("+CMT:");
if (cmtIndex != -1) {
int phoneNumberStart = message.indexOf("\"", cmtIndex);
int phoneNumberEnd = message.indexOf("\"", phoneNumberStart + 1);
String phoneNumber = message.substring(phoneNumberStart + 1, phoneNumberEnd);
// Debug print for extracted phone number
if (DBG) Serial.print("Extracted phone number: ");
if (DBG) Serial.println(phoneNumber);
// Check if the phone number is allowed
if (phoneNumber == "+21658582837" || phoneNumber == "+216125358") {
// Extract message body
int messageStart = message.indexOf("\n", phoneNumberEnd) + 1;
String messageBody = message.substring(messageStart);
// Debug print for message body
if (DBG) Serial.print("Extracted message body: ");
if (DBG) Serial.println(messageBody);
// Process message
if (messageBody.indexOf("LAMPE ON") != -1) {
digitalWrite(relaisPin, HIGH); // Turn the relay on
if (DBG) Serial.println("Turning lamp on.");
//sendConfirmation("Lampe allumee");
}
else if (messageBody.indexOf("LAMPE OFF") != -1) {
digitalWrite(relaisPin, LOW); // Turn the relay off
if (DBG) Serial.println("Turning lamp off.");
//sendConfirmation("Lampe eteinte");
} else {
if (DBG) Serial.println("Received an unrelated message.");
}
// Debug relay pin state
if (DBG) Serial.print("Relay pin state: ");
if (DBG) Serial.println(digitalRead(relaisPin));
} else {
if (DBG) Serial.println("Unauthorized phone number.");
}
}
processing = false;
if (DBG) Serial.println("End processing....");
}
String readFromEEPROM() {
String message = "";
char c;
int eepromIndex = 0;
while ((c = EEPROM.read(eepromIndex++)) != '\0') { // Read until null terminator
message += c;
}
return message;
}
void updateSerial() {
while (Serial.available()) {
mySerial.write(Serial.read());
}
while (mySerial.available()) {
Serial.write(mySerial.read());
}
}
void sendConfirmation(String message) {
if (DBG) Serial.println("Sending confirmation: " + message);
mySerial.print("AT+CMGS=\"+21658582837\"\r"); // Replace with your phone number
delay(1000);
mySerial.print(message);
delay(1000);
mySerial.write(26); // ASCII code for CTRL+Z to send the SMS
delay(1000);
if (DBG) Serial.println("Confirmation sent: " + message);
}
void clearSerialBuffer() {
while (mySerial.available() > 0) {
char c = mySerial.read();
delay(10); // Adjust delay as necessary
}
}
void checkVoltage() {
int sensorValue = analogRead(sensorPin);
voltage = sensorValue * factor; // Convert to voltage
if (((voltage > (old_voltage * 1.1)) || (voltage < (old_voltage *0.9))) && DBG) {
Serial.print("AC Voltage: ");
Serial.print(voltage);
Serial.println(" V");
old_voltage = voltage;
}
if (voltage > Max_Volt && !isLampOn) {
if (DBG) Serial.println("Voltage > 100V and lamp is off. Sending confirmation...");
//sendConfirmation("Lampe allumee");
isLampOn = true;
}
else if (voltage < Min_Volt && isLampOn) {
if (DBG) Serial.println("Voltage < 10V and lamp is on. Sending confirmation...");
//sendConfirmation("Lampe eteinte");
isLampOn = false;
}
}
Do you think that some Arduino PIN are not initialised properly? :face_with_open_eyes_and_hand_over_mouth:
I'm just saying that, because the sim A6 is not working properly with some ports of the Arduino (Such us A1 / A2 instead of 7 and 8...)
(I'm just trying everything to figure out the issue)
I'm able to reproduce the same issue with this simple code:
#include <SoftwareSerial.h>
// Create software serial object to communicate with A6
SoftwareSerial mySerial(A1, A2); // A6 Tx & Rx is connected to Arduino #A1 & #A2
const int relayPin = A3; // Define the relay pin
void setup()
{
// Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
// Begin serial communication with Arduino and A6
mySerial.begin(9600);
// Initialize the relay pin as an output
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW); // Ensure the relay is off initially
Serial.println("Initializing...");
delay(1000);
mySerial.println("AT"); // Once the handshake test is successful, it will return OK
updateSerial();
mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
updateSerial();
mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
updateSerial();
}
void loop()
{
updateSerial();
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
mySerial.write(Serial.read()); // Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
char incomingByte = mySerial.read();
Serial.write(incomingByte); // Forward what Software Serial received to Serial Port
// Accumulate the received message
static String receivedMessage = "";
receivedMessage += incomingByte;
// Print the accumulated message so far
Serial.print("Received message so far: ");
Serial.println(receivedMessage);
// Check if the message contains "Lampe"
if (receivedMessage.indexOf("Lampe") >= 0) {
digitalWrite(relayPin, HIGH); // Turn the relay on
Serial.println("Relay ON (Message contains 'Lampe')");
} else {
digitalWrite(relayPin, LOW); // Turn the relay off
Serial.println("Relay OFF (Message does not contain 'Lampe')");
}
// Clear the received message if end of message is detected (this is just an example, you might need a more robust method)
if (incomingByte == '\n') {
Serial.print("Complete message received: ");
Serial.println(receivedMessage);
receivedMessage = "";
}
}
}
Where I switch the relay status depending on the message...
Look, you open a post with problem saving correctly messages to eeprom when not connected to computer. After 3 codes you uploaded here, there is still not a line where you write to eeprom. If that is not your interest, just start from beginning with matching code and problem. And clean your serial stuff from the code, if you don't have that available!
The issue is related to the initialisation of the module when not connected to the computer.
The following code works now:
#include <SoftwareSerial.h>
#include <avr/wdt.h> // Include the watchdog timer library
// Create software serial object to communicate with A6
SoftwareSerial mySerial(A2, A1); // A6 Tx & Rx is connected to Arduino #A1 & #A2
const int relayPin = A3; // Define the relay pin
void setup()
{
// Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
Serial.begin(9600);
// Begin serial communication with Arduino and A6
mySerial.begin(9600);
// Initialize the relay pin as an output
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW); // Ensure the relay is off initially
Serial.println("Initializing...");
// Enable the watchdog timer with a 4-second timeout
wdt_enable(WDTO_4S);
// Initialize the GSM module
if (initializeGSM()) {
Serial.println("GSM Module Initialized Successfully");
wdt_disable(); // Disable watchdog timer after successful initialization
} else {
Serial.println("GSM Module Initialization Failed");
while (1); // Enter infinite loop to trigger watchdog reset
}
}
void loop()
{
updateSerial();
}
void updateSerial()
{
while (Serial.available())
{
mySerial.write(Serial.read()); // Forward what Serial received to Software Serial Port
}
while(mySerial.available())
{
char incomingByte = mySerial.read();
Serial.write(incomingByte); // Forward what Software Serial received to Serial Port
// Accumulate the received message
static String receivedMessage = "";
receivedMessage += incomingByte;
// Print the accumulated message so far
Serial.print("Received message so far: ");
Serial.println(receivedMessage);
// Check if the message contains "Lampe"
if (receivedMessage.indexOf("Lampe") >= 0) {
digitalWrite(relayPin, HIGH); // Turn the relay on
Serial.println("Relay ON (Message contains 'Lampe')");
} else {
digitalWrite(relayPin, LOW); // Turn the relay off
Serial.println("Relay OFF (Message does not contain 'Lampe')");
}
// Clear the received message if end of message is detected (this is just an example, you might need a more robust method)
if (incomingByte == '\n') {
Serial.print("Complete message received: ");
Serial.println(receivedMessage);
receivedMessage = "";
}
}
}
bool initializeGSM() {
// Try initializing the GSM module multiple times
for (int i = 0; i < 3; i++) {
if (sendCommandToGSM("AT", 2000) && sendCommandToGSM("AT+CMGF=1", 2000) && sendCommandToGSM("AT+CNMI=1,2,0,0,0", 2000)) {
return true;
}
delay(5000); // Wait before retrying
}
return false;
}
bool sendCommandToGSM(const char* command, unsigned long timeout) {
mySerial.println(command);
unsigned long start = millis();
while (millis() - start < timeout) {
if (mySerial.available()) {
String response = mySerial.readString();
Serial.println(response); // Print the GSM module's response
if (response.indexOf("OK") != -1) {
return true;
}
}
}
return false;
}