有限ステートマシンを使用したArduinoのデジタル時計
コンポーネントと消耗品
> |
| × | 1 | |||
| × | 1 |
アプリとオンラインサービス
| ||||
|
このプロジェクトについて
ねえ、
YAKINDU Statechart Toolsを使用してデジタル時計を作成し、LCDキーパッドシールドを使用するArduinoで実行する方法を紹介します。
デジタル時計の元のモデルは、デビッドハレルから取られました。彼は、「ステートマシンとステートダイアグラムの従来の形式の広範な拡張」に関する論文を発表しました。
この論文では、彼は研究のためにデジタル時計の例を使用しました。私はそれをインスピレーションとして使用し、YAKINDU Statechart Tools(ステートマシンのグラフィカルモデルを作成し、それを使用してC / C ++コードを生成するためのツール)を使用して時計を再構築し、Arduinoで復活させました。
デジタル時計のしくみ
デジタル時計がどのように機能するかを定義することから始めましょう。これらを覚えていますか...たとえば...誰もが90年代に持っていた「超クールな」デジタル時計?統合されたストップウォッチ、さまざまなアラーム、および1時間ごとの迷惑なビープ音。そうでない場合は、90年代のデジタル時計をご覧ください。
つまり、基本的には、さまざまなモードで構成可能な時計です。主に現在時刻が表示されますが、他にもいくつかの機能があります。入力として、オン/オフがあります 、モード およびセット ボタン。さらに、ライトのオンとオフを切り替えることができます。
モードを使用 ボタンを押すと、モードを区別したり、時計機能を有効/無効にしたりできます。
- 時刻を表示する(時計)
- 日付(日付)を表示する
- アラームを設定します(アラーム1、アラーム2)
- チャイムの有効化/無効化(チャイムの設定)
- ストップウォッチを使用する(ストップウォッチ)
メニュー内でオン/オフを使用できます ボタンをクリックしてモードを設定します。 セット ボタンを使用すると、時間を設定できます-例:時計やアラームのために。ストップウォッチは、ライトオンボタンとライトオフボタンを使用して制御(開始および停止)できます。統合されたラップカウンターを使用することもできます。
さらに、私たちのすべてを鐘を鳴らすチャイムがあり、制御可能なバックライトが統合されています。最初のステップでは、それらをArduinoに配線しませんでした。
ステートマシン <図> <図> <図> <図> <図> <図>
この例の説明については、あまり詳しく説明したくありません。複雑すぎるからではなく、少し大きすぎます。それがどのように機能するかの基本的な考え方を説明しようと思います。モデルを確認するか、モデルをダウンロードしてシミュレートすることにより、実行は自明である必要があります。 set time のように、ステートマシンの一部はサブリージョンにまとめられます。 領域。これにより、ステートマシンの可読性を確保する必要があります。
モデルは、グラフィックとテキストの2つの部分に分割されます。テキスト部分では、イベント、変数などが定義されます。グラフィック部分(状態図)では、モデルの論理実行が指定されています。指定された動作を満たすステートマシンを作成するには、モデルで使用できるいくつかの入力イベントが必要です。 onoff 、セット 、モード 、ライト 、および light_r。 定義セクション内では、100ミリ秒ごとに時間値をインクリメントする内部イベントが使用されます。
100 ms /時間ごと+ =1
100ミリ秒のステップに基づいて、現在の時刻が HH:MM:SS で計算されます。 フォーマット:
display.first =(time / 36000)%24;
display.second =(time / 600)%60;
display.third =(time / 10)%60;
値は、操作 updateLCD を使用して、LCDディスプレイに配線されます。 ステートマシンが呼び出されるたび:
display.updateLCD(display.first、display.second、display.third、display.text)
ステートマシンの基本的な実行は、デジタル時計の仕組みのセクションですでに定義されています。 。ツール内で、 CompositeState のようないくつかの「特別な」モデリング要素を使用しました。 、履歴 、サブ図 、 ExitNodes、 など。詳細な説明は、ユーザーガイドに記載されています。
LCDキーパッドシールド
LCDキーパッドシールドは、視覚化のための画面と入力としていくつかのボタンを必要とする単純なプロジェクト(典型的な単純なHMI(ヒューマンマシンインターフェイス))には非常に優れています。 LCDキーパッドシールドには、5つのユーザーボタンとリセット用のもう1つのボタンが含まれています。 5つのボタンはすべて一緒にArduinoのA0ピンに接続されています。それぞれが分圧器に接続されており、ボタンを区別することができます。
analogRead(0)を使用して特定の値を見つけることができますが、もちろんメーカーによって異なる場合があります。この単純なプロジェクトは、LCDに現在の値を表示します:
#include
#include
LiquidCrystal lcd(8、9、4、5、6、7);
void setup(){
lcd.begin(16、2);
lcd.setCursor(0,0);
lcd.write( "測定値");
}
void loop(){
lcd.setCursor(0,1);
lcd.print( "");
lcd。 setCursor(0,1);
lcd.print(analogRead(0));
delay(200);
}
これらは私の測定結果です:
- なし:1023
- 選択:640
- 左:411
- ダウン:257
- 最大:100
- 右:0
これらのしきい値を使用すると、ボタンを読み取ることができます。
#define NONE 0
#define SELECT 1
#define LEFT 2
#define DOWN 3
#define UP 4
#define RIGHT 5
static int readButton(){
int result =0;
result =analogRead(0);
if(result <50){
return右;
}
if(result <150){
return UP;
}
if(result <300){
return DOWN;
}
if(result <550){
return LEFT;
}
if(result <850){
return SELECT;
}
return NONE;
}
ステートマシンとのインターフェース
ステートマシンの生成されたC ++コードは、ステートマシンを制御するために実装する必要があるインターフェイスを提供します。最初のステップは、inイベントをキーパッドシールドのキーに接続することです。ボタンの読み方についてはすでに説明しましたが、ボタンをステートマシンに接続するには、ボタンをデバウンスする必要があります。そうしないと、イベントが複数回発生し、予期しない動作が発生します。ソフトウェアデバウンスの概念は新しいものではありません。 Arduinoのドキュメントを見ることができます。
私の実装では、立ち下がりエッジを検出します(ボタンを離します)。ボタンの値を読み取り、80ミリ秒待って(50ではなく80でより良い結果が得られました)、結果を保存して新しい値を読み取ります。 oldResult の場合 NONE ではありませんでした (押されていない)そして新しい結果は NONE 、私は知っています、ボタンは以前に押されていて、現在は離されています。次に、ステートマシンのそれに応じた入力イベントを発生させます。
int oldState =NONE;
static void raiseEvents(){
int buttonPressed =readButton();
delay(80);
oldState =buttonPressed;
if(oldState!=NONE &&readButton()==NONE){
switch(oldState){
case SELECT:{
stateMachine-> getSCI_Button()-> raise_mode();
break;
}
case LEFT:{
stateMachine-> getSCI_Button()-> raise_set();
break;
}
ケースダウン:{
stateMachine-> getSCI_Button()-> raise_light();
break;
}
ケースアップ:{
stateMachine-> getSCI_Button() -> raise_light_r();
break;
}
case RIGHT:{
stateMachine-> getSCI_Button()-> raise_onoff();
break;
}
デフォルト:{
break;
}
}
}
}
一緒に配線する
メインプログラムは3つの部分を使用します:
- ステートマシン
- タイマー
- ディスプレイハンドラー(通常はlcd.print(...))
DigitalWatch * stateMachine =new DigitalWatch();
CPPTimerInterface * timer_sct =new CPPTimerInterface();
DisplayHandler * displayHandler =new DisplayHandler();
ステートマシンはディスプレイハンドラーを使用し、タイマーを取得します。タイマーは、時限イベントを制御するために更新されます。その後、ステートマシンが初期化されて入力されます。
void setup(){
stateMachine-> setSCI_Display_OCB(displayHandler);
stateMachine-> setTimer(timer_sct);
stateMachine-> init();
stateMachine-> enter();
}
ループは3つのことを行います:
- 入力イベントを発生させる
- 経過時間を計算してタイマーを更新します
- ステートマシンを呼び出す
long current_time =0;
long last_cycle_time =0;
void loop(){
raiseEvents();
last_cycle_time =current_time;
current_time =millis();
timer_sct-> updateActiveTimer(stateMachine、
current_time --last_cycle_time);
stateMachine-> runCycle();
}
例を見る
それでおしまい。おそらく、実装の詳細については触れていませんが、例を見るか、コメントを残すことができます。
次のコマンドを使用して、実行中のIDEに例を追加します。
ファイル->新規->例-> YAKINDUステートチャートの例->次へ-> Arduino-デジタル時計(C ++)
>>ここからIDEをダウンロードできます<<
30日間のトライアルから始めることができます。その後、ライセンスを取得する必要があります。このライセンスは、非営利目的での使用は無料です。 !
製造プロセス