Обработчик по кнопке и функция которая ему мешает.
- Войдите на сайт для отправки комментариев
Пнд, 06/06/2016 - 18:52
Здравствуйте.
Помогите понять в чем дело. У меня в функции loop работает небольшой обработчик, который в зависимости от количества нажатий аппаратной кнопки запускает разные виды отображаемой информации. И все бы ничего, но на одной из функций он тупо не отрабатывает. Вопрос почему?
Обработчик:
void loop() {
MyDataOutput data = GetSensorsData(); //Получаю данные с датчиков
//ShowResultSerial(data);
buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
//Serial.print(buttonState);
//Serial.print( lastButtonState);
//Serial.println( buttonPushCounter);
if (buttonState == HIGH) {
display.clearScreen();
// Serial.print(buttonState);
// Serial.print( lastButtonState);
// Serial.println( buttonPushCounter);
buttonPushCounter++;
}
delay(50);
}
if (buttonPushCounter > 2) {
lastButtonState = 0;
buttonPushCounter = 0;
}
else {
lastButtonState = buttonState;
}
//В зависимости от количества нажатий вывожу разные отображения информации
switch (buttonPushCounter) {
case 1:
InfoMode(data);
break;
case 2:
GraphMode(data);
break;
default:
ClockMode(data);
LittleInfo(data);
break;
}
}
Функция, которая запустившись уже не видит нажатий и не позволяет перейти к началу. Если ее заменить другой, все работает отлично:
void GraphMode(MyDataOutput data)
{
//Выводим иконки
display.drawBitmap(0, 0, temp, 64, 49, WHITE);
display.setTextSize(1);
display.setCursor(100,10);
display.print("0");
display.setTextSize(3);
display.setCursor(105,15);
display.println("C");
display.setTextSize(5);
display.setCursor(35,65);
display.print(data.avtemp,0);
if (data.avtemp > 30)
{
display.fillRect(0, 125, 128, 5, RED);
}
else
{
display.fillRect(0, 125, 128, 5, GREEN);
}
delay(5000);
display.clearScreen();
display.drawBitmap(0, 0, hum, 33, 45, WHITE);
display.setTextSize(3);
display.setCursor(105,15);
display.println("%");
display.setTextSize(5);
display.setCursor(35,65);
display.print(data.hum,0);
if (data.hum > 70 || data.hum < 30 )
{
display.fillRect(0, 125, 128, 5, RED);
}
else
{
display.fillRect(0, 125, 128, 5, GREEN);
}
delay(5000);
display.clearScreen();
display.drawBitmap(0, 0, CO2, 64, 50, WHITE);
display.setTextSize(2);
display.setCursor(85,15);
display.println("ppm");
display.setTextSize(5);
if(data.co2 < 999)
{
display.setCursor(23,65);
}
else
{
display.setCursor(5,65);
}
display.print(data.co2,0);
if (data.co2 > 750)
{
display.fillRect(0, 125, 128, 5, RED);
}
else
{
display.fillRect(0, 125, 128, 5, GREEN);
}
delay(5000);
display.clearScreen();
display.drawBitmap(0, 0, airpress, 40, 49, WHITE);
display.setTextSize(3);
display.setCursor(85,15);
display.print(utf8rus("мм"));
display.setTextSize(5);
display.setCursor(23,65);
display.print(data.ap,0);
if (data.ap > 750)
{
display.fillRect(0, 125, 128, 5, RED);
}
else
{
display.fillRect(0, 125, 128, 5, GREEN);
}
delay(5000);
display.clearScreen();
}
Проблема стопудово в delay(5000);
Ну, про delay(5000) Вам уже написали. Надеюсь, Вы достаточно долго ждёте, чтобы быть уверенным, что все эти задержки прошли?
Если Вы уверены, что дело не в delay, и Вы дожидаетесь, попробуйте в этой функции закомментировать все вызовы drawBitmap. Остальное оставьте на месте и посмотрите. что получится.
Блин, это печаль, как еще организовать послайдовый показ я не знаю. То есть мне надо нажать кнопку в тот безумно маденький промежуток времени пока не запустился delay, во время которого ничего не отрабатывает?
Т.е. Вы выяснили, что проблема именно в delay? Если подождать, пока всё кончится, то всё нормально работает?
То есть мне надо нажать кнопку в тот безумно маденький промежуток времени пока не запустился delay, во время которого ничего не отрабатывает?
Нет, нужно просто избаиться от delay и сделать без него.
Блин, это печаль, как еще организовать послайдовый показ я не знаю.
Очень просто: избавляетесь от delay, в глобальной переменной запоминаете номер слайда и время старта его показа, в loop проверяете - не кончилось ли время продолжительности показа текущего слайда, если да - запоминаете время начала показа следующего слайда, и показывате следующий слайд. Две переменных и чутка кода - вот и всё.
Не совсем, я закомментировал delay и попробовал, поскольку функция вызывается в loop, то все крутится все равно в цикле, но в отличие от варианта с delay, если часто жать кнопку, то можно все-таки переключиться на первый режим.
Блин, это печаль, как еще организовать послайдовый показ я не знаю.
Очень просто: избавляетесь от delay, в глобальной переменной запоминаете номер слайда и время старта его показа, в loop проверяете - не кончилось ли время продолжительности показа текущего слайда, если да - запоминаете время начала показа следующего слайда, и показывате следующий слайд. Две переменных и чутка кода - вот и всё.
Звучит неплохо. С моим уровнем это будет сложно сделать, но я попоробую. Спасибо!
Две переменные это:
В качестве идеи:
if (millis() - previousMillis > interval) { previousMillis = millis(); switch (slide) { case 0: /*вывод слайда 0*/ break; case 1: /*вывод слайда 1*/ break; case 2: /*вывод слайда 2*/ break; } slide++; }В качестве идеи:
Ага, по-моему должно сработать. Немного разгребусь и попробую. Спасибо!
Все работает.
Спасибо всем. Andy, DIYMan, особенно.