Код приемника RF 433 МГц работает только после сброса Arduino.

Я работаю над радиочастотными модулями с помощью Arduino, но заметил, что оператор if запускается только один раз, и мне нужно каждый раз сбрасывать приемник, чтобы он работал с изменениями в передатчике в реальном времени. .

Я подключил ЖК-дисплей 16X2 для отображения данных. Если я запускаю передатчик и начинаю отправлять данные как «1», он показывает «Пока». но когда я меняю данные передатчика на "0", то также показывает "Пока" только.

Я немного изменил код, но я чувствовал, что это проблема с предыдущими данными, хранящимися в переменной buf.

Я ожидаю, что на ЖК-дисплее должно отображаться "Привет" когда я изменил передаваемые данные на "0" от "1" чего не бывает только "Пока" отображается каждый раз.

Вот код приемника Arduino:

#include <RH_ASK.h>
#include <SPI.h> 
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
RH_ASK rf_driver;
char message[2];

void setup()
{
    rf_driver.init();
    Serial.begin(9600);
    lcd.begin(16,2);
}

void loop()
{
    uint8_t buf[2];
    uint8_t buflen = sizeof(buf);
    
    buf[1] = '\0';
 
    if (!rf_driver.recv(buf, &buflen))
    {
        if (strcmp((char*)buf, "0") == 0) {
            Serial.println("Hi");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Hi");
            }

            lcd.display();
        }
        else if (strcmp((char*)buf, "1") == 0) { 
            Serial.println("Bye");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Bye");
                lcd.display();
            }
        }
    }
    message[0] = (char*)buf[0];
}

Вот код передатчика:

#include <RH_ASK.h>
#include <SPI.h> 
RH_ASK rf_driver;
 
void setup()
{
    rf_driver.init();
    Serial.begin(9600);
}
 
void loop()
{
    const char *msg = "1";
    rf_driver.send((uint8_t *)msg, strlen(msg));
    rf_driver.waitPacketSent();
    delay(1000);
}

Вывод последовательного монитора выглядит следующим образом:

, 👍0

Обсуждение

Выводит ли последовательный монитор «Привет», если вы измените передаваемое значение на «0»? (Возможно, вы захотите немного расширить код вашего передатчика для облегчения отладки.) -- Почему вы каждый раз инициализируете ЖК-дисплей, так ли это необходимо? -- Пожалуйста, делайте правильный отступ в источнике, его трудно читать. Я редактировал его один раз, но вы его перезаписали, поэтому я повторяю редактирование., @the busybee

Нет, он не выводит «Привет», когда я изменяю передаваемое значение на «1». Постоянно показывает только "до свидания"., @Vishnu Vardhan

Хм? С «1» вы хотите вывести «Пока». Почему вы ожидаете "привет"?, @the busybee

извините, он не выводит «Привет», когда я меняю передаваемое значение на «0». Постоянно показывает только "до свидания". Только я нажимаю кнопку сброса на Arduino, она работает, @Vishnu Vardhan

Что отображается в последовательном мониторе, если вы выводите полученное сообщение?, @the busybee

char message[2]; ... if (strcmp(message[0], Вы должны получить предупреждение об этом. Если нет, повысьте уровень предупреждения в настройках., @timemage

Он просто постоянно показывает «до свидания» независимо от изменений в передаваемом сообщении., @Vishnu Vardhan

вернитесь к началу... сократите свой код... забудьте о декодировании полученных данных... распечатайте полученные данные и длину полученных данных... вы получаете то, что ожидаете получить?, @jsotola


1 ответ


1

Я указал на это в комментарии, думая, что вопрос, вероятно, будет закрыт, если это будет воспринято как опечатка, но я думаю, что это не опечатка.

char message[2]; ... if (strcmp(message[0], Вы должны получать предупреждение за это. Если нет, повысьте уровень предупреждения в предпочтения.

Если вы увеличите уровень предупреждения, вы должны увидеть что-то, что хотя бы намекает на то, что я говорю ниже.

Сокращение кода до части, соответствующей описанию проблемы:

char message[2];
// ...
uint8_t buf[2];
// ...
if (strcmp(message[0], (char*)buf[0]) != 0) {

strcmp() ожидает указатель на символ как для первого, так и для второго аргументов. Однако message[0] имеет тип char, а buf[2] имеет тип uint8_t (в конечном итоге беззнаковый символ). Используемые отдельные символы интерпретируются как значения указателя (как в адресах памяти), которые strcmp() предполагают ссылаться на первые символы строк. Другими словами, он обращается к некоторой паре адресов памяти от 0 до 255 и пытается интерпретировать все, что он находит в этих местах, как строки и сравнивать их. Сочетание того, что вы делаете, не определено и не имеете сильных ожиданий того, что можно найти по этим адресам памяти, неудивительно (во всяком случае, для меня), как оцениваются ваши сравнения.

Минимальное изменение, которое должно сделать strcmp более понятным:

if (strcmp(message, (char*)buf) != 0) {

message и buf в конечном итоге будут оцениваться по фактическому расположению их строк. Вы уже сделали половину этой строки правильно при другом использовании buf в if (strcmp((char*)buf, "0") == 0); обратите внимание, что здесь не используется [0].


В приведенном выше я обращаюсь к этому напрямую и считаю само собой разумеющимся, что у вас есть какая-то причина хотеть использовать строку, содержащую один (не нулевой) символ, что вы намеревались каким-то образом расширить этот код для более длинных сообщений. . В противном случае имеет смысл вообще отказаться от строк и заставить rh_driver.recv считываться непосредственно в один символьный тип, а затем использовать сравнение на равенство ==, а не стркмп().

Секции кода будут выглядеть примерно так:

char message; // теперь отдельный символ
// ...
uint8_t buf;  // теперь отдельный символ
// ...
if (!rf_driver.recv(&buf, sizeof buf)) { // размер buf равен 1
    if (buf == '0') { // теперь простое применение ==
        Serial.println("Hi");
        if (message != buf) {  // теперь простое применение !=
            lcd.print("Hi");
        }
// ...
message = buf; // больше не используется [0], потому что это больше не массив
,