工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方

必要な部品と用品

部品 説明 数量
Arduino UNO どのArduinoでも可、場合によってはArduino以外でも可能 1
タクトスイッチ(非ラッチング) プルダウン抵抗(1kΩ使用)とセットで 1
抵抗 10kΩ 1

アプリとオンラインサービス

ツール 説明
Arduino IDE

プロジェクト概要

あるプロジェクトで、ボタンを押している間だけ時間を計測するArduinoクロノメーターが必要になりました。複雑なものではありませんが、このコードが他の方のプロジェクトの参考になればと思い公開します。おそらく1時間程度のコーディング時間を節約できるはずです。

EEPROM(不揮発性メモリ)

シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方

電源を切ってもデータが保持されるArduino内部のメモリです。#include <EEPROM.h>ライブラリを使用します(標準でインストール済み)。

割り込み(Interrupts)

シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方
シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方
シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方

Arduino内部で処理が進行中でも、特定のピンがHIGHになった瞬間に実行を中断し、ISR(割り込みサービスルーチン)を実行させる機能です。追加ライブラリは不要です。

プロジェクトのコード

定義とインクルード

#include <EEPROM.h>
#define interruptPin 2
#define eeAddress 0 // EEPROMのアドレス(内部不揮発性メモリ)
float starttime = 0; // 計算用変数
float endtime = 0;
float resulttime = 0, oldresulttime = 0;

EEPROMライブラリをインクルードし、ボタンをピン2に接続。EEPROMのアドレス0を使用(Arduino UnoはATmega328で1024バイトありますが、整理のためアドレス0を選択)。

setup()

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // シリアルポート接続待ち(ネイティブUSBポートの場合のみ必要)
  }
  Serial.println("Serial comms are ready sir!:.. bip bip");
  attachInterrupt(digitalPinToInterrupt(interruptPin), refreshTime, CHANGE);
}

通常のシリアル通信初期化(9600ボーレート)に加え、

attachInterrupt(digitalPinToInterrupt(interruptPin), refreshTime, CHANGE);

で割り込みを設定。CHANGEモードなので、ピンの論理レベルが変化するたび(LOW→HIGH、HIGH→LOW両方)にトリガーされます。プルダウン抵抗により、ボタンを押していないときはLOWに固定されます。

loop()

void loop() {
  // ここにメインの処理を書く!
}

メインループは空。割り込みで処理するため、ここに他の処理を入れられます。

その他の関数

void refreshTime() {
  if (digitalRead(interruptPin)) {
    starttime = millis();
    Serial.print("Start time: ");
    Serial.println(starttime);
  } else if (digitalRead(interruptPin) == LOW) {
    endtime = millis();
    resulttime = endtime - starttime;
    Serial.print("End time: ");
    Serial.println(endtime);
    Serial.print("Result time: ");
    Serial.println(resulttime);
    WhatsNewEeprom(); // EEPROMに保存
  }
}

割り込み発生時に実行される関数。ピンがHIGHなら開始時刻、LOWなら終了時刻を記録し、差分を計算。最後にEEPROM保存処理を呼びます。

void WhatsNewEeprom() {
  Serial.println("-----------checking eeprom");
  EEPROM.get(eeAddress, oldresulttime);
  Serial.print("oldresulttime"); Serial.println(oldresulttime);
  Serial.print("resulttime"); Serial.println(resulttime);
  if (resulttime != oldresulttime) {
    EEPROM.put(eeAddress, resulttime);
    Serial.print("-----Ding! New time recorded in eeprom: "); Serial.println(resulttime);
  } else {
    Serial.println("No new time found, eeprom was not disturbed");
  }
}

EEPROMに保存されている値と新しい計測値を比較し、異なれば更新します。

おまけ:ボタンのチャタリング対策

シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方

人間のボタン操作はArduinoにとって非常に遅く、一度の押下で信号がハイ・ローを繰り返す「チャタリング」が発生します。対策はソフトウェア・ハードウェア両方で可能です。

  • ソフトウェアでのデバウンス
  • ハードウェアでのデバウンス:コンデンサを使う!
シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方
シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方

センスピンとGNDの間に220nFのコンデンサを並列接続します。コンデンサが急激な電圧変化を吸収してくれます。

コード

arduino chronometer (Arduino)

EEPROMと割り込みを使用、容易に改造可能

// coded by Javier Muñoz 23/10/2017
// questions to javimusama@gmail.com
#include <EEPROM.h>
#define interruptPin 2
#define eeAddress 0
float starttime = 0;
float endtime = 0;
float resulttime = 0, oldresulttime = 0;

void setup() {
  Serial.begin(9600);
  while (!Serial) { ; }
  Serial.println("Serial comms are ready sir!:.. bip bip");
  attachInterrupt(digitalPinToInterrupt(interruptPin), refreshTime, CHANGE);
}

void loop() {
  // ここに処理を追加
  // (EEPROM保存済み) 最後の計測時間(ミリ秒)"float resulttime"
}

void refreshTime() {
  if (digitalRead(interruptPin)) {
    starttime = millis();
    Serial.print("Start time: ");
    Serial.println(starttime);
  } else if (digitalRead(interruptPin) == LOW) {
    endtime = millis();
    resulttime = endtime - starttime;
    Serial.print("End time: ");
    Serial.println(endtime);
    Serial.print("Result time: ");
    Serial.println(resulttime);
    WhatsNewEeprom();
  }
}

void WhatsNewEeprom() {
  Serial.println("-----------checking eeprom");
  EEPROM.get(eeAddress, oldresulttime);
  Serial.print("oldresulttime"); Serial.println(oldresulttime);
  Serial.print("resulttime"); Serial.println(resulttime);
  if (resulttime != oldresulttime) {
    EEPROM.put(eeAddress, resulttime);
    Serial.print("-----Ding! New time recorded in eeprom: "); Serial.println(resulttime);
  } else {
    Serial.println("No new time found, eeprom was not disturbed");
  }
}

回路図

プルダウン抵抗付きボタンのシンプルな接続

シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方

製造プロセス

  1. Adafruit 60 LED NeoPixelリングとArduinoで作るスタイリッシュな壁掛け時計
  2. DIY Arduinoワードクロック – 文字で時刻を表示する洗練されたリアルタイムクロック
  3. Arduino Nanoで20kHzオシロスコープを自作:Nokia 5110 LCD搭載・簡易DIYガイド
  4. Bluetooth操作のArduinoスパイボットを自作する
  5. FlickMote:ジェスチャー操作のIRリモコンでスマートホームを制御
  6. 自作Arduino TV-B-Gone:全テレビ対応の万能リモコン
  7. 12メートル先から見える大型LEDマスタークロック(アラーム機能付き)を自作しよう
  8. Arduinoでシンプルな障害物センサーを自作 – IR LEDとフォトダイオード入門
  9. ArduinoとBluetoothで作るスマート紛失防止タグ「Find Me」
  10. Arduinoプロジェクトのための最適化電源ソリューション
  11. DS1302 RTCとArduino UNOで作る信頼性の高い目覚まし時計