NRF24l01 и датчик BME280

Тема в разделе "Arduino & Shields", создана пользователем Eragon, 28 дек 2017.

  1. Eragon

    Eragon Нерд

    Товарищи знатоки, помогите пожалуйста разобраться с проблемой. Хочу сделать метеостанцию с уличным датчиком. Передавать данные планирую с помощью 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. Я даже НЕ ПЫТАЮСЬ ОТПРАВЛЯТЬ ЭТИ ДАННЫЕ С ДАВЛЕНИЕМ. Просто объявляю переменную и считываю данные... А оно отказывается работать. Вопрос сам собой напрашивается, что за Х#?!Я происходит!? Попробовал сменить тип дынных массива и переменных - всё без толку(((
    Помогите пожалуйста отгадать эту загадку....:)
     
  2. ImrDuke

    ImrDuke Гик

    Я бы добавил вывод в порт, что бы посмотреть что там идет.
     
    lol нравится это.
  3. Eragon

    Eragon Нерд

    Всё отлично, передаётся, проверял неоднократно:) Проблемы начинаются, когда давление пытаюсь считывать...
     
  4. parovoZZ

    parovoZZ Гуру

    А зачем float??? Разделите значения на два - до запятой и после. Всё прекрасно умещается в BYTE. Либо умножьте на сто, а на прёмной стороне поделите. Тогда будет INT.
    У Вас точно BME, а не BMP? В serial выведете полученные данные после float pre.
     
  5. Eragon

    Eragon Нерд

    Можно и 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]);
    }
    Но сами дынные с датчика считываются отлично, в мониторе порта всё отображается корректно. У меня лишь одно объяснение происходящему - это конфликт библиотек. Но, что с чем конфликтует не ясно(((
     
  6. parovoZZ

    parovoZZ Гуру

    Не, библиотеки не причем. У меня была такая же байда, когда пытался 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 байта.
     
    Последнее редактирование: 30 дек 2017
  7. Eragon

    Eragon Нерд

    Может быть и не библиотека виновата, но как объяснить этот феномен Я ДАЖЕ НЕ ПЕРЕДАЮ ТРЕТИЙ ПАРАМЕТР С ДАТЧИКА, Я ТУПО ЗАПИХИВАЮ ЕГО В ПЕРЕМЕРЕННУЮ И БОЛЬШЕ НИЧЕГО С ЭТОЙ ПЕРЕМЕННОЙ НЕ ДЕЛАЮ... НО ВСЁ ЖЕ ПЕРЕДАЧА ПРИ ЭТОМ ПРЕКРАЩАЕТСЯ
    Спасибо, за подробный ответ)) Попробую ваш способ!
    Вопрос про буфер... Я как понимаю он по принципу массива работает? Или как-то иначе? Просто не сталкивался с такой записью - Buf[0]= receivePayload.id;
     
  8. Eragon

    Eragon Нерд

    Может быть это как то связано с типом дынных. В библиотеке по этому поводу есть такие строчки..
    Код (C++):
    class BME280
    {
    public:
      bool init(void);
      float getTemperature(void);
      uint32_t getPressure(void);
      uint32_t getHumidity(void);
      float calcAltitude(float pressure);
    Хотя логически причём тут тип данных....:confused:
     
  9. parovoZZ

    parovoZZ Гуру

    Код (C++):
    u08 Buf [11]; // byte
    У меня DS18B20. Работаю без всяких библиотек, соответственно развязаны руки. Планирую перейти на BME - место в структуре зарезервировано; + анемометр. Это будет где-то в январе - тогда и отпишусь.
     
  10. Eragon

    Eragon Нерд

    Нашел у себя bmp180, он тоже 3 параметра считывает. Попробую с ним поработать, посмотрим, что из этого получится....)
     
  11. parovoZZ

    parovoZZ Гуру

    А чем он тогда отличается от BME?
     
  12. Eragon

    Eragon Нерд

    BMЕ280 - Температура, влажность, давление, высота над уровнем моря
    BMP180 - Температура, давление, высота над уровнем моря
     
  13. parovoZZ

    parovoZZ Гуру

    Давление и высота над уровнем моря это одно и тоже. Давление - абсолютная величина, а высота - относительная. Находится как разность между абсолютным давлением и давлением на уровне моря.
     
  14. ImrDuke

    ImrDuke Гик

    Удалось что то получить?
     
  15. ImrDuke

    ImrDuke Гик

    Столкнулся с такой же проблемой.
    Стоит добавить "bme.begin(&Wire);" и все - нет передачи.