РЕШЕНО Nrf24l01+ и esp8266 и туда же arduino nano

Тема в разделе "Проводная и беспроводная связь", создана пользователем Evgeniy2017, 12 июл 2020.

  1. Evgeniy2017

    Evgeniy2017 Нерд

    Всем доброго времени суток!
    Столкнулся с проблемой того что модуль имеет всего 6 каналов для связи. Погуглил и нашел несколько схем решения. RF network не рассматриваю так как велик шанс отказа системы в любом узле. Другие схемы тож отмёл осталась идеальная для моей цели. Финт заключается в том что база знает адреса всех "датчиков" и периодически с ними связывается, назовём это штатной работой и также параллельно штатной работе мы держим еще две трубы для чего-то важного например тревог или регистрации нового датчика для системы. Пока что только начал реализовывать и сразу проблема [​IMG] вообщем:
    Код передатчика ("датчика"):
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    #define key 201
    byte id_sensor = 0;
    byte type_sensor = 1;
    RF24 radio(9, 10);
    byte sent = key;
    struct message {
      byte id;
      byte type;
      byte data;
    };
    message send_data;
    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"};
    void setup() {
    // Serial.begin(9600);
      radio.begin();
      radio.setDataRate(RF24_250KBPS);
      radio.setPALevel(RF24_PA_MAX);
      radio.setPayloadSize(32);
      radio.openReadingPipe(1, address[0]);
      radio.openReadingPipe(2, address[1]);
      radio.setChannel(0x60);
      radio.powerUp();
      radio.startListening();
      delay(100);
      if (id_sensor == 0) {
        //Serial.println("Sensor null!!!");
        radio.stopListening();
        delay(10);
        //Start send te reg message
        radio.openWritingPipe(address[1]);
        delay(10);
        boolean send_status = false;
        int i = 0;
        //Serial.println("Start sending reg packet!");
        while (!send_status && i < 600) {
          send_status = radio.write(&sent, sizeof(sent));
          delay(100);
          i++;
          //Serial.println(".");
        }
        //Serial.println("Sended!");
        radio.startListening();
        delay(10);
        //Serial.println("Starting reciving");
        while (!radio.available()) {
          delay(50);
        }
        //Data recived!
        //Serial.println("DATA OK");
        radio.read(&sent, sizeof(sent));
        delay(10);
        id_sensor = sent;
        radio.closeReadingPipe(2);
        delay(10);
        radio.stopListening();
        delay(10);
        radio.openWritingPipe(address[0]);
        delay(10);
        radio.startListening();
        delay(10);
        //Serial.println("All start ok!");
      }
    }
    void loop() {
      if ( radio.available() ) {
        byte keyy = 0;
        radio.read(&keyy, sizeof(keyy));
        if (keyy == key) {
          //Serial.println("KEY OK");
          radio.stopListening();
          send_data.id = id_sensor;
          send_data.type = type_sensor;
          send_data.data = random(5, 31);
          radio.write(&send_data, sizeof(send_data));
          delay(10);
          radio.startListening();
        }
      }
    }
    Код приемника (базы):
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    #define key 201
    struct message {
      byte id;
      byte type;
      byte data;
    };
    byte pipe = 0;
    message rx_data;
    RF24 radio(D4, D8);
    byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"};
    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.setDataRate(RF24_250KBPS);
      radio.setPALevel(RF24_PA_MAX);
      radio.setPayloadSize(32);
      radio.openReadingPipe(1, address[0]);
      radio.openReadingPipe(2, address[1]);
      radio.setChannel(0x60);
      //radio.setRetries(5,10);
      radio.powerUp();
      radio.startListening();
    }
    boolean send_request(byte addr) {
      radio.stopListening();
      delay(10);
      radio.openWritingPipe(address[addr]);
      delay(10);
      byte data = key;
      byte i = 0;
      boolean status_ = false;
      while (!status_ && i < 5) {
        status_ = radio.write(&data, sizeof(data));
        i++;
        delay(1);
      }
      if (status_) {
        Serial.print("Request ok, retries: ");
        Serial.println(i);
        return true;
      }
      else {
        Serial.println("Request error");
        return false;
      }
    }
    void loop() {
      if (Serial.available() > 0) {
        String bufer = Serial.readString();
        if (bufer == "tx") {
          byte sensor = 0;
          Serial.println("Sending....");
          send_request(sensor);
          radio.startListening();
        }
      }
      if ( radio.available(&pipe) ) {
        if (pipe == 2) {
          byte reg = 0;
          radio.read(&reg, sizeof(reg));
          Serial.println("New module start register!");
          radio.stopListening();
          delay(10);
          radio.openWritingPipe(address[1]);//New pipe for send packet register to arduino
          delay(10);
          if (reg == key) {
            Serial.println("Yeah he wont register!");
            byte sent_id = 201;
            boolean send_status = false;
            int i = 0;
            while (!send_status && i < 100) {
              send_status = radio.write(&sent_id, sizeof(sent_id));
              delay(50);
              i++;
            }
            if (send_status) {
              Serial.println("REG OK");
            }
            else {
              Serial.println("REG ERR");
            }
            delay(50);
          }
          radio.startListening();
        }
        else {
          radio.read(&rx_data, sizeof(rx_data));
          delay(10);
          Serial.print("Resived data from:");
          Serial.print(rx_data.id);
          Serial.print("with message:");
          Serial.print(rx_data.data);
          Serial.println("");
        }
      }
    }

    Это одна из версий да написано коряво были более красивые) но не рабочие так что пока так потом сделаю по красивее =)
    Ну а теперь проблема )
    Проблема:
    В сериал порте базы наблюдаем такую картину:
    19:17:03.579 -> Sending....
    19:17:03.850 -> Request error
    19:17:24.041 -> Sending....
    19:17:24.312 -> Request error
    19:17:40.655 -> New module start register!
    19:17:40.655 -> Yeah he wont register!
    19:17:40.788 -> REG OK
    19:18:51.323 -> Sending....
    19:18:51.358 -> Request ok, retries: 1
    19:18:51.358 -> Resived data from:201with message:16
    19:19:10.308 -> Sending....
    19:19:10.341 -> Request ok, retries: 1
    19:19:10.341 -> Resived data from:201with message:22
    19:19:16.805 -> Sending....
    19:19:16.852 -> Request ok, retries: 1
    19:19:16.852 -> Resived data from:201with message:10
    Где-то здесь я выключил датчик и самое интересно что база не написала что датчик зарегался в системе (тип как-будто новый датчик) а после одного пакета
    начинает работать так как нужно) хотя по идеи база даже не знает что он уже "в сети"
    19:20:37.765 -> Sending....
    19:20:37.798 -> Request ok, retries: 1
    19:20:46.813 -> Sending....
    19:20:46.847 -> Request ok, retries: 1
    19:20:46.847 -> Resived data from:201with message:16
    19:21:00.771 -> Sending....
    19:21:00.818 -> Request ok, retries: 1
    19:21:00.818 -> Resived data from:201with message:22
    21:12:00.233 -> Sending....
    21:12:00.267 -> Request ok, retries: 1
    21:12:04.989 -> Sending....
    21:12:05.022 -> Request ok, retries: 1
    21:12:05.022 -> Resived data from:201with message:16
    Я уверен что ошибка в коде но просто я раза три его переписывал, а реакция точно такая же, а бывает наоборот что прекрасно работает раза три точно (подряд) регался все было видно на базе и работало все дальше безупречно ( то есть не было этого пустого ответа )
     
  2. b707

    b707 Гуру

    не понял в чем проблема
     
  3. Evgeniy2017

    Evgeniy2017 Нерд

    Извиняюсь, не точно выразился. Вообщем если отключить датчик и заново включить, с какой-то вероятностью в ком порте базы не будет не малейшего намека на то что она нашла новое устройство, но грубо говоря если слать пакеты в слепую то датчик отвечает тоесть он дошел до void loop но как)))) если база вроде как не получала от него пакета регистрации
     
  4. parovoZZ

    parovoZZ Гуру

    Откуда 6? Канал связи всего один. Pipe - 6. Но одновременно по ним вещать нельзя. Принимать тоже. Частота одна на всех.

    я тоже
     
  5. parovoZZ

    parovoZZ Гуру

    А это чё такое
    :eek::eek::eek::eek::eek:
     
  6. b707

    b707 Гуру

    это адреса,
    какая разница. напишешь ли ты 0х3AABB или "5NODE" - суть то одна
     
  7. parovoZZ

    parovoZZ Гуру

    Вот только у nRF24 адрес это ещё и преамбула, начало которой должно быть 010101 или 00110011 для лучшего захвата ФАПЧ приёмника несущей частоты. А здесь что?
     
  8. Evgeniy2017

    Evgeniy2017 Нерд

    Переделаю)
    Да я про pipe`s ) этой мой сленг) 6 труб для связи



    Вообщем всю ночь думал) таки ошибку одну нашел, на передатчике мы не проверяем что данные пришли во вторую трубу и берем любой байт соответственно когда мы слали запрос на получение инфы то отсылали байт, и передатчик его брал за ответ и дальше продолжал работу. Теперь вопрос остался почему тогда база не отвечает на его пакеты......
     
  9. b707

    b707 Гуру

    не знаю. Но в куче примеров так и у всех работает :)
     
  10. Evgeniy2017

    Evgeniy2017 Нерд

    Я так видел у Алекса Гайвера ( ютубер), и по-моему даже в документации на RF24



    Вроде бы все перечитал, не знаю где может таится ошибка, тоесть раза 7 из 10 "датчик" проходит регистрацию и дальше все работает правильно. Но бывает что почему-то не проходит регистрацию. Видимо кто-то кого-то игнорит, но кто? почему? Я не знаю :(
     
  11. Evgeniy2017

    Evgeniy2017 Нерд

    Подскажите как хранить массив труб, если правильно понял то как-то так
    Код (C++):
    uint64_t pipes[] = {0xAABBCCDD01LL,0xAABBCCDD0BLL};
    Проблема решена! На 100% не понял причину но грешу на питание. Подробнее описано https://community.alexgyver.ru/threads/nrf24l01-i-esp8266-i-tuda-zhe-arduino-nano.3475/
    Кому пригодится код:
    Код приемника:
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    #define key 201
    byte id_sensor = 0;
    byte type_sensor = 1;
    RF24 radio(9, 10);
    struct message {
      byte id;
      byte type;
      byte data;
    };
    message send_data;
    byte pipe = 0;
    boolean register_sensor() {
      radio.stopListening();
      delay(10);
      radio.openWritingPipe(0xAABBCCDD22LL);
      delay(10);
      byte data = 255;
      boolean status_ = false;
      byte i = 0;
      while (!status_ && i < 100) {
        status_ = radio.write(&data, sizeof(data));
        delay(100);
        i++;
      }
      if (status_) {
        Serial.println("Send OK");
      }
      else {
        Serial.println("Send ERR");
        Serial.println("Restart....");
      }
      delay(50);
      radio.startListening();
      data = 0;
      while (!radio.available()) {
        delay(40);
      }
      radio.read(&data, sizeof(data));
      if (data > 0) {
        Serial.println("REG OK");
        id_sensor = data;
        delay(10);
        radio.closeReadingPipe(2);
        delay(10);
        return true;
      }
      else {
        Serial.println("REG ERR");
        return false;
      }
    }
    void setup() {
      Serial.begin(9600);
      radio.begin();
      radio.setAutoAck(true);
      radio.setChannel(120);
      radio.setDataRate (RF24_1MBPS);
      radio.setPALevel (RF24_PA_MAX);
      radio.powerUp();
      delay(10);
      radio.startListening();
      delay(10);
      radio.openReadingPipe (1, 0xAABBCCDD11LL);
      radio.setAutoAck(1, true);
      radio.openReadingPipe (2, 0xAABBCCDD22LL);
      radio.setAutoAck(2, true);
      //RF24_1MBPS
      Serial.println("Radio configured!");
      delay(100);
      if (id_sensor == 0) {
        register_sensor();
      }
    }
    void loop() {
      if (radio.available(&pipe)) {
        if (pipe == 1) {
          byte request = 0;
          radio.read(&request, sizeof(request));
          if (request == 100) {
            radio.stopListening();
            delay(10);
            radio.openWritingPipe(0xAABBCCDD11LL);
            delay(10);
            boolean send_status = false;
            byte i = 0;
            while (!send_status && i < 10) {
              send_status = radio.write(&id_sensor, sizeof(id_sensor));
              i++;
              delay(100);
            }
            delay(10);
            radio.startListening();
          }
        }
      }
    }
    Код базы:
    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    RF24     radio(D4, D8);
    byte transmit_data;
    uint8_t  pipe;

    void setup()
    {
      radio.begin();
      radio.setChannel(120);
      radio.setDataRate(RF24_1MBPS);
      radio.setPALevel(RF24_PA_MAX);
      radio.openReadingPipe (1, 0xAABBCCDD11LL);
      radio.setAutoAck(1, true);
      radio.openReadingPipe (2, 0xAABBCCDD22LL);
      radio.setAutoAck(2, true);
      /*
        radio.openReadingPipe (3, 0xAABBCCDD33LL);
        radio.setAutoAck(3, true);
        radio.openReadingPipe (4, 0xAABBCCDD44LL);
        radio.setAutoAck(4, true);
        radio.openReadingPipe (5, 0xAABBCCDD55LL);
        radio.setAutoAck(5, true);
      */

      radio.startListening();

      Serial.begin(115200);
      Serial.println("Start..");
    }


    void loop()
    {
      if (Serial.available() > 0) {
        String buf = Serial.readString();
        if (buf == "tx") {
          Serial.println("Start sening...");
          radio.stopListening();
          delay(10);
          radio.openWritingPipe(0xAABBCCDD11LL);
          byte bytte = 100;
          boolean status_data = radio.write(&bytte, sizeof(bytte));
          if (status_data) {
            Serial.println("Data sended!");
          }
          else {
            Serial.println("Data sent error");
          }
          delay(10);
          radio.startListening();
        }
      }
      if (radio.available(&pipe))
      {
        Serial.print("Got from..");
        radio.read( &transmit_data, sizeof(transmit_data) );

        if (pipe == 1)
        {
          Serial.println("Pipe 1");
          Serial.println(transmit_data);
        }
        if (pipe == 2)
        {
          Serial.println("Pipe 2 register pipe");
          if (transmit_data == 255) {
            Serial.println("Starting register!");
            radio.stopListening();
            delay(10);
            radio.openWritingPipe(0xAABBCCDD22LL);
            delay(10);
            byte new_id = random(1, 230);
            Serial.print("new id is:");
            Serial.println(new_id);
            boolean status_send = false;
            byte i = 0;
            while (!status_send && i < 10) {
              status_send = radio.write(&new_id, sizeof(new_id));
              delay(100);
              i++;
            }
            if (status_send) {
              Serial.println("Register OK");
            }
            else {
              Serial.println("Register ERR");
            }
            delay(10);
            radio.startListening();
          }
        }
      }
    }
     
  12. Evgeniy2017

    Evgeniy2017 Нерд

    (Для модеров! Сообщение не дает редачится слишком большое более 1к символов)
    Всем доброго времени суток)
    Подскажите в чем не прав, вроде все по доках. Так не работает "регистрация"
    Код (C++):
    uint8_t address[][6] = {0xAABBCCDD11LL, 0xAABBCCDD22LL, 0xAABBCCDD33LL, 0xAABBCCDD44LL, 0xAABBCCDD55LL};
    , а так все работает
    Код (C++):
    uint8_t address[][6] = {"1Node", "2Node"};
    Код базы:
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    byte id_sensor = 0;
    byte type_sensor = 1;
    RF24 radio(D4, D8);
    struct message {
      byte id;
      byte type;
      byte data;
    };
    message rx_data;
    uint8_t pipe = 0;
    //uint8_t address[][6] = {0xAABBCCDD11LL, 0xAABBCCDD22LL, 0xAABBCCDD33LL, 0xAABBCCDD44LL, 0xAABBCCDD55LL};
    uint8_t address[][6] = {"1Node", "2Node"};
    boolean send_request() {
      radio.stopListening();
      radio.openWritingPipe(address[0]);
      boolean status_s = false;
      byte i = 0;
      byte data = 101;
      while (!status_s && i < 15) {
        status_s = radio.write(&data, sizeof(data));
        i++;
        delay(5);
      }
      if (status_s) {
        Serial.println("Request send!");
      }
      else {
        Serial.println("Request error");
      }
      radio.startListening();
      return status_s;
    }
    boolean register_() {
      radio.stopListening();
      radio.openWritingPipe(address[1]);
      boolean status_s = false;
      byte i = 0;
      rx_data.id = random(1, 50);
      Serial.print("New id is ");
      Serial.println(rx_data.id);
      while (!status_s && i < 15) {
        status_s =  radio.write(&rx_data, sizeof(rx_data));
        i++;
        delay(5);
      }
      if (status_s) {
        Serial.println("REG OK");
      }
      else {
        Serial.println("REG ERR");
      }
      radio.startListening();
      return status_s;
    }
    void setup() {
      Serial.begin(115200);
      radio.begin();
      radio.setAutoAck(true);
      radio.setChannel(120);
      radio.setDataRate(RF24_1MBPS);
      radio.setPALevel (RF24_PA_MAX);
      radio.openReadingPipe(1, address[0]);
      radio.openReadingPipe(2, address[1]);
      radio.setAutoAck(1, true);
      radio.setAutoAck(2, true);
      radio.powerUp();
      delay(100);
      radio.startListening();
    }

    void loop() {
      if (Serial.available() > 0) {
        String buffer_ = Serial.readString();
        if (buffer_ == "tx") {
          Serial.println("Start sending...");
          send_request();
        }
      }
      if (radio.available(&pipe)) {
        Serial.println("DATA recived!");
        radio.read(&rx_data, sizeof(rx_data));
        if (pipe == 1) {
          Serial.print("Pipe 1 Id: ");
          Serial.print(rx_data.id);
          Serial.print(" Type sensor: ");
          Serial.print(rx_data.type);
          Serial.print(" Data: ");
          Serial.println(rx_data.data);
        }
        else if (pipe == 2) {
          Serial.println("New module, veryfing....");
          if (rx_data.id == 0 && rx_data.data == 255) {
            Serial.println("VERIFED! Starting register...");
            register_();
          }
        }
        Serial.println(pipe);

      }

    }
    Код датчика:
    Код (C++):
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    byte id_sensor = 0;
    byte type_sensor = 1;
    RF24 radio(9, 10);
    struct message {
      byte id;
      byte type;
      byte data;
    };
    message send_data;
    uint8_t pipe = 0;
    //uint8_t address[][6] = {0xAABBCCDD11LL, 0xAABBCCDD22LL, 0xAABBCCDD33LL, 0xAABBCCDD44LL, 0xAABBCCDD55LL};
    uint8_t address[][6] = {"1Node", "2Node"};
    void setup() {
      Serial.begin(115200);
      radio.begin();
      radio.setAutoAck(true);
      radio.setChannel(120);
      radio.setRetries(1,7);
      radio.setDataRate(RF24_1MBPS);
      radio.setPALevel (RF24_PA_MAX);
      radio.openReadingPipe(1, address[0]);
      radio.openReadingPipe(2, address[1]);
      radio.openWritingPipe(address[0]);
      radio.powerUp();
      radio.startListening();
      delay(100);
      if (id_sensor == 0) {
        //Start reg!
        Serial.println("Start registering....");
        radio.stopListening();
        delay(50);
        radio.openWritingPipe(address[1]);
        delay(300);
        Serial.println("Radio done!");
        send_data.id = 0;
        send_data.type = type_sensor;
        send_data.data = 255;
        boolean send_status = false;
        byte i = 0;
        while (!send_status && i < 15) {
          send_status = radio.write(&send_data, sizeof(send_data));
          delay(150);
          i++;
        }
        radio.startListening();
        if (!send_status) {
          Serial.println("Error register!(start infinyt while)");
          while (true) {}
        }
        while (!radio.available()) {}
        Serial.println("Data recived! Veryfing....");
        radio.read(&send_data, sizeof(send_data));
        if (send_data.id != 0 && send_data.type == type_sensor && send_data.data == 255) {
          Serial.println("REG OK");
          id_sensor = send_data.id;
        }
        else {
          Serial.println("REG ERR");
        }
        radio.stopListening();
        radio.openWritingPipe(address[0]);
        radio.startListening();
      }
    }

    void loop() {
      if (radio.available(&pipe)) {
        if (pipe == 1) {
          Serial.println("Data recived!");
          byte request = 0;
          radio.read(&request, sizeof(request));
          if (request == 101) {
            Serial.println("Request OK Start sending data..");
            radio.stopListening();
            boolean send_s = false;
            byte i = 0;
            send_data.id = id_sensor;
            send_data.type = type_sensor;
            send_data.data = random(1, 30);
            while (!send_s && i < 10) {
              send_s = radio.write(&send_data, sizeof(send_data));
              delay(50);
              i++;
            }
            if (send_s) {
              Serial.println("Data sended!");
            }
            else {
              Serial.println("Error of sending data");
            }
            radio.startListening();
          }
        }
      }
    }
    Задержка в 300мс в датчике нужна тип чтоб кондер зарядился, но на практике вроде все равно(не помню выше писал или нет что были проблемы с питанием от не полного входа вилки в розетку, так как быстро менял розетки для проверки дальности)


    ------15/07/2020---------
    Вообщем в доках написано так
    Код (C++):
    uint8_t addresses[][6] = {"1Node","2Node"};
    openReadingPipe(1,addresses[0]);
    openReadingPipe(2,addresses[1]);
    Значит будем делать так)
    http://tmrh20.github.io/RF24/classRF24.html#a9edc910ccc1ffcff56814b08faca5535
     
    Последнее редактирование: 15 июл 2020