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
@JeeLet, 👍-2
Обсуждение2 ответа
Отзыв по модулю Электрические измерения. с шиной 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*/
//---------------------- Конец пгм ------------------------ ----
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
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Что именно вы имеете в виду под лимитом? Лимит данных, передаваемых за одну транзакцию, равен размеру буфера в библиотеке 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