простая (нет) беспроводная сеть датчиков

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
RX DS18B20 RF433:
#include <GyverOneWire.h>
#include <Gyver433.h>
#include <GyverDS18.h>
#define G433_SPEED 1000
#define RADIO_BUF_SIZE 5
#define RADIO_DATA 8
#define RADIO_VCC 9
GyverDS18Single ds(10);  // пин
Gyver433_TX <RADIO_DATA, G433_XOR> tx;
void setup() {
    pinMode(RADIO_VCC, OUTPUT);         // Пины
    Serial.begin(9600);
    ds.setResolution(9);
    ds.requestTemp();  // первый запрос на измерение
}
void loop() {
    
    if (ds.ready()) {         
        if (ds.readTemp()) {
            Serial.print("temp: ");
            Serial.print(ds.getTemp());
            Serial.println("C*");
        } else {
            Serial.println("error");
        }
        uint16_t result = ds.getTemp();
    uint8_t data[3];              // Формируем и отсылаем пакет
    data[0] = 0xA1;
    data[1] = highByte(result);
    data[2] = lowByte(result);
    digitalWrite(RADIO_VCC, HIGH);
    _delay_ms(1);
    tx.sendData(data);
    tx.sendData(data);
    tx.sendData(data);
    tx.sendData(data);
    tx.sendData(data);
    digitalWrite(RADIO_VCC, LOW);
    delay(30000);
    ds.requestTemp();
    }
}
Ардуино нано. В сериал исправно пишет температуру, пакеты уходят в эфир.

Приёмник не могу даже скомпилировать, ругается Compilation error: no matching function for call to 'GyverDS18::getTemp(int)'

что я делаю не так? Верно ли выставил RADIO_BUF_SIZE 5 и ds.setResolution(9); одинаковыми на передатчике и на приёмнике?

Код приёмника на NodeMCU 1.0 ESP-12
TX RF433 (SYN480r) NodeMCU 1.0 ESP-12 LOL1n:
#define RADIO_DATA 0
#define RADIO_BUF_SIZE 5
#define G433_SPEED 1000

#include <Gyver433.h>
#include <GyverDS18.h>

Gyver433_RX <RADIO_DATA, G433_XOR> rx;
GyverDS18 ds(0);

void setup() {
  Serial.begin(9600);
  ds.setResolution(9);
}

void loop() {
  if (rx.tickWait()) {
      switch (rx.buffer[0]) {
      case 0xA1:           
      
      Serial.print("DS18B20: ");
      Serial.print(ds.getTemp(rx.buffer[1] << 8 | rx.buffer[2]));
      Serial.println(" *C");
      break;
    }
  }
}
Одно устройство должно периодически отправлять текущую температуру, а второе её получать и писать в порт сериал

Заранее благодарен за ответы.
 

viktor1703

★★★★✩✩✩
9 Дек 2021
801
203
что я делаю не так?
Одно устройство должно периодически отправлять текущую температуру, а второе её получать
А зачем же вы тогда в коде приемника температуру читаете не с приёмника, а с датчика?
Далее
не могу даже скомпилировать, ругается Compilation error: no matching function for call to 'GyverDS18::getTemp(int)'
Всё правильно, так и должно быть. Потому что при попытке чтения температуры из датчика (непонятно зачем вы это делаете в коде приемника), вы пытаетесь передать в эту функцию некие значения, а в этой функции такое не предусмотрено.

ds.getTemp(rx.buffer[1] << 8 | rx.buffer[2])
Ещё.
Разве этой функцией вы получаете данные? Эта функция возвращает количество успешно принятых байт. Не изобретайте велосипед, в библиотеке есть примеры, возьмите их за основу.
Верно ли выставил RADIO_BUF_SIZE 5
Этим вы "сказали" компилятору, что дальше по коду вместо RADIO_BUT_SIZE нужно ставить значение, равное 5. Только же вы больше нигде его не упоминаете. Его нужно вставить в строку
Gyver433_RX <RADIO_DATA, G433_XOR> rx;
между RADIO_DATA и G433_XOR
 
Изменено:

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
пример из библиотеки:
/*
   Скетч для базовой станции
*/
#define RADIO_DATA 2
#define RADIO_BUF_SIZE 10
#define G433_SPEED 1000

