ArduinoをADコンバータやサーボドライバとして働いてもらうには、I2C接続がよいと考えた。
実際やってみると、いろいろと下準備が必要だったので、整理してみる。
IMG_3836

下準備

  1. Arduinoのプログラミング
  2. 回路
  3. Raspberry PiのI2Cセットアップ
  4. Raspberry Piのパッケージのインストール
  5. Raspberry Piのプログラミング

Arduinoのプログラミング

#include <Wire.h>

int SLAVE_ADDRESS = 0x04; //I2Cのアドレスを0x04に設定
int ledPin = 13;
int analogPin = A0;

boolean ledOn = false; //LEDの点灯制御用

void setup(){
  pinMode(ledPin, OUTPUT);

//I2C接続を開始する 
  Wire.begin(SLAVE_ADDRESS);

//Raspberry Piから何かを受け取るたび、processMessage関数を呼び出す 
  Wire.onReceive(processMessage); 

//Raspberry Piから要求された場合に、sendAnalogReading関数を呼び出す 
  Wire.onRequest(sendAnalogReading);
}

void loop(){
}

void processMessage(int n){
 char ch = Wire.read();
 if (ch == '1'){
  toggleLED(); 
 }
}

//LEDの点灯・消灯用の関数
void toggleLED(){
  ledOn = !ledOn; //trueとfalseの入れ替え
  digitalWrite(ledPin, ledOn);  
}

//Analogピンの数値を読み、Raspberry Piに送る
void sendAnalogReading(){
  int reading = analogRead(analogPin);
  Wire.write(reading >> 2); //ビットを2つ右にずらした数値を送る(4で割った数値)
}

最後のほうで、ビット演算子を使って、数値を4で割っているが、数値を1byteに収める目的でやっている。

回路

キャプチャ

Arduinoとラズパイの SDA SCL をつなぎます。
SDAはSDAに、SCLはSCLです。
それから、GND同士もつなぎます。

Arduinoとラズパイの電源は、別々でも構いませんが
わたしは、ラズパイの5VをArduinoに供給する方法を選びました。
(つないだ瞬間ラズパイが再起動して驚いたけど)

ラズパイのI2Cセットアップ

ターミナルで
sudo nano /etc/modules
を実行し、次の記述を末尾に追加する。

i2c-bcm2708
i2c-dev  

それから、
sudo nano /etc/modprobe.d/raspi-blacklist.conf
も実行し、

blacklist i2c-bcm2708

と記述されていた場合は、

#blacklist i2c-bcm2708

へ変更する。

パッケージのインストール

Raspberry Piのプログラミングで必要となるsmbusというパッケージをインストールする
sudo apt-get install i2c-tools python-smbus
これで、プログラミングの下準備は完了

Raspberry Piのプログラミング

import smbus
import time

bus = smbus.SMBus(1)

SLAVE_ADDRESS = 0x04

def request_reading():
    reading = int(bus.read_byte(SLAVE_ADDRESS))
    print(reading)

while True:
    command = raw_input("Enter command: 1-Toggle LED, r-read A0:")
    if command == '1':
        bus.write_byte(SLAVE_ADDRESS, ord('1'))
    elif command == 'r':
        request_reading()

1行目は、先ほどインストールしたsmbusをimport
2行目はtimeのimport(importする意味はあるのかな?本の通りにやったから…)

4行目のbus = ... はI2C通信をするための初期化命令、変数busを色々使っていきます。

6行目の変数SLAVE_ADDRESSには、Arduinoに設定したI2Cアドレスと同じものを入れます。

8行目から、関数の定義。(ArduinoのA0ピンの数値を読む)
bus.read_byte(SLAVE_ADDRESS)でArduinoのonRequestが呼び出される。
その結果が変数readingに入る。
print命令で、Python Shellに結果が表示される。

12行目からメインループ。
Python shell上で、ユーザーのコマンド入力を待つ。
1と入力されたら、ArduinoのLEDを点灯あるいは消灯させる。
rと入力されたら、関数request_readingを呼び出す。つまりArudinoのA0を読む。

IMG_3838
実行すると、shell上で青字でコマンド入力を待つプロンプトが表示される。

これをもう少し発展させていけば、サーボドライバ化できそう。

参考書籍

Raspberry Piクックブック (Make:PROJECTS) - Amazon  


Raspberry Piで学ぶ電子工作 超小型コンピュータで電子回路を制御する (ブルーバックス) - Amazon