Тема: Варим пиво с Ардуино
Приветствую всех.
Недавно ко мне обратились за помощью в написании скетча для варки пива .
Скажем так хочу поделиться им с вами.
Процесс прост, в резервуар подается пар, а Ардуино в свое время контролирует температуру открывая или закрывая клапан подачи холодной воды в контур резервуара.
Для воссоздания вам понадобиться:
Arduino UNO - Контроллер
Arduino Keypad Shield - Дисплей + кнопки
RTC DS1302 - Часы
5В Реле
Термометр DS18B20 влагозащищенный + резистор 4.7 кОм
Электромагнитный (соленоидный) клапан 12В
Ну и собственно сам скетч
#include <iarduino_RTC.h>
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <CyberLib.h>
// Кнопки.
const byte BUTTON_NONE = 0;
const byte BUTTON_RIGHT = 1;
const byte BUTTON_UP = 2;
const byte BUTTON_DOWN = 3;
const byte BUTTON_LEFT = 4;
const byte BUTTON_SELECT = 5;
static byte currentButtonState, previousButtonState = BUTTON_NONE;
// Дисплей.
LiquidCrystal lcdDisplay(8, 9, 4, 5, 6, 7);
const byte MENU_MAIN = 0;
const byte MENU_DATETIME = 101;
volatile byte currentMode = MENU_MAIN;
volatile byte dtPos = 255;
volatile bool cBlink = false;
// Температура.
OneWire oneWire(12);
DallasTemperature tempSensor(&oneWire);
uint8_t degree[8] = {140, 146, 146, 140, 128, 128, 128, 128};
volatile float currTemp = DEVICE_DISCONNECTED_C;
volatile float workTemp = DEVICE_DISCONNECTED_C;
const float deadzone = 0.5;
// Часы.
iarduino_RTC timeModule(RTC_DS1302, 11, 3, 2);
#define LEAP_YEAR(_year) ((_year % 4) == 0)
static byte monthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Работа.
struct datetime {
byte seconds = 0;
byte minutes = 0;
byte hours = 0;
byte day = 0;
byte month = 0;
byte year = 0;
};
volatile datetime currentTime;
volatile datetime editTime;
volatile datetime procTime;
volatile datetime step0Time;
volatile datetime step1Time;
volatile datetime step2Time;
volatile datetime step3Time;
volatile datetime step4Time;
volatile datetime step5Time;
volatile datetime step6Time;
volatile datetime step7Time;
volatile datetime step8Time;
volatile datetime step9Time;
volatile byte editTemp;
volatile byte step0Temp;
volatile byte step1Temp;
volatile byte step2Temp;
volatile byte step3Temp;
volatile byte step4Temp;
volatile byte step5Temp;
volatile byte step6Temp;
volatile byte step7Temp;
volatile byte step8Temp;
volatile byte step9Temp;
volatile byte procStart;
// Получить текущее время и дату.
datetime getDatetime()
{
datetime dt;
timeModule.gettime();
dt.seconds = timeModule.seconds;
dt.minutes = timeModule.minutes;
dt.hours = timeModule.Hours;
dt.day = timeModule.day;
dt.month = timeModule.month;
dt.year = timeModule.year;
return dt;
}
void copyDatetime(volatile datetime * d1, volatile datetime * d2)
{
d1->seconds = d2->seconds;
d1->minutes = d2->minutes;
d1->hours = d2->hours;
d1->day = d2->day;
d1->month = d2->month;
d1->year = d2->year;
}
// Установить время и дату.
void setDatetime(volatile datetime * dt)
{
timeModule.settime(dt->seconds, dt->minutes, dt->hours);
timeModule.settime(-1, -1, -1, dt->day, dt->month, dt->year);
}
// Прочитать из EEPROM дату и время.
datetime readDatetime(int Pos, volatile datetime * dt)
{
dt->seconds = ReadEEPROM_Byte(Pos + 0);
dt->minutes = ReadEEPROM_Byte(Pos + 1);
dt->hours = ReadEEPROM_Byte(Pos + 2);
dt->day = ReadEEPROM_Byte(Pos + 3);
dt->month = ReadEEPROM_Byte(Pos + 4);
dt->year = ReadEEPROM_Byte(Pos + 5);
}
// Прочитать из EEPROM время.
datetime readTime(int Pos, volatile datetime * dt)
{
dt->seconds = ReadEEPROM_Byte(Pos + 0);
dt->minutes = ReadEEPROM_Byte(Pos + 1);
dt->hours = ReadEEPROM_Byte(Pos + 2);
dt->day = 0;
dt->month = 0;
dt->year = 0;
}
// Записать в EEPROM дату и время.
void writeDatetime(int Pos, volatile datetime * dt)
{
WriteEEPROM_Byte(Pos + 0, dt->seconds);
WriteEEPROM_Byte(Pos + 1, dt->minutes);
WriteEEPROM_Byte(Pos + 2, dt->hours);
WriteEEPROM_Byte(Pos + 3, dt->day);
WriteEEPROM_Byte(Pos + 4, dt->month);
WriteEEPROM_Byte(Pos + 5, dt->year);
}
// Записать в EEPROM время.
void writeTime(int Pos, volatile datetime * dt)
{
WriteEEPROM_Byte(Pos + 0, dt->seconds);
WriteEEPROM_Byte(Pos + 1, dt->minutes);
WriteEEPROM_Byte(Pos + 2, dt->hours);
WriteEEPROM_Byte(Pos + 3, 0);
WriteEEPROM_Byte(Pos + 4, 0);
WriteEEPROM_Byte(Pos + 5, 0);
}
// Получение текущей нажатой кнопки.
byte getPressedButton()
{
int buttonValue = A0_Read;
if (buttonValue < 100) return BUTTON_RIGHT; else
if (buttonValue < 200) return BUTTON_UP; else
if (buttonValue < 400) return BUTTON_DOWN; else
if (buttonValue < 600) return BUTTON_LEFT; else
if (buttonValue < 800) return BUTTON_SELECT; else
return BUTTON_NONE;
}
// Обработка мирцающего курсора в редакторах.
void cursorBlink(byte col, byte row)
{
cBlink = !cBlink;
lcdDisplay.setCursor(col, row);
if (cBlink) lcdDisplay.cursor(); else lcdDisplay.noCursor();
}
// Преобразование даты и времени в timestamp (количество секунд прошедших с 1 января 1970 года).
unsigned long makeDateTime(byte sec, byte min, byte hour, byte day, byte month, int year)
{
int i;
unsigned long seconds = 0;
if (year < 69) year += 2000;
seconds = (year - 1970) * (60 * 60 * 24L * 365);
for (i = 1970; i < year; i++)
if (LEAP_YEAR(i)) seconds += 60 * 60 * 24L;
for (i = 0; i< month; i++)
if (i == 1 && LEAP_YEAR(year)) seconds += 60 * 60 * 24L * 29; else seconds += 60 * 60 * 24L * monthDays[i];
seconds += (day - 1) * 3600 * 24L;
seconds += (hour * 3600L) + (min * 60L) + sec;
return seconds;
}
// Преобразование времени в количество секунд.
unsigned long makeTime(byte sec, byte min, byte hour)
{
return (hour * 3600L) + (min * 60L) + sec;
}
// Обработка нажатия кнопки.
void ButtonEventProc(byte buttonIndex)
{
switch(buttonIndex)
{
case BUTTON_SELECT:
if (currentMode) currentMode = 0; else currentMode = 1;
dtPos = 255;
break;
case BUTTON_LEFT:
dtPos = 255;
if (currentMode == MENU_DATETIME)
{
setDatetime(&editTime);
currentMode = MENU_MAIN;
}
if (currentMode == 104)
{
writeTime(100, &editTime);
WriteEEPROM_Byte(200, editTemp);
copyDatetime(&step0Time, &editTime);
step0Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 105)
{
writeTime(110, &editTime);
WriteEEPROM_Byte(210, editTemp);
copyDatetime(&step1Time, &editTime);
step1Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 106)
{
writeTime(120, &editTime);
WriteEEPROM_Byte(220, editTemp);
copyDatetime(&step2Time, &editTime);
step2Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 107)
{
writeTime(130, &editTime);
WriteEEPROM_Byte(230, editTemp);
copyDatetime(&step3Time, &editTime);
step3Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 108)
{
writeTime(140, &editTime);
WriteEEPROM_Byte(240, editTemp);
copyDatetime(&step4Time, &editTime);
step4Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 109)
{
writeTime(150, &editTime);
WriteEEPROM_Byte(250, editTemp);
copyDatetime(&step5Time, &editTime);
step5Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 110)
{
writeTime(160, &editTime);
WriteEEPROM_Byte(260, editTemp);
copyDatetime(&step6Time, &editTime);
step6Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 111)
{
writeTime(170, &editTime);
WriteEEPROM_Byte(270, editTemp);
copyDatetime(&step7Time, &editTime);
step7Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 112)
{
writeTime(180, &editTime);
WriteEEPROM_Byte(280, editTemp);
copyDatetime(&step8Time, &editTime);
step8Temp = editTemp;
currentMode = MENU_MAIN;
}
if (currentMode == 113)
{
writeTime(190, &editTime);
WriteEEPROM_Byte(290, editTemp);
copyDatetime(&step9Time, &editTime);
step9Temp = editTemp;
currentMode = MENU_MAIN;
}
break;
case BUTTON_RIGHT:
if (currentMode == 1)
{
currentMode = MENU_DATETIME;
copyDatetime(&editTime, ¤tTime);
}
if (currentMode == 2)
{
procStart = 1;
WriteEEPROM_Byte(1, procStart);
copyDatetime(&procTime, ¤tTime);
writeDatetime(10, &procTime);
currentMode = MENU_MAIN;
}
if (currentMode == 3)
{
procStart = 0;
WriteEEPROM_Byte(1, procStart);
currentMode = MENU_MAIN;
}
if (currentMode == 4)
{
copyDatetime(&editTime, &step0Time);
editTemp = step0Temp;
currentMode = 104;
}
if (currentMode == 5)
{
copyDatetime(&editTime, &step1Time);
editTemp = step1Temp;
currentMode = 105;
}
if (currentMode == 6)
{
copyDatetime(&editTime, &step2Time);
editTemp = step2Temp;
currentMode = 106;
}
if (currentMode == 7)
{
copyDatetime(&editTime, &step3Time);
editTemp = step3Temp;
currentMode = 107;
}
if (currentMode == 8)
{
copyDatetime(&editTime, &step4Time);
editTemp = step4Temp;
currentMode = 108;
}
if (currentMode == 9)
{
copyDatetime(&editTime, &step5Time);
editTemp = step5Temp;
currentMode = 109;
}
if (currentMode == 10)
{
copyDatetime(&editTime, &step6Time);
editTemp = step6Temp;
currentMode = 110;
}
if (currentMode == 11)
{
copyDatetime(&editTime, &step7Time);
editTemp = step7Temp;
currentMode = 111;
}
if (currentMode == 12)
{
copyDatetime(&editTime, &step8Time);
editTemp = step8Temp;
currentMode = 112;
}
if (currentMode == 13)
{
copyDatetime(&editTime, &step9Time);
editTemp = step9Temp;
currentMode = 113;
}
if (currentMode >= 4 && currentMode <= 13)
{
editTime.day = 0;
editTime.month = 0;
editTime.year = 0;
if (editTime.seconds = 255) editTime.seconds = 0;
if (editTime.minutes = 255) editTime.minutes = 0;
if (editTime.hours = 255) editTime.hours = 0;
if (editTemp = 255) editTemp = 0;
}
if (currentMode == MENU_DATETIME)
{
dtPos++;
if (dtPos > 5) dtPos = 0;
}
if (currentMode >= 104 && currentMode <= 113)
{
dtPos++;
if (dtPos > 3) dtPos = 0;
}
break;
case BUTTON_UP:
if (currentMode > 0 && currentMode < 100)
{
currentMode++;
if (currentMode > 13) currentMode = 1;
}
if (currentMode == MENU_DATETIME)
{
switch (dtPos)
{
case 0: editTime.day++; if (editTime.day > 31) editTime.day = 1; break;
case 1: editTime.month++; if (editTime.month > 12) editTime.month = 1; break;
case 2: editTime.year++; if (editTime.year > 30) editTime.year = 17; break;
case 3: editTime.hours++; if (editTime.hours > 23) editTime.hours = 0; break;
case 4: editTime.minutes++; if (editTime.minutes > 59) editTime.minutes = 0; break;
case 5: editTime.seconds++; if (editTime.seconds > 59) editTime.seconds = 0; break;
}
}
if (currentMode >= 104 && currentMode <= 113)
{
switch (dtPos)
{
case 0: editTime.hours++; break;
case 1: editTime.minutes++; if (editTime.minutes > 59) editTime.minutes = 0; break;
case 2: editTime.seconds++; if (editTime.seconds > 59) editTime.seconds = 0; break;
case 3: editTemp++; break;
}
}
break;
case BUTTON_DOWN:
if (currentMode > 0 && currentMode < 100)
{
currentMode--;
if (currentMode < 1) currentMode = 13;
}
if (currentMode == MENU_DATETIME)
{
switch (dtPos)
{
case 0: editTime.day--; if (editTime.day < 1) editTime.day = 31; break;
case 1: editTime.month--; if (editTime.month < 1) editTime.month = 12; break;
case 2: editTime.year--; if (editTime.year < 17) editTime.year = 30; break;
case 3: editTime.hours--; if (editTime.hours > 23) editTime.hours = 23; break;
case 4: editTime.minutes--; if (editTime.minutes > 59) editTime.minutes = 59; break;
case 5: editTime.seconds--; if (editTime.seconds > 59) editTime.seconds = 59; break;
}
}
if (currentMode >= 104 && currentMode <= 113)
{
switch (dtPos)
{
case 0: editTime.hours--; break;
case 1: editTime.minutes--; if (editTime.minutes > 59) editTime.minutes = 59; break;
case 2: editTime.seconds--; if (editTime.seconds > 59) editTime.seconds = 59; break;
case 3: editTemp--; break;
}
}
break;
}
if (!currentMode && buttonIndex == BUTTON_NONE)
{
lcdDisplay.clear();
lcdDisplay.noCursor();
}
}
// Отрисовка экрана.
void Draw(byte menu)
{
char rowBuffer[16];
switch(menu)
{
case MENU_MAIN:
if (currTemp == DEVICE_DISCONNECTED_C)
{
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("TEMP SENSOR: ");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("DEVICE ERROR ");
} else {
// Текущая Дата и Время.
lcdDisplay.setCursor(8, 0);
sprintf(rowBuffer, "%02d.%02d.%02d", currentTime.day, currentTime.month, currentTime.year);
lcdDisplay.print(rowBuffer);
lcdDisplay.setCursor(8, 1);
sprintf(rowBuffer, "%02d:%02d:%02d", currentTime.hours, currentTime.minutes, currentTime.seconds);
lcdDisplay.print(rowBuffer);
// Текущая температура.
lcdDisplay.setCursor(0, 0);
lcdDisplay.print(currTemp, 1);
lcdDisplay.write((uint8_t)0);
lcdDisplay.print("C ");
// Уставка.
lcdDisplay.setCursor(0, 1);
if (workTemp != DEVICE_DISCONNECTED_C)
{
lcdDisplay.print(workTemp, 1);
lcdDisplay.write((uint8_t)0);
lcdDisplay.print("C ");
} else lcdDisplay.print(" ");
}
break;
case 1:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET DATE/TIME ");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 2:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("PROCESS START ");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 3:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("PROCESS STOP ");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 4:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 1 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 5:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 2 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 6:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 3 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 7:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 4 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 8:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 5 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 9:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 6 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 10:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 7 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 11:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 8 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 12:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 9 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case 13:
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("SET STEP 10 CONF");
lcdDisplay.setCursor(0, 1);
lcdDisplay.print("RIG-SET SEL-ESC");
break;
case MENU_DATETIME:
lcdDisplay.setCursor(0, 0);
sprintf(rowBuffer, "%02d.%02d.%02d LEF-SET", editTime.day, editTime.month, editTime.year);
lcdDisplay.print(rowBuffer);
lcdDisplay.setCursor(0, 1);
sprintf(rowBuffer, "%02d:%02d:%02d SEL-ESC", editTime.hours, editTime.minutes, editTime.seconds);
lcdDisplay.print(rowBuffer);
switch (dtPos)
{
case 0: cursorBlink(1, 0); break;
case 1: cursorBlink(4, 0); break;
case 2: cursorBlink(7, 0); break;
case 3: cursorBlink(1, 1); break;
case 4: cursorBlink(4, 1); break;
case 5: cursorBlink(7, 1); break;
}
break;
case 104:
case 105:
case 106:
case 107:
case 108:
case 109:
case 110:
case 111:
case 112:
case 113:
lcdDisplay.setCursor(0, 0);
sprintf(rowBuffer, "%02d:%02d:%02d LEF-SET", editTime.hours, editTime.minutes, editTime.seconds);
lcdDisplay.print(rowBuffer);
lcdDisplay.setCursor(0, 1);
sprintf(rowBuffer, "%03d SEL-ESC", editTemp);
lcdDisplay.print(rowBuffer);
switch (dtPos)
{
case 0: cursorBlink(1, 0); break;
case 1: cursorBlink(4, 0); break;
case 2: cursorBlink(7, 0); break;
case 3: cursorBlink(2, 1); break;
}
break;
}
}
// Основной цикл программы (Датчики, Экран, Реле).
void work()
{
currentTime = getDatetime();
currTemp = tempSensor.getTempCByIndex(0);
tempSensor.requestTemperatures();
// Основная работа.
workTemp = DEVICE_DISCONNECTED_C;
if (procStart)
{
unsigned long cTime = makeDateTime(currentTime.seconds, currentTime.minutes, currentTime.hours, currentTime.day, currentTime.month, currentTime.year);
unsigned long pTime = makeDateTime(procTime.seconds, procTime.minutes, procTime.hours, procTime.day, procTime.month, procTime.year);
unsigned long dTime0 = makeTime(step0Time.seconds, step0Time.minutes, step0Time.hours);
unsigned long dTime1 = makeTime(step1Time.seconds, step1Time.minutes, step1Time.hours);
unsigned long dTime2 = makeTime(step2Time.seconds, step2Time.minutes, step2Time.hours);
unsigned long dTime3 = makeTime(step3Time.seconds, step3Time.minutes, step3Time.hours);
unsigned long dTime4 = makeTime(step4Time.seconds, step4Time.minutes, step4Time.hours);
unsigned long dTime5 = makeTime(step5Time.seconds, step5Time.minutes, step5Time.hours);
unsigned long dTime6 = makeTime(step6Time.seconds, step6Time.minutes, step6Time.hours);
unsigned long dTime7 = makeTime(step7Time.seconds, step7Time.minutes, step7Time.hours);
unsigned long dTime8 = makeTime(step8Time.seconds, step8Time.minutes, step8Time.hours);
unsigned long dTime9 = makeTime(step9Time.seconds, step9Time.minutes, step9Time.hours);
unsigned long lTime = 0;
if (cTime >= pTime + lTime) workTemp = step0Temp; lTime += dTime0;
if (cTime >= pTime + lTime) workTemp = step1Temp; lTime += dTime1;
if (cTime >= pTime + lTime) workTemp = step2Temp; lTime += dTime2;
if (cTime >= pTime + lTime) workTemp = step3Temp; lTime += dTime3;
if (cTime >= pTime + lTime) workTemp = step4Temp; lTime += dTime4;
if (cTime >= pTime + lTime) workTemp = step5Temp; lTime += dTime5;
if (cTime >= pTime + lTime) workTemp = step6Temp; lTime += dTime6;
if (cTime >= pTime + lTime) workTemp = step7Temp; lTime += dTime7;
if (cTime >= pTime + lTime) workTemp = step8Temp; lTime += dTime8;
if (cTime >= pTime + lTime) workTemp = step9Temp; lTime += dTime9;
if (currTemp >= workTemp + deadzone) D13_High;
if (currTemp <= workTemp - deadzone) D13_Low;
} else D13_Low;
// Отрисовка меню.
Draw(currentMode);
}
// Настройки при запуске контроллера.
void setup()
{
// Чтение из памяти значений.
procStart = ReadEEPROM_Byte(1);
readDatetime(10, &procTime);
readTime(100, &step0Time); step0Temp = ReadEEPROM_Byte(200);
readTime(110, &step1Time); step1Temp = ReadEEPROM_Byte(210);
readTime(120, &step2Time); step2Temp = ReadEEPROM_Byte(220);
readTime(130, &step3Time); step3Temp = ReadEEPROM_Byte(230);
readTime(140, &step4Time); step4Temp = ReadEEPROM_Byte(240);
readTime(150, &step5Time); step5Temp = ReadEEPROM_Byte(250);
readTime(160, &step6Time); step6Temp = ReadEEPROM_Byte(260);
readTime(170, &step7Time); step7Temp = ReadEEPROM_Byte(270);
readTime(180, &step8Time); step8Temp = ReadEEPROM_Byte(280);
readTime(190, &step9Time); step9Temp = ReadEEPROM_Byte(290);
// Дисплей.
lcdDisplay.begin(16, 2);
lcdDisplay.createChar(0, degree);
lcdDisplay.clear();
// Термодатчик.
tempSensor.begin();
tempSensor.setWaitForConversion(false);
tempSensor.requestTemperatures();
// Модуль часов.
timeModule.begin();
// Реле.
D13_Out;
D13_Low;
// Запуск основной работы по прерыванию в 250мс.
StartTimer1(work, 500000);
}
// Основной цикл программы (Кнопки).
void loop()
{
// Проверка нажатия кнопок.
currentButtonState = getPressedButton();
if(currentButtonState != previousButtonState)
{
// Антидребезг.
delay_ms(10);
currentButtonState = getPressedButton();
if (currentButtonState != previousButtonState)
{
// Обработка нажатия кнопок.
ButtonEventProc(currentButtonState);
previousButtonState = currentButtonState;
}
}
delay_ms(1);
}
Принцип работы.
В прошивке реализовано меню.
В меню есть 10 шагов. В каждом шаге можно задать температуру и время которое эту температуру нужно держать.
Процесс идет от первого шага к десятому.
Так же в меню есть настройки часов.
И два меню предназначенных для запуска процесса варки и его принудительного выключения.
Прошивка рабочая но не законченная, делалась на скорую руку по этому часть кода можно было сделать и получше.
Пишите если понадобится помощь.