Как получить значения датчиков с помощью передатчика и приемника

Я использовал датчик HC-SR04 и подключил его к плате arduino (BOARD1) с передатчиком 433 МГц, а другая плата (BOARD2) подключена к приемнику 433 МГц, но я не знаю, как увидеть показания значения датчика от (BOARD1) и увидеть их на последовательном мониторе.

ВОТ КОД ПЕРЕДАТЧИКА

#include <RH_ASK.h>
#include <SPI.h> // На самом деле не используется, но необходим для компиляции


RH_ASK driver;
int echo=11;
int trig=9; int sensorval;
void setup()
{

    Serial.begin(9600);   // Только отладка

   driver.init();

}

void loop()
{
    digitalWrite(trig,LOW);
   delayMicroseconds(10);
   digitalWrite(trig,HIGH);
   delayMicroseconds(10);
   digitalWrite(trig,LOW);
   delayMicroseconds(10);
   sensorval=pulseIn(echo,HIGH);
     const char *msg = sensorval;

    driver.send((uint8_t *)msg, strlen(msg));
    driver.waitPacketSent();
    delay(200);
}

ВОТ КОД ПРИЕМНИКА

#include <RH_ASK.h>

#include <SPI.h> // На самом деле не используется, но необходим для компиляции


RH_ASK driver;
const int sensorval;
void setup()
{
    Serial.begin(9600);   // Debugging only
    driver.init();

}

void loop()
{
    uint8_t buf[4];
    uint8_t buflen = sizeof(buf);

    if (driver.recv(buf, &buflen)) // Non-blocking
    {
    Serial.print("message Received: ");
 Serial.println((char*)buf);
    }
}

, 👍2


1 ответ


2

Во-первых: краткий рассказ о c-строках

В C строка представляет собой массив символов. Такой массив определяется с помощью

char msg[10];

10 - это размер массива. Каждая допустимая строка c должна заканчиваться нулевым символом \0. Этот символ не печатается, поэтому вы обычно его не видите. Но стандартные строковые функции (такие как printf(), strlen ()и т. Д.) используют нулевой символ для поиска конца строки. Поэтому при обработке строк в виде массивов char вам абсолютно всегда нужно заканчивать строку нулевым символом. Стандартные функции увеличиваются по массиву, пока не найдут нулевой символ. Если он отсутствует, они не останавливаются в конце массива.

Необходимость в нулевом символе также означает, что приведенный выше массив символов может содержать только 9 символов (так как 10 - й является нулевым символом).

Стандартные функции для создания строки (например, printf() и ее братья и сестры) уже правильно завершают строку символом null.


Очевидно, вы пытаетесь отправить строку в кодировке ASCII. Но sensorval-это не строка, а тип int (число). В C/C++ не просто неявно преобразуется число в строку (пожалуйста, вставьте образ боромира из "Властелина колец" здесь в голове). На самом деле вы должны сказать компилятору, как преобразовать число в строку. Также sensorval не может сам удерживать эту строку (так как это целое число). Для этого вам нужен массив символов (часто называемый c-string) для сохранения всех символов вашей строки.

Итак, сначала нам нужно определить массив char для хранения нашей строки:

char msg[10];

Это создает массив char с 10 элементами, каждый из которых может содержать символ вашей строки. Таким образом, у вас есть место для 9 символов. Если вам нужно больше, вы можете увеличить это число.

Теперь нам нужно построить строку в msg, которая представляет собой значение sensorval. Для этого мы можем использовать функцию sprintf(), которая позволяет нам отформатировать строку из данных и сохранить ее в массиве char.

sprintf(msg, "%d", sensorval);

Первый параметр-это массив символов, в который помещается строка. Второй параметр называется format-string. Это строковый литерал, который определяет формат. %d представляет целочисленное значение; это заполнитель для фактических данных и описывает, как он должен быть отформатирован (вы можете прочитать о различных вариантах форматирования в документации C++, если вы ищете printf()). Следующие параметры (здесь только один) являются значениями данных для заполнителей в строке формата. Давайте возьмем пример: предположим, что sensorval равен 1000. Тогда msg будет следующим:

1000\0

\0-это нулевой символ.

Таким образом, в вашем коде вы бы заменили

const char *msg = sensorval;

с

char msg[10];
sprintf(msg, "%d", sensorval);

Что вы сделали в своем коде:

Эта линия

const char *msg = sensorval;

не будет создавать строку. Вы определяете msg как указатель на постоянный символ (указатель-это переменная, которая содержит адрес другой переменной в памяти, используйте термины Google, такие как "указатели C", для получения дополнительной информации). А затем вы устанавливаете указатель на sensorval, который, конечно же, не является действительным указателем (действительное значение указывает здесь на что-то разумное). Он просто указывает куда - то в память.

Пример, из которого вы его получили, использует:

const char *msg = "hello";

Это работает, потому что компилятор берет все строковые литералы (строки, заключенные в двойные кавычки) и помещает их фиксированными в память, что-то вроде переменной без имени. Итак, здесь компилятор инструктирует микроконтроллер сохранить строку "hello" в памяти. С помощью приведенной выше строки мы определяем указатель на то место в памяти, где эта строка сохраняется.

Так что это хорошо работает для строковых литералов, но нет, если вам сначала нужно фактически построить строку.

,

мне жаль, что я новичок в этом, поэтому я не совсем понимаю, что делать. Из того, что я прочитал в вашем ответе, следует ли мне заменить `const char *msg=sensorval; на char msg[10]; sprintf(msg, "%d", sensorval);` или перед настройкой void я поставлю строковый сенсор"?, @Thomas Raymond Santos

@ThomasRaymondSantos Я переработал свой ответ, чтобы более подробно объяснить, что здесь происходит и что делать., @chrisl

хорошо, я постараюсь понять, большое вам спасибо за помощь!, @Thomas Raymond Santos

В противном случае было бы неплохо сделать несколько учебных пособий по c-строкам. Я уверен, что в Интернете их много, @chrisl

спасибо, @chrisl, ценю это!, @Thomas Raymond Santos