0

I'm using software serial on my weather station. The way it's supposed to work is that you send an SMS to the device and it replies with the wind speed, etc.

At the moment, The wind speed is detected, waiting for an incoming SMS. The SMS arrives and it sends a response but the response SMS is sent over and over infinitely. I'm guessing the problem is due to the:

 if (mySerial.available()>0){

As this is what I'm using to test whether the SMS has arrived and presumably, it's then always set to available.

Does anyone know how to basically reset the software serial after the message has been sent?

 #include <SoftwareSerial.h>
 #include <ADSWeather.h>

SoftwareSerial mySerial(9, 10);

#define ANEMOMETER_PIN 2
#define VANE_PIN 0
#define RAIN_PIN 3

#define CALC_INTERVAL 1000

unsigned long nextCalc;
unsigned long timer;

int windDir;
int windSpeed;
int rainAmmount;

ADSWeather ws1(RAIN_PIN, VANE_PIN, ANEMOMETER_PIN); //This should configure all pins correctly

void setup()
{
  Serial.begin(9600); 
  attachInterrupt(digitalPinToInterrupt(RAIN_PIN), ws1.countRain, FALLING); //ws1.countRain is the ISR for the rain gauge.
  attachInterrupt(digitalPinToInterrupt(ANEMOMETER_PIN), ws1.countAnemometer, FALLING); //ws1.countAnemometer is the ISR for the anemometer.
  nextCalc = millis() + CALC_INTERVAL;
  
  mySerial.begin(9600);   // Setting the baud rate of GSM Module  
  delay(100);
}


void loop()
{
  timer = millis();

  int rainAmmount;
  long windSpeed;
  long windDirection;
  int windGust;
  int sent;

  ws1.update(); //Call this every cycle in your main loop to update all the sensor values

  if(timer > nextCalc)
  {
    
    nextCalc = timer + CALC_INTERVAL;
    rainAmmount = ws1.getRain();
    windSpeed = ws1.getWindSpeed();
    windDirection = ws1.getWindDirection();
    windGust = ws1.getWindGust();

//     windSpeed / 10 will give the interger component of the wind speed
//     windSpeed % 10 will give the fractional component of the wind speed
    Serial.print("Wind speed: ");
    Serial.print(windSpeed / 10);
    Serial.print('.');
    Serial.print(windSpeed % 10);
    Serial.print(" ");

    Serial.print("Gusting at: ");
    Serial.print(windGust / 10);
    Serial.print('.');
    Serial.print(windGust % 10);
    Serial.println("");

    
  }

  
  if (Serial.available()>0)
  {
      RecieveMessage();
  }

  //If an message comes in
 if (mySerial.available()>0){
  // Serial.write(mySerial.read());
  Serial.write("Message received");

  //Send the wind speed response.
  SendMessage();

  //At this point the SendMessage() repeats and the message is sent over and over.
}
}

 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=\"NUMRemoved\"\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);
}


 void RecieveMessage()
{
  mySerial.println("AT+CNMI=2,2,0,0,0"); // AT Command to receive a live SMS
  delay(1000);
 }

 void serialFlush(){
  while(mySerial.available() > 0) {
    char t = mySerial.read();
  }
}   
  • 2
    You need to read the stuff from SoftwareSerial. Use mySerial.read() until available is false. If you don’t care what was sent then simply use read and ignore the value that was read. – Delta_G Sep 6 at 14:21
  • you have a serialFlush() function in the sketch. use it. – Juraj Sep 6 at 17:11
  • @Juraj It doesn't work. The SMS messages keep coming. – connersz Sep 6 at 23:15
  • change the sketch in question so we can see how do you use serialFlush(); – Juraj Sep 7 at 5:09
1

For the hardware serial port, the buffer is 64 and I was reading at least 100 times. Every read will clear one byte of data from the serial buffer at a time.

For the software serial port, you do a dummy read and then check whether the buffer is empty or not using

    while(mySerial.available()>0)  {  
       dummy = mySerial.read();  
    }

So, in summary, you have to read the buffer until it is empty.

Useful notes:

  1. You should be knowing when to expect actual data and when not to
  2. have a way to identify the valid messages (some fixed header bytes)
  3. have a way to validate the contents (checksum)

Leave a comment if you have any questions

| improve this answer | |
  • I've tried using this loop to flush the serial port, it's even in the code I posted above but it does not work. The SMS messages keep coming. Am I calling it in the wrong place? – connersz Sep 6 at 23:14
  • You never call it. – Nick Gammon Sep 7 at 2:14
0
 if (mySerial.available()>0){

You are checking if any serial data has arrived. Then you never read it. So naturally it is always available. You have a serialFlush function which does read it, however that function is never called.

You need, however, to read more than one byte. Otherwise you will send an SMS for every byte in the input message.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.