SSブログ

Maruduinoでラーメンタイマー、、、ただし6個いっぺんに作れます。 [アプリケーション]

※なんかイマイチ感がありありだったので、スケッチを修正しました。今度はいっぺんに6個までカップラーメンを作ることができます。

Img_2070.jpgいや、ほら、カップラーメンって全部3分と言うわけでなく、3分だったり、4分だったり、うどんは5分が多いかな。
逆に焼きそばは1分とか、もうまちまち。
一人なら問題無いけれど、多人数で一つのキッチンタイマーでは苦しすぎる。
で、5個6個いっぺんに計測可能なラーメンタイマーを作りましたヨ。

これでキッチンタイマーの奪い合いも無くなり、平和にラーメンをすすれますネ。

LCDの接続はスケッチをごらんいただくとして、スピーカー出力はDI13(DIGITAL13)をAUX1に接続します。2つのスイッチを使いますが、SW1はDI2、SW2はDI3に接続します。

※例の100円スピーカーを接続するのをお忘れなく。
※メロディ発生のスケッチはexamplesのdigitalのtoneMelodyから流用していますので、pitches.hをプロジェクトフォルダーにコピーして使ってください。
※色々と気になる点はありますが、まあ善しとしましょう。
※なんか気の抜けるネタばかりですいません。
/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 8
 * LCD Enable pin to digital pin 9
 * LCD D4 pin to digital pin 4
 * LCD D5 pin to digital pin 5
 * LCD D6 pin to digital pin 6
 * LCD D7 pin to digital pin 7

 * 10K resistor:
 * ends to +5V and ground
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 25 July 2009
 by David A. Mellis
 
 
 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>
#include "pitches.h"

int int0_count,int1_count;
unsigned char store_sw_status[3];  /*スイッチ状態の記録*/
/*SW1はDI2に接続し、割り込み0、SW2はDI3に接続し、割り込み1で処理する。*/
unsigned long guard1_time,guard2_time;
int timers;
struct RECORD 
{
  int minutes;
  unsigned long end_time;
} rec[6];

const struct SCORE
{
  int note;
  int dura;
} score[] =
{
  {NOTE_G4,4},
  {NOTE_A4,4},
  {NOTE_B4,2},
  {NOTE_A4,4},
  {NOTE_G4,8},
  {0,8},
  {NOTE_G4,4},
  {NOTE_A4,4},
  {NOTE_B4,4},
  {NOTE_A4,4},
  {NOTE_G4,4},
  {NOTE_A4,1},
};

const struct POSITION
{
  int x;
  int y;
} pos[] =
{
  {0,0},
  {5,0},
  {10,0},
  {0,1},
  {5,1},
  {10,1},
};

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup()
{
  lcd.begin(16, 2);
  for( int i = 0; i < sizeof(pos) / sizeof(pos[0]); i++ )
  {
    lcd.setCursor(pos[i].x,pos[i].y);
    lcd.print("0:00");
  }

  attachInterrupt(0, sw1_int_handler, RISING);
  attachInterrupt(1, sw2_int_handler, RISING);
}

void loop()
{
  int i;
  char buffer[16];
  static int count1,count2;

  for( i = 0; i < sizeof(pos) / sizeof(pos[0]); i++ )
  {
    /*表示位置の設定*/
    lcd.setCursor(pos[i].x,pos[i].y);

    if( rec[i].end_time != 0 )
    {
      if( rec[i].end_time <= millis() )
      {
        rec[i].minutes = 0;
        rec[i].end_time = 0;
        play_melody();
        lcd.print(millis2min(buffer,0));
      }
      else
        lcd.print(millis2min(buffer,rec[i].end_time - millis()));
    }
  }

  if( count1 != int0_count )  /*割り込みカウントと不一致が検出された時*/
  {
    count1 = int0_count;  /*更新*/

    /*レコードが空いているかの判断*/
    for( i = 0; i < sizeof(pos) / sizeof(pos[0]); i++ )
    {
      if( rec[ timers ].end_time == 0 ) break;
      if( ++timers >= sizeof(pos) / sizeof(pos[0]) ) timers = 0;
    }

    /*書き込み可能な場合*/
    if( i != sizeof(pos) / sizeof(pos[0]) )
    {
      rec[ timers ].minutes = rec[ timers ].minutes + 1;
      rec[ timers ].minutes %= 10;
      lcd.setCursor(pos[ timers ].x,pos[ timers ].y);
      lcd.print(millis2min(buffer,rec[ timers ].minutes * 60 * 1000UL));
    }
  }

  if( count2 != int1_count )  /*割り込みカウントと不一致が検出された時*/
  {
    count2 = int1_count;  /*更新*/

    /*レコードが空いているかの判断*/
    for( i = 0; i < sizeof(pos) / sizeof(pos[0]); i++ )
    {
      if( rec[ timers ].end_time == 0 ) break;
      if( ++timers >= sizeof(pos) / sizeof(pos[0]) ) timers = 0;
    }

    if( i != sizeof(pos) / sizeof(pos[0]) )
    {
      rec[ timers ].end_time = (rec[ timers ].minutes * 60 * 1000UL) + millis();
      if( ++timers >= sizeof(pos) / sizeof(pos[0]) ) timers = 0;  /*レコード番号の更新*/
    }
  }

  delay( 50 );  /*表示更新時間*/
}

