Scratch Boardを作る
2017/1/4 スケッチ、試験プログラムを3.02に更新しました。
Scratch上から色々なセンサーの情報を取込むためのScratch Boardがありますが、規定以外のセンサーを接続するのは難しいために、非標準のセンサーを接続できる同等機能のボードの作成します。
日本で入手可能なScratch Boardが「日本で買えるScratchセンサーボード」で紹介されています、また「Scratch Boardの仕様」についても紹介されています。
この中で「ちっちゃいものくらぶ」の「NanoBoardAG」がファームウェアも公開されており改造できそうです、また「スイッチサイエンス」の猫の形で可愛らしい「nekoboard2」も同様に公開されていますが、ファームウェアの改変は非推奨(ISP端子から書換えられる?)のようです。
どちらも安価ですが、現状のMUGBOT/Fabbotは、既にRaspberry PiとArduinoを使用しており、更にマイコンボードを追加して豪華な構成になるのは避けたいところです。
そのために、現行のMUGBOT/Fabbotに使われているArduino上に組込み、超音波距離センサーの計測値をScratch上で読取れることを目標にします。
使用するセンサーに応じてスケッチを変更することができますので、ちょっと変わったセンサーを使用してMUGBOT/Fabbotが操作者からの応答を受取ることができるようになります。
押しボタンスイッチなどとは違ったセンサーで操作者と対話形式のScratchプログラムを作るのも楽しいと思います。
注意)筆者はScratchには習熟していないために、ここで書かれた方法以外にスマートな方法があるかも知れません・・
接続図(今回追加するセンサーの接続だけを図示)
Scratchプログラムの例:
スケッチ:
[mugbot_arduino_2.ino]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <Servo.h> //Mugbot Project Tokyo City University Koike Lab. 2016 //Mugbot System ver. 1.1 // Goji 2.00 - PicoBoard compatible #include <SoftwareSerial.h> SoftwareSerial SSerial(12, 13); // RX, TX /* * */ // Goji 2.00 - PicoBoard compatible #define neko3_TICK 25 unsigned long cal_millis; void SS_delay(int n) { unsigned long now_millis = millis(); unsigned long new_millis = now_millis; while ((new_millis + n) > (cal_millis + neko3_TICK)) { neko3_loop(); new_millis = millis(); if ((new_millis + 10) > (now_millis + n)) break; } new_millis = millis(); if ((now_millis + n) > new_millis) delay((now_millis + n) - new_millis); } void setup() { // Goji 2.00 - PicoBoard compatible neko3_setup(); // for neko3 // for neko3 Setup SSerial.begin( 9600); // for xxxBOT // use Software Serial /* * */ } void loop() { // Goji 2.00 - PicoBoard compatible neko3_loop(); // use Software Serial if (SSerial.available() > 0) { char ch = SSerial.read(); /* * */ SS_delay( 100 ); // Change all delay() -> SS_delay() /* * */ } } |
[neko3.ino]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
// neko3 - Goji /* ver 1.00 2016/12/26 Alpha version ver 2.00 2016/12/27 for xxxBOT Arduino */ #define SSENSOR #define PORT_A 1 // Analog port #define PORT_D 2 // Digital port #define PORT_S 4 // Sensor #define MAX_TBL 9 #define PORT_TAB(ch, ad, p0, p1) ((ch << 12)|(ad << 8)|(p0 << 4)|(p1)) const unsigned int resTbl[MAX_TBL] = { PORT_TAB(15, 0, 4, 0), // Firmware ID = 4 PORT_TAB( 0, PORT_S, 9, 3), // Pulse (D9), LED(D3) D Left PORT_TAB( 1, PORT_S, 10, 5), // Pulse (D10), LED(D5) C Right PORT_TAB( 2, PORT_A, 2, 0), // Analog (A2) B PORT_TAB( 3, PORT_D, 7, 0), // Digital(D7) (0x3FF or 0x000) PORT_TAB( 4, PORT_A, 3, 0), // Analog (A3) A PORT_TAB( 5, PORT_A, 4, 0), // Analog (A4) Light PORT_TAB( 6, PORT_A, 5, 0), // Analog (A5) Mic #ifdef ARDUINO_AVR_NANO PORT_TAB( 7, PORT_A, 6, 0), // Analog (A6) Slider for Nano #else PORT_TAB( 7, PORT_A, 4, 0), // Analog (A4) Slider #endif }; unsigned int resVal[MAX_TBL] = { 0xF804 }; // Firmware ID = 4 #ifdef ARDUINO_AVR_NANO const int analogPin[] = { A0, A1, A2, A3, A4, A5, A6, A7 }; #else const int analogPin[] = { A0, A1, A2, A3, A4, A5 }; #endif #define SS_TABn 1 #define SS_VALs 6 int ss_vals[2][SS_VALs]; int ss_valp = 0; int neko3_pass = 0; int getDistance(int pinNo) { pinMode(pinNo, OUTPUT); digitalWrite(pinNo, LOW); delayMicroseconds( 5); digitalWrite(pinNo, HIGH); delayMicroseconds(20); digitalWrite(pinNo, LOW); pinMode(pinNo, INPUT); unsigned long dist = pulseIn(pinNo, HIGH, (unsigned long)(40000)); return (dist / 58); } void neko3_setup() { Serial.begin(38400); for (int i = 1; i < MAX_TBL; i++) { int portAD = (resTbl[i] & 0x0F00) >> 8; int portNo = (resTbl[i] & 0x00F0) >> 4; int portSS = (resTbl[i] & 0x000F); if (portAD) { if (portAD == PORT_A || portAD == PORT_D) pinMode(((portAD == PORT_A) ? analogPin[portNo] : portNo), INPUT); if (portAD == PORT_D) digitalWrite(portNo, HIGH); if (portAD == PORT_S) pinMode(portSS, OUTPUT); } } } void neko3_loop () { int n, vals, valw; if ((Serial.available() > 0) && (Serial.read() == 0x01)) { cal_millis = millis(); for (int i = 0; i < MAX_TBL; i++) { Serial.write(resVal[i] >> 8); delay(1); Serial.write(resVal[i] & 0xFF); } for (int i = 1; i < MAX_TBL; i++) { int portAD = (resTbl[i] & 0x0F00) >> 8; int portNo = (resTbl[i] & 0x00F0) >> 4; switch (portAD) { case PORT_D: vals = ((digitalRead(portNo) == 0) ? : (1024 - 1)); break; case PORT_A: vals = (1024 - 1) - analogRead(portNo); break; case PORT_S: if ((i - SS_TABn) != neko3_pass) continue; vals = getDistance(portNo); if ((vals == 0) || (vals > 102)) vals = 102; ss_vals[i - SS_TABn][ss_valp] = vals; if ((i - SS_TABn) == 1) if (++ss_valp >= SS_VALs) ss_valp = 0; for (n = 0, valw = 0; n < SS_VALs; valw += ss_vals[i - SS_TABn][n++]); vals = valw / SS_VALs; analogWrite((resTbl[i]&0x000F), (vals>80)?0:((vals<25)?255:12)); vals *= 10; break; } resVal[i] = 0x8000|((resTbl[i]&0xF000)>>1)|((vals&0x0380)<<1)|(vals&0x007F); } if (++neko3_pass > 1) neko3_pass = 0; } } |
動作確認Scratchプログラム:
*ScratchのコードはMAD(Mugbot Action Designer)上で動作します。
*Scratchのコードは試験用で完成度は低いです( ̄ー ̄; ヒヤリ
- MUGBOTは東京都市大学 メディア情報学部社会メディア学科 小池情報デザイン研究室で作られたソーシャルロボットです。
- FabbotはMUGBOTをベースにファブラボ関内で作られた簡単ロボットキットです。
- MAD(Mugbot Action Designer)は、MUGBOTを制御できるようにカスタマイズされたScratchです。
MADは山梨英和大学の杉浦学先生の著作物です。
この記事へのトラックバック URL :
Leave a comment