Зависание ардуино во время работы

Tagir
Offline
Зарегистрирован: 18.01.2018

Сделал вольтамперваттметр с некоторыми дополнительными функциями. Все вроде как работает, однако прямо во время работы просто зависает и все, Никакие значения не выдаёт и все стоит.

Вот код:

[code]

#define button1B 4  // пин кнопки button1
#define button2B 5
boolean button1S;   // храним состояния кнопок (S - State)
boolean button1F;   // флажки кнопок (F - Flag)
boolean button1R;   // флажки кнопок на отпускание (R - Release)
boolean button1P;   // флажки кнопок на нажатие (P - Press)
boolean button1H;   // флажки кнопок на удержание (многократный вызов) (H - Hold)
boolean button1HO;  // флажки кнопок на удержание (один вызов при нажатии) (HO - Hold Once)
boolean button1D;   // флажки кнопок на двойное нажатие (D - Double)
boolean button1DP;  // флажки кнопок на двойное нажатие и отпускание (D - Double Pressed)
boolean button2S;   // храним состояния кнопок (S - State)
boolean button2F;   // флажки кнопок (F - Flag)
boolean button2R;   // флажки кнопок на отпускание (R - Release)
boolean button2P;   // флажки кнопок на нажатие (P - Press)
boolean button2H;   // флажки кнопок на удержание (многократный вызов) (H - Hold)
boolean button2HO;  // флажки кнопок на удержание (один вызов при нажатии) (HO - Hold Once)
boolean button2D;   // флажки кнопок на двойное нажатие (D - Double)
boolean button2DP;  // флажки кнопок на двойное нажатие и отпускание (D - Double Pressed)
 
 
#define double_timer 100   // время (мс), отведённое на второе нажатие
#define hold 500           // время (мс), после которого кнопка считается зажатой
#define debounce 80        // (мс), антидребезг
unsigned long button1_timer; // таймер последнего нажатия кнопки
unsigned long button1_double; // таймер двойного нажатия кнопки
unsigned long button2_timer; // таймер последнего нажатия кнопки
unsigned long button2_double; // таймер двойного нажатия кнопки
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27,20,4); // задаем адрес устройства,к-во символов,к-во строк
 
int analogInput = A0; // переменная для удобства инициализации и работы с аналог. портом 0
float vout = 0.0; // переменная с значением выходного напряжения
float vin = 0.0; // переменная с результатом измерений
float R1 = 97700.0; // сопротивление R1
float R2 = 9970.0; // сопротивление R2
int value = 0; // переменная хранения данных
float I = 0.0;
float Imax = 0.0;
int mVperAmp = 100;
int RawValue = 0;
double Voltage = 0;
double Amps = 0;
int ACSoffset = 2500;
float P = 0.0;
 
void buttons() {
  //-------------------------button1--------------------------
  // нажали (с антидребезгом)
  if (button1S && !button1F && millis() - button1_timer > debounce) {
    button1F = 1;
    button1HO = 1;
    button1_timer = millis();
  }
  // если отпустили до hold, считать отпущенной
  if (!button1S && button1F && !button1R && !button1DP && millis() - button1_timer < hold) {
    button1R = 1;
    button1F = 0;
    button1_double = millis();
  }
  // если отпустили и прошло больше double_timer, считать 1 нажатием
  if (button1R && !button1DP && millis() - button1_double > double_timer) {
    button1R = 0;
    button1P = 1;
  }
  // если отпустили и прошло меньше double_timer и нажата снова, считать что нажата 2 раз
  if (button1F && !button1DP && button1R && millis() - button1_double < double_timer) {
    button1F = 0;
    button1R = 0;
    button1DP = 1;
  }
  // если была нажата 2 раз и отпущена, считать что была нажата 2 раза
  if (button1DP && millis() - button1_timer < hold) {
    button1DP = 0;
    button1D = 1;
    button1_timer = millis();
  }
  // Если удерживается более hold, то считать удержанием
  if (button1F && !button1D && !button1H && millis() - button1_timer > hold) {
    button1H = 1;
  }
  // Если отпущена после hold, то считать, что была удержана
  if (!button1S && button1F && millis() - button1_timer > hold) {
    button1F = 0;
    button1H = 0;
    button1_timer = millis();
  }
  if (button2S && !button2F && millis() - button2_timer > debounce) {
    button2F = 1;
    button2HO = 1;
    button2_timer = millis();
  }
  // если отпустили до hold, считать отпущенной
  if (!button2S && button2F && !button2R && !button2DP && millis() - button2_timer < hold) {
    button2R = 1;
    button2F = 0;
    button2_double = millis();
  }
  // если отпустили и прошло больше double_timer, считать 1 нажатием
  if (button2R && !button2DP && millis() - button2_double > double_timer) {
    button2R = 0;
    button2P = 1;
  }
  // если отпустили и прошло меньше double_timer и нажата снова, считать что нажата 2 раз
  if (button2F && !button2DP && button2R && millis() - button2_double < double_timer) {
    button2F = 0;
    button2R = 0;
    button2DP = 1;
  }
  // если была нажата 2 раз и отпущена, считать что была нажата 2 раза
  if (button2DP && millis() - button2_timer < hold) {
    button2DP = 0;
    button2D = 1;
    button2_timer = millis();
  }
  // Если удерживается более hold, то считать удержанием
  if (button2F && !button2D && !button2H && millis() - button2_timer > hold) {
    button2H = 1;
  }
  // Если отпущена после hold, то считать, что была удержана
  if (!button2S && button2F && millis() - button2_timer > hold) {
    button2F = 0;
    button2H = 0;
    button2_timer = millis();
  }
  
  //-------------------------button1--------------------------
}
//------------------------ОТРАБОТКА КНОПОК-------------------------
 