char *millis2min( char *dest, unsigned long milli )
{
  int minute,second,temp;
  
  if( milli > 10 * 60 * 1000UL ) return 0;
  temp = (int)(milli / 1000UL);
  minute = temp / 60;
  second = temp % 60;

  dest[0] = (minute % 10) + '0';
  dest[1] = ':';
  dest[2] = (second / 10) + '0';
  dest[3] = (second % 10) + '0';
  dest[4] = '\0';

  return dest;
}

void play_melody()
{
  for (int thisNote = 0; thisNote < sizeof(score) / sizeof(score[0]); thisNote++)
  {
    int noteDuration = 1000/score[thisNote].dura;
    tone(13, score[thisNote].note,noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
  }
}

void sw1_int_handler()
{
  if( millis() > guard1_time )  /*現在時刻がガードタイムを越した時のみ有効とする*/
  {
    int0_count++;  /*有効割り込み数*/
    guard1_time = millis() + 300UL;  /*不感帯時間の再設定*/
  }
}

void sw2_int_handler()
{
  if( millis() > guard2_time )  /*現在時刻がガードタイムを越した時のみ有効とする*/
  {
    int1_count++;  /*有効割り込み数*/
    guard2_time = millis() + 300UL;  /*不感帯時間の再設定*/
  }
}


ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Maruduino(Arduino)で簡易的なストップウオッチの製作 またかよ編 [アプリケーション]

Img_2043.jpgまたかよぅ、と言った感じですが、、、

今までの方式で最大の問題は、計測時間が正確ではなかった点です。
今までの時間の取得は50ms+内部処理時間周期でSW1の状態を監視していたので、ワーストケースでは50ms+LCD表示など内部処理に掛かる時間だけ実際のスイッチの変化から遅れて計測がスタート、ストップしていました。
これを解消するためには、スイッチの変化に対して即座に反応し、計測の開始時間や終了時間を記憶する必要があります。

そこで、Arduinoのライブラリの中のattachInterruptと言う割り込みハンドラの登録機能を利用します。
これは、スイッチの状態の変化が検出されると通常のloop処理以外の流れ(コンテキスト)にマイコンの処理を切り替え、そこで必要な処理を行おうというものです。
必要な処理はユーザーが自分で作成し、登録します。

つまりこのユーザーが登録した別のコンテキストの先頭で変化を検出した時間を記録しておき、その値を計測時間として利用します。
また、同時にチャタリング?対策もここで行ってしまいます。

※厳密に言えばこの方法でもスイッチの変化から割り込みハンドラが起動して時間が記録されるまでに数十とか数百μsくらいの遅延は発生しているのですが、10msの精度から見れば十分に許容範囲内です。

ただしattachInterruptで利用できる端子は限定されており、DIGITAL2またはDIGITAL3のみです。その為、Hello Worldで利用しているLCD端子の移動が必要です。
以下に掲載するスケッチのコメント部にも具体的な割付を書きましたが、DIGITAL2をLCDの制御線から移動し、代わりにSW1からの入力に利用しています。

と言う訳で、スケッチをここに掲載しておきます。
/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 8
 * LCD Enable pin to digital pin 9
 * LCD D4 pin to digital pin 4
 * LCD D5 pin to digital pin 5
 * LCD D6 pin to digital pin 6
 * LCD D7 pin to digital pin 7

 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 25 July 2009
 by David A. Mellis
 
 
 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>
int mode;  /*初期状態は0(計測スタート待ち)*/
  /*初期状態→計測中→停止中→初期状態に戻る  の状態遷移を行う*/
int int_count;
unsigned long passed_time,latest_time;
unsigned long int_time,guard_time;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Play Stopwatch.");
  attachInterrupt(0, sw1_int_handler, RISING);
}

