Not properly getting the message from A6 module when not connected to a PC

Hello,

This is my first question to the forum :slight_smile: , 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" :sweat_smile:

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

Don't hesitate to ask / comment!

Thank you!

Please post schematics for the troubeling version.

Received from where to where?

...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

Not solving your problem but why do you run setup() twice?

It's just me trying to find a solution for the problem
That line should be removed

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

I'm using a 3A power supply
For sure it's giving more current than the computer

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

I don't quite understand. There is no reference to any EEPROM code in the code that you presented.

I just used the eeprom library

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 not really following now, how is the message written to eeprom?

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;
}

I'll let you know about the advancements