Raspberry piにはピンが出ていて、デジタル信号を操作した工作などができるようになっている。ただし、そのピンは基本デジタルであってアナログな信号は直接やり取りできない。アナログ(電圧値など)の入出力をコントロールするならワンチップマイコンの出番なわけだ。ArduinoならばUSB経由でPCと通信できるので、工作するまでもなく、単純にUSBケーブルでつなぐだけでよいのだけれど、それじゃあんまりおもしろくない。てことでワンチップArduinoをRaspberry piのピンヘッダに直接乗っけてやろうと言うことになった。
ワンチップと言いながら、シリアル通信をすることもあり、ある程度精度はほしいのでクリスタルとかコンデンサは最低限つなぐためにユニバーサル基板の切れ端でちょっとしたIOボードを作ってやる。猛者は亀の子のような工作をしたりするがAtMegaを使っている時点である程度の大きさはあるため、実用上は意味はない。
Piの1pinが電源なのでこれをAtmagaの7pinに繋ぎ、6pin→8pin (GND)、9pin→10pF→1pin と1Pin→10kΩ→1pinでリセット回路、後は8pin→1kΩ→2pin、10pin→1kΩ→3pinでシリアル通信。クリスタルは9,10ピンに繋いでやる。10pFコンデンサをそれぞれの足からGNDに落として完成。
Raspberry Piには設定>Add/Remove softwareでArduinoを検索して出てくるIDEを入れてやる。
プログラムの書き込みはシリアルポートを設定してやらないとならない。
シリアルポートはRaspbianの標準ではシリアルコンソールに使う設定となっているので、シリアル通信ポートに設定を変えてやっておく必要がある。
$ sudo raspi-config
で5 Interfacing Option→P6 Serial→No→Yes→Ok→Finish
/etc/rc.localの1. Exit 0の前に
/user/bin/gpio mode 0 alt5
と入れて、11pin をRTS信号に割り付けておく。
今回、AtMega168pに前もってArduinoのファームウェアをインストール済みだったので、そのまま繋ぐとプログラムは動き出す。
Arduino IDEでシリアルポートを指定して、ボードをArduino Diecimila or Duemilanove w/ ATmega168pを選択する。
これでプログラムコンパイル→書き込みしてやればプログラムを即実行できる。
LM35DZを使った温度ロガープログラムの例
#include <TimeLib.h> // These constants won't change. They're used to give names // to the pins used: const int analogInPin = A0; // Analog input pin that the potentiometer is attached to const int ledPin = 13; // the number of the LED pin int sensorValue = 0; // value read from the pot int outputValue = 0; // value output to the PWM (analog out) int ledState = LOW; // ledState used to set the LED long previousMillis = 0; // will store last time LED was updated long interval = 10000; void setup() { // initialize serial communications at 9600 bps: Serial.begin(9600); pinMode(ledPin, OUTPUT); } void loop() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { previousMillis = currentMillis; if (ledState == LOW) ledState = HIGH; else ledState = LOW; digitalWrite(ledPin, ledState); // read the analog in value: sensorValue = analogRead(analogInPin); // map it to the range of the analog out: outputValue = map(sensorValue, 0, 1023, 0, 330); //3.3V駆動としているので330 // change the analog out value: analogWrite(analogOutPin, outputValue); // print the results to the serial monitor: Serial.print(now()); Serial.print("\t sensor = " ); Serial.print(sensorValue); Serial.print("\t temp = "); Serial.println(outputValue); } }
シリアルコンソールを開くと10秒ごとにアナログポートの値とそれを温度変換した数値が表示されるはずだ。
温度計測と同時にLEDがついたり消えたりするので動作も確認できる。
なお、LM35DZを写真のような基板上にはんだ付けしてしまうとATmegaやRaspberry Piの熱の影響がもろに伝わってしまい、常に30度以上になってしまうので、センサーはツイストケーブルとかを使って本体から離したほうがよさそうだ。