void loop() {
  static int count;

  if( count != int_count )  /*割り込みカウントと不一致が検出された時*/
  {
    count = int_count;  /*更新*/

    switch ( mode )
    {
      case 0 :  /*初期状態から計測中に遷移*/
        passed_time = int_time;  /*計測開始時刻*/
        mode = 1;
        break;
      case 1 :
        latest_time = int_time;  /*計測停止時刻*/
        mode = 2;
        break;
      default :
        lcd.setCursor(0, 1);
        lcd.print("                ");  /*表示クリア*/
        mode = 0;
        break;
    }
  }

  lcd.setCursor(0, 1);
  if( mode == 1 )
    lcd.print((double)(millis() - passed_time) / 1000.0);  /*0.1秒単位で出力*/
  else if( mode == 2 )
    lcd.print((double)(latest_time - passed_time) / 1000.0);  /*計測完了*/
  else
    lcd.print(0.0);  /*表示を0に戻す*/

  delay( 50 );  /*表示更新時間*/
}

void sw1_int_handler()
{
  if( millis() > guard_time )  /*現在時刻がガードタイムを越した時のみ有効とする*/
  {
    int_count++;  /*有効割り込み数*/
    int_time = millis();
    guard_time = int_time + 500UL;  /*不感帯時間の再設定*/
  }
}


Maruduinoの基本パーツの組み立て4 [組み立て]

外部電源入力を実装します。これで基本パーツセットの組み立ては最後です。

Img_2058.jpg 実装位置は基板左下となります。
Img_2059.jpg セオリー通りちっさい抵抗から実装します。ちなみにこの抵抗は金属皮膜抵抗で、今まで使っていた抵抗に比較して精度が良くなっています。
120Ωの抵抗が茶赤黒黒茶
360Ωの抵抗が橙青黒黒茶です。
Img_2060.jpg ダイオードを実装します。D2はちょっと半田が載り難いです。しっかり温めてください。
Img_2061.jpg ICを実装します。足の幅が変化したところを折り曲げ加工して実装します。これも特に真ん中のピンはしっかりと温める必要があります。
3mmのネジとナットがあれば、先にこのICを固定してから半田付けするとやり易いです。
Img_2062.jpg 105と表記されている1μFのコンデンサを実装します。
Img_2063.jpg C6(100μF)の電解コンデンサを実装します。やはりこれも上に載せた基板とぶつかる可能性がありますので、寝かせた状態で実装します。また極性にも十分注意してください。
このコンデンサもしっかり温める必要があります。
Img_2065.jpg DCジャックを実装します。
Img_2066.jpg 電源LEDの横の電源スイッチを実装します。これが最後の部品です。
Img_2067.jpg 9V出力(センタープラス、内径φ2.1)のACアダプター等を接続し、電源スイッチを入れるとLEDが点灯します。
注意!、外部電源は、単独で動かす場合などUSBで電源を供給できない時に使用します。USBで接続している時は、必ずAC入力をを外した状態で動かしてください。


ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

  • 作者: 大人の科学マガジン編集部
  • 出版社/メーカー: 学習研究社
  • 発売日: 2010/05/12
  • メディア: ムック



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Maruduinoの基本パーツの組み立て3 [組み立て]

