Как очистить значения 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
- Проблема с Software Serial: нет ответа
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
Вам нужно прочитать материал из SoftwareSerial. Используйте mySerial.read() до тех пор, пока available не станет ложным. Если вам все равно, что было отправлено, просто используйте read и игнорируйте прочитанное значение., @Delta_G
у вас есть функция
serialFlush()
в скетче. используй это., @Juraj@Juraj Это не работает. СМС-сообщения продолжают приходить., @connersz
измените рассматриваемый скетч, чтобы мы могли увидеть, как вы используете
serialFlush();
, @Juraj