#include <Gyver433.h>
#include <GyverNTC.h>
#include <microDS18B20.h>

Gyver433_RX <RADIO_DATA, RADIO_BUF_SIZE, G433_XOR> rx;
GyverNTC ntc (0, 10000, 4600, 25, 10000);
MicroDS18B20 <0> ds;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (rx.tickWait()) {      // Ждем пакет по радио
    switch (rx.buffer[0]) { // Получаем адрес модуля
      case 0xA1:            // Кнопка
        Serial.println(rx.buffer[1] ? "Button released" : "Button pressed");
        break;
      case 0xA2:            // Термистор
        Serial.print("NTC: ");
        Serial.print(ntc.computeTemp(rx.buffer[1] << 8 | rx.buffer[2]));
        Serial.println(" *C");
        break;
      case 0xA3:            // Фоторезистор
        Serial.print("Photo value: ");
        Serial.println(rx.buffer[1] << 8 | rx.buffer[2]);
        break;
      case 0xA4:            // PIR детектор
        Serial.println("Pir detected: ");
        break;
      case 0xA5:            // DS18B20
        Serial.print("DS18B20: ");
        Serial.print(ds.calcRaw(rx.buffer[1] << 8 | rx.buffer[2]));
        Serial.println(" *C");
        break;
    }
  }
}
ds.calcRaw заменил на ds.getRaw

компилируется, но не работает. В сериал приёмника пустота. Приемник передатчик рядом, с антеннами. Передатчик я отчётливо слышу в рацию за 600 метров

передатчик:
#include <GyverOneWire.h>
#include <Gyver433.h>
#include <GyverDS18.h>
#define G433_SPEED 2000
#define RADIO_BUF_SIZE 5
#define RADIO_DATA 8
#define RADIO_VCC 9
GyverDS18Single ds(10);  // пин
Gyver433_TX <RADIO_DATA, G433_XOR> tx;

void setup() {
    pinMode(RADIO_VCC, OUTPUT);         // Пины
    Serial.begin(9600);
    ds.setResolution(12);
    ds.requestTemp();  // первый запрос на измерение
}
void loop() {
    
    if (ds.ready()) {         
        if (ds.readTemp()) {
            Serial.print("temp: ");
            Serial.print(ds.getTemp());
            Serial.println("C*");

        } else {
            Serial.println("error");
        }
        uint16_t result = ds.getTemp();
    uint8_t data[3];              // Формируем и отсылаем пакет
    data[0] = 0xA5;
    data[1] = highByte(result);
    data[2] = lowByte(result);
    digitalWrite(RADIO_VCC, HIGH);
    _delay_ms(1);
    tx.sendData(data);
    tx.sendData(data);
    tx.sendData(data);
    tx.sendData(data);
    tx.sendData(data);
    digitalWrite(RADIO_VCC, LOW);
    _delay_ms(1000);
    ds.requestTemp();
    _delay_ms(1000);
    }
}
приёмник:
/*
   Скетч для базовой станции
*/
#define RADIO_DATA 5
#define RADIO_BUF_SIZE 5
#define G433_SPEED 2000

#include <Gyver433.h>
#include <GyverNTC.h>
#include <microDS18B20.h>

Gyver433_RX <RADIO_DATA, RADIO_BUF_SIZE, G433_XOR> rx;
GyverNTC ntc (0, 10000, 4600, 25, 10000);
MicroDS18B20 <0> ds;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (rx.tickWait()) {      // Ждем пакет по радио
    switch (rx.buffer[0]) { // Получаем адрес модуля
      case 0xA1:            // Кнопка
        Serial.println(rx.buffer[1] ? "Button released" : "Button pressed");
        break;
      case 0xA2:            // Термистор
        Serial.print("NTC: ");
        Serial.print(ntc.computeTemp(rx.buffer[1] << 8 | rx.buffer[2]));
        Serial.println(" *C");
        break;
      case 0xA3:            // Фоторезистор
        Serial.print("Photo value: ");
        Serial.println(rx.buffer[1] << 8 | rx.buffer[2]);
        break;
      case 0xA4:            // PIR детектор
        Serial.println("Pir detected: ");
        break;
      case 0xA5:            // DS18B20
        Serial.print("DS18B20: ");
        Serial.print(ds.getRaw(rx.buffer[1] << 8 | rx.buffer[2]));
        Serial.println(" *C");
        break;
    }
  }
}
в serial передатчика:
temp: 25.12C*
temp: 25.12C*
temp: 25.12C*
temp: 25.12C*
temp: 25.12C*
temp: 25.12C*
temp: 25.12C*
temp: 25.12C*
temp: 25.12C*
temp: 25.06C*
temp: 25.12C*
temp: 25.06C*
temp: 25.06C*