残りのスイッチ、LED、それにオーディオ出力の実装を行います。
Img_2046.jpg 残っていたスイッチ、LEDの取り付けを終わらせてしまいます。手順は前々回の取り付けを参考に行ってください。
Img_2047.jpg 実装位置は基板中央、上側、ちょうどLCDの真下になりますので、一旦LCDを外しておいてください。
Img_2048.jpg セオリー通りちっさい方の抵抗から実装します。
0Ωの抵抗は黒い帯が一本です。
10Ωの抵抗は茶黒黒金です。
300KΩの抵抗は橙黒黄金です。
Img_2049.jpg おっきい方の抵抗を実装します。
Img_2052.jpg ICを実装しますが、新品のICは大概が足が広がった状態ですので、事前に平らなところで広がりを修正しておきます。
Img_2053.jpg かならずこの方向で実装してください。
Img_2054.jpg C16(1000pF、102と表記)とC15(0.047μF、473と表記)を実装します。頭の黒いのがC16です。
Img_2055.jpg オーディオ出力用のジャックを取り付けます。
Img_2056.jpg 電解コンデンサを実装しますが、電解コンデンサには極性(プラスとマイナス)があります。これを間違えると、最悪は破裂とかしてしまいます。写真の様に白い帯が縦に入っている方がマイナスとなります。基板上には白い円の中で一部白く塗りつぶされているところがありますが、これがマイナスを示しています。
Img_2057.jpg 立てて実装するとLCDとぶつかってしまいますので、写真の様に寝かせて実装します。本体から大体2mmくらいの位置を、ピンセットで折り曲げ加工してください。
ちょっと太いほうが220μF(C14)、細い方が100μF(C13)です。
Img_2064.jpg 最後に音量調整用の可変抵抗器を実装します。
Img_2069.jpg ちょっと何か鳴らしてみましょうか。写真は100均で買った、勿論100円のステレオスピーカーです。まともに部品屋さんでスピーカーを購入すると意外と高かったり、ほとんどがリードタイプで基板実装タイプが見つからなかったりと苦労します。3.5mmのジャックなのでこの様にダイレクトにスピーカーユニットを接続できると言う訳です。
Img_2068.jpg ArduinoのexampleのdigitalのtoneMelodyを開いて、DI8とAUX1を接続し、スケッチをArduinoに転送してみてください。なんだか力が抜けるメロディが流れてくるかと思われます。
音量が小さくて聞き取れないときは、VR2のVOLUMEで調整します。


ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Maruduino(Arduino)で簡易的なストップウオッチの製作2 [アプリケーション]

Img_2043.jpgさて、前回は簡易的なストップウオッチを作成しました。機能的にだけではなく論理で簡易的にもやっているので、幾つかの問題があります。
その一つは押下の検出にSW1の論理レベルを使っている事です。

もう一度スイッチの押下について考えてみます。
スイッチの情報を得る場合、2つの状態が考えられます。
1.今現在の状態の取得。つまり現在スイッチが押されているのか、それとも離されているのか?です。
2.スイッチの状態の変化の取得。つまり離されている状態から押された状態に変化したのか、それともその逆なのか?です。
実はこの2つの状態はよく組み合わせで使われます。スイッチを瞬間的に押された事を検出するなら2を、長押しを検出するなら1とかです。

前回のスケッチでは1の方法で検出をしていました。これはストップウオッチで1秒以上長押しされる事はあまり無い”だろう”と言う、あくまでもこちらの側の都合ですね。
で、今回は2の方法を実現してみます。

変化点を検出する為には、過去と現在の2つの状態が必要です。
スイッチが押された事を検出するなら、「過去は離されていたが、今見たら押されている!」と言う状態の検出です。

と言うわけで過去の状態を保存する変数と現在の状態を代入するbool型の変数の2つを用意してコーディングし直してみました。
この方法は、比較する論理レベルを逆にするとスイッチが離された事の検出に使えますし、bool型ではなく変数を整数型で複数ポートを一気に読み出し、代入を行うと、複数ポートの変化を論理だけで検出する事ができます。
※ITRON等で使う場合、変化点をXOR(排他的論理和)として検出し、その値をイベントフラグに代入すると、結構スマートな使い方が出来る。
/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 25 July 2009
 by David A. Mellis
 
 
 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>
const int sw1 = 13;  /*スイッチ1の入力*/
int mode;  /*初期状態は0(計測スタート待ち)*/
  /*初期状態→計測中→停止中→初期状態に戻る  の状態遷移を行う*/
int ignore_time;
unsigned long passed_time,latest_time;
boolean kako,ima;  /*sw1の状態を過去の時点と今の時点で保存する変数*/

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  pinMode( sw1, INPUT );
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Play Stopwatch.");
  kako = (digitalRead( sw1 ) == HIGH) ? true : false;  /*初期化時に過去の値を保存して置く*/
}

