もろもろ
備忘まで。
wiringPi
以下、中身確認の方向。
- git://git.drogon.net/wiringPi
arduino アナログ入力な確認
とりあえず値がシリアル経由で取り出せれば OK な方向。これから確認着手。
まず、うぶんつ号に arduino パケジ導入。
$ sudo apt-get install arduino
で、開発ツールを Applications Menu から起動。とりあえず xyz な値が取れてるのかどうかを確認してみます。
で、とりあえず加速度センサを接続して云々してたのですがよく分からないのでとりあえずl Hello World なソレを仕込んでみました。
void setup() { Serial.begin(9600); } void loop() { Serial.println("Hello World"); delay(1000); }
Tools -> Serial Monitor ではハロワなソレが 1 秒ごとに、というのが確認できます。ええと、以下なソレを使ってるんですが Serial Monitor では値は確認できんのか。
const int accel_pin[] = { 0, 1, 2 }; int accel_val[] = { 0, 0, 0 }; void setup() { Serial.begin(9600); } void loop() { byte buffer[2]; for (int i = 0; i < 3; i++) { accel_val[i] = analogRead(accel_pin[i]); } for (int i = 0; i < 3; i++) { buffer[0] = byte(accel_val[i]); buffer[1] = byte(accel_val[i] >> 8); Serial.write(buffer, 2); } delay(1000); }
デバイス壊したのかな、と思ったのですがとりあえず arduino は生きてるのか。上記ですが、シリアルデバイスから int を読みだして云々なプログラムが必要らしい。一応上記プログラムの出力は Serial Monitor から確認できるんですが豆腐。
これって fgets で sscanf で読める形にするのであれば Serial.println しないと、なのかな。
あら
つうか /dev/ttyACM0 からハロワな出力を確認していない事に気づくもなかなか出力できず。
以下で、との事で試験してみたのですが
$ stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr \n -isig -icanon -iexten -echo -echo3 -echok -echoctl -echoke noflsh -ixon -crtscts
tail -f で確認できました。
$ tail -f /dev/ttyACM0 tail: inotify resources exhausted tail: inotify canoot be used, reverting to polling Hello World Hello World Hello World Hello World Hello World Hello World Hello World
でもこれ、普通に fgets するプログラムからだと読みこめんな。つーかそもそも一般ユーザアカウントが
$ grep dial /etc/group dialout:x:20:rms
ってなってるのに
$ ls -l /dev/ttyACM0 crw-rw---- 1 root dialout 166, 0 Jul 28 15:05 /dev/ttyACM0 $ tail -f /dev/ttyACM0 tail: cannot open `/dev/ttyACM0' for reading: Permission denied
て何なのか。あるいは以下なソレをでっちあげて
#!/usr/bin/env ruby require 'rubygems' require 'serialport' port_str = "/dev/ttyACM0" baud_rate = 9600 data_bits = 8 stop_bits = 1 parity = SerialPort::NONE sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity) while true do while (i = sp.gets.chomp) do puts i end end sp.close
動かしてみたのですが動作微妙。
$ chmod a+x test.rb $ ./test.rb He ./test.rb:17:in `<main>':undefined method `chomp' for nil:NilClass (NoMethodError)
ぐぬ。いちおう tail -f では何らかの出力は確認できます。chomp 取ったら以下。
Hel lo Worl d Hell o Wo rld He llo Worl d Hell o Wo rld
これはこれで使いモノにならぬな。tail -f は正常動作してるのでデバイスが壊れている訳ではないはず。でも stty してない端末だと tail な出力はだんまり状態。ちなみに ruby なソレは同じ形で出力されますね。これは一体何なんだろう。
baud rait?
ええと、115200 にしてみたら少しマトモになりました。成程。とりあえずこれで arduino と Linux 間のソレは目処ができました。次はセンサからもらった値をシリアル経由でどう取得するか、なのか。
本当は以下なソレを
buffer[0] = byte(accel_val[i]); buffer[1] = byte(accel_val[i] >> 8); Serial.write(buffer, 2);
文字列にして渡したいのだけれど。つうか角度まで求めてからそれを文字列にしないとアレですね。角度を求めるスケッチを以下に控え。
const int xAxisPin = 0; const int yAxisPin = 1; const int zAxisPin = 2; void setup() { } void loop() { int xAxisValue = analogRead(xAxisPin); int yAxisValue = analogRead(yAxisPin); int zAxisValue = analogRead(zAxisPin); float xAxisSinTheta = mapInFloat(xAxisValue, 306, 716, -1, 1); float yAxisSinTheta = mapInFloat(yAxisValue, 306, 716, -1, 1); float zAxisSinTheta = mapInFloat(zAxisValue, 306, 716, -1, 1); xAxisSinTheta = constrain(xAxisSinTheta, -1, 1); yAxisSinTheta = constrain(yAxisSinTheta, -1, 1); zAxisSinTheta = constrain(zAxisSinTheta, -1, 1); int xAxisTilt = floor(asin(xAxisSinTheta) * 180 / PI); int yAxisTilt = floor(asin(yAxisSinTheta) * 180 / PI); int zAxisTilt = floor(asin(zAxisSinTheta) * 180 / PI); String x = String(xAxisTilt); String y = String(yAxisTilt); String z = String(zAxisTilt); } float mapInFloat(float x, float iMin, float iMax, float oMin, float oMax) { return (x - iMin) * (oMax - oMin) / (iMax - iMin) + oMin; }
で、それぞれを comma 区切りでシリアル方面に出力すれば良いのかな。あと、関数作れるのであれば以下なソレが良いですね。
const int xAxisPin = 0; const int yAxisPin = 1; const int zAxisPin = 2; void setup() { Serial.begin(115200); } void loop() { String x = String(retAxisTilt(analogRead(xAxisPin))); String y = String(retAxisTilt(analogRead(yAxisPin))); String z = String(retAxisTilt(analogRead(zAxisPin))); String msg = "x : "; msg.concat(x); msg.concat(", y : "); msg.concat(y); msg.concat(", z : "); msg.concat(z); Serial.println(msg); delay(1000); } int retAxisTilt(int AxisValue) { float AxisSinTheta = mapInFloat(AxisValue, 306, 716, -1, 1); AxisSinTheta = constrain(AxisSinTheta, -1, 1); return floor(asin(xAxisSinTheta) * 180 / PI); } float mapInFloat(float x, float iMin, float iMax, float oMin, float oMax) { return (x - iMin) * (oMax - oMin) / (iMax - iMin) + oMin; }
で、ruby なプログラムでも文字列取得できてますね。
x : 9, y : -4, z : 90 x : 8, y : -4, z : 90 x : 8, y : -4, z : 90 x : 9, y : -4, z : 90 x : 8, y : -4, z : 90
みたいなカンジ。
問題は
これをどう自由研究な課題にするか、だな (ぇ
つーか
文字列の長さを短くすると出力安定したりするのかな。
String msg = ""; msg.concat(x); msg.concat(","); msg.concat(y); msg.concat(","); msg.concat(z);
これも関数にしたい。とりあえずエラー率 (?) は下がってそげ。
とりあえず、
これを RasPi に接続するとどうなるか、を確認してみます。て、rbenv 入れるとこから、なのか。これはこれは。
で、1.9.3-p448 を導入なう、なのですが、これっていつ終わるのかな。あと 15 分でヤマトが始まろうとしております。わはは。あと晩メシも作らなきゃ、なんですが。