もろもろ

備忘まで。

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 にしてみたら少しマトモになりました。成程。とりあえずこれで arduinoLinux 間のソレは目処ができました。次はセンサからもらった値をシリアル経由でどう取得するか、なのか。
本当は以下なソレを

    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 分でヤマトが始まろうとしております。わはは。あと晩メシも作らなきゃ、なんですが。

以下

結線の図、です。
kxm52-1050