void loop() {
  ima = (digitalRead( sw1 ) == HIGH) ? true : false;  /*今の状態を取得*/

  if( ignore_time == 0 && kako == false && ima == true )  /*つまり不感帯以外で過去に偽、今が真の時を探す*/
  {
    ignore_time = 20;  /*1秒の不感帯とする*/
    switch ( mode )
    {
      case 0 :  /*初期状態から計測中に遷移*/
        passed_time = millis();  /*計測開始時刻*/
        mode = 1;
        break;
      case 1 :
        latest_time =  millis();  /*計測停止時刻*/
        mode = 2;
        break;
      default :
        lcd.setCursor(0, 1);
        lcd.print("                ");  /*表示クリア*/
        mode = 0;
        break;
    }
  }
  kako = ima;  /*今の状態を過去に代入*/

  lcd.setCursor(0, 1);
  if( mode == 1 )
    lcd.print((double)(millis() - passed_time) / 1000.0);  /*0.1秒単位で出力*/
  else if( mode == 2 )
    lcd.print((double)(latest_time - passed_time) / 1000.0);  /*計測完了*/
  else
    lcd.print(0.0);  /*表示を0に戻す*/

  if( --ignore_time <= 0 ) ignore_time = 0;  /*スイッチを無視する時間の更新と上限*/

  delay( 50 );  /*表示更新時間*/
}


ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Maruduino(Arduino)で簡易的なストップウオッチの製作1 [アプリケーション]

Img_2043.jpg組み立て編でスイッチ、LED、LCDを実装しましたので、この辺で何か作ってみましょう。
わりと判り易いと思われるストップウオッチです、、、既にArduinoの作例として何処かに登録されている様な気がしないでもないけれどネ。

機能としては一応100分の1秒表示。スイッチは一つ、その一つのスイッチで
1.計測待ち
2.計測
3.計測停止
の3状態を1~3に、また1に戻ると言った簡単な状態遷移で行います。

肝心の時間の計測には起動時からの時間をms単位で返すmillisライブラリを使用します。簡単ですから。
スイッチの押下の検出は自分でやらねばなりません。

ところでスイッチの入力となるといつも問題なるのがチャタリングでしょう。切り替えた時に接点がバウンス(はね返り)してONとOFFの状態が連続して表れるとか。
ですが、このストップウオッチのスイッチ入力に巨大なレバー式スイッチなど使いませんので、現実的にはバウンスが問題になる訳ではありません。

使用しているタクトスイッチは、上から押し込む事で離れていた導電ゴムの接点が押しつぶされる様に接触しますので、どっちかと言えば接触するかしないかの際での人間の指の状態とか、人によって長く押したり、短く押したりと言った時間的不確実性の方が問題です。

やっぱり何等かの不確実性を解消しないといけないのは事実ですので、もう少しこのストップウオッチにおけるスイッチの役目を考えてみると、
1.まず押された事を検出できれば良い、、、つまり離された事まで考慮する必要が無い。
2.ONとOFFが繰り返される事は時間のフィルターを用いる事で解消できる。

と言う訳で今回のストップウオッチにおけるスイッチ押下による状態遷移の条件として、前回の変化から一定以上の時間が経過している事。押下のみ検出とします。

LiquidCrystalのHell Worldを改造して以下の様なスケッチを書いて見ました。
しかし100分の1秒の精度は実に怪しいですね。
※一桁間違えたので修正(笑)
/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 25 July 2009
 by David A. Mellis
 
 
 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>
const int sw1 = 13;  /*スイッチ1の入力*/
int mode;  /*初期状態は0(計測スタート待ち)*/
  /*初期状態→計測中→停止中→初期状態に戻る  の状態遷移を行う*/
int ignore_time;
unsigned long passed_time,latest_time;


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  pinMode( sw1, INPUT );
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Play Stopwatch.");
}

void loop() {
  if( ignore_time == 0 && digitalRead( sw1 ) == HIGH )  /*スイッチが押されるとHIGHとなる*/
  {
    ignore_time = 20;  /*1秒の不感帯とする*/
    switch ( mode )
    {
      case 0 :  /*初期状態から計測中に遷移*/
        passed_time = millis();  /*計測開始時刻*/
        mode = 1;
        break;
      case 1 :
        latest_time =  millis();  /*計測停止時刻*/
        mode = 2;
        break;
      default :
        lcd.setCursor(0, 1);
        lcd.print("                ");  /*表示クリア*/
        mode = 0;
        break;
    }
  }

  lcd.setCursor(0, 1);
  if( mode == 1 )
    lcd.print((double)(millis() - passed_time) / 1000.0);  /*0.1秒単位で出力*/
  else if( mode == 2 )
    lcd.print((double)(latest_time - passed_time) / 1000.0);  /*計測完了*/
  else
    lcd.print(0.0);  /*表示を0に戻す*/

  if( --ignore_time <= 0 ) ignore_time = 0;  /*スイッチを無視する時間の更新と上限*/

  delay( 50 );  /*表示更新時間*/
}


ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

  • 作者: 大人の科学マガジン編集部
  • 出版社/メーカー: 学習研究社
  • 発売日: 2010/05/12
  • メディア: ムック



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Maruduinoの基本パーツの組み立て2 [組み立て]

