I2C_Что угодно++

запрос информации сформулирован, как сказать?

в Ascii: диалоговое окно i2C: Tx -----> Прием ----> PCF8574

рисунок https://nsm09.casimages.com/img/2023/02/28/23022802163423870818122937.jpg

3 элемента на шине i2C

  • Arduino "Tx" считывать значения с электрического счетчика
  • Arduino "Rx" для повторного использования значений, а также для диалога по шине Rs485
  • и PCF8574, который получает команды от Arduino "Rx" для управления телесценами

1-й вопрос:

I2C_writeAnything (foo1); 
(foo2);
(foo3);
I2C_writeAnything (foo X?); 

Какое максимальное количество foo1 .. foo2 ...foo10 я могу поместить ?

Это правильный метод? или мы должны сгруппировать их по пакетам?

2-й вопрос:

когда мы используем несколько библиотек, в их скетче мы находим вызовы #include <Wire.h> которые добавляются к основному скетчу. Может ли это быть причиной проблем?

спасибо

Arduino "Tx" for electrical measurements (simulation with a "random") 

void loop()  {

unsigned long foo1 = random(2294967295);  
unsigned long foo2 = random(2294967295);
unsigned long foo3 = random(2294967295);
unsigned long foo4 = random(2294967295);
unsigned long foo5 = random(2294967295);

if (timer0.available()) { 
Wire.beginTransmission (SLAVE_ADDRESS);
 
I2C_writeAnything (foo1);
I2C_writeAnything (foo2);
I2C_writeAnything (foo3);
I2C_writeAnything (foo4);
I2C_writeAnything (foo5);
       
Wire.endTransmission ();
   
if (!Wire.endTransmission ()) { Serial.println ("endTransmission () : "); }
timer0.restart();
} 
} /*Loop*/  




//Arduino "Rx" for reading and using the Electrical values 
#include <Wire.h>
#include <I2C_Anything.h>           //http://www.gammon.com.au/i2c
const byte MY_ADDRESS = 42;
  
volatile boolean haveData = false;
volatile unsigned long foo1; 
volatile unsigned long foo2;
volatile unsigned long foo3;
volatile unsigned long foo4;
         
#include "PCF8574.h"                //https://github.com/RobTillaart/Arduino/tree/master/libraries/PCF8574
PCF8574 PCF27a (0x3D);  // adjust addresses i2c pcf8574

//...setup
//...loop

void receiveEvent (int howMany)  {


// if (howMany >=  4) 
if (howMany >=  (sizeof foo1))    {
I2C_readAnything (foo1);  
I2C_readAnything (foo2); 
I2C_readAnything (foo3);
I2C_readAnything (foo4); 

haveData = true;  
}  
}  // end of receiveEvent 

, 👍-2

Обсуждение

Что именно вы имеете в виду под лимитом? Лимит данных, передаваемых за одну транзакцию, равен размеру буфера в библиотеке Wire. И второй вопрос не читается. Пожалуйста, отредактируйте свой вопрос, чтобы было понятно, о чем вы спрашиваете., @chrisl

да, я изменил свой текст спасибо Крис, @JeeLet

Может ли это быть причиной проблем? ... вы ничего не сказали о проблемах, @jsotola

Включение библиотек создаст проблемы только в том случае, если есть несовместимость с чем-то в остальной части вашего кода. Вы видели проблемы? Почему вы думаете, что это может быть проблемой? Вам нужно включить Wire, так как вы используете его для связи I2C., @chrisl

Пожалуйста, правильно отформатируйте код, особенно исправьте отступы., @the busybee

Тестовая сборка работает, но через час-два связь остается зависшей. Сброс на Arduino, и он начинается снова. Я сделал тест, добавив в настройку эту строку: Wire.setWireTimeout(3000,правда); https://www.fpaynter.com/2020/07/i2c-hangup-bug-cured-miracle-of-miracles-film-at-11/ и моя сборка работает хорошо, больше никаких блокировок. Мне просто нужно найти, как управлять своими данными пакетами по 32 байта., @JeeLet


