加速度計で遊ぶその2

さすがにシリアルコンソールに数字が表示されるだけでは寂しいので、ちょっと改造をした。
Arduino側をまずバイナリーで出力するようにする。


void loop()
{
for(count = 0; count < 3; count++)
{
SensorOutputADC[ count ] = analogRead( inputAnalogPin[ count ] );
byteOutput[ count] = map(SensorOutputADC[ count ], 0, 1023, 0, 255);
}
//
Serial.write(byteOutput, 3);
//
delay(100);
}
次にPC側でシリアルを受信する独自のアプリを作る。
これでフォームに配置したlabelX, labelY, labelZに加速度計の値が0-255の範囲で出力され、さらにフォームに配置したpictureBoxResult内で加速度計の動きに合わせてボールが弾むようになる。

namespace ArduinoAccelerometer
{
public partial class Form1 : Form
{
int ball_x, ball_y;
int ball_dx, ball_dy;
int AccelerometerOffsetX, AccelerometerOffsetY;
int SizeOfBall = 10;
bool isInitialized;
static int SerialDataOffsetX = 0;
static int SerialDataOffsetY = 1;
static int SerialDataOffsetZ = 2;

public Form1()
{
InitializeComponent();
//
openSerialport();
// initial ball position and speed
ball_x = pictureBoxResult.Width / 2;
ball_y = pictureBoxResult.Height / 2;
ball_dx = 0;
ball_dy = 0;
//
isInitialized = false;
AccelerometerOffsetX = 0;
AccelerometerOffsetY = 0;
}

void openSerialport()
{
serialPortArduino.PortName = "COM3";
serialPortArduino.BaudRate = 9600;
serialPortArduino.DataBits = 8;
serialPortArduino.Parity = System.IO.Ports.Parity.None;
serialPortArduino.StopBits = System.IO.Ports.StopBits.One;
serialPortArduino.Handshake = System.IO.Ports.Handshake.None;
serialPortArduino.Open();
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
serialPortArduino.Close();
}

private void onDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
DelegateUpdateLabel delegateUpdateLabel = new DelegateUpdateLabel(updateLabels);
int ReadByteSize = serialPortArduino.BytesToRead;
byte[] ReadBuffer = new byte[4096];
serialPortArduino.Read(ReadBuffer, 0, ReadByteSize);
if (ReadByteSize == 3) this.Invoke(delegateUpdateLabel, ReadBuffer);
}

delegate void DelegateUpdateLabel(byte[] values);

void updateLabels(byte[] serialInputValues)
{
// Accelerometer Offset initialization only once
if (!isInitialized)
{
AccelerometerOffsetX = serialInputValues[SerialDataOffsetX];
AccelerometerOffsetY = serialInputValues[SerialDataOffsetY];
isInitialized = true;
}
//
labelX.Text = string.Format("X= {0}", serialInputValues[SerialDataOffsetX]);
labelY.Text = string.Format("Y= {0}", serialInputValues[SerialDataOffsetY]);
labelZ.Text = string.Format("Z= {0}", serialInputValues[SerialDataOffsetZ]);
ball_dx += -(serialInputValues[SerialDataOffsetX] - AccelerometerOffsetX);
ball_dy += (serialInputValues[SerialDataOffsetY] - AccelerometerOffsetY);
ball_x += ball_dx;
ball_y += ball_dy;
if (ball_x < 0)
{
ball_dx = -ball_dx;
ball_x = 0;
}
if (ball_x > pictureBoxResult.Width)
{
ball_dx = -ball_dx;
ball_x = pictureBoxResult.Width;
}
if (ball_y < 0)
{
ball_dy = -ball_dy;
ball_y = 0;
}
if (ball_y > pictureBoxResult.Height)
{
ball_dy = -ball_dy;
ball_y = pictureBoxResult.Height;
}
Invalidate();
}

private void onPaint(object sender, PaintEventArgs e)
{
Bitmap bmpPictureBoxResult = new Bitmap(pictureBoxResult.Width, pictureBoxResult.Height);
Graphics gfx = Graphics.FromImage(bmpPictureBoxResult);
gfx.DrawEllipse(Pens.Black, ball_x - SizeOfBall / 2, ball_y - SizeOfBall / 2, SizeOfBall, SizeOfBall);
pictureBoxResult.Image = bmpPictureBoxResult;
gfx.Dispose();
}

}
}

Arduino Uno Rev3

Arduino Uno Rev3

(実際にはこのキットではない、日本で手に入らないキットで、ADXL335の他、LCDポテンショメータ、ロータリーエンコーダなどがついている)