Отработка нажатия вне процедуры
- Войдите на сайт для отправки комментариев
Доброго времени суток! В программировании я новичек. Делаю блок запуска двигателя автомобиля.По плану: блок полностью эмулирует работу штатного замка зажигания, запуск двигателя производится педалью тормоза, контроль запуска по сигналу с тахометра. Сейчас на машине стоит схема на реле ЗПТФ (около 2 лет уже эксплуатируется).
Не могу разобраться с кодом, а именно почему выполняется обработка нажатия кнопки, когда по коду программа находится в функции, в которой таких условий нет. На 91 строчке процедура обработки входа "brake" и управления выходом "ST" . При первом запуске платы все проходит нормально, ложных срабатываний нет. Также все хорошо, если последовательно выполнить процедуры "off","acc","ign","start". Но если пропустить процедуру "start" и перейти к "off", то по высокому уровню входа "brake" произвольное количество раз выполняется процедура "start", причем может выполниться один раз и затихнуть, а может и 4, а потом все-таки остановиться.
Прошу помоши, уже второй день голову ломаю ;)
/*global setup*/
const int button = 5; //button pin
const int brake = 3; // brake pin
const int ACC = 6; //acc pin
const int IGN = 7; //ign pin
const int ST = 8; //starter pin
/*variables*/
int MOD = 0; //mode switch
/*debounce*/
int buttonState;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
/*rpm counter*/
float value = 0;
volatile float rev = 0;
int RPM = 0;
int oldtime = 0;
int Time = 0;
void isr() //interrupt service routine
{
rev++;
}
void setup() {
attachInterrupt(digitalPinToInterrupt(2), isr, RISING); //attaching the interrupt
Serial.begin(9600); //debug
pinMode(button, INPUT_PULLUP);//enable built-in pullups
pinMode(brake, INPUT_PULLUP);
pinMode(ACC, OUTPUT); //setup relays
pinMode(IGN, OUTPUT);
pinMode(ST, OUTPUT);
digitalWrite(button, HIGH); //pullups
digitalWrite(button, HIGH);
digitalWrite(ACC, LOW); //set initial state
digitalWrite(IGN, LOW); //on relays
digitalWrite(ST, LOW); //
}
void rpm() {
Time = millis() - oldtime; //finds the time
detachInterrupt(digitalPinToInterrupt(2));
RPM = (rev / Time) * 60000; //calculates rpm
oldtime = millis(); //saves the current time
rev = 0;
//Serial.print("RPM =");
//Serial.print(RPM);
attachInterrupt(digitalPinToInterrupt(2), isr, RISING);
}
void mode() { //switch mode
if (MOD == 0) {
Serial.println("!!!PROGRAM BEGIN!!!");
}
if (MOD == 1) {
off();
}
if (MOD == 2) {
acc();
}
if (MOD == 3) {
ign();
}
}
void off() { //relay off, stop engine
Serial.println("All off");
digitalWrite(ACC, LOW);
digitalWrite(IGN, LOW);
digitalWrite(ST, LOW);
RPM = 0; //set rpm "0"
}
void acc() { //ACC on
Serial.println("ACC");
digitalWrite(ACC, HIGH);
digitalWrite(IGN, LOW);
digitalWrite(ST, LOW);
}
void ign() { //ACC+IGN on, wait for pressing brake then start
Serial.println("ACC+IGN-on");
digitalWrite(ST, LOW);
digitalWrite(ACC, HIGH);
digitalWrite(IGN, HIGH);
//delay(500);
while (RPM <= 800) { //if engine stop
rpm(); //read rpm
buttonstate(); //read button if no need to start engine
if (digitalRead(brake) == HIGH) {
delay(30);
st(); //goto start procedure
break;
}
}
}
void st() { //starter procedure
digitalWrite(ACC, LOW);
digitalWrite(ST, HIGH);
Serial.println("Starting!!!!!");
while (digitalRead(brake) == HIGH) { //cycle
rpm();
if (RPM >= 1000) {
break;
}
}
mode();
}
void buttonstate() { //read state of button ,debounce, increase counter
int reading = digitalRead(button);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
MOD = ++MOD;
mode(); //call mode switch procedure
}
}
}
lastButtonState = reading;
if (MOD == 4) { //set max counter
MOD = 1;
mode();
}
}
void loop() { //infinitelly call button reading
buttonstate();
}