2016年9月13日火曜日

ルネサスナイトの教育効果について

ルネサスナイトは、GRボード(ルネサス社マイコン製品を搭載したボードで電子部品ベンダーと連携し販売)を活用した作品を、4分間のライトニングトークで発表するイベントである。人気投票で上位者にはルネサス社から豪華賞品が提供される。また、ライトニングトークセッションとセットで、新製品ハンズオンセミナーや参加者懇親会のイベントも開催され楽しく有用なイベントである。

このGRボードは、ボビィエストや学生の間で人気のあるArduinoボードと互換だが、圧倒的に高機能で使い勝手が良い。顧問をしているロボットサークルでも、学生は自分の作品製作にGR-SAKURAやGR-KURUMIなどのGRボードを活用している。下記にロボットサークルの作品を紹介する。

GR-SAKURAを使ったディスプレイ

GR-KURUMIを使ったオセロゲーム
さて、ルネサス社GRボードを使用する理由はボード機能だけではない。顧問としてロボットサークルを指導する上で、下記の3つのことを心掛けている。
  1. 自分で調べて作り、問題・課題点はメンバーと議論する。
  2. 途中で投げ出さず、とにかく作品に仕上げる。
  3. 自分の作った作品の優位点・課題をしっかり説明できる。
こういったエンジニアマインドを育ててゆく上で、「ルネサスナイト」は非常に有効である。ルネサスナトの前半部は新製品ボード紹介やハンズオンセミナーである。これから製品化されるボードをていねいに説明してくれる。このボードは試作品で、ユーザーフィードバックを得るために無料で提供される場合が多い。セミナーで使ったボードはそのまま持ち帰れるので、学生は家に帰ってすぐに作品制作に取り掛かれる。技術のスキルアップや金銭面からも、学生にとってはこの上なくありがたいセッションである。
ハンズオンセミナー参加風景
そしてルネサスナイトの後半部がライトニングトークである。ここでは見学参加もプレゼン参加も可能である。プレゼン参加の場合、期日までにデモできる作品を仕上げる必要がある。これは指導目標②の訓練にはうってつけである。サークルメンバーはみな、どのような作品に仕上げどう見せるか時間と自分のスキルが試される。
作品制作風景
ライトニングトークには小学生も参加し優勝することもある。発表作品は技術だけではなく、オリジナリティや楽しさ・面白さがポイントとなる。サークルの学生たちは技術面で自信を無くしたりすることも多いが、小学生がたびたび入賞するのを見て、オリジナリティや発想の重要性に気づかされる。ライトニングトークは4分間という短い時間で終了する。4分経過と同時に、マイクが切れプレゼンが強制終了となる。4分間のプレゼンに作品の魅力を伝えデモを行う必要がるので、プレゼン資料の修正や発表練習を繰り返す。これは指導目標③の訓練となる。
ライトニングトーク発表練習
ルネサスナイトは、大勢の場で自分の作品発表する貴重な機会で、見事に入賞を勝ち取るとうれしさも人一倍である。


以上のことから、ルネサスナイトは学生の技術スキルアップ、課題や納期に対する開発方法の組立て方、自分の実力や作品を100%伝えるプレゼンテーション力の訓練に大いに役立っている。また、こういった経験や実績が学生のキャリアプラン・就職活動にも役立っている。

実際、今年度ロボットサークルの4年生が大手電子部品商社に内定した。最終面接では自己PRとして、ロボットサークルで開発した作品デモと1ページの自己PR資料を手渡し、しっかり時間内で自己PRができたそうだ。下記はその自己PR資料です。

自己PR資料(表上段)
自己PR資料(表下段)
自己PR資料(裏上段)
自己PR資料(裏下段)








2016年4月7日木曜日

ラッチ型スイッチでLEDをオン・オフ

Multi-function ShieldのLED1とプッシュスイッチSW1を使って簡単なプログラムを作ってみましょう。

