Как очистить значения 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();
}
}
@connersz, 👍0
Обсуждение3 ответа
Для аппаратного последовательного порта буфер равен 64, и я читал не менее 100 раз. Каждое чтение будет очищать по одному байту данных из последовательного буфера за раз.
Для программного последовательного порта вы выполняете фиктивное чтение, а затем проверяете, пуст ли буфер или не используется
while(mySerial.available()>0) {
dummy = mySerial.read();
}
Итак, вы должны читать буфер, пока он не станет пустым.
Полезные примечания:
- Вы должны знать, когда ожидать фактических данных, а когда нет
- иметь способ идентифицировать действительные сообщения (некоторые фиксированные байты заголовка)
- иметь способ проверки содержимого (контрольная сумма)
Оставьте комментарий, если у вас есть вопросы
Я пытался использовать этот цикл для сброса последовательного порта, он есть даже в коде, который я разместил выше, но он не работает. СМС-сообщения продолжают приходить. Я называю это не в том месте?, @connersz
Ты никогда не называешь это., @Nick Gammon
if (mySerial.available()>0){
Вы проверяете, не поступили ли серийные данные. Тогда вы никогда это не читаете. Поэтому, естественно, он всегда доступен. У вас есть функция serialFlush, которая читает его, однако эта функция никогда не вызывается.
Однако вам нужно прочитать более одного байта. В противном случае вы будете отправлять SMS для каждого байта входящего сообщения.
if (mySerial.available() > 0) {
// Serial.write(mySerial.read());
Serial.write("Message received");
//Отправить ответ скорости ветра.
SendMessage();
mySerial.begin(9600); // Сброс myserial буфера
// В этот момент SendMessage() повторяется, и сообщение отправляется снова и снова.
}
- AT-команда не отвечает на последовательный монитор
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- SIM800L не регистрируется в сети
- Ардуино для чтения с преобразователя RS232 в последовательный модуль TTL
- Как читать и записывать на устройство rs232 с/на Arduino
- Программное обеспечениеSerial с ESP8266
- Проблема с Software Serial: нет ответа
Вам нужно прочитать материал из SoftwareSerial. Используйте mySerial.read() до тех пор, пока available не станет ложным. Если вам все равно, что было отправлено, просто используйте read и игнорируйте прочитанное значение., @Delta_G
у вас есть функция
serialFlush()
в скетче. используй это., @Juraj@Juraj Это не работает. СМС-сообщения продолжают приходить., @connersz
измените рассматриваемый скетч, чтобы мы могли увидеть, как вы используете
serialFlush();
, @Juraj