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 변수의 내용에 따라 각기 다른 데이터를 전송할 수 있다.
'연구 > Ardpy' 카테고리의 다른 글
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 |