void setup()
{
pinMode(analogInput, INPUT); // инициализируем аналоговый порт 0, как вход
pinMode(2, OUTPUT);
pinMode(A1, INPUT);
pinMode(3,OUTPUT);
pinMode(button1B, INPUT_PULLUP);
pinMode(12, OUTPUT);
Serial.begin(9600);
digitalWrite(8, 1);
 
lcd.init(); // производим инициализацию LCD
lcd.clear(); // очищаем экран
lcd.backlight();
}
void loop() // производим чтение аналогового сигнала и выводим на дисплей
{
    //-------опрос кнопок--------
  button1S = !digitalRead(button1B);
  buttons(); //отработка кнопок
  //-------опрос кнопок--------
 
  // отработка режимов (опускание флага обязательно!)
  if (button1P) {
    Imax += 0.1;
    button1P = 0;
  }
  if (button1D) {
    Imax++;
    button1D = 0;
  }
  if (button1H && button1HO) {
    while(true) {
      Imax += 0.1;
      if(button1R) {
        break;
      }
    }
     button1HO = 0;
  }
     //-------опрос кнопок--------
  button2S = !digitalRead(button2B);
  buttons(); //отработка кнопок
  //-------опрос кнопок--------
 
  // отработка режимов (опускание флага обязательно!)
  if (button2P) {
    Imax -= 0.1;
    button2P = 0;
  }
  if (button2D) {
    Imax--;
    button2D = 0;
  }
if (button2H && button2HO) {
    while(true) {
      Imax -= 0.1;
      if(button2R) {
        break;
      }
    }
     button2HO = 0;
}
value = analogRead(analogInput);// читаем аналоговый сигнал, с аналог. порта - 0
vout = (value * 5.0) / 1024.0; // не забываем про внесение поправки (5.0 - это идеальный вариант,хотя все возможно)
vin = vout / (R2/(R1+R2)); // в переменной будет значение входного напряжения
if (vin<0.09) // проверка, для получ. 0
{
vin=0.0; // обнуляем нежелательное значение
}
if (vin<10) {
digitalWrite (2, 1);
}
if (vin>10) {
digitalWrite (2, 0);
 
}
RawValue = analogRead(A1);
Voltage = (RawValue / 1024.0) * 5000;
Amps = ((Voltage - ACSoffset) / mVperAmp);
I = Amps;
P = I * vin;
lcd.clear();
lcd.print(vin);// выводим значение напряжения, что на входе
lcd.print("V ");
Serial.println(vin);
lcd.print(P);
Serial.println(P);
lcd.print("W");
lcd.setCursor(0, 1);
lcd.print(I);
Serial.println(I);
lcd.print("A");
lcd.print(Imax); // выводим надпись Imax на lCD
lcd.print("A");
 
if (I >= Imax) {
  lcd.clear();
  lcd.print("currect exeeded");
  digitalWrite (3, 1);
  if (button1P) {
    digitalWrite(12, 1);
    button1P = 0;
  }
 
}
delay(500); // задержка 500 мс.
}
 
[/code]
 
DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ответ: в циклах while(true) никак не обновляется состояние кнопок, поэтому виснет в одном из таких циклов.

Tagir
Offline
Зарегистрирован: 18.01.2018

А что сделать для исправления? Я кнопку то пока вообще и не подцеплял 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Tagir пишет:

А что сделать для исправления? Я кнопку то пока вообще и не подцеплял 

Код вы писали? Тогда знаете, что нужно сделать. Проблему я вам обрисовал.

Tagir
Offline
Зарегистрирован: 18.01.2018

Хорошо, спасибо!