2 ответа


0

Отзыв по модулю Электрические измерения. с шиной i2C. (это может быть полезно для других людей)

Больше никаких ошибок, никаких блокировок, он мурлычет как котенок.

Для структуры скопировал работу Peter_n (спасибо вам) Это мне очень помогло: https://forum.arduino.cc/t/i2c-not- отправка всех данных с помощью i2c_anything/293609

и для: Wire.setWireTimeout(3000,true); не уверен, куда его положить, он надет на обе части.

копия скетчей

Master_I2C_Anything_Linky_uneStructure_bigOctes.ino

  // base Автор: Ник Гэммон, май 2012 г.:
// структура Peter_n: https://forum.arduino.cc/t/i2c-not-sending-all-data-with-i2c_anything/293609

//--- Диалог по шине i2c между 2 ATMega328 - Arduino-Uno ------------
// --- 2x6 32-битных значений или 1x 7
//--- функциональная тестовая модель ---------------------------
// Добавить в настройки: Wire.setWireTimeout(3000,true);

  #include <Wire.h>
  #include <I2C_Anything.h>   //http://www.gammon.com.au/i2c

  const byte SLAVE_ADDRESS = 42;

  #include "Timers.h"         //https://github.com/nettigo/Таймеры
  Timer timer0;   // задерживать

//------------ структура -------------------------
//------------ linky info ---- 7 типов переменных --------//
 
  struct sensorData_STRUCT {
  byte sensorNumber;
    uint16_t A;   // uint16_t PAPP в ВА
    uint32_t B;   // uint32_t БАЗОВЫЙ индекс в Втч
    uint32_t C;   // uint32_t HCHC индекс heures creuses en Wh
    uint32_t D;   // uint32_t HCHP Index heures pleines en Wh
    uint8_t E;    // uint8_t IINST возвращает в амперах
    uint8_t F;    // uint8_t ISOUSC Возвращает ISOUSC
    uint8_t G;    // uint8_t Текущий тарифный период PTEC (0 = HP, 1 = HC)
     uint8_t H;    // тест
  } sensorData[1]; // [x] количество структур

//---------------------- НАСТРАИВАТЬ --------------------
void setup() {
  Serial.begin (115200);
  Serial.println(F(" Master_I2C_Anything_Linky_structure_double.ino "));
  Serial.print(__DATE__); Serial.println(__FILE__);
  
  Wire.begin ();  

  Wire.setWireTimeout(3000,true); 
  
  // заполняем фиксированные данные
  sensorData[0].sensorNumber = 0;
 // Данные датчика[1].SensorNumber = 1; // деактивировать

  timer0.begin(SECS(3));  //задержка передачи

  } /*Setup*/

//-------------------- ПЕТЛЯ -----------------------
  void loop()  {
      
//---------------- состав ------------
// собираем новые данные
  sensorData[0].A = 10 ; 
  sensorData[0].B = random(2000000000);
  sensorData[0].C = random(2000000000);
  sensorData[0].D =  random(2000000000) ;      
  sensorData[0].E =  random(2000000000) ;
  sensorData[0].F =  random(2000000000) ; // фиксированная стоимость
  sensorData[0].G = 70 ; // фиксированная стоимость
  // = 19 байт
// unsigned long: неотрицательное целое число от 0 до 4 294 967 295 на 32 битах по 4 байта
   
//------------------
         
  if (timer0.available()) { 

 // 1; 2; выбор количества конструкций
  for( int sensor = 0; sensor < 1; sensor++)  {
    // передаем данные
    Wire.beginTransmission( SLAVE_ADDRESS);
    I2C_writeAnything( sensorData[sensor]);
       
    int error = Wire.endTransmission (); //(истинный) ?
     if( error != 0) {
      Serial.println(F("Error, no acknowledge from Slave"));
    }
  }

    timer0.restart();
  }
  
  } /*Loop*/  

//---------------------- Конец пгм ------------------------ ----
,

0

Slave_I2C_Anything_PCF8574_4DO_uneStructure_bigOctes.ino