今度はLiquidCrystalのHello Worldを動かします。

Img_2036.jpg 0Ω抵抗(真中に黒帯のみ)、可変抵抗、2列14ピンソケットヘッダーを取り付けます。勿論0Ωから付けます。
※基板上にソケットヘッダーを付けるか、ピンヘッダーを付けるかはもう完全に好みです。私は圧倒的にソケットヘッダー。
Img_2037.jpg LCD側には2列14ピンのピンヘッダーを取り付けますが、その前にLCDを裏返してJ2とJ3にこんもりと半田を盛って置きます。このジャンパーをショートする事でバックライトが点灯します。
Img_2038.jpg LCDと基板を合体させますが、LCDの右側の取り付け穴に、基本パーツセットの中のプラスチックスペーサーと長いネジ、ナット、ワッシャを使ってLCDの固定を行ってください。左側は物凄い振動を与えるとかしない限り必要無いでしょう。
Img_2039.jpg 基板上にCN14の横に白い文字でLCDの各信号線名が描かれていますが、LCDを搭載すると見難いので、この写真を参考としてください。
Img_2040.jpg 配線を行います。やはり単芯線を適当な長さに切断し、exampleのLiquidCrystalのHello Worldのソースコードに書かれている布線内容に合わせて接続します。
LCD RSがDI12
LCD EがDI11
LCD D4がDI5
LCD D5がDI4
LCD D6がDI3
LCD D7がDI2
Img_2041.jpg exampleのLiquidCrystalのHello Worldを転送し、LCDに無事に表示が出ている事を確認します。もし見えないときは、可変抵抗器VR1(CONTRAST)を回して調整してみてください。


ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



武蔵野電波のブレッドボーダーズ―誰でも作れる!遊べる電子工作

武蔵野電波のブレッドボーダーズ―誰でも作れる!遊べる電子工作

  • 作者: スタパ齋藤
  • 出版社/メーカー: オーム社
  • 発売日: 2009/11
  • メディア: 単行本



Maruduinoの基本パーツの組み立て1 [組み立て]

組み立てを行います。
と、その前に、、、Maruduinoのパーツリストとかご覧いただければ判りますが、やたら部品が多い。フル実装だと私でも半日位は掛かってしまいます。
これはしんどいので、できれば必要な時に必要なだけ実装する事をお勧めします。
では、第一目標としてお約束のDIGITAL13のLEDチカチカから。

