Товарищи знатоки, помогите пожалуйста разобраться с проблемой. Хочу сделать метеостанцию с уличным датчиком. Передавать данные планирую с помощью NRF. Имеется уна и мега, уна - передатчик, мега - приёмник. К уне подключён датчик BME280. Написал простой код для передатчика и приёмника, сначала экспериментировал без датчика, передавал в массиве 3 рандомных значения - всё отлично работало)) Подключил датчик, дописал код - не работает(( Стал разбираться... Ради интереса попробовал передать в том же массиве только температуру - заработало! Передаю температуру и влажность - работает! Спойлер: Рабочий код Код (C++): #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include "Seeed_BME280.h" #include <Wire.h> BME280 bme280; RF24 radio(9, 10); // CE, CSN const uint64_t pipe = 0xF0F1F2F3F4LL; // индитификатор передачи, "труба" unsigned long gen1P = 0UL; byte i =0; void setup() { Serial.begin(9600); if(!bme280.init()){ Serial.println("Device error!"); } delay(1000); gen1P = millis(); radio.begin(); delay(2); radio.setChannel(9); // канал (0-127) radio.setDataRate(RF24_1MBPS); // устанавливаем скорость передатчика radio.setPALevel(RF24_PA_HIGH); // устанавливаем мощность передатчика radio.openWritingPipe(pipe); // открываем трубу на передачу. } void loop() { float temp = (bme280.getTemperature()); float hum = (bme280.getHumidity()); //float pre = (bme280.getPressure()); float data[2]= {temp,hum}; if (isTimer (gen1P, 1000)) { gen1P = millis(); i= ++i%61; } if(i==60) radio.write(data, sizeof(data)); // раз в минуту отправляем данные } bool isTimer(unsigned long startTime, unsigned long period ) { unsigned long currentTime; currentTime = millis(); if (currentTime >= startTime) return (currentTime >= (startTime + period)); else return (currentTime >= (4294967295 - startTime + period)); } НО стоит только РАСКОММЕНТИРОВАТЬ строку где считывается давление (/float pre = (bme280.getPressure())) ПЕРЕСТАЁТ РАБОТАТЬ ОТПРАВКА ПО NRF. Я даже НЕ ПЫТАЮСЬ ОТПРАВЛЯТЬ ЭТИ ДАННЫЕ С ДАВЛЕНИЕМ. Просто объявляю переменную и считываю данные... А оно отказывается работать. Вопрос сам собой напрашивается, что за Х#?!Я происходит!? Попробовал сменить тип дынных массива и переменных - всё без толку((( Помогите пожалуйста отгадать эту загадку....
Всё отлично, передаётся, проверял неоднократно Проблемы начинаются, когда давление пытаюсь считывать...
А зачем float??? Разделите значения на два - до запятой и после. Всё прекрасно умещается в BYTE. Либо умножьте на сто, а на прёмной стороне поделите. Тогда будет INT. У Вас точно BME, а не BMP? В serial выведете полученные данные после float pre.
Можно и byte сделать... только сути проблемы это не меняет((( Вот так приём/передача есть Спойлер: Скетч Код (C++): byte temp = (bme280.getTemperature()); byte pre = (bme280.getPressure() / 133); //byte hum = bme280.getHumidity(); byte data[3]= {temp,pre}; if (isTimer (gen1P, 1000)) { gen1P = millis(); i= ++i%3; } if(i==2) radio.write(data, sizeof(data)); // раз в минуту отправляем данные if ( radio.isAckPayloadAvailable() ) { // Ждем получения... radio.read(&message,sizeof(message)); //... и имеем переменную message с числом 111 от приемника. } if(message) PORTD ^= (1<<7); Serial.println(data[0]); } Раскоментируем одну строку, считывающую третий параметр... и передача прекращается...((( Спойлер: Скетч Код (C++): byte temp = (bme280.getTemperature()); byte pre = (bme280.getPressure() / 133); byte hum = bme280.getHumidity(); byte data[3]= {temp,pre}; if (isTimer (gen1P, 1000)) { gen1P = millis(); i= ++i%3; } if(i==2) radio.write(data, sizeof(data)); // раз в минуту отправляем данные if ( radio.isAckPayloadAvailable() ) { // Ждем получения... radio.read(&message,sizeof(message)); //... и имеем переменную message с числом 111 от приемника. } if(message) PORTD ^= (1<<7); Serial.println(data[0]); } Но сами дынные с датчика считываются отлично, в мониторе порта всё отображается корректно. У меня лишь одно объяснение происходящему - это конфликт библиотек. Но, что с чем конфликтует не ясно(((
Не, библиотеки не причем. У меня была такая же байда, когда пытался nrf скормить такую структуру: Код (C++): typedef struct payload { u16 temperature; // 2 byte u08 humidity; // 1 byte u16 pressure; // 2 byte u08 solar; // 1 byte u08 wind; // 1 byte u08 direction_w; // 1 byte u08 rain; // 1 byte u08 _error; // 1 byte u08 id; // 1 byte }; передача то ли шла, но не принималась, то ли не шла вовсе. Тогда решил сделать промежуточный буфер и его скормить: Код (C++): Buf[0] = receivePayload.id; Buf[1] = (u08)receivePayload.temperature; Buf[2] = (u08)(receivePayload.temperature >> 8); Buf[3] = (u08)receivePayload.pressure; Buf[4] = (u08)(receivePayload.pressure >> 8); Buf[5] = receivePayload.humidity; Buf[6] = receivePayload.rain; Buf[7] = receivePayload.solar; Buf[8] = receivePayload.wind; Buf[9] = receivePayload.direction_w; Buf[10] = receivePayload._error; Разумеется на приемной стороне точно такой же буфер. Также у меня выключен динамический размер пакета и автоответ. Вот что приходит в ответ в сырце: Код (Bash): Fri Dec 29 23:11:21 2017 0=de, 1=30, 2=0, 3=c0, 4=da, 5=64, 6=38, 7=1, 8=5, 9=f, 10=30 id=222, temperature=3.000000, error=48 Да, и данные с датчика я принимаю и передаю в HEX. Перевод в DEC на стороне клиента. Никаких float в nrf я не засовываю. В нем максимальный размер пакета для разовой передачи - 32 байта.
Может быть и не библиотека виновата, но как объяснить этот феномен Я ДАЖЕ НЕ ПЕРЕДАЮ ТРЕТИЙ ПАРАМЕТР С ДАТЧИКА, Я ТУПО ЗАПИХИВАЮ ЕГО В ПЕРЕМЕРЕННУЮ И БОЛЬШЕ НИЧЕГО С ЭТОЙ ПЕРЕМЕННОЙ НЕ ДЕЛАЮ... НО ВСЁ ЖЕ ПЕРЕДАЧА ПРИ ЭТОМ ПРЕКРАЩАЕТСЯ Спасибо, за подробный ответ)) Попробую ваш способ! Вопрос про буфер... Я как понимаю он по принципу массива работает? Или как-то иначе? Просто не сталкивался с такой записью - Buf[0]= receivePayload.id;
Может быть это как то связано с типом дынных. В библиотеке по этому поводу есть такие строчки.. Код (C++): class BME280 { public: bool init(void); float getTemperature(void); uint32_t getPressure(void); uint32_t getHumidity(void); float calcAltitude(float pressure); Хотя логически причём тут тип данных....
Код (C++): u08 Buf [11]; // byte У меня DS18B20. Работаю без всяких библиотек, соответственно развязаны руки. Планирую перейти на BME - место в структуре зарезервировано; + анемометр. Это будет где-то в январе - тогда и отпишусь.
Нашел у себя bmp180, он тоже 3 параметра считывает. Попробую с ним поработать, посмотрим, что из этого получится....)
BMЕ280 - Температура, влажность, давление, высота над уровнем моря BMP180 - Температура, давление, высота над уровнем моря
Давление и высота над уровнем моря это одно и тоже. Давление - абсолютная величина, а высота - относительная. Находится как разность между абсолютным давлением и давлением на уровне моря.