РЕШЕНО Связь nodemcu v3 с arduino nano по i2c

Тема в разделе "ESP8266, ESP32", создана пользователем Laytin, 23 сен 2021.

  1. Laytin

    Laytin Нуб

    Добрый день. Тут такая проблема. Есть немалое количество датчиков, подключенных к ардуинке, нужно бы их передать на NodeMcu для дальнейшей передачи. Объем переменных довольно большой, сразу приглянулся i2c. Соединил с горе пополам (ибо там и не смог сделать Ардуино мастером, пришлось через ответный запрос делать), но даже так не передается больше 3 float переменных.

    upload_2021-9-23_11-40-25.png

    Может кто-то знает как можно организовать передачу нескольких переменных по этому протоколу? Были идеи по поводу ЮАРТ, но так и не разобрался с передачей массивов с помощью его.

    Код ардуинки:
    Код (C++):
    #include <Wire.h>
    #include "I2C_Anything.h"

    float zn1 = 1.1;
    float zn2 = 1.2;
    float zn3 = 1.3;
    float zn4 = 2.4;
    float zn5 = 2.5;
    float zn6 = 2.6;


    void setup() {
    Wire.begin(8);                /* задаем на шине i2c 8 адрес */
    Wire.onRequest(requestEvent); /* регистрируем запрошенное событие */
    Serial.begin(9600);           /* открываем серийный порт для дебаггинга */
    }

    void loop() {
    delay(100);
    }

    // Функция для извлечения любых принимаемых данных от мастера на шину

    // Функция для извлечения любых отправляемых данных от мастера на шину
    void requestEvent() {
      Wire.beginTransmission (8);
    I2C_writeAnything (zn1);
    I2C_writeAnything (zn2);
    I2C_writeAnything (zn3);
    I2C_writeAnything (zn4);
    I2C_writeAnything (zn5);
    I2C_writeAnything (zn6);
    Wire.endTransmission ();
    }
    Код NodeMCU:
    Код (C++):
    #include <Wire.h>
    #include "I2C_Anything.h"

    volatile boolean haveData = false;
    volatile float zn1;
    volatile float zn2;
    volatile float zn3;
    volatile float zn4;
    volatile float zn5;
    volatile float zn6;

    void setup() {
    Serial.begin(9600); /* открываем серийный порт для дебаггинга */
    Wire.begin(D1, D2); /* задаем i2c мост через контакты SDA=D1 и SCL=D2 на NodeMCU */
    }

    void loop() {
    Wire.beginTransmission(8); /* Начинаем передачу на адресе 8 */


    Wire.requestFrom(8, 13); /* запрашиваем и считываем данные с 8 и 13 адреса slave устройства */
    while(Wire.available()){
        I2C_readAnything (zn1);
        I2C_readAnything (zn2);
        I2C_readAnything (zn3);
        I2C_readAnything (zn4);
        I2C_readAnything (zn5);
        I2C_readAnything (zn6);
    }  // end of receiveEvent
    Serial.println (zn1);
      Serial.println (zn2);
      Serial.println (zn3);
      Serial.println (zn4);
      Serial.println (zn5);
      Serial.println (zn6);
    Serial.println();
    delay(1000);

      Wire.endTransmission();    /* прекращаем передачу */
    }
    I2C_Anything.h:

    Код (C++):
    #include <Arduino.h>
    #include <Wire.h>
    template <typename T> int I2C_writeAnything (const T& value)
    {
       const byte * p = (const byte*) &value;
       unsigned int i;
       for (i = 0; i < sizeof value; i++)
             Wire.write(*p++);
       return i;
    }  // end of I2C_writeAnything
    template <typename T> int I2C_readAnything(T& value)
    {
       byte * p = (byte*) &value;
       unsigned int i;
       for (i = 0; i < sizeof value; i++)
             *p++ = Wire.read();
       return i;
    }  // end of I2C_readAnything
     
  2. ИгорьК

    ИгорьК Гуру

    Запакуйте ваши данные в json вместо массивов, отправляйте по uart на esp и далее. ИМХО, это самый простой способ.
     
  3. b707

    b707 Гуру

    Умея передавать за раз три флоат, можно передать хоть всю ленинскую библиотеку
    тут ключевое слово "за раз". сначала первые три переменные. потом следующие и так далее
     
  4. b707

    b707 Гуру

    имхо. он станет еще проще. если выкинуть json
    передать массив по Уарт - как нефиг делать
     
  5. ИгорьК

    ИгорьК Гуру

    Да. Но там планируется дальнейшая передача. А там этот нефиг зело вырастет. Это же гдетоктото "ловить" будет. Не думаю, что такая же Ардуина.
     
  6. ИгорьК

    ИгорьК Гуру

    Json - унифицированный формат передачи данных. Его понимает любая система "на том конце".
     
  7. Laytin

    Laytin Нуб

    К сожалению на том конце такая же Ардиуина
     
  8. ИгорьК

    ИгорьК Гуру

    Ну и распакуйте json обратно.
     
  9. Laytin

    Laytin Нуб

    Мне важно передавать данные с как можно меньшей задержкой, поэтому скорее всего придется просто переписывать на ЮАРТ
     
  10. Laytin

    Laytin Нуб

    А разве обычным юартом с разделителями не проще будет? не особо понял преимущество json'a.
     
  11. b707

    b707 Гуру

    проще бинарным массивом без разделителей. И быстрее
     
  12. ИгорьК

    ИгорьК Гуру

    Понимаете, многое зави
    Тут все зависит от задачи. Если "на том конце" компьютер - json рулит. Если Ардуина - делайте любым понятным вам способом.
     
  13. ИгорьК

    ИгорьК Гуру

    "Проще" всегда зависит от уровня подготовки и времени на решение задачи.
     
  14. Laytin

    Laytin Нуб

    По времени не ограничен, но с контроллерами не так давно учусь работать. В общем буду пробовать ЮАРТ, выглядит не так страшно как казалось. По поводу json подумаю, сначала стоит попробовать обычный ЮАРТ, без ""дополнительных средств".
    Благодарю за помощь :)
     
  15. ИгорьК

    ИгорьК Гуру

    Вы точно уверены, что там ESP нужно, может что-то попроще?
     
  16. Laytin

    Laytin Нуб

    Нужно передать данные с одной ардуинки на другую, расстояние <50 метров, местность открытая. Так как с радиосвязью у меня плохие отношения (как бы я не пытался, не получается у меня подключить RF69 передатчик), то выбрал ESP. Все равно лежат 4 NodeMCU платы, как раз пригодились.
     
  17. ИгорьК

    ИгорьК Гуру

    HC-12 - и будет вам счастье. И быстрее и проще.
     
  18. DetSimen

    DetSimen Гуру

    Этой строкой ты запрашиваешь 13 байт с устройства с адресом 8. Так как float занимает 4 байта, то 3 значения ты и получаешь, остальные - мусор, в чём ты сам и удибился.

    Подтяни свои знания по i2c шине. Перед requestFrom() не нужен beginTransmission(). И больше 32 байт за раз ты по шине не передашь, это ограничено размером буфера приема/передачи в библиотеке Wire. Разбивай на фреймы, если передаваемые данные длиннее.
     
    Последнее редактирование: 23 сен 2021
    Andrey12 и b707 нравится это.
  19. DetSimen

    DetSimen Гуру

    Для таких задач я обычно использую JDY как Serial-удлиннители и протокол с контролькой и квитированием.
     
  20. parovoZZ

    parovoZZ Гуру

    по I2C на ESP здесь