i2c에서 통신은 프로토콜 특성상 항상 마스터에서 요구하며. 마스터에서 전송할 때도 그렇고 슬레이브에서 읽어올 때도 마스터에서 먼저 요구하면 슬레이브에서 그 요구를 받아서 데이터를 전송한다.


 아두이노의 Wire라이브러리를 이용하면 Wire.onReceive() 함수와 Wire.onRequest() 함수를 이용하여 핸들러 함수를 등록해야 한다.


Wire.onReceive( _onReceive ); #데이터를 받는다.
Wire.onRequest( _onRequest ); #데이터를 보낸다.

smbus의 관련함수들은 다음과 같다.


read_i2c_block_data(addr, cmd [, length] )
write_i2c_block_data(addr, cmd, lst)

smbus의 write_2ic_block_data() 함수는 다음과 같이 데이터를 전송하기 위해서 _onReceive()함수를 호출하게 된다. 전송되는 데이터의 첫 바이트가 cmd라는 것을 유의해야 한다. _onReceive( len)함수의 인수도 cmd까지 고려한 길이가 인수로 넘어간다.


cmd

lst[0]

lst[1]

...

lst[-1]


 그런데 smbus의 read_2ic_block_data()함수는 cmd 한 바이트를 먼저 전송한 후 데이터를 읽는다. 즉, 실제 동작은 _onReceive()함수가 먼저 호출되고 그 다음 _onRequest()함수를 호출한다. 따라서 예를 들면 아두이노의 핸들러 함수는 다음과 같이 작성해야 한다.


byte _cmd_i2c;
byte _rcvBuf[32];

void _onReceive(int count) {
   _cmd_i2c = Wire.read(); // 첫 바이트는 *항상* command

   //만약 smbus.read_i2c_block_data()호출이라면 여기서 종료되고
   //바로 _onRequest() 함수가 호출된다.
   if (count > 1) {
       _rcvBuf[0] = _cmd_i2c;
       _idx = 1;
       while(Wire.available())
           _rcvBuf[_idx++] = Wire.read();
   }
}

void _HRP_::_onRequest() {
   switch(_cmd_i2c) {
       // _cmd_i2c 에 따라 해당 데이터를 전
   }
}

위와 같이 작성하면 master에서 전송된 데이터는 command까지 포함해서 모두 _rcvBuf 배열에 저장되고 데이터를 전송하는 경우에는 _cmd_i2c 변수의 내용에 따라 각기 다른 데이터를 전송할 수 있다.

n{rp005}


'연구 > Ardpy' 카테고리의 다른 글

python3-smbus 와 아두이노간 통신 동작  (0) 2016.10.25
Ardpy API reference  (0) 2016.10.23
Ardpy examples  (0) 2016.10.23
Ardpy setup  (0) 2016.10.23
About Ardpy  (0) 2016.10.23
ardpy 개발 동기  (0) 2016.05.02
Posted by 살레시오

댓글을 달아 주세요