в serial приёмника вот что творится:
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

����

�D�9���.Iމ4�DS18B20: 16416 *C

DS18B20: 16416 *C

DS18B20: 16416 *C

DS18B20: 16416 *C

DS18B20: 16416 *C

DS18B20: 16416 *C

DS18B20: 16416 *C

DS18B20: 16416 *C



--------------- CUT HERE FOR EXCEPTION DECODER ---------------



Soft WDT reset



Exception (4):

epc1=0x40100320 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000



очевидно, что приёмник распознаёт по адресу пакет. Выводит данные, но делает ошибки в реестровом сдвиге. В итоге нелепые значения температуры
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,341
1,325
Москва
Я думаю, что ошибки при чтении данных нет. в передатчике используется библиотека датчика температуры, которая переводит 2-х байтовое число в число с точкой , а в приемнике этого действия нет - там тупо выводится целое число,, скорее всего беззнаковое, хотя знак есть
 
  • Лойс +1
Реакции: bwana

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
заметил, что опрос ds18b20 у передатчика был библиотекой GyverDS18.h, а приёмник microDS18B20.h

переделал всё на microDS18B20.h

данные передатчика 25.62
данные приёмника 19356
 

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
Что делает эта строка кода? Как работает getRaw по вашему мнению?
ds.getRaw(rx.buffer[1] << 8 | rx.buffer[2])
в оригинальной версии скетча было ds.calcRaw, с изменением библиотеки компилятор идёт в отказ. Нагуглил решение заменить на getRaw, полагая что строка кода заставит вычислить данные
 

Bruzzer

★★★★✩✩✩
23 Май 2020
776
237
Повторю вопрос
> Как работает getRaw по вашему мнению?
Если вы собираете программу методом тыка, то на перебор всех возможных "тыков" уйдет не счетное количество времени.
 

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
Повторю вопрос

Если вы собираете программу методом тыка, то на перебор всех возможных "тыков" уйдет не счетное количество времени.
так и есть. В библиотеке microDS18B20.h есть пример "raw and calc". Копаю там. Назначается переменная uint16_t (беззнаковое целое число 2 байта), ей присваивается значение из (rx.buffer[1] << 8 | rx.buffer[2]).
Функция DS_rawToFloat преобразует его во float, должно быть как на отправке. По факту нули.
А если сразу Serial.print(DS_rawToFloat(rx.buffer[1] << 8 | rx.buffer[2]));
то снова нелепые значения 1,56

как оказалось библиотека microDS18B20.h ещё и устарела, а в рекомендованной GyverDS18 не вижу обработки "сырых" данных
 

Bruzzer

★★★★✩✩✩
23 Май 2020
776
237
На стороне передатчика вы получили температуру uint16_t result = ds.getTemp();
И отправляете ее в приемник.
Зачем на стороне приемника нужна библиотека DS18B20 вообще не понятно. Зачем на стороне приемника выполнять какие то преобразования? Если вы отправили число 45 то и получить должны 45. Если есть сомнения, то отошлите с передатчика uint16_t result = 45;
 
  • Лойс +1
Реакции: bwana

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
@Bruzzer, я так понимаю, в этой библиотеке Giver433 есть функционал фильтрации пакетов для корректности шифрованием XOR. Я не могу получить то, что отправил
 

viktor1703

★★★★✩✩✩
9 Дек 2021
801
203
Зачем на стороне приемника нужна библиотека DS18B20 вообще не понятно
Я ему про это уже давно писал
при попытке чтения температуры из датчика (непонятно зачем вы это делаете в коде приемника)
Но товарищ @bwana не желает слушать советов и идет своим сложным, тернистым путем проб и ошибок.

