Косячных битов так и не дождался, но они были очень редко, может и сварка где то работала или молнии стреляли, пока пропустим этот момент, но косяк с данной либой на лицо.
Далее - включил writeMask на слейве: как в примере bool bbb[2] = {0, 0}; и после I2C2.begin.. I2C2.writeMask(bbb); После 5 секунд разово мастером пишу в оба регистра B11111111 вижу такое:
// чтение одного байта данных из устройства с указанием
uint8_t iarduino_I2C_connect::readByte(uint8_t i, uint8_t j){ // адрес устройства, адрес регистра
uint8_t k=0; // переменная для ответа
Wire.beginTransmission(i); // инициируем передачу данных по шине I2C к устройству с адресом i (При этом сама передача не начинается)
Wire.write(j); // указываем, что требуется передать байт j - адрес регистра из которого требуется прочитать данные
Wire.endTransmission(true); // выполняем инициированную передачу данных (бит RW=0 => запись)
if(Wire.requestFrom(i,uint8_t(1))){ // запрашиваем 1 байт данных от устройства с адресом i, функция Wire.requestFrom() возвращает количество принятых байтов
while(Wire.available()){k=Wire.read();} // читаем очередной принятый байт, если таковой имеется в буфере для чтения
} return k; // возвращаем последний принятый байт данных
}
После записи зачем то закрывается соединение сообщением STOP, хотя далее хотим читать с этого же адреса. Соответственно между записью и чтением должна быть задержка в 100-400 микросекунд (считайте сами от скорости - я чёт уже сплю), а её нет... delay спасёт положение. Но это всё идеологически не правильно, правильнее вообще соединение не рубить на корню, а прописать Wire.endTransmission(false); - чтобы читать байт сразу же.
А по маскировочному массиву
k=0; if(I2C2VC.I2C_flag_MASK){if(I2C2VC.I2C_length_MASK<I2C2VC.I2C_index_REG){if(I2C2VC.I2C_array_MASK[I2C2VC.I2C_index_REG]){k=1;}}}else{k=1;} // разрешаем запись если маскирующий массив не указывался, или если он указывался и значение его элемента позволяет записывать данные в соответствующий элемент массива I2C2VC.I2C_array_REG
на первый взгляд if(I2C2VC.I2C_length_MASK>I2C2VC.I2C_index_REG), но не проверял дальше, завтра разберусь
А ещё не логично что возвращает 0 при любом раскладе, надо бы причесать всё это добро... А CRC я всё таки оставлю, так надёжнее имхо, не охото что бы в грозу свет моргал) не зря же am2320, dallas и прочие более менее сурьезные вещи в стоке юзают избыточный код, а беспроводные ещё и двойную отправку для восстановления потерь
Продолжил ковыряния... Две меги между собой по I2C, на каждой плате уже стоит подтяжка scl и sda 10кОм
Код слейва
#include <Wire.h> #include <iarduino_I2C_connect.h> iarduino_I2C_connect I2C2; byte REG_MASSIVE[2] = {B01010101, B10101010}; void setup() { Wire.begin(2); I2C2.begin(REG_MASSIVE); } void loop() { }Код мастера:
#include <Wire.h> #include <iarduino_I2C_connect.h> iarduino_I2C_connect I2C2; byte ReadSlaveR0 = 0; byte ReadSlaveR1 = 0; void setup() { Wire.begin(); Serial.begin(9600); Serial.println("start"); } void loop() { ReadSlaveR0 = I2C2.readByte(2,0); ReadSlaveR1 = I2C2.readByte(2,1); if(ReadSlaveR0!=B01010101) { Serial.print("Error, byte 0 = "); Serial.println(ReadSlaveR0, BIN); } if(ReadSlaveR1!=B10101010) { Serial.print("Error, byte 1 = "); Serial.println(ReadSlaveR1, BIN); } }В консоли видим раз в 1-5 cекунд:
Косячных битов так и не дождался, но они были очень редко, может и сварка где то работала или молнии стреляли, пока пропустим этот момент, но косяк с данной либой на лицо.
Далее - включил writeMask на слейве: как в примере bool bbb[2] = {0, 0}; и после I2C2.begin.. I2C2.writeMask(bbb); После 5 секунд разово мастером пишу в оба регистра B11111111 вижу такое:
writeMask меняю на разрешение записи {1,1} - ничего не меняется, так что юзать его не стоит вообще.
Проверил на голой Wire - там всё стабильно как АК-47, вердикт - библиотека УГ ) Пошёл её ковырять...
iarduino_I2C_connect.cpp
46 строка меняем на Wire.endTransmission(false);
// чтение одного байта данных из устройства с указанием uint8_t iarduino_I2C_connect::readByte(uint8_t i, uint8_t j){ // адрес устройства, адрес регистра uint8_t k=0; // переменная для ответа Wire.beginTransmission(i); // инициируем передачу данных по шине I2C к устройству с адресом i (При этом сама передача не начинается) Wire.write(j); // указываем, что требуется передать байт j - адрес регистра из которого требуется прочитать данные Wire.endTransmission(true); // выполняем инициированную передачу данных (бит RW=0 => запись) if(Wire.requestFrom(i,uint8_t(1))){ // запрашиваем 1 байт данных от устройства с адресом i, функция Wire.requestFrom() возвращает количество принятых байтов while(Wire.available()){k=Wire.read();} // читаем очередной принятый байт, если таковой имеется в буфере для чтения } return k; // возвращаем последний принятый байт данных }После записи зачем то закрывается соединение сообщением STOP, хотя далее хотим читать с этого же адреса. Соответственно между записью и чтением должна быть задержка в 100-400 микросекунд (считайте сами от скорости - я чёт уже сплю), а её нет... delay спасёт положение. Но это всё идеологически не правильно, правильнее вообще соединение не рубить на корню, а прописать Wire.endTransmission(false); - чтобы читать байт сразу же.
А по маскировочному массиву
k=0; if(I2C2VC.I2C_flag_MASK){if(I2C2VC.I2C_length_MASK<I2C2VC.I2C_index_REG){if(I2C2VC.I2C_array_MASK[I2C2VC.I2C_index_REG]){k=1;}}}else{k=1;} // разрешаем запись если маскирующий массив не указывался, или если он указывался и значение его элемента позволяет записывать данные в соответствующий элемент массива I2C2VC.I2C_array_REGна первый взгляд if(I2C2VC.I2C_length_MASK>I2C2VC.I2C_index_REG), но не проверял дальше, завтра разберусь
Да и available() для одного байта дергать несколько странно.
А ещё не логично что возвращает 0 при любом раскладе, надо бы причесать всё это добро... А CRC я всё таки оставлю, так надёжнее имхо, не охото что бы в грозу свет моргал) не зря же am2320, dallas и прочие более менее сурьезные вещи в стоке юзают избыточный код, а беспроводные ещё и двойную отправку для восстановления потерь