I2C управляем реле и отсылаем статус

KosteT
Offline
Зарегистрирован: 17.07.2016

Продолжил ковыряния... Две меги между собой по 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екунд:

Error, byte 1 = 0
Error, byte 0 = 0
Error, byte 1 = 0
Error, byte 0 = 0
Error, byte 1 = 0
Error, byte 1 = 0
Error, byte 1 = 0
Error, byte 0 = 0

Косячных битов так и не дождался, но они были очень редко, может и сварка где то работала или молнии стреляли, пока пропустим этот момент, но косяк с данной либой на лицо.

Далее - включил writeMask на слейве: как в примере bool bbb[2] = {0, 0}; и после I2C2.begin.. I2C2.writeMask(bbb); После 5 секунд разово мастером пишу в оба регистра B11111111 вижу такое:

Error, byte 1 = 0
Error, byte 0 = 0
Error, byte 0 = 0
Error, byte 0 = 0
Error, byte 1 = 0
Error, byte 0 = 0
5 sec, write 0,1!
Error, byte 1 = 1010101
Error, byte 0 = 10101010
Error, byte 1 = 1010101
Error, byte 0 = 10101010
Error, byte 1 = 1010101
Error, byte 0 = 10101010

writeMask меняю на разрешение записи {1,1} - ничего не меняется, так что юзать его не стоит вообще.

Проверил на голой Wire - там всё стабильно как АК-47, вердикт - библиотека УГ ) Пошёл её ковырять...

KosteT
Offline
Зарегистрирован: 17.07.2016

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), но не проверял дальше, завтра разберусь

sadman41
Offline
Зарегистрирован: 19.10.2016

Да и available() для одного байта дергать несколько странно.

KosteT
Offline
Зарегистрирован: 17.07.2016

А ещё не логично что возвращает 0 при любом раскладе, надо бы причесать всё это добро... А CRC я всё таки оставлю, так надёжнее имхо, не охото что бы в грозу свет моргал) не зря же am2320, dallas и прочие более менее сурьезные вещи в стоке юзают избыточный код, а беспроводные ещё и двойную отправку для восстановления потерь