1.スイッチSW1とLED1の接続関係
LED D1~D4は、Arduinoボードの13ピンから10ピンに接続されています。ピン10~13にLOWが出力されるとLED D4~D1がオンする接続になっています。
またスイッチS1~S3はArduinoボードのA1ピンからA3ピンに接続されています。スイッチをオンするとLOW(アナログ値:0)を読み、オフのするとHIGH(アナログ値:1023)を読みます。デジタルまたはアナログのどちらでも読み取ることができますが、今回はデジタルで読むことにします。



2.スイッチを押すとLEDがオンし離すとオフするプログラム
スイッチS1を押している時だけLED D1がオンし、スイッチを離すとLEDはオフします。その様子が下記のビデオです。

下記がその制御プログラムです。

#define S1 A1   // スイッチS1 A1ピン     :モード切替SW
#define S2 A2   // スイッチS2 A2ピン     :ラップタイマーリセット
#define S3 A3   // スイッチS3 A3ピン
#define D1 13   // LED D1 1: off, 0: On
#define D2 12   // LED D2
#define D3 11   // LED D3
#define D4 10   // LED D4
#define ON 0    // LED is on
#define OFF 1   // LED is off

void setup ()
{
  pinMode(D1, OUTPUT);          //LED  D1の初期化
  digitalWrite(D1, OFF);
  pinMode(S1, INPUT);          
}

/* Main program */
void loop()
{
  if (digitalRead(S1) == 0)
    digitalWrite(D1, ON);
  else
    digitalWrite(D1, OFF);
}

3. 一度スイッチを押すとLEDがオンし、もう一度押すとオフするプログラム
スイッチS2を押すとLED D2がオンします。スイッチを離してもLEDはオフしません。もう一度スイッチを押すとLEDはオフします。その様子が下記のビデオです。


下記がその制御プログラムです。
#define S1 A1   // スイッチS1 A1ピン
#define S2 A2   // スイッチS2 A2ピン
#define S3 A3   // スイッチS3 A3ピン
#define D1 13   // LED D1 1: off, 0: On
#define D2 12   // LED D2
#define D3 11   // LED D3
#define D4 10   // LED D4
#define ON 0    // LED is on
#define OFF 1   // LED is off

byte S2Latch = 0;   //
boolean D2On = false;
void setup ()
{
  pinMode(D2, OUTPUT);          //LED  D2の初期化
  digitalWrite(D2, OFF);
  pinMode(S2, INPUT);
}

void loop()
{
  if ( digitalRead(S2) == 0) {
    if (S2Latch == 0) {
      S2Latch = 1;
      digitalWrite(D2, D2On);
      D2On = !D2On;
    }
  } else S2Latch = 0;
}




2016年3月30日水曜日

Multi-function Shield と超音波距離センサーを使ったラップタイマー(制作編)

1.Multi-function Shieldの取付け注意事項

Multi-function Shield をArduino UNOに装着する場合、4桁セグメントLEDの裏面ピンがArduino UNOのUSBコネクタに接触します。この表示動作時に誤動作を起こしたり、ボード故障の原因になりますので、セグメントLEDのピンは短くカットして、USBコネクタの上面には絶縁テープを貼ってください。


2.超音波距離センサーの取り付け

超音波距離センサー(HCSR04)をMulti function Shieldにスマートに固定するためにシールド左上の7ピンコネクタ(APC220 Bluetooth)を使用します。簡単なソケットボードを制作してシールドに固定してください。

コネクタのピン3-4は、Arduino UNOのシリアルピン0-1に使用されていますので使えません。なので、コネクタピン6-7を使用します。Arduno UNOのピン5-6がシールド右下のコネクタに引き出されていますので、これを使用します。下記のようにArduno UNOのピン5-6が、HC-SR04のEcho, Trigピンつながるように配線してください。



3.ラップライマーのプログラム

ラップライマーとして動作するプログラムソースを下記に添付します。
/*
 * 第一工業大学東京上野キャンパス
 * 木下研究室 3年生プレゼミ教材
 * 2016年4月㏠
 */