/*
 *  DESCRIPTION :    
 *  un Arduino Uno en liaison avec un module i2c PCF8574 avec 4 Relais
 *  il recoi aussi d'un autre Arduino des valeurs en Kw pour le basculement des relay
 *   
 *    
 *  LIBRAIRIES:
 *    - Rob Tillaart pour PCF8574 https://github.com/RobTillaart/Arduino/tree/master/libraries/PCF8574
 *    - Nick Gammon  for bus i2c  http://www.gammon.com.au/i2c
 *    - Timers de Łukasz Tretyn   https://github.com/nettigo/Timers
 *    
 *  ELEMENTS: sur le bus i2c
 *    - Expander PCF8574 avec module Metasys JC / 4DO - 0X3D  i2c adress
 *    - ATMega328  pour mesure Electrique
 *    - ATMega328  en Reception 
 *         
 *  MODIFICATION:  
 *    -x- model de Peter_n : https://forum.arduino.cc/t/i2c-not-sending-all-data-with-i2c_anything/293609/11
 *    -o- 
 *    -o-
 * 
 *     RAS 
*/

//------ Март 2023 -------- Linky PCF8574 - Шина 4DO/i2c ------------------//

// ------------- Функциональный тест шины I2C ---------//
// одна структура из 19 октетов, максимум 32 октавы

   
//------ Шина i2C ------------
  #include <Wire.h>
  #include <I2C_Anything.h>
  const byte MY_ADDRESS = 42;
  
  // Структура должна быть одинаковой в Мастере и в Ведомом
  // unsigned long: 4 октета (32 бита) - макс. 4294967295
  struct sensorData_STRUCT {
  byte sensorNumber;
    uint16_t A;   // uint16_t PAPP в ВА
    uint32_t B;   // uint32_t БАЗОВЫЙ индекс в Втч
    uint32_t C;   // uint32_t HCHC индекс heures creuses en Wh
    uint32_t D;   // uint32_t HCHP Index heures pleines en Wh
    uint8_t E;    // uint8_t IINST возвращает в амперах
    uint8_t F;    // uint8_t ISOUSC Возвращает ISOUSC
    uint8_t G;    // uint8_t Текущий тарифный период PTEC (0 = HP, 1 = HC)
     uint8_t H;    //
    };

/*  struct sensor2Data_STRUCT {
  byte sensor2Number;
    int G;
    int H;
    int I;
    int J;
    int K;
    int L;
    }; */

    
  // Специальная структура для полученных данных датчика
  volatile sensorData_STRUCT sensorDataNew;
  
  // Флаг для обозначения новых данных
  volatile boolean haveData = false;

  // Нормальные данные датчика
  sensorData_STRUCT sensorData[1];  //номер структуры [2]
   
          
//---------------- PCF8574 ----------------------------------------------
  #include "PCF8574.h"
  PCF8574 PCF27a (0x3D);  // настроить адреса i2c pcf8574

  #define RELAY_ON  0    //
  #define RELAY_OFF 1    //

// ------------------------------------------------ -----------------------------
// ----------------- НАСТРАИВАТЬ ---------------------
// ------------------------------------------------ -----------------------------

void setup() {

  Wire.begin (MY_ADDRESS);  // шина i2C
  Wire.onReceive (receiveEvent);

  Serial.begin (115200);
  Serial.println(F(" SlaveI2CAnythingPCF8574Structure_bigOctes "));
  Serial.print(__DATE__); Serial.println(__FILE__);
  
  // заполняем фиксированные данные
  sensorData[0].sensorNumber = 0; 

  Wire.setWireTimeout(3000,true); 

  PCF27a.begin();           // i2C PCF8574
  
//--------- тестирование IsConnected i2c PCfx ------------
  Serial.print(F(" PCF8574_LIB_VERSION : \t")); Serial.println(PCF8574_LIB_VERSION);
  if (!PCF27a.begin())   {
    Serial.println(F("could not initialize..."));
    }
  if (!PCF27a.isConnected())   {
    Serial.println(F("=> not connected"));
  }
  else   {
    Serial.println(F("=> connected!!"));
    }  
         
  } /* fin Setup */
  