Img_2008.jpg まずはArduinoボードを搭載できるようにします。Arduinoボードを搭載するのは、基板左上のこの位置になります。
通常いっぺんに全ての部品を実装するなら、実装時に背の低い部品から順番に行うのがセオリーですが、部分的に実装して行く方針なので、その辺は無視しています。
Img_2010.jpg とは言え、部分部分では、実装時の背の低さが順番に影響を与えます。このブロックではダイオードがそれです。ピンセットで足を適切な間隔に折り曲げ加工を行って実装して下さい。
Img_2011.jpg イメージとしてはこの様になります。まだピンヘッダーの半田付けは行っていません。
シングルラインのピンヘッダーなので、半田付けする際、不安定となってしまいます。そこで、、、
Img_2013.jpg 先にArduinoボードにピンヘッダーを挿してしまいましょう。
Img_2014.jpg この状態でMaruduinoベースボードの所定の位置に差し込みます。
まず足の一箇所を半田付けして、上手く出来ているか確認します。問題が無ければそのまま四隅を半田付けしてしまいます。四隅を半田付けしてしまえばもう滅多な事では外れたりしませんので、じっくり全部の足の半田付けを完了させてください。
Img_2016.jpg 次は電源LEDです。いざと言う時にあると安心できます。
実装位置は基板下側になります。
Img_2018.jpg 抵抗をこの様にピンセットを使って折り曲げて置きます。折り曲げた足の間隔は約5mmです。大体抵抗本体から0,5mm~1mm程度の位置で折り曲げます。ちなみにこの抵抗のカラーコードは橙橙茶金です。
Img_2019.jpg LEDの足の長さと、アノード、カソードの位置を十分に確認してください。電源LEDの場合はこの様な足の位置関係となります。
Img_2020.jpg 単に抵抗をランドに指しただけでは、半田付けする際に裏返した場合、落っこちてしまいかねないので、裏から指でしっかり押さえた状態で、足をピンセットでしっかりつまみ、上方向に強く引っ張りながら広げます。
こうすると裏返しても落ち難くなります。
Img_2021.jpg LEDも抵抗と同様に足を広げて落ち難くして、半田付けを行います。
Img_2033.jpg LEDチカチカする為にLEDを実装しましょう。ところでこの基板のLED周りの回路ですが、一つのポート(Arduinoの入出力端子)でLEDの点滅、またはスイッチの入力が行える様になっています。例えばポートを出力に設定し、digitalWriteでHIGHを書けばLEDが点灯、LOWならば消灯です。また入力として設定すると、スイッチが押されていない時はdigitalReadではLOWが見え、スイッチが押されるとHIGHが見えます。必要な抵抗、LED、スイッチを実装して下さい。
各抵抗のカラーコードですが、100Ωの抵抗は茶黒茶金、10KΩの抵抗は茶黒橙金、220Ωの抵抗は赤赤茶金です。
Img_2022.jpg LEDの足の向きはこの方向となります。
Img_2025.jpg Maruduinoでは、Arduinoボードの各ポート(信号線)は直接LEDやLCD、スイッチ等には接続されていません。代わりに中継用のシングルラインソケットヘッダーに全ての信号線が接続され、そこから必要な回路にジャンプワイヤー等を使って接続する事となります。
写真はソケットヘッダーです。四角い穴にジャンプワイヤー等を差し込む事となります。
Img_2024.jpg またまたシングルラインの半田付けです。そこでちょっと工夫をしてみましょう。基本パーツセットの中には、2列14ピンのピンヘッダーが同梱されています。これを使ってシングルラインソケットヘッダー2個を連結してしまいます。まずは基板中央やや上のCN5とCN14です。こうする事で半田付け時に安定させる事ができます。
Img_2026.jpg まずは一箇所だけ半田付けして状態を確認してください。ピンが浮いていたり、斜めになっていたら半田を盛った足にこてを当て直して修正します。綺麗に半田付けできたら対角上のピンを半田付けして安定させ、そこからは落ち着いて全部の足を半田付けしてください。
Img_2027.jpg 次にこのソケットヘッダーの左隣のCN2を実装しますが、やはり2列14ピンのピンヘッダーを写真の様に使ってCN2を固定してしまい、その状態で半田付けを行ってください。
同じ手順で右側にあるCN3、CN1とCN7。CN6とCN12を半田付けしてLEDチカチカ用の部品の半田付けは終了です。
Img_2028.jpg ジャンプワイヤーでもよいのですが、単芯線を適切な長さに切ってワイヤーストリッパーで剥きます。22と数字が書いてあるところで剥いてください。
Img_2029.jpg 接続は、DI13(DIGITAL13の意味)と、
※基板上に白い文字で”DI13”と書かれています。
Img_2030.jpg SW1への配線となります。 ※基板上に白い文字で”SW1”と書かれています。
Img_2031.jpg 基板を直接机の上などに置いて、うっかり電源ショートとかしてしまうのを避ける為に、基板付属のスタットスペーサーを必ず付けましょう。
Img_2035.jpg では所定の位置にArduinoを差し込んで、exampleのdigitalのblinkを転送してみてください。電源LEDが点灯している事、無事にLEDが点滅していればOKです。


ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

ITRONプログラミング入門―H8マイコンとHOSで始める組み込み開発

  • 作者: 濱原 和明
  • 出版社/メーカー: オーム社
  • 発売日: 2005/04/25
  • メディア: 単行本



Arduinoをはじめよう

Arduinoをはじめよう

  • 作者: Massimo Banzi
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2009/03/27
  • メディア: 単行本(ソフトカバー)



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



工具紹介 [ツール]

Maruduinoの基本パーツセットを組み立てる時に使用した工具を紹介しておきます。