#define EchoPin 5   // 超音波距離センサ HC-SR0 ピン 入力
#define TrigPin 6   // 超音波距離センサ HC-SR0 ピン 出力
#define LATCH_DIO 4 // シフトレジスタ 74HC595 ピン OUTPUT
#define CLK_DIO 7   // シフトレジスタ 74HC595 ピン OUTPUT
#define DATA_DIO 8  // シフトレジスタ 74HC595 ピン OUTPUT
#define SW1 A1      // スイッチSW1 A1ピン     :モード切替SW
#define SW2 A2      // スイッチSW1 A1ピン     :ラップタイマーリセット
#define SW3 A3      // スイッチSW1 A1ピン
#define SW3 A3      // スイッチSW1 A1ピン
#define Mode_0 0    // モード0: トラック位置設定
#define Mode_1 1    // モード1: ラップタイマーモード
#define LED1 13     // LED1 ON:トラック位置設定、
#define LED2 12     // LED2 ON: ラップタイマーモード
#define LED3 11     // LED3
#define LED4 10     // LED4
#define ON 0         // LED is on
#define OFF 1       // LED is off
#define SPEAKER 3        // 
int cm;                 // 超音波距離センサー計測値(センチメートル)
int TrackCenter = 15;   // トラック中央値 (デフォルト)
bool DP_on = false;     //2桁目LEDのDPのOn/Off
byte OperationMode = Mode_0;    // 動作モード
bool Sw2IsOn = false;           // スイッチ2が押された
bool LapTimerStart = false;     // ラップライマー制御
bool LapTimerRunning = false;
unsigned long Last_100ms_Count = 0; //100ms カウント最終値
int Count_100ms = 0; // 100ms カウンタ
bool SpeakerOn = false;     //スピーカーをオン用フラグ(オンは0.1秒に固定
unsigned long SpeakerDuration = 0;
void setup ()
{
  Serial.begin(9600);   //シリアルを使用する

  // シフトレジスタ 74HC595初期化
  pinMode(LATCH_DIO, OUTPUT);
  pinMode(CLK_DIO, OUTPUT);
  pinMode(DATA_DIO, OUTPUT);

  // 超音波距離センサピン初期化
  pinMode(TrigPin, OUTPUT);
  pinMode(EchoPin, INPUT);
  digitalWrite(TrigPin, LOW);

  // Speaker 設定(オンオフは方向レジスタで制御)
  pinMode(SPEAKER, INPUT);

  // LED1-4の初期化
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);

  digitalWrite(LED1, ON);  //ON
  digitalWrite(LED2, ON);
  digitalWrite(LED3, ON);
  digitalWrite(LED4, ON);
  delay(1000);
  digitalWrite(LED1, OFF);  //OFF
  delay(100);
  digitalWrite(LED2, OFF);
  delay(100);
  digitalWrite(LED3, OFF);
  pinMode(SPEAKER, OUTPUT);
  delay(100);
  digitalWrite(LED4, OFF);
  pinMode(SPEAKER, INPUT);
}

