Как очистить значения SoftwareSerial?

Я использую software serial на своей метеостанции. Предполагается, что это работает следующим образом: вы отправляете SMS на устройство, а оно отвечает скоростью ветра и т. д.

На данный момент обнаружена скорость ветра, ожидание входящего SMS. СМС приходит и отправляет ответ, но ответное СМС отправляется снова и снова бесконечно. Я предполагаю, что проблема связана с:

 if (mySerial.available()>0){

Поскольку это то, что я использую для проверки того, пришло ли SMS, и, предположительно, оно всегда установлено как доступное.

Кто-нибудь знает, как сбросить software serial программы после отправки сообщения?

 #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); // Это должно правильно настроить все выводы

void setup()
{
  Serial.begin(9600); 
  attachInterrupt(digitalPinToInterrupt(RAIN_PIN), ws1.countRain, FALLING); //ws1.countRain — это ISR для датчика дождя.
  attachInterrupt(digitalPinToInterrupt(ANEMOMETER_PIN), ws1.countAnemometer, FALLING); //ws1.countAnemometer — это ISR для анемометра.
  nextCalc = millis() + CALC_INTERVAL;
  
  mySerial.begin(9600);   // Установка скорости передачи GSM-модуля
  delay(100);
}


void loop()
{
  timer = millis();

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

  ws1.update(); // Вызовите это каждый цикл в вашем основном цикле, чтобы обновить все значения датчика

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

//windSpeed/10 даст целочисленную составляющую скорости ветра
// WindSpeed % 10 даст дробную составляющую скорости ветра
    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 (mySerial.available()>0){
  // Serial.write(mySerial.read());
  Serial.write("Message received");

  //Отправить ответ скорости ветра.
  SendMessage();

  // В этот момент SendMessage() повторяется, и сообщение отправляется снова и снова.
}
}

 void SendMessage()
{
  mySerial.println("AT+CMGF=1");    // Устанавливает модуль GSM в текстовый режим
  delay(1000);  // Задержка 1000 миллисекунд или 1 секунда
  mySerial.println("AT+CMGS=\"NUMRemoved\"\r"); // Заменить x на номер мобильного телефона
  delay(1000);
  mySerial.println("I am SMS from GSM Module");// Текст SMS, который вы хотите отправить
  delay(100);
   mySerial.println((char)26);// ASCII-код CTRL+Z
  delay(1000);
}


 void RecieveMessage()
{
  mySerial.println("AT+CNMI=2,2,0,0,0"); // AT-команда для получения живого SMS
  delay(1000);
 }

 void serialFlush(){
  while(mySerial.available() > 0) {
    char t = mySerial.read();
  }
}   

, 👍0

Обсуждение

Вам нужно прочитать материал из SoftwareSerial. Используйте mySerial.read() до тех пор, пока available не станет ложным. Если вам все равно, что было отправлено, просто используйте read и игнорируйте прочитанное значение., @Delta_G

у вас есть функция serialFlush() в скетче. используй это., @Juraj

@Juraj Это не работает. СМС-сообщения продолжают приходить., @connersz

измените рассматриваемый скетч, чтобы мы могли увидеть, как вы используете serialFlush();, @Juraj


3 ответа


2

Для аппаратного последовательного порта буфер равен 64, и я читал не менее 100 раз. Каждое чтение будет очищать по одному байту данных из последовательного буфера за раз.

Для программного последовательного порта вы выполняете фиктивное чтение, а затем проверяете, пуст ли буфер или не используется

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

Итак, вы должны читать буфер, пока он не станет пустым.

Полезные примечания:

  1. Вы должны знать, когда ожидать фактических данных, а когда нет
  2. иметь способ идентифицировать действительные сообщения (некоторые фиксированные байты заголовка)
  3. иметь способ проверки содержимого (контрольная сумма)

Оставьте комментарий, если у вас есть вопросы

,

Я пытался использовать этот цикл для сброса последовательного порта, он есть даже в коде, который я разместил выше, но он не работает. СМС-сообщения продолжают приходить. Я называю это не в том месте?, @connersz

Ты никогда не называешь это., @Nick Gammon


0
 if (mySerial.available()>0){

Вы проверяете, не поступили ли серийные данные. Тогда вы никогда это не читаете. Поэтому, естественно, он всегда доступен. У вас есть функция serialFlush, которая читает его, однако эта функция никогда не вызывается.

Однако вам нужно прочитать более одного байта. В противном случае вы будете отправлять SMS для каждого байта входящего сообщения.

,

0
if (mySerial.available() > 0) {
  // Serial.write(mySerial.read());
  Serial.write("Message received");

  //Отправить ответ скорости ветра.
  SendMessage();

  mySerial.begin(9600);   // Сброс myserial буфера

  // В этот момент SendMessage() повторяется, и сообщение отправляется снова и снова.
}
,