状态机的 Arduino 状态机问题
Arduino State Machine issue with a state machine
所以我想制作一个状态机,它从用户那里获取输入字母并输出莫尔斯码
使用 LED。我使用了一个开关,但出于某种原因它不想工作。它只适用于
字母 a,当我添加另一个字母时它停止工作。
我使用了 3 个函数(点、线和暂停)并将它们组合起来用于 LED 的闪烁。我们学校不允许使用“延迟()”所以我做了一个计时器。
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define STATUS_IDLE (0)
#define STATUS_A (1)
#define STATUS_B (2)
// Global Variables
unsigned char status;
unsigned long int t_ref; // Reference time
unsigned char last_PINB;
unsigned char mainStatus;
// define inputs and outputs
#define OUTPUT_H1_LAMPE (PC0)
// whenever a variable is used by both, Interrupt and main programm we
// need to tell the compiler about it ==> volatile
volatile unsigned long int millisekunden; // milli seconds timer
unsigned long int last_msg; //
char buffer[128];
unsigned int c;
unsigned int counter;
void setup() {
DDRC |= (1 << OUTPUT_H1_LAMPE);
// Timer 0 konfigurieren
TCCR0A = (1 << WGM01); // CTC Modus
TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
// ((16000000/64)/1000) = 25
OCR0A = 250;
// Compare Interrupt erlauben
TIMSK0 |= (1 << OCIE0A);
Serial.begin(9600);
}
int last_char = -1;
void dot() {
while (millisekunden - t_ref <= 300) {
if (millisekunden - t_ref > 300) {
t_ref = millisekunden;
break;
}
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
}
void line() {
while (millisekunden - t_ref <= 900) {
if (millisekunden - t_ref > 900) {
t_ref = millisekunden;
break;
}
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
}
void pause() {
while (millisekunden - t_ref <= 300) {
if (millisekunden - t_ref > 300) {
t_ref = millisekunden;
break;
}
PORTC &= ~(1 << OUTPUT_H1_LAMPE);
}
}
void loop() {
if (millisekunden - last_msg >=1000) {
sprintf(buffer, "t=[%lu] state=[%d] PORTC=[%2.2x] t_ref=[%lu]",
millisekunden, mainStatus, PORTC, t_ref);
Serial.println(buffer);
last_msg = millisekunden;
}
// user input => get key ...
if (Serial.available())
{
last_char = Serial.read(); // Read a character
sprintf(buffer, "you have pressed the [%c]-key", (char)last_char);
Serial.println(buffer);
}
if (tolower(last_char) == 'a') {
t_ref = millisekunden;
mainStatus = STATUS_A;
last_char = -1;
}
if (tolower(last_char) == 'b') {
t_ref = millisekunden;
mainStatus = STATUS_B;
last_char = -1;
}
switch (mainStatus) {
case STATUS_IDLE:
PORTC &= ~(1 << OUTPUT_H1_LAMPE);
break;
case STATUS_A:
dot();
pause();
line();
mainStatus = STATUS_IDLE;
break;
case STATUS_B:
line();
pause();
dot();
pause();
dot();
pause();
dot();
mainStatus = STATUS_IDLE;
break;
}
}
// Timer-Interrupt-Routine
ISR(TIMER0_COMPA_vect) {
millisekunden++;
}```
这段代码可以说很多。我真的不明白你为什么要那样做。但是,如果我进行最小的更改以使您的代码正常工作,则如下所示。
您在 dot
、line
、pause
:
中重复了这种模式
while (millisekunden - t_ref <= 300) {
if (millisekunden - t_ref > 300) {
t_ref = millisekunden;
break;
}
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
我已经为以上内容选择了 dot
。偶尔会发生 millisekunden - t_ref <= 300
为假,而 millisekunden - t_ref > 300
从未为真。同样,我不明白你为什么要这样做。但是,最终结果是,有时您的循环会在执行 t_ref = millisekunden
后退出,有时它会在未执行该操作的情况下退出。
如果将这些更改为:
while (millisekunden - t_ref <= 300) {
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
t_ref = millisekunden;
通过这种安排,您对 t_ref
的更新将始终在循环退出时发生,并且程序的行为或多或少符合我的预期,希望是您预期的方式。
继续设置 PORTC
中的位也没有任何意义,但正如我所说,最小的变化。
所以我想制作一个状态机,它从用户那里获取输入字母并输出莫尔斯码 使用 LED。我使用了一个开关,但出于某种原因它不想工作。它只适用于 字母 a,当我添加另一个字母时它停止工作。
我使用了 3 个函数(点、线和暂停)并将它们组合起来用于 LED 的闪烁。我们学校不允许使用“延迟()”所以我做了一个计时器。
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define STATUS_IDLE (0)
#define STATUS_A (1)
#define STATUS_B (2)
// Global Variables
unsigned char status;
unsigned long int t_ref; // Reference time
unsigned char last_PINB;
unsigned char mainStatus;
// define inputs and outputs
#define OUTPUT_H1_LAMPE (PC0)
// whenever a variable is used by both, Interrupt and main programm we
// need to tell the compiler about it ==> volatile
volatile unsigned long int millisekunden; // milli seconds timer
unsigned long int last_msg; //
char buffer[128];
unsigned int c;
unsigned int counter;
void setup() {
DDRC |= (1 << OUTPUT_H1_LAMPE);
// Timer 0 konfigurieren
TCCR0A = (1 << WGM01); // CTC Modus
TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64
// ((16000000/64)/1000) = 25
OCR0A = 250;
// Compare Interrupt erlauben
TIMSK0 |= (1 << OCIE0A);
Serial.begin(9600);
}
int last_char = -1;
void dot() {
while (millisekunden - t_ref <= 300) {
if (millisekunden - t_ref > 300) {
t_ref = millisekunden;
break;
}
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
}
void line() {
while (millisekunden - t_ref <= 900) {
if (millisekunden - t_ref > 900) {
t_ref = millisekunden;
break;
}
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
}
void pause() {
while (millisekunden - t_ref <= 300) {
if (millisekunden - t_ref > 300) {
t_ref = millisekunden;
break;
}
PORTC &= ~(1 << OUTPUT_H1_LAMPE);
}
}
void loop() {
if (millisekunden - last_msg >=1000) {
sprintf(buffer, "t=[%lu] state=[%d] PORTC=[%2.2x] t_ref=[%lu]",
millisekunden, mainStatus, PORTC, t_ref);
Serial.println(buffer);
last_msg = millisekunden;
}
// user input => get key ...
if (Serial.available())
{
last_char = Serial.read(); // Read a character
sprintf(buffer, "you have pressed the [%c]-key", (char)last_char);
Serial.println(buffer);
}
if (tolower(last_char) == 'a') {
t_ref = millisekunden;
mainStatus = STATUS_A;
last_char = -1;
}
if (tolower(last_char) == 'b') {
t_ref = millisekunden;
mainStatus = STATUS_B;
last_char = -1;
}
switch (mainStatus) {
case STATUS_IDLE:
PORTC &= ~(1 << OUTPUT_H1_LAMPE);
break;
case STATUS_A:
dot();
pause();
line();
mainStatus = STATUS_IDLE;
break;
case STATUS_B:
line();
pause();
dot();
pause();
dot();
pause();
dot();
mainStatus = STATUS_IDLE;
break;
}
}
// Timer-Interrupt-Routine
ISR(TIMER0_COMPA_vect) {
millisekunden++;
}```
这段代码可以说很多。我真的不明白你为什么要那样做。但是,如果我进行最小的更改以使您的代码正常工作,则如下所示。
您在 dot
、line
、pause
:
while (millisekunden - t_ref <= 300) {
if (millisekunden - t_ref > 300) {
t_ref = millisekunden;
break;
}
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
我已经为以上内容选择了 dot
。偶尔会发生 millisekunden - t_ref <= 300
为假,而 millisekunden - t_ref > 300
从未为真。同样,我不明白你为什么要这样做。但是,最终结果是,有时您的循环会在执行 t_ref = millisekunden
后退出,有时它会在未执行该操作的情况下退出。
如果将这些更改为:
while (millisekunden - t_ref <= 300) {
PORTC |= (1 << OUTPUT_H1_LAMPE);
}
t_ref = millisekunden;
通过这种安排,您对 t_ref
的更新将始终在循环退出时发生,并且程序的行为或多或少符合我的预期,希望是您预期的方式。
继续设置 PORTC
中的位也没有任何意义,但正如我所说,最小的变化。