/* Main program */
void loop()
{
  ReadSwitch();     //SW1, SW2 の読み取り

  // キャリブレーションモード
  if (OperationMode == Mode_0) {
    digitalWrite(LED1, ON);
    digitalWrite(LED2, OFF);
    Display(cm);
    DP_on = false;
    Count_100ms = 0;
    TrackCenter = 2 * cm / 3;
    LapTimerStart = false;
    LapTimerRunning = false;
  }

  // ラップタイマーモード
  if (OperationMode == Mode_1) {
    digitalWrite(LED1, OFF);
    digitalWrite(LED2, ON);
    DP_on = true;
    Display(Count_100ms);

    // ラップタイマーストップ状態でマイコンカーが横切ったらカウントスタート
    if (LapTimerStart == false && cm  < TrackCenter ) {
      LapTimerStart = true;
      TurnSpeakerOn();
    }

    // ラップタイマーラン状態でマイコンカーが横切ったらカウントストップ
    if (LapTimerRunning == true && cm  < TrackCenter ) {
      LapTimerStart = false;
      TurnSpeakerOn();
    }

    // ラップタイマーストップ状態で、SW2を押した場合
    if (Sw2IsOn == true &&  LapTimerStart == false) {
      Count_100ms = 0;              // カウントを0.0秒にリセット
      LapTimerRunning = false;      // ラップタイマー停止
      Sw2IsOn = false;              // SW2 ONクリア
    }
  }
  // 100ms インターバル処理
  if (millis() - Last_100ms_Count > 100) {
    Last_100ms_Count = millis();
    cm = readDistance();        // 距離計測は100msごと

    if (LapTimerStart == true) {
      if (Count_100ms < 9999) {
        Count_100ms++;
        if (Count_100ms > 10 ) LapTimerRunning = true;  // ラップライマーがスタートして1秒間はラン状態にしない。
        else LapTimerRunning = false;
      } else  Count_100ms = 0;
    }
  }

  if (SpeakerOn == true) {     // スピーカーを0.5秒オンする
    if (millis() - SpeakerDuration > 50) {
    SpeakerOn = false;
    pinMode(SPEAKER, INPUT);
    }
  }

}
// SW1, SW2の読み取り, スイッチはアナログ読み
void ReadSwitch(void) {
  static byte Sw1Latch;
  static byte Sw2Latch;
  if ( analogRead(SW1) < 100) {
    if (Sw1Latch == 0) {
      Sw1Latch = 1;
      TurnSpeakerOn();
      if (OperationMode == Mode_0) {
        OperationMode = Mode_1;

      } else {
        OperationMode = Mode_0;
        Sw2IsOn = false;
        LapTimerStart = false;
      }
    }
  } else Sw1Latch = 0;

  if ( analogRead(SW2) < 100) {
    if (Sw2Latch == 0) {
      Sw2Latch = 1;
      Sw2IsOn = true;
      TurnSpeakerOn();
    }
  } else Sw2Latch = 0;

}

void TurnSpeakerOn(void) {
  SpeakerOn = true;
  pinMode(SPEAKER, OUTPUT);
  SpeakerDuration = millis();
}


/*4SEG LEDにNumberを表示する
  loop()関数内に配置すれば、3ms毎にスキャン表示を行いう
  Number: 0-9999 の4桁の整数
  表示間隔: 5ms
*/
void Display(int Number)
{
  static unsigned long Last_ms_Count;
  static byte ScanSeg = 0;
  if (millis() - Last_ms_Count > 3) {
    Last_ms_Count = millis();
    switch (ScanSeg++) {
      case 0:
        WriteNumberToSegment(0 , Number / 1000);
        break;
      case 1:
        WriteNumberToSegment(1 , (Number / 100) % 10);
        break;
      case 2:
        WriteNumberToSegment(2 , (Number / 10) % 10);
        break;
      case 3:
        WriteNumberToSegment(3 , Number % 10);
        break;
      default:
        ScanSeg = 0;
    }
  }
}
/* セグメント表示
    Segment: セグメント位置:0 - 3
     Value:表示する値 : 0 - 9
*/
void WriteNumberToSegment(byte Segment, byte Value)
{
  // セグメント表示パターン:  0 - 9
  const byte SEGMENT_MAP[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0X80, 0X90};  
  const byte SEGMENT_SELECT[] = {0xF1, 0xF2, 0xF4, 0xF8}; // 4-seg LED 選択パターン: 1 to 4
  byte SegPattern;

  if (DP_on == 1 && Segment == 2)           // LED2のDP On/Off判定
    SegPattern = SEGMENT_MAP[Value] & 0x7F;     // DPパターンのマスク
  else
    SegPattern = SEGMENT_MAP[Value];
  digitalWrite(LATCH_DIO, LOW);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SegPattern);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
  digitalWrite(LATCH_DIO, HIGH);
}

