Всем привет. Посмотрите пожалуйста мой код. Закралась ошибка. Не могу ее вычислить.
Данный код предназначен для управление коллекторным двигателем. В данном случае приводом медогонки.
Предполагается работа в двух режимах - ручном и автоматическом.
Ручной режим : нажали кнопку"Старт" - Двигатель плавно разгоняется до заданного значения - Продолжает работать с заданной скоростью при удержании кнопки Старт- остановка при отпускании
Автоматический режим : Однократное нажатие на Старт - Плавный разгон - Работа на заданной скорости нужное время - Остановка
Выбор между режимами производится переключением двухпозиционной кнопкой(типа тумблер).
Сам код :
#define SMOOTH_TIME 15000 // время разгона от нуля до макс. в милисек
//#define HOLD_TIME 80
const int pwmPin = 9;//подключ. двигателя
const int Speed = A0;
const int Time = A1;
const int MIN_speed = 0; //мин. частота вращ. двигателя
const int MAX_speed = 85;// макс. частота вращ двигателя
const int MIN_time = 10;//мин. время работы программы в сек.
const int MAX_time = 300;////макс. время работы программы в сек.
long previousMillis = 0;
long MotorDelay = 0;
long interval = SMOOTH_TIME/255;//скорость разгона двигателя
int i = 0;
int val_1 = 0;
int val_prc;
long val_2 = 0;
boolean MotorRun = false ;//начальное состояние двигателя
#include <LiquidCrystal_I2C.h> //библиотека дисплея
LiquidCrystal_I2C lcd(0x27,16,2);
#include <GyverButton.h> //библиотека работы с кнопкой и назначения кнопок управления
GButton Button(2, LOW_PULL, NORM_OPEN);
GButton Manual(5, LOW_PULL, NORM_OPEN);
GButton Auto(7, LOW_PULL, NORM_OPEN);
void setup()
{
pinMode(pwmPin, OUTPUT);
pinMode(Speed, INPUT);
pinMode(Time, INPUT);
//Button.setTickMode(MANUAL);
Serial.begin(9600);
lcd.init(); // Инициализация дисплея
lcd.backlight(); // Подключение подсветки
lcd.setCursor(0,0); // Установка курсора в начало первой строки
lcd.print("PrivodMedogonki"); // Набор текста на первой строке
lcd.setCursor(8,1); // Установка курсора в начало второй строки
lcd.print("Vers.1");
delay(1000);
}
void loop ()//выбор режима работы и вывод инфо на экран
{
Manual.tick();//опрос кнопки перехода в ручной режим управления
Auto.tick();//опрос кнопки перехода в автоматический режим управления
if (Auto.isHold())//если удержана кнопка автоматич.работы
{
MotorRunAuto();
Serial.println("Auto");
}
else if (Manual.isHold())//если удержана кнопка ручной.работы
{
MotorRunManual();
Serial.println("Manual");
}
else if (!Manual.isHold()&& !Auto.isHold())//не выбран режим работы
{
i = 0;
analogWrite(pwmPin,i);
Serial.println("Vubor");
MotorRun = false ;
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("PrivodMedogonki");
lcd.setCursor(0,1);
lcd.print(" "); // Набор текста на первой строке
lcd.setCursor(2,1); // Установка курсора в начало второй строки
lcd.print("Vyberi_rezim");
}
else if (Manual.isHold()&& Auto.isHold())//аварийный вариает
{
i = 0;
analogWrite(pwmPin,i);
Serial.println("Oshibka");
MotorRun = false ;
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("PrivodMedogonki");
lcd.setCursor(0,1);
lcd.print(" "); // Набор текста на первой строке
lcd.setCursor(4,1); // Установка курсора в начало второй строки
lcd.print("Oshibka");
}
delay (100);
}
void MotorRunAuto() //функция автоматич. управления
{
Serial.println(MotorRun);
//MotorRun = false ;///!!!!
lcd.setCursor(0,0); //вывод параметров работы на экран
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("Auto: Speed %");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" Time c");
val_1=analogRead(Speed); //читаем потенциометр на частоту вращ. двигателя
val_1=map(val_1, 0, 1023, MIN_speed , MAX_speed);
val_1=constrain(val_1, 0, 255);
val_prc=val_1*100/MAX_speed;//перевод заданного значения в проценты от максимума
lcd.setCursor(12,0);//вывод значенияв процентах на экран
lcd.print(val_prc);
val_2=analogRead(Time);//читаем потенциометр на время работы двигателя
val_2=map(val_2, 0, 1023, MIN_time , MAX_time);
lcd.setCursor(12,1);//вывод времени работы на экран
lcd.print(val_2);
//val_2=constrain(val, 0, 255);
//i=MIN_speed;
//Serial.println(val_2);
Button.tick();//опрос кнопки на начало работы
Serial.println(MotorRun);
if(Button.isHolded())//если кнопка нажата
{
MotorRun = true;//разрешить работу
Serial.println("AutoStart");
//Serial.println(MotorRun);
}
if (MotorRun == true)
{
unsigned long currentMillis = millis();//начало разгона двигателя
if(currentMillis-previousMillis > interval)
{
previousMillis = currentMillis;
analogWrite(pwmPin,i);
i ++;
//Serial.println(i);
if (i > val_1)
{
i = val_1;
//Serial.println(i);
analogWrite(pwmPin,i);
unsigned long MotorTime = millis(); //выдержка времени после выхода на режим
if (MotorTime - MotorDelay > val_2*1000)
{
MotorDelay = MotorTime;
i = 0;
analogWrite(pwmPin,i);
//Serial.println(millis());
MotorRun = false ;
Serial.println(MotorRun);
}
}
}
}
else /*if (!Button.isPress())*///если кнопка не нажата
{
MotorRun = false ;//запрет работы
i=0;
analogWrite(pwmPin,i);
Serial.println("AutoStop");
//Serial.println(MotorRun);
}
}
void MotorRunManual() //функция ручного управления по аналогии с автоматическим режимом
{
Serial.println(MotorRun);
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("Manual: ");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" Speed %");
val_1=analogRead(Speed);
val_1=map(val_1, 0, 1023, MIN_speed , MAX_speed);
val_1=constrain(val_1, 0, 255);
val_prc=val_1*100/MAX_speed;
lcd.setCursor(12,1);
lcd.print(val_prc);
//i=MIN_speed;
//Serial.println(i);
Serial.println(MotorRun);
Button.tick();
if(Button.isHold())//если кнопка нажата
{
Serial.println("ManualStart");
unsigned long currentMillis = millis();//начало разгона
if(currentMillis-previousMillis > interval)
{
previousMillis = currentMillis;
analogWrite(pwmPin,i);
i ++;
if (i>val_1)//работа с постоянной частотой вращения
{
i = val_1;
}
}
}
else /* (Button.isRelease())//если кнопка отпушена*/
{
//
i=0;
analogWrite(pwmPin,i);
MotorRun = false ;//запрет работы
Serial.println("ManualStop");
//Serial.println(MotorRun);
}
}
Ошибка проявляет себя так : каждый режим по отдельности работает нормально. Но если произвели старт двигателя в ручном режиме, а затем произвели переход в автоматический режим происходит однократное выполнение программы самопроизвольно. Такое чувство как-будто программа запоминает состояние кнопки Старт в ручном режиме и при переходе в автоматический режим не обнуляет состояние кнопки
Данный код предназначен для управление коллекторным двигателем. В данном случае приводом медогонки.
Предполагается работа в двух режимах - ручном и автоматическом.
Ручной режим : нажали кнопку"Старт" - Двигатель плавно разгоняется до заданного значения - Продолжает работать с заданной скоростью при удержании кнопки Старт- остановка при отпускании
Автоматический режим : Однократное нажатие на Старт - Плавный разгон - Работа на заданной скорости нужное время - Остановка
Выбор между режимами производится переключением двухпозиционной кнопкой(типа тумблер).
Сам код :
#define SMOOTH_TIME 15000 // время разгона от нуля до макс. в милисек
//#define HOLD_TIME 80
const int pwmPin = 9;//подключ. двигателя
const int Speed = A0;
const int Time = A1;
const int MIN_speed = 0; //мин. частота вращ. двигателя
const int MAX_speed = 85;// макс. частота вращ двигателя
const int MIN_time = 10;//мин. время работы программы в сек.
const int MAX_time = 300;////макс. время работы программы в сек.
long previousMillis = 0;
long MotorDelay = 0;
long interval = SMOOTH_TIME/255;//скорость разгона двигателя
int i = 0;
int val_1 = 0;
int val_prc;
long val_2 = 0;
boolean MotorRun = false ;//начальное состояние двигателя
#include <LiquidCrystal_I2C.h> //библиотека дисплея
LiquidCrystal_I2C lcd(0x27,16,2);
#include <GyverButton.h> //библиотека работы с кнопкой и назначения кнопок управления
GButton Button(2, LOW_PULL, NORM_OPEN);
GButton Manual(5, LOW_PULL, NORM_OPEN);
GButton Auto(7, LOW_PULL, NORM_OPEN);
void setup()
{
pinMode(pwmPin, OUTPUT);
pinMode(Speed, INPUT);
pinMode(Time, INPUT);
//Button.setTickMode(MANUAL);
Serial.begin(9600);
lcd.init(); // Инициализация дисплея
lcd.backlight(); // Подключение подсветки
lcd.setCursor(0,0); // Установка курсора в начало первой строки
lcd.print("PrivodMedogonki"); // Набор текста на первой строке
lcd.setCursor(8,1); // Установка курсора в начало второй строки
lcd.print("Vers.1");
delay(1000);
}
void loop ()//выбор режима работы и вывод инфо на экран
{
Manual.tick();//опрос кнопки перехода в ручной режим управления
Auto.tick();//опрос кнопки перехода в автоматический режим управления
if (Auto.isHold())//если удержана кнопка автоматич.работы
{
MotorRunAuto();
Serial.println("Auto");
}
else if (Manual.isHold())//если удержана кнопка ручной.работы
{
MotorRunManual();
Serial.println("Manual");
}
else if (!Manual.isHold()&& !Auto.isHold())//не выбран режим работы
{
i = 0;
analogWrite(pwmPin,i);
Serial.println("Vubor");
MotorRun = false ;
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("PrivodMedogonki");
lcd.setCursor(0,1);
lcd.print(" "); // Набор текста на первой строке
lcd.setCursor(2,1); // Установка курсора в начало второй строки
lcd.print("Vyberi_rezim");
}
else if (Manual.isHold()&& Auto.isHold())//аварийный вариает
{
i = 0;
analogWrite(pwmPin,i);
Serial.println("Oshibka");
MotorRun = false ;
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("PrivodMedogonki");
lcd.setCursor(0,1);
lcd.print(" "); // Набор текста на первой строке
lcd.setCursor(4,1); // Установка курсора в начало второй строки
lcd.print("Oshibka");
}
delay (100);
}
void MotorRunAuto() //функция автоматич. управления
{
Serial.println(MotorRun);
//MotorRun = false ;///!!!!
lcd.setCursor(0,0); //вывод параметров работы на экран
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("Auto: Speed %");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" Time c");
val_1=analogRead(Speed); //читаем потенциометр на частоту вращ. двигателя
val_1=map(val_1, 0, 1023, MIN_speed , MAX_speed);
val_1=constrain(val_1, 0, 255);
val_prc=val_1*100/MAX_speed;//перевод заданного значения в проценты от максимума
lcd.setCursor(12,0);//вывод значенияв процентах на экран
lcd.print(val_prc);
val_2=analogRead(Time);//читаем потенциометр на время работы двигателя
val_2=map(val_2, 0, 1023, MIN_time , MAX_time);
lcd.setCursor(12,1);//вывод времени работы на экран
lcd.print(val_2);
//val_2=constrain(val, 0, 255);
//i=MIN_speed;
//Serial.println(val_2);
Button.tick();//опрос кнопки на начало работы
Serial.println(MotorRun);
if(Button.isHolded())//если кнопка нажата
{
MotorRun = true;//разрешить работу
Serial.println("AutoStart");
//Serial.println(MotorRun);
}
if (MotorRun == true)
{
unsigned long currentMillis = millis();//начало разгона двигателя
if(currentMillis-previousMillis > interval)
{
previousMillis = currentMillis;
analogWrite(pwmPin,i);
i ++;
//Serial.println(i);
if (i > val_1)
{
i = val_1;
//Serial.println(i);
analogWrite(pwmPin,i);
unsigned long MotorTime = millis(); //выдержка времени после выхода на режим
if (MotorTime - MotorDelay > val_2*1000)
{
MotorDelay = MotorTime;
i = 0;
analogWrite(pwmPin,i);
//Serial.println(millis());
MotorRun = false ;
Serial.println(MotorRun);
}
}
}
}
else /*if (!Button.isPress())*///если кнопка не нажата
{
MotorRun = false ;//запрет работы
i=0;
analogWrite(pwmPin,i);
Serial.println("AutoStop");
//Serial.println(MotorRun);
}
}
void MotorRunManual() //функция ручного управления по аналогии с автоматическим режимом
{
Serial.println(MotorRun);
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print("Manual: ");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" Speed %");
val_1=analogRead(Speed);
val_1=map(val_1, 0, 1023, MIN_speed , MAX_speed);
val_1=constrain(val_1, 0, 255);
val_prc=val_1*100/MAX_speed;
lcd.setCursor(12,1);
lcd.print(val_prc);
//i=MIN_speed;
//Serial.println(i);
Serial.println(MotorRun);
Button.tick();
if(Button.isHold())//если кнопка нажата
{
Serial.println("ManualStart");
unsigned long currentMillis = millis();//начало разгона
if(currentMillis-previousMillis > interval)
{
previousMillis = currentMillis;
analogWrite(pwmPin,i);
i ++;
if (i>val_1)//работа с постоянной частотой вращения
{
i = val_1;
}
}
}
else /* (Button.isRelease())//если кнопка отпушена*/
{
//
i=0;
analogWrite(pwmPin,i);
MotorRun = false ;//запрет работы
Serial.println("ManualStop");
//Serial.println(MotorRun);
}
}
Ошибка проявляет себя так : каждый режим по отдельности работает нормально. Но если произвели старт двигателя в ручном режиме, а затем произвели переход в автоматический режим происходит однократное выполнение программы самопроизвольно. Такое чувство как-будто программа запоминает состояние кнопки Старт в ручном режиме и при переходе в автоматический режим не обнуляет состояние кнопки