諸事情あって自力でI2C通信の関数を作った。
動作確認済みのライブラリなので公開する。
“NoWire”という名前にしているのは”Wire.h”というベタなライブラリを使っていないから。
const int i2cNoWire_sck = XX; // 好きなピンをアサインする
const int i2cNoWire_sda = XX; // 好きなピンをアサインする
const int i2cNoWire_bit2bit_delay = xxx; // us // 仕様に応じて決める(最低でも5us)
const int rdy0 = XX; // もしReadyピンのあるICが相手だったら
void i2cNoWire_write(int address, int data)
{
pinMode(no_ack, OUTPUT);
pinMode(ack, OUTPUT);
digitalWrite(no_ack, LOW);
digitalWrite(ack, LOW);
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
pinMode(i2cNoWire_sck, INPUT);
pinMode(i2cNoWire_sda, INPUT);
// start bit
while(i2cNoWire_read_sda() ==0){}
i2cNoWire_clear_sda();
delayMicroseconds(i2cNoWire_bit2bit_delay);
i2cNoWire_clear_sck();
int control_byte = (I2C_ADD << 1) & 0xFE;
// send IC address + write bit
i2cNoWire_writebyte(control_byte);
if(i2cNoWire_readbit()){
Serial.println(“NO ACK (sending control_byte)”);
digitalWrite(no_ack, HIGH);
return;
}
else{
Serial.println(“<< ACK OK >> (sending control_byte)”);
digitalWrite(ack, HIGH);
}
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
// send address byte
i2cNoWire_writebyte(address);
if(i2cNoWire_readbit()){
Serial.println(“NO ACK (sending address_byte)”);
return;
}
else{
Serial.println(“<< ACK OK >> (sending address_byte)”);
}
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
i2cNoWire_writebyte(data);
if(i2cNoWire_readbit()){
Serial.println(“NO ACK (sending data_byte)”);
return;
}
else{
Serial.println(“<< ACK OK >> (sending data_byte)”);
}
digitalWrite(i2cNoWire_sck, LOW);
pinMode(i2cNoWire_sda, OUTPUT);
// stop bit
digitalWrite(i2cNoWire_sda, LOW);
digitalWrite(i2cNoWire_sck, HIGH);
delayMicroseconds(i2cNoWire_bit2bit_delay);
digitalWrite(i2cNoWire_sda, HIGH);
digitalWrite(i2cNoWire_sck, HIGH);
Serial.println(“Write OK”);
///// read //////////////////////////////////////
int read_data = i2cNoWire_read(address);
if(data == read_data){
Serial.println(“Read OK”);
}
else{
Serial.print(“Read fail : “);
Serial.print(data);
Serial.print(“->”);
Serial.print(read_data);
Serial.println(“”);
}
}
int i2cNoWire_read(int address)
{
int data = 0;
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
pinMode(i2cNoWire_sck, INPUT);
pinMode(i2cNoWire_sda, INPUT);
// start bit
while(i2cNoWire_read_sda() ==0){}
i2cNoWire_clear_sda();
delayMicroseconds(i2cNoWire_bit2bit_delay);
i2cNoWire_clear_sck();
int control_byte = (I2C_ADD << 1) & 0xFE;
i2cNoWire_writebyte(control_byte);
// waiting for ACK
if(i2cNoWire_readbit()){
Serial.println(“NO ACK (sending control_byte)”);
return -10;
}
else{
Serial.println(“<< ACK OK >> (sending control_byte)”);
}
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
// send address byte
i2cNoWire_writebyte(address);
if(i2cNoWire_readbit()){//digitalRead(sda) == HIGH){
Serial.println(“NO ACK (sending address_byte)”);
return -20;
}
else{
Serial.println(“<< ACK OK >> (sending address_byte)”);
}
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
// re-start bit
i2cNoWire_read_sda();
delayMicroseconds(i2cNoWire_bit2bit_delay);
while(i2cNoWire_read_sck() == 0){}
delayMicroseconds(i2cNoWire_bit2bit_delay);
while(i2cNoWire_read_sda() == 0){}
i2cNoWire_clear_sda();
delayMicroseconds(i2cNoWire_bit2bit_delay);
i2cNoWire_clear_sck();
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
control_byte = (I2C_ADD << 1) | 0x01;
i2cNoWire_writebyte(control_byte);
if(i2cNoWire_readbit()){
Serial.println(“NO ACK (sending control_byte) in read_test”);
return -30;
}
else{
Serial.println(“<< ACK OK >> (sending control_byte) in read_test”);
}
while(readRDY() == HIGH){} // 適当にタイムアウトを設ける
data = i2cNoWire_readbyte();
i2cNoWire_writebit(LOW);
// stop bit
i2cNoWire_clear_sda();
delayMicroseconds(i2cNoWire_bit2bit_delay);
while(i2cNoWire_read_sck() ==0){}
delayMicroseconds(i2cNoWire_bit2bit_delay);
while(i2cNoWire_read_sda() ==0){}
delayMicroseconds(i2cNoWire_bit2bit_delay);
return data;
}
void i2cNoWire_clear_sck()
{
pinMode(i2cNoWire_sck, OUTPUT);
digitalWrite(i2cNoWire_sck, LOW);
}
int i2cNoWire_read_sck()
{
pinMode(i2cNoWire_sck, INPUT);
return digitalRead(i2cNoWire_sck);
}
void i2cNoWire_clear_sda()
{
pinMode(i2cNoWire_sda, OUTPUT);
digitalWrite(i2cNoWire_sda, LOW);
}
int i2cNoWire_read_sda()
{
pinMode(i2cNoWire_sda, INPUT);
return digitalRead(i2cNoWire_sda);
}
int i2cNoWire_writebit(bool b)
{
if(b){
i2cNoWire_read_sda();
}
else{
i2cNoWire_clear_sda();
}
delayMicroseconds(i2cNoWire_bit2bit_delay);
while(i2cNoWire_read_sck() == 0){}
if(b && i2cNoWire_read_sda() == 0){
return -1;
}
delayMicroseconds(i2cNoWire_bit2bit_delay);
i2cNoWire_clear_sck();
}
int i2cNoWire_writebyte(int data)
{
bool b;
for(int i = 0; i < 8; i++){
b = (data &0x80) != 0;
Serial.print(b);
i2cNoWire_writebit((data &0x80) != 0);
data <<= 1;
}
}
int i2cNoWire_readbit()
{
int b;
i2cNoWire_read_sda();
delayMicroseconds(i2cNoWire_bit2bit_delay);
while(i2cNoWire_read_sck() == 0){}
b = i2cNoWire_read_sda();
delayMicroseconds(i2cNoWire_bit2bit_delay);
i2cNoWire_clear_sck();
return b;
}
int i2cNoWire_readbyte()
{
int bt = 0;
int b = 0;
for(int i = 0; i < 8; i++){
delayMicroseconds(i2cNoWire_bit2bit_delay);
b = i2cNoWire_readbit();
Serial.print(b);
bt = (bt << 1) | (b & 0x01);
}
return bt;
}
int readRDY(){
pinMode(rdy0, INPUT);
digitalWrite(rdy0, HIGH);
return digitalRead(rdy0);
}