// 距離測定:センチメートル
int readDistance(void) {
  long t ;
  int ans ;
  digitalWrite(TrigPin, HIGH) ;         // 超音波センサーに5usのパルスを出力する
  delayMicroseconds(5) ;
  digitalWrite(TrigPin, LOW) ;
  t = pulseIn(EchoPin, HIGH, 5000) ;    // パルス幅の時間を測る
  ans = (t / 29) / 2 ;                  // 往復なので2で割る
  return ans ;                          //cm単位戻す
}

Multi-function Shield と超音波距離センサーを使ったラップタイマー(操作編)

Multi-function Shieldは、Amazon.com などで1000円程度で購入できる Arduino UNO用のプログラミング学習用シールドです。Arduino UNOに、このボートと超音波距離センサー(HC-SR04)を取り付けて、マイコンカー用のラップライマーを制作したので紹介します。

1. 動作
  • ラップタイマーと反射ブロックの間をマイコンカーが走り抜けると、ラップタイマーがスタートします。そして再度、マイコンカーがラップタイマーの前を通過したときにタイマーがストップします。
  • Arduino Unoは超音波距離センサーと反射ブロックまでの距離を計測していますが、マイコンカーが超音波を遮ると計測距離が短くなります。この原理を利用してラップライマーを起動・停止させます。

2. 設置方法
  • ラップタイマー(このボード)を、マイコンカーのコーストラックの右サイドにを設置してください。
  • 反射ブロックをコーストラックの左サイドに配置してください。このとき、反射ブロックと超音波距離センサーの距離は30cm以下にしてください。
  • そして、ラップタイマーに電源を投入してください。
3. 操作方法
  • キャリブレーションモード: 電源がオンすると、LED1から4がオンしブザー音がして、このモードになります。このときLED1(D1)がオンします。 そして、4桁セグメントLEDには反射ブロックまでの距離が表示(単位:センチメートル)されます。反射ブロックを動かすと表示距離が変化します。マイコンカーのガイド用センターラインが反射ブロックと超音波距離センサーのちょうど中間に来るように反射ブロックを配置してください。このモードでSW1を押すと計測モードに移行します。
  • 計測モード: このモードでは、LED2(D2)がオンします。 4桁セグメントLEDにはラップタイマーのカウント値が秒で表示(0.1秒まで)されます。表示は"000.0"でストップしています。この状態で、マイコンカーがセンサーの前を横切るとカウントがスタートします。そして再度マイコンカーがセンサーの前に来たときカウントがストップします。この表示値がラップタイム(秒)です。SW2スイッチを押すと、ラップタイムが"000.0"にリセットされカウントスタート状態になります。 "000.0" 以外のカウント停止状態では、マイコンカーがセンサーを通過してもカウントはスタートしませんので注意してください。このモードでSW1を押すとキャリブレーションモードに移行します。


2016年2月3日水曜日

JavaScriptによるハノイの塔



ハノイの塔の実行は赤い部分だけで済んでしまうのには驚きます。
(参照: ゼロからわかるJavaScript超入門 河西朝雄 著(技術評論社)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8" />
    <title>ハノイの塔(テキスト版)</title>
    <script type="text/javascript">
        var result;
        function hanoi(n, a, b, c) {
            if (n > 0) {
                hanoi(n - 1, a, c, b);
                result.value += "板" + n + ": " + a + " --> " + b + "\n";
                hanoi(n - 1, c, b, a);
            }
        }
        function start() {
            var N = document.getElementById("level").value;
            result = document.getElementById("result");
            result.value = "";
            hanoi(N, "a", "b", "c");          
        }
    </script>
</head>
<body>
    <div>ハノイの塔</div>
    <input id="level" type="text" size="2" value="4"/>
    <input type="button" value="START" onclick="start()" />
    <br />
    <textarea id="result" rows="20" cols="20"></textarea>
</body>
</html>