「タイムラプス撮影や長時間露光撮影をしてみたい!」
ということで、この3連休を使ってCanonのタイマーレリーズをマイコンで自作してみました。前々から作ってみようと考えていたので、パーツ類は既に揃っていて、あとは手を動かすだけの状態でした。
「タイムラプス撮影や長時間露光撮影をしてみたい!」
ということで、この3連休を使ってCanonのタイマーレリーズをマイコンで自作してみました。前々から作ってみようと考えていたので、パーツ類は既に揃っていて、あとは手を動かすだけの状態でした。
完成品 |
開発の様子 |
正直なところ,プロコンでマイコンの使い方を間違えてみた(笑)ので,極めて普通に扱うコレは,簡単に出来ました。全く,プロコンの時は本当にハードウェアのバグ(無理なことやったせい)に依存していたなぁ。
僕的には,ハードとソフトを両立させてやってみたかったので,いきなりマイコンに触れてどちらかというと嬉しかったですけどね。(その点で学科も制御か情報で迷ったんです)おかげ様で,今こんな感じで遊べますしw
作業時間:3時間
開発環境:Visual Studio 2010, Arduino IDE 0021
開発言語:C#(.NET Framework 4),Arduino言語
CPU使用率の取得は,.NETの「PerformanceCounterクラス」を使用。
シリアル通信は,同じく.NETの「SerialPortクラス」を使用。
※開発してたら,GUIが横長になってたので「Stick Performance Monitor」なんて名前を付けちゃいました。
ソースコード
適当に作ったので,ソースコードも適当です。
クラスなんて,使う必要が無いよな~。
Arduino側
#define START_PIN 9<br>#define PINS_NUM 10<br><br>byte Connected;<br><br>void setup()<br>{<br> //Open Serial Port<br> Serial.begin(9600);<br><br> //PinMode set OUTPUT<br> for(byte i = START_PIN; i < (START_PIN + PINS_NUM); i++) <br> pinMode(i, OUTPUT);<br><br> Connected = 0; //Not Connected<br>}<br><br>void loop()<br>{<br> if(Serial.available() > 0) {<br> Connected = 1; //Connected<br> updateLED(); //<br> }<br> else if(!Connected) {<br> Blink();<br> }<br>}<br><br>void updateLED()<br>{<br> byte value;<br> //LED All OFF<br> for(byte i = START_PIN; i < (START_PIN + PINS_NUM); i++)<br> digitalWrite(i, LOW);<br><br> value = Serial.read(); //Read data from Serial port<br><br> if(value != 0xFF) {<br> //LED ON<br> for(byte i = START_PIN; i < (START_PIN + value); i++)<br> digitalWrite(i, HIGH);<br> }<br> else Connected = 0; //Disconnected<br><br> delay(100);<br>}<br><br>void Blink()<br>{<br> for(byte i = START_PIN; i < (START_PIN + PINS_NUM); i++) {<br> digitalWrite(i, HIGH);<br> digitalWrite(i + 1, HIGH);<br> delay(75);<br> digitalWrite(i, LOW);<br> delay(75);<br> }<br>}<br>
PC側
using System;<br>using System.Windows.Forms;<br>using System.Diagnostics;<br>using System.IO.Ports;<br><br>namespace PerformanceMonitor<br>{<br> public partial class Form1 : Form<br> {<br> //CPU使用率取得クラス<br> cpuUseage cpu = new cpuUseage();<br><br> //Arduino通信が可能かどうか<br> bool senderAvailable;<br><br> //SerialPortクラス<br> SerialPort serialSender = new SerialPort();<br><br> public Form1()<br> {<br> InitializeComponent();<br> }<br><br> //Formロード<br> private void Form1_Load(object sender, EventArgs e)<br> {<br> //表示の初期化<br> progressBar1.Maximum = 100;<br> progressBar1.Value = 0;<br> timer1.Enabled = true;<br> timer1.Interval = 100;<br> label2.Text = "";<br><br> //シリアル接続部のGUIの初期化<br> formInitialize(false);<br><br> //シリアルポート名を取得<br> string[] serialPortNames = SerialPort.GetPortNames();<br> foreach (string name in serialPortNames)<br> {<br> serialNameList.Items.Add(name);<br> }<br><br> }<br><br> //一定時間ごとの処理<br> private void timer1_Tick(object sender, EventArgs e)<br> {<br> //CPU使用率の取得<br> float value = cpu.getValue();<br> //Arduinoに送信する値<br> byte[] ledLevel = new byte[1];<br><br> //GUI表示<br> progressBar1.Value = (int)value;<br> label2.Text = (value / 100).ToString("P1");<br><br> //Arduino送信部<br> if (senderAvailable)<br> {<br> //0-10の11段階に分ける<br> //その際,小数点以下は切り上げる<br> ledLevel[0] = (byte)(Math.Floor((double)value / 10.0));<br> //送信<br> serialSender.Write(ledLevel, 0, 1);<br> //System.Diagnostics.Trace.WriteLine(Math.Floor((double)value / 10.0));<br> }<br> }<br><br> //接続ボタンクリック<br> private void connectButton_Click(object sender, EventArgs e)<br> {<br> //<br> if (!senderAvailable)<br> {<br> //未接続の場合→接続処理<br> if (serialNameList.SelectedItem != null)<br> {<br> //ポート名が選択されている場合<br><br> //serialSender初期化<br> serialSender = new SerialPort(serialNameList.SelectedItem.ToString(), 9600, Parity.None, 8, StopBits.One);<br><br> try<br> {<br> //接続開始<br> serialSender.Open();<br> //接続状態に<br> formInitialize(true);<br> }<br> catch(Exception exp)<br> {<br> //エラー発生<br> //未接続状態へ移行<br> formInitialize(false);<br> //エラーメッセージの表示<br> MessageBox.Show(exp.Message);<br> }<br><br> }<br> }<br> else<br> {<br> byte[] i = new byte[1];<br> i[0] = (byte)0xFF;<br> serialSender.Write(i, 0, 1);<br> //接続している場合→切断処理<br> serialSender.Close();<br> //未接続状態へ移行<br> formInitialize(false);<br> }<br> }<br><br> private void formInitialize(bool connected)<br> {<br> if (!connected)<br> {<br> /* 接続されていないとき */<br> serialNameList.Enabled = true;<br> connectButton.Enabled = true;<br> connectButton.Text = "Connect";<br> senderAvailable = false;<br> }<br> else<br> {<br> /* 接続されているとき */<br> serialNameList.Enabled = false;<br> connectButton.Text = "Disconnect";<br> senderAvailable = true;<br> }<br> }<br><br> private void Form1_FormClosing(object sender, FormClosingEventArgs e)<br> {<br> if (senderAvailable)<br> {<br> byte[] i = new byte[1];<br> i[0] = (byte)0xFF;<br> serialSender.Write(i, 0, 1);<br> //接続している場合→切断処理<br> serialSender.Close();<br> //未接続状態へ移行<br> formInitialize(false);<br> }<br> }<br><br> }<br><br> class cpuUseage<br> {<br> PerformanceCounter pc = new PerformanceCounter();<br><br> public cpuUseage()<br> {<br> pc.CategoryName = "Processor";<br> pc.CounterName = "% Processor Time";<br> pc.InstanceName = "_Total";<br> pc.NextValue();<br> }<br><br> public float getValue()<br> {<br> return pc.NextValue();<br> }<br> }<br>}<br>