mixture-art@Q
技術+アイディア+世俗+なんとなく思ったこと、すべての融合がmixture-art
Arduino用I2C通信のオリジナルライブラリ(サンプルコード)

諸事情あって自力で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);
}

 


Tags: