• 検索結果がありません。

2 回路図

N/A
N/A
Protected

Academic year: 2021

シェア "2 回路図"

Copied!
18
0
0

読み込み中.... (全文を見る)

全文

(1)

課題研究報告書

Arduino を使った電子工作(フィーリングカップル)

1. テーマ設定の理由 課題研究を通して、工業祭で展示・実演を行い、学校を盛り上げたいというのが第一の理由で ある。 また、課題研究を通して電子工作などの技術を高めるため、少し難易度の高そうな「フィーリング カップル」というテーマに設定した。 2. 実践内容 (1)制作方法 ① 使用部品・機材 品 名 個数 ノート PC 1 Arduino MEGA 1 抵抗(10kΩ) 10 抵抗(1kΩ) 20 抵抗(300Ω) 10 抵抗(200Ω) 10 抵抗(100Ω) 10 トグルスイッチ 50 パワーMOSFET 2SK2232 10 テープ LED 適量 AC アダプタ(12V) 1 ユニバーサル基板 13

(2)
(3)

③ 制作手順(電子回路部分) 上記回路図のように、ユニバーサル基板を利用して回路を作成する。 そして、木工班の制作した土台へテープ LED を設置し、配線を行って装置の回路部分は 完成となる。 それから、フィーリングカップルの動作に必要なプログラムも制作する。 ④ 制作手順(プログラム部分) Arduino のプログラム作成・書き込み手順 1) Arduino IDE を起動してプログラムを記述する。

2) 「ツール」メニュー → 「ボード」 → 「Arduino Mega or Mega 2560」を選択。 3) 「ツール」メニュー → 「ポート」にて対象の Arduino を選択。 4) 「ファイル」メニュー → 「マイコンボードに書き込む」を選択。 (2)制作物の説明 制作した電子回路では、どのスイッチが ON になっているかを電圧によって判断するため、 Arduino のアナログポートに各スイッチを接続している。 フィーリングカップルの結果発表に利用する LED は、Arduino のデジタルポートからの出力によ って制御し、パワーMOSFET の 2SK2232 を使って AC アダプタから電源供給を行う。 続いて、プログラム部分の説明に移る(ソースコードは非常に長いため別紙参照)。 今回制作したプログラムは2つあり、一つは Arduino 側のプログラムである。 Arduino 側のプログラムでは、スイッチの状態読み取り、LED の制御を行っている。 また、PC とシリアル通信して、結果発表などを PC 上から操作できるようにし、BGM が流れるタイ ミングの制御もしている。 もう一方は PC 側のプログラムで、言語は C#で作成した(図1)。 PC 側のプログラムでは、Arduino とシリアル通信をして、カップルの成立状態の確認、結果発表 の操作を司会側できるようになっている。 図1 PC 側のプログラム

(4)

(3)制作物の評価 スイッチが少し不安定ではあるものの、工業祭で実演にまで至ったため成功といっていいので はないだろうか。 また、限られた時間の中で、当初実現したかった BGM の自動再生・シリアル通信も実装できた ので上出来だと思う。 3. 感想・反省 1 年間課題研究をやってきて、自分で研究することの面白さや難しさ、チームワークの大切さを 学ぶことができた。 反省としては、スイッチの電源が1個であるため、分圧により、抵抗が他のスイッチの電圧まで下 げてしまうために不安定になる所も改善したかった。 具体的な改善策としては、スイッチ毎に電源を取る、アナログポートでなくデジタルポートを利用 して入力するなどで実現できると思う。

(5)

/* Arduino 側のプログラム */

int sw_a[5] = { -1, -1, -1, -1, -1 }; // スイッチ状態記憶用の配列(男側) int sw_b[5] = { -1, -1, -1, -1, -1 }; // スイッチ状態記憶用の配列(女側) int swa_count = sizeof(sw_a) / sizeof(sw_a[0]); // sw_a 配列の要素をカウント int swb_count = sizeof(sw_b) / sizeof(sw_b[0]); // sw_b 配列の要素をカウント void setup() { Serial.begin(57600); // シリアル通信を開始 delay(100); Serial.println(""); Serial.println(".<START>"); // シリアル開始のメッセージ // LED を点灯させるためにデジタルポート 2~11 を出力に設定 for (int port = 2; port <= 11; port++)

{ pinMode(port, OUTPUT); } for (;;) { // シリアルポートにデータが送られている場合 if (Serial.available()) {

int pin = Serial.read(); // データを変数に格納 int state = LOW;

// シリアルポートにデータが送られてくるまでループ for (;;) { // シリアルポートにデータが送られている場合 if (Serial.available()) { state = Serial.read(); // データを変数に格納 break; // ループから抜ける } } // 1 バイト目が 0xFC、2 バイト目が 0xFF だった場合にスイッチの変更を受付終了 if (pin == 0xFC && state == 0xFF)

{

Serial.println("Switch read stop."); break;

(6)

} } // スイッチ判定関数を呼び出し sw_scan(); delay(1200); } //LED 制御コマンド受付 for (;;) { // シリアルポートにデータが送られている場合 if (Serial.available()) {

int pin = Serial.read(); // データを変数に格納 int state = LOW;

// シリアルポートにデータが送られてくるまでループ for (;;) { // シリアルポートにデータが送られている場合 if (Serial.available()) { state = Serial.read(); // データを変数に格納 break; // ループから抜ける } } // 1 バイト~2 バイト目が 0xFE だった場合に LED をすべて消灯 if (pin == 0xFE && state == 0xFE)

{ LedAllOff(); } //カップル非成立の場合 else if (pin == 0xFD) { digitalWrite(state, HIGH);

for (int port = 35; port <= 39; port++) digitalWrite(port, HIGH);

delay(1000);

for (int port = 35; port <= 39; port++) digitalWrite(port, LOW);

(7)

delay(2500); Serial.println(".<BGM>0"); digitalWrite(52, HIGH); delay(4000); LedAllOff(); delay(2000); Serial.println(".<BGM>STOP"); Serial.println(".<BTN_ENABLE>"); } //カップル成立の場合 else { digitalWrite(pin, HIGH);

for (int port = 35; port <= 39; port++) digitalWrite(port, HIGH);

delay(1000);

for (int port = 35; port <= 39; port++) digitalWrite(port, LOW); digitalWrite(state, HIGH); delay(1500); Serial.println(".<BGM>2"); delay(1200); digitalWrite(53, HIGH); delay(17500); LedAllOff(); delay(2000); Serial.println(".<BGM>STOP"); Serial.println(".<BTN_ENABLE>"); } } delay(1);

(8)

} }

/* 全 LED を消灯させる関数 */ void LedAllOff()

{

for (int port = 30; port <= 39; port++) digitalWrite(port, LOW); digitalWrite(52, LOW); digitalWrite(53, LOW); } void loop() { } /* 電圧の値からスイッチを判定する関数 */ int sw_judge(int voltage)

{

if (voltage >= 0 && voltage <= 50) return 0;

else if (voltage >= 400 && voltage <= 515) return 1;

else if (voltage >= 700 && voltage <= 890) return 2;

else if (voltage >= 900 && voltage <= 975) return 3;

else if (voltage >= 976 && voltage <= 996) return 4; else return -1; } /* スイッチの判定結果を配列に格納する関数 */ void sw_scan() { /* アナログポート A0~A[swa_count]までを走査 */ Serial.print(".<A>");

for (int i = 0; i < swa_count; i++) {

int tmp = analogRead(i); sw_a[i] = sw_judge(tmp);

(9)

Serial.print(sw_a[i]); if (i < swa_count - 1) Serial.print("/"); } Serial.println(""); /* アナログポート A[swa_count+1]~A[sw_bcount]までを走査 */ Serial.print(".<B>");

for (int i = 0; i < swb_count; i++) {

int tmp = analogRead(i + swa_count); sw_b[i] = sw_judge(tmp); Serial.print(sw_b[i]); if (i < swb_count - 1) Serial.print("/"); } Serial.println(""); }

(10)

/* PC 側のプログラム(C# + .NET Framework 3.5 使用) */ using System; using System.Drawing; using System.Linq; using System.Windows.Forms; using System.Diagnostics; using System.IO.Ports; using System.Threading; using System.Text.RegularExpressions; using System.Media; namespace FeelingGUI {

public partial class Form1 : Form

{

string[] bgm = new string[] { "29-バツ.wav", "50-選択中.wav", "78-成立.wav" }; SoundPlayer sp = null;

int[] sw_a = null; int[] sw_b = null;

int[] line_a = new int[5]; int[] line_b = new int[5];

int start = 0;

Regex regex = new Regex(@"-?[0-9]");

public Form1() {

InitializeComponent(); }

private void Form1_Load(object sender, EventArgs e) {

//利用可能COM番号を取得

foreach (string port in SerialPort.GetPortNames()) comboBox1.Items.Add(port);

if (comboBox1.Items.Count > 0) comboBox1.SelectedIndex = 0; else

(11)

// シリアルポートの通信速度指定 sp1.BaudRate = 57600;

InitForm(); }

// ボタンなどの初期状態を設定 private void InitForm() {

button2.Enabled = false; button3.Enabled = false; ResultButtonDisable();

button4.ForeColor = Color.Red; button5.ForeColor = Color.Red; button6.ForeColor = Color.Red; button7.ForeColor = Color.Red; button8.ForeColor = Color.Red;

DrawImage(pictureBox1, 0); DrawImage(pictureBox2, 1); DrawImage(pictureBox3, 2); DrawImage(pictureBox4, 3); DrawImage(pictureBox5, 4);

sw_a = new int[] { -1, -1, -1, -1, -1 }; sw_b = new int[] { -1, -1, -1, -1, -1 }; }

// BGMを再生する

private void BGMPlay(string wav) {

sp = new SoundPlayer(wav); sp.PlayLooping();

}

// BGMを停止する private void BGMStop() {

sp.Stop(); }

private void button1_Click(object sender, EventArgs e) {

(12)

sp1.PortName = comboBox1.Text; // ソフトウェアリセットON sp1.DtrEnable = true; // シリアルポートを開く sp1.Open(); if (sp1.IsOpen) { textBox1.Text = comboBox1.Text + "に接続しました。通信まで2秒待機しま す。";

this.Enabled = false; Thread.Sleep(2000); sp1.DtrEnable = false; this.Enabled = true;

this.sp1.DataReceived += new

SerialDataReceivedEventHandler(this.sp1_DataReceived);

textBox1.Text = "シリアル通信を開始します。"; button1.Enabled = false; button2.Enabled = true; button3.Enabled = true; // BGM再生 BGMPlay(bgm[1]); } }

private void button2_Click(object sender, EventArgs e) {

sp1.Close(); if (!sp1.IsOpen) {

this.sp1.DataReceived -= new

SerialDataReceivedEventHandler(this.sp1_DataReceived);

textBox1.Text = sp1.PortName + "を切断しました。"; button1.Enabled = true;

button2.Enabled = false; button3.Enabled = false;

(13)

start = 0; InitForm(); //BGM停止 BGMStop(); } }

private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e) {

// シリアルポートから受け取ったデータを変数に格納

string dat = sp1.ReadLine(); Console.WriteLine(dat); if (start != 0) { // 受け取ったデータによって処理を分岐する // .<A> : 男側のスイッチ状態を読み出して配列に格納 if (dat.IndexOf(".<A>") == 0) { string tmp = dat.Remove(0, 4); string[] tmp_array = tmp.Split('/');

if (tmp_array.Count() == sw_a.Count()) {

for (int i = 0; i < tmp_array.Count(); i++) {

if (regex.IsMatch(tmp_array[i]))

sw_a[i] = Int32.Parse(tmp_array[i]); } } } // .<B> : 女側のスイッチ状態を読み出して配列に格納 else if (dat.IndexOf(".<B>") == 0) { string tmp = dat.Remove(0, 4); string[] tmp_array = tmp.Split('/');

if (tmp_array.Count() == sw_b.Count()) {

for (int i = 0; i < tmp_array.Count(); i++) {

if (regex.IsMatch(tmp_array[i]))

(14)

} }

}

else if (dat.IndexOf(".<BGM>STOP") == 0) BGMStop();

else if (dat.IndexOf(".<BGM>") == 0) {

string tmp = dat.Remove(0, 6); int b = Convert.ToInt32(tmp);

if (regex.IsMatch(tmp)) BGMPlay(bgm[b]); }

else if (dat.IndexOf(".<BTN_ENABLE>") == 0) ResultButtonEnable();

// カップルが成立したかどうかを判定し、表示領域に描画する for (int i = 0; i < sw_a.Count(); i++)

{

for (int j = 0; j < sw_b.Count(); j++) {

if (sw_a[i] == j && sw_b[j] == i && sw_a[i] >= 0 && sw_b[j] >= 0) { line_a[i] = 1; line_b[j] = 1; } } if (i == 0) DrawImage(pictureBox1, i); else if (i == 1) DrawImage(pictureBox2, i); else if (i == 2) DrawImage(pictureBox3, i); else if (i == 3) DrawImage(pictureBox4, i); else if (i == 4) DrawImage(pictureBox5, i); line_a = new int[5];

line_b = new int[5]; }

(15)

}

else if (dat.IndexOf(".<START>") == 0) {

start = 1; }

}

private void button3_Click(object sender, EventArgs e) { ino_sendCommand(0xFC, 0xFF); BGMStop(); button3.Enabled = false; ResultButtonEnable(); } // 表示領域にカップル成立の状態を表示する private void DrawImage(PictureBox p, int id) {

Bitmap bmp = new Bitmap(p.Width, p.Height); Graphics g = Graphics.FromImage(bmp);

g.FillRectangle(Brushes.White, 0, 0, p.Width, p.Height);

g.FillRectangle(Brushes.DarkBlue, 0, 0, p.Width, 16);

g.DrawString((id + 1).ToString(), newFont("MS UI Gothic", 9), Brushes.White,

new Point(2, 2));

for (int i = 0; i < 5; i++) {

g.DrawString((i + 1).ToString(), new Font("MS UI Gothic", 9),

Brushes.Blue, new Point(10 + (32 * i), 20));

g.DrawString((i + 1).ToString(), new Font("MS UI Gothic", 9),

Brushes.Red, new Point(10 + (32 * i), 120));

DrawLine(line_a, i, g, newPoint(15 + (32 * i), 37), newPoint(79, 75)); DrawLine(line_b, i, g, newPoint(15 + (32 * i), 115), newPoint(79, 75)); }

p.Image = bmp; }

(16)

// 線を描く

private void DrawLine(int[] line, int id, Graphics g, Point p0, Point p1) {

if (line[id] == 0)

g.DrawLine(Pens.WhiteSmoke, p0, p1); else

g.DrawLine(Pens.Red, p0, p1); } // 特殊コマンド // FC FF : スイッチの受付終了 // FD xx : xx番の結果発表 // FF xx : delay(0.1秒単位) // 結果発表を行う

private void ViewResult(int id, Button btn) {

int margin = 30; int match = 0;

btn.ForeColor = Color.Black;

ResultButtonDisable();

for (int j = 0; j < sw_b.Count(); j++) {

if (sw_a[id] == j && sw_b[j] == id && sw_a[id] >= 0 && sw_b[j] >= 0) {

match = 1;

byte port = (byte)(id + margin);

byte port2 = (byte)(j + sw_a.Count() + margin); ino_sendCommand(port, port2); } } if (match != 1) {

byte port = (byte)(id + margin);

ResultButtonDisable();

ino_sendCommand((byte)0xFD, port); }

(17)

}

// 結果発表のボタンを無効化する private void ResultButtonDisable() { button4.Enabled = false; button5.Enabled = false; button6.Enabled = false; button7.Enabled = false; button8.Enabled = false; } // 結果発表のボタンを有効化する

private delegate void _DButtonEnabled(Button btn, bool enabled);

private void ResultButtonEnable() {

this.Invoke(new _DButtonEnabled(DButtonEnabled), new object[] { button4,

true });

this.Invoke(new _DButtonEnabled(DButtonEnabled), new object[] { button5,

true });

this.Invoke(new _DButtonEnabled(DButtonEnabled), new object[] { button6,

true });

this.Invoke(new _DButtonEnabled(DButtonEnabled), new object[] { button7,

true });

this.Invoke(new _DButtonEnabled(DButtonEnabled), new object[] { button8,

true }); }

private void DButtonEnabled(Button btn, bool enabled) {

btn.Enabled = enabled; }

//シリアルポートに引数の2バイト送信する

private void ino_sendCommand(byte cmd0, byte cmd1) {

byte[] b = new byte[] { cmd0, cmd1 }; sp1.Write(b, 0, b.GetLength(0)); }

private void button4_Click(object sender, EventArgs e) {

(18)

}

private void button5_Click(object sender, EventArgs e) {

ViewResult(1, (Button)sender); }

private void button6_Click(object sender, EventArgs e) {

ViewResult(2, (Button)sender); }

private void button7_Click(object sender, EventArgs e) {

ViewResult(3, (Button)sender); }

private void button8_Click(object sender, EventArgs e) {

ViewResult(4, (Button)sender); }

private void Form1_FormClosed(object sender, FormClosedEventArgs e) {

BGMStop();

sp1.DataReceived -= new

SerialDataReceivedEventHandler(this.sp1_DataReceived);

if (sp1.IsOpen) sp1.Close(); Application.Exit(); }

private void comboBox1_TextChanged(object sender, EventArgs e) { if (comboBox1.Text.Length != 0) button1.Enabled = true; } } }

参照

関連したドキュメント

2-2 再エネ電力割合の高い電力供給事業者の拡大の誘導 2-3 多様な再エネ電力メニューから選択できる環境の整備

月〜土曜(休・祝日を除く) 9:00 9 :00〜 〜17:00

2-2 再エネ電力割合の高い電力供給事業者の拡大の誘導 2-3 多様な再エネ電力メニューから選択できる環境の整備

図表の記載にあたっては、調査票の選択肢の文言を一部省略している場合がある。省略して いない選択肢は、241 ページからの「第 3

QRされた .ino ファイルを Arduino に‚き1む ことで、 GUI |}した ƒ+どおりに Arduino を/‡((スタンドアローン})させるこ とができます。. 1)

ƒ 、または Arduinoのリセットボタン”oƒ、2 }~x してか らコマンド @2 しま Q*した Arduino す。 プログラムを Arduino に…き:む Äsについては「

*+パラメータを Arduino MICRO マイコンでK!す るためのソフト(ソースコード)を Arduino IDE でコンパイルJなMN ( スケッチ )

二酸化窒素については、 「二酸化窒素の人の健康影響に係る判定条件等について」 (中 央公害対策審議会、昭和 53 年3月 22