Уточните, вы всё еще мучаете код из сообщения №4. Или уже новый какой намутили? Просто в том коде вы и не принимаете ничего. Точнее принимаете, но не используете их, а отправляете в функцию получения температуры от неподключенного(?) к приемнику датчика. Функция возвращает 0, и на выходе у вас получается, то что
не могу получить то, что отправил
 
Изменено:

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
В общем не сложилось у меня с гайверовскими либами, меньше всего хочется чтобы актуальная на сегодня версия вдруг стала не актуальной.
Написал с радиохедом, вроде работает и на довольно большом расстоянии. Расход передатчика не мерил, думаю если выпаять светодиоды и подавать не в type-C, а на пин 5v то будет батарейку расходовать куда меньше. Задействовал бортовой led для отладки. Заказал Attiny попробую на них сделать экономичный передатчик.

передатчик:
#include <RH_ASK.h>
#include <SPI.h>
#include <LowPower.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define TX_DATA_PIN 12
#define TX_POWER_PIN 10
#define SENSOR_PIN 2
RH_ASK driver(2000, 11, TX_DATA_PIN);
OneWire oneWire(SENSOR_PIN);
DallasTemperature sensors(&oneWire);
struct DataPacket {
    float temp;
    uint32_t counter;
};
DataPacket msg;
void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(TX_POWER_PIN, OUTPUT);
    digitalWrite(TX_POWER_PIN, LOW);
    sensors.begin();
    driver.init();
    Serial.begin(9600);
}
void loop() {
    digitalWrite(TX_POWER_PIN, HIGH);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(10);
    sensors.requestTemperatures();
    //float tempC = sensors.getTempCByIndex(0);
    //Serial.println(tempC);
    msg.temp = sensors.getTempCByIndex(0);
    
    for (int i = 0; i < 3; i++) {
    driver.send((uint8_t *)&msg, sizeof(msg));
    driver.waitPacketSent();
    delay(30);}
    digitalWrite(TX_POWER_PIN, LOW);
    digitalWrite(LED_BUILTIN, LOW);
    for (int i = 0; i < 7; i++) { 
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    }
}
приёмник:
#include <RH_ASK.h>
#include <SPI.h>

#define RX_PIN 11

RH_ASK driver(2000, RX_PIN, 12);

struct DataPacket {
    float temp;
    uint32_t counter;
};

DataPacket msg;

void setup() {
    Serial.begin(9600);
    pinMode(LED_BUILTIN, OUTPUT);
    if (!driver.init()) {
        Serial.println("не ОК!");
    } else {
        Serial.println("ОК");
    }
}

void loop() {
    uint8_t buf[sizeof(msg)];
    uint8_t buflen = sizeof(msg);
    if (driver.recv(buf, &buflen)) {
        memcpy(&msg, buf, sizeof(msg));
        Serial.print("Температура: ");
        Serial.print(msg.temp);
        Serial.println(" °C");   
    }
    if (msg.temp >= 25.00){
    digitalWrite(LED_BUILTIN, HIGH);
    }else {digitalWrite(LED_BUILTIN, LOW);}
}
 

viktor1703

★★★★✩✩✩
9 Дек 2021
801
203
То есть, вы сделали то, что вам давно предлагали, взять код из примера и попробовать как от будет работать, а именно читать данные из буфера и выводить их в serial, а не тыкать их в функцию чтения температуры с датчика. Только для этого вы пошли другим путем и прикрутили другую библиотеку. Ну чтож , ваше право.
 

bwana

✩✩✩✩✩✩✩
3 Окт 2024
22
0
@viktor1703, я вообще месяц как поверхностно знаком с C++ и не имел никакого опыта в программировании со времён basic на ZX Spectrum, который с аудиокассеты загружался в 1994 году. Мне в силу IQ не составит труда изучить этот язык, как я изучил множество других направлений и сфер деятельности, где имею экспертные компетенции. Не только ментальные, но и физические. Но я никогда не поднимал себе оценку за счёт тех, кто меньше меня шарит, ибо с самооценкой всё норм. Всегда помогу и подскажу. А таких как Вы (местоимение вежливого обращения к одному лицу пишется с большой буквы) мне жаль.