// ------------------------------------------------ --------------------------
// ----------------- ПЕТЛЯ ------------------------
// ------------------------------------------------ --------------------------
 void loop() {
 
//---------------- Шина i2C ------------------------------ -
  int sensor;  int sensor2;
  
    if( haveData)  {
    // Пришли новые данные, копируем их в один из двух sensorData.
    // Отключить прерывания как можно короче
    // Прерывания отключены, чтобы избежать прерывания по ReceiveEvent, которое записывает новые данные.
    noInterrupts();
    sensor = sensorDataNew.sensorNumber;


  if( sensor == 0 || sensor == 1) {         // пункт назначения, источник, размер
  memcpy( &sensorData[sensor], (const void *) &sensorDataNew, sizeof( sensorData_STRUCT));

  }
  haveData = false;
  interrupts();
    
    printData(sensor) ; //печатать данные
    cmdRelay() ;        // Реле PCF8574
   }
   
 } /* fin Loop */

// ------------------------------------------------ -----------------------------
// ------------------- Получение сообщений I2C ------------------
// ------------------------------------------------ -----------------------------
//сколько это количество полученных байтов и, следовательно, сколько вы можете прочитать
// с Wire.read(), максимум 32 байта.

 void receiveEvent( int howMany) {
  if( howMany == sizeof( sensorData_STRUCT)) {
    I2C_readAnything( sensorDataNew); 
         haveData = true;
  }
  else {
    // что-то не так. Получено неправильное количество байтов.
    // можно установить изменчивую переменную в ошибку.
  }
 }

// ------------------------------------------------ -----------------------------
// ------------------- Управление реле ------------------
// ------------------------------------------------ -----------------------------
 void cmdRelay() {
//-------- Реле 1 ---------
  if (sensorData[0].A > 829308135 ) { PCF27a.write(0, RELAY_ON); }
  else { PCF27a.write(0, RELAY_OFF); }
     //Serial.println(PCF27a.read(0));
//-------- Реле 2 ---------
  if (sensorData[0].B > 304929158) { PCF27a.write(1, RELAY_ON); }
  else { PCF27a.write(1, RELAY_OFF); }
      //Serial.println(PCF27a.read(1));
//-------- Реле 3 ---------
  if (sensorData[0].C > 590793899 ) { PCF27a.write(2, RELAY_ON); }
  else { PCF27a.write(2, RELAY_OFF); }
     //Serial.println(PCF27a.read(2));
//-------- Реле 4 ---------
  if (sensorData[0].D > 304929158) { PCF27a.write(3, RELAY_ON); }
  else { PCF27a.write(3, RELAY_OFF); }
      //Serial.println(PCF27a.read(3));
 }

// ------------------------------------------------ -----------------------------
// ------------------- Распечатать данные ------------------
// ------------------------------------------------ -----------------------------
  void printData(int sensor) {

  if (sensor == 0 ) {
    Serial.print(F( "------ sensor["));
    Serial.print( sensor); Serial.println(F( "] ------"));
    Serial.print(F( "a PAPP  = ")); Serial.println( sensorData[0].A);
    Serial.print(F( "b BASE  = ")); Serial.println( sensorData[0].B);
    Serial.print(F( "c HCHC  = ")); Serial.println( sensorData[0].C);
    Serial.print(F( "d HCHP  = ")); Serial.println( sensorData[0].D);
    Serial.print(F( "e IINST = ")); Serial.println( sensorData[0].E);
    Serial.print(F( "f ISOUSC= ")); Serial.println( sensorData[0].F);
    Serial.print(F( "g PTEC  = ")); Serial.println( sensorData[0].G);
     Serial.print(F( "h test  = ")); Serial.println( sensorData[0].G);

Serial.println(sizeof( sensorData_STRUCT));
    }
    Serial.println();
  }
//----------------------------- Конец пгм ---------------- ---------------------
,

Разве это не должно быть частью вашего другого ответа?, @sempaiscuba