Img_2001.jpg まず半田は0.6mmの鉛入り半田を使っています。細い半田の方が適切な量で済む事と、鏝先の温度を下げずに済みますので、1mm位の太い奴を使って悩んでいる人にはお勧めです。なお鉛の件ですが、ヨーロッパに輸出でもしない限り、個人の電子工作の範囲なら特に鉛フリーに拘る理由は無いでしょう。
今回はヘルパーハンドは使っていませんが、あると色々と便利です。
写真には写っていませんが、細身のプラスドライバーが必要です。
Img_2002.jpg ちょっと拘りたい工具の一つがピンセットです。写真はHOZANのP-892です。肉厚があり、腰が強くて、しっかりと掴む事ができます。チップ部品のつまみも容易です。
Img_2004.jpg 半田ごてはそれ程拘っていません。近所のホームセンターで買ってきた白光のN454です。
Img_2007.jpg ただし半田ごての鏝先は交換しています。N-454-T-2Cです。標準の円錐形の鏝先は使い難いですから。 基本的に、短時間で必要なところを十分加熱する必要があります。円錐形の鏝先では点、または線でしか接触できませんので、暖め方に斑が発生し、部分的に加熱してよい温度を超えてしまったりします。
写真を見れば判る様に、この鏝先は面で接触させる事が可能で、より効率的に熱を対象に伝える事が可能です。結果、均一に素早く暖める事が可能で、半田付けの能率も上がります。
Img_1994_s.jpg おまけ
工具ではありませんが配線用に、ジャンプワイヤーの代わりにこの単芯線を使っています。今までは拠線の被覆を向いて予備半田して利用していましたが、これは被覆を向くだけでそのまま利用できるのでとても便利です。
専用のジャンプワイヤーも便利なのですが、どうしても配線長が余り気味で、それがイマイチ美観が良くないので、最低限の長さに調整できるこちらの方が、やっていて気持ちが良いです。



大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

  • 作者: 大人の科学マガジン編集部
  • 出版社/メーカー: 学習研究社
  • 発売日: 2010/05/12
  • メディア: ムック



Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



超音波距離計の製作2 [アプリケーション]

Img_1996_s.jpg前回ブレッドボード上でプロトタイピングを行い、なんとか動かせる目処が付いたので、折角なので基板化してみました。回路は変更ありません。


Img_2000_s.jpg作成した基板の表側?です。スピーカー、マイク、LEDがこちらを見ています。


Img_1999_s.jpg裏側です。リード部品を所狭しと搭載しています。スピーカーと反対側にこれらの部品を実装したからなんとか収まった様なものです。


実際にブレッドボード上でプロトタイピングしたので大体は上手く動くのですが、基板化する事により発生した問題なんてのもあります。

ブレッドボード上にスピーカーを載せた時は、スピーカーの固定はゆるゆるです。あの穴にズボっと挿すだけですから。
ところが基板上に半田付けしてしまうとかなりかっちり固定される事となります。
超音波を発している時間は極短い時間ですし、周波数も40KHzと可聴領域の遥か上です。それなのに、なにやら音がポツッ!、ポツッ!と聞こえてきます。

そうです、どうも超音波を駆動した時、スピーカー自身がそのショックで振動してしまうようです。この振動が剛性のある基板を経由してマイク側に伝わるものですから、受信側は大変な事になってしまいます。
※耳にはっきりと聞き取れる位の音なので、可聴領域の周波数だとしても、その振動の継続時間がかなり長くなっていると思われ、これがゲート時間を超えています。

対策は色々あると思いますが、最も良いのはスピーカー側の固定をフローティングする事でしょう。但し機構的に難しいので妥協として出力レベルを押さえる事とします。

ADM3202の出力には最低300Ωの抵抗が入っています。これは短絡に対する保護だと思われますが、出力抵抗が300Ωだと考えれば、抵抗で分圧する事でスピーカーの入力を小さくできます。
今は240Ωの抵抗をスピーカーの2つの端子間に入れています。これだと2m弱位の測定距離となる様です。

まあ、まだまだカットアンドトライが必要みたいですが、一応完成と言う事で。
ultra_sonic_distance_02.png

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ

  • 作者: 小林 茂
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/05/27
  • メディア: 大型本



Making Things Talk ―Arduinoで作る「会話」するモノたち

Making Things Talk ―Arduinoで作る「会話」するモノたち

  • 作者: Tom Igoe
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2008/11/17
  • メディア: 大型本



大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

大人の科学マガジン Vol.27(8ビットマイコン) (Gakken Mook)

  • 作者: 大人の科学マガジン編集部
  • 出版社/メーカー: 学習研究社
  • 発売日: 2010/05/12
  • メディア: ムック



この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。