409 lines
16 KiB
C++
409 lines
16 KiB
C++
/*
|
||
SmartCharge - Menu MVP (ESP32 + OLED + Encoder) [U8g2 + кириллица]
|
||
- I2C OLED @ 0x3C (сканер уже нашёл)
|
||
- USE_SH1106: 1 = SH1106, 0 = SSD1306
|
||
- SDA=21, SCL=22
|
||
- Encoder: A=32, B=33, BTN=26
|
||
*/
|
||
|
||
#define USE_SH1106 1 // <<< если у тебя SSD1306, поставь 0
|
||
|
||
#include <Wire.h>
|
||
#include <Preferences.h>
|
||
#include <Bounce2.h>
|
||
#include <U8g2lib.h>
|
||
|
||
// -------- OLED (U8g2) --------
|
||
#if USE_SH1106
|
||
// Полный буфер, аппаратный I2C
|
||
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /*reset=*/ U8X8_PIN_NONE);
|
||
#else
|
||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /*reset=*/ U8X8_PIN_NONE);
|
||
#endif
|
||
|
||
// Шрифт с кириллицей (компактный, читаемый)
|
||
#define MENU_FONT u8g2_font_6x12_t_cyrillic
|
||
|
||
// -------- ENCODER --------
|
||
const int ENC_A_PIN = 32;
|
||
const int ENC_B_PIN = 33;
|
||
const int ENC_BTN_PIN = 26;
|
||
|
||
Bounce encBtn;
|
||
volatile int16_t encDelta = 0;
|
||
int8_t transTable[16] = {
|
||
0, -1, +1, 2,
|
||
+1, 0, 2, -1,
|
||
-1, 2, 0, +1,
|
||
2, +1, -1, 0
|
||
};
|
||
inline void encoderPoll() {
|
||
uint8_t a = digitalRead(ENC_A_PIN);
|
||
uint8_t b = digitalRead(ENC_B_PIN);
|
||
static uint8_t last = 0;
|
||
uint8_t s = (a << 1) | b;
|
||
uint8_t idx = ((last & 0x03) << 2) | (s & 0x03);
|
||
int8_t d = transTable[idx & 0x0F];
|
||
if (d == +1) encDelta++;
|
||
else if (d == -1) encDelta--;
|
||
last = s;
|
||
}
|
||
int16_t encoderReadAndClear() { noInterrupts(); int16_t v=encDelta; encDelta=0; interrupts(); return v; }
|
||
uint32_t ms(){ return millis(); }
|
||
|
||
// -------- PROFILES --------
|
||
enum : uint8_t { CHEM_LIION=0, CHEM_LFP=1, CHEM_LTO=2 };
|
||
static inline const char* chemToStr(uint8_t c){
|
||
switch(c){ case CHEM_LIION: return "Li-ion"; case CHEM_LFP: return "LiFePO4"; case CHEM_LTO: return "LTO"; }
|
||
return "Li-ion";
|
||
}
|
||
struct Profile {
|
||
uint8_t chem; // CHEM_*
|
||
uint8_t S; // 1..4
|
||
uint16_t capacity_mAh; // 100..10000
|
||
float rateC; // 0.1..1.0
|
||
float ItermA; // A
|
||
};
|
||
Preferences prefs;
|
||
const int NUM_PROFILES = 5;
|
||
Profile profiles[NUM_PROFILES];
|
||
int lastProfileIndex = 0;
|
||
|
||
void loadProfiles() {
|
||
prefs.begin("sc", true);
|
||
for (int i=0;i<NUM_PROFILES;i++){
|
||
String k = String("p")+i+"_";
|
||
profiles[i].chem = prefs.getUChar((k+"chem").c_str(), i==0?CHEM_LIION:CHEM_LFP);
|
||
profiles[i].S = prefs.getUChar((k+"S").c_str(), (i==1)?3:1);
|
||
profiles[i].capacity_mAh = prefs.getUShort((k+"cap").c_str(), (i==0)?2500:1000);
|
||
profiles[i].rateC = prefs.getFloat((k+"rate").c_str(), 0.5f);
|
||
float itdef = (profiles[i].chem==CHEM_LIION?0.05f:0.02f) * profiles[i].capacity_mAh/1000.0f;
|
||
profiles[i].ItermA= prefs.getFloat((k+"iterm").c_str(), itdef);
|
||
}
|
||
lastProfileIndex = prefs.getUChar("lastIdx", 0);
|
||
prefs.end();
|
||
}
|
||
void saveProfile(int i) {
|
||
prefs.begin("sc", false);
|
||
String k = String("p")+i+"_";
|
||
prefs.putUChar((k+"chem").c_str(), profiles[i].chem);
|
||
prefs.putUChar((k+"S").c_str(), profiles[i].S);
|
||
prefs.putUShort((k+"cap").c_str(), profiles[i].capacity_mAh);
|
||
prefs.putFloat((k+"rate").c_str(), profiles[i].rateC);
|
||
prefs.putFloat((k+"iterm").c_str(),profiles[i].ItermA);
|
||
prefs.end();
|
||
}
|
||
void saveLastIndex(int idx){ prefs.begin("sc", false); prefs.putUChar("lastIdx", idx); prefs.end(); }
|
||
|
||
// -------- UI STATE --------
|
||
enum UiState {
|
||
UI_HOME=0,
|
||
UI_START_MODE, UI_START_PROFILE,
|
||
UI_START_QUICK_CAP, UI_START_QUICK_RATEC, UI_START_QUICK_ITERM, UI_START_CONFIRM,
|
||
UI_PROFILES_LIST, UI_PROFILE_EDIT_FIELD,
|
||
UI_EDIT_CHEM, UI_EDIT_S, UI_EDIT_CAP, UI_EDIT_RATEC, UI_EDIT_ITERM,
|
||
UI_SETTINGS, UI_SERVICE, UI_MESSAGE
|
||
};
|
||
UiState ui = UI_HOME;
|
||
|
||
int cursor=0, topIndex=0;
|
||
uint32_t btnDownAt=0, lastClickAt=0;
|
||
bool btnWasDown=false, lastClickUsed=false;
|
||
|
||
enum StartMode { SM_CHARGE=0, SM_DISCHARGE, SM_RINT };
|
||
StartMode startMode = SM_CHARGE;
|
||
int startProfileIdx = 0;
|
||
uint16_t quickCap_mAh = 2500; float quickRateC=0.5f, quickItermA=0.10f;
|
||
|
||
// -------- DRAW HELPERS (U8g2) --------
|
||
void setFont(){ u8g2.setFont(MENU_FONT); }
|
||
|
||
void drawHeader(const char* t){
|
||
setFont();
|
||
// белая плашка
|
||
u8g2.setDrawColor(1); u8g2.drawBox(0,0,128,12);
|
||
// чёрным по белому
|
||
u8g2.setDrawColor(0); u8g2.setCursor(2,10); u8g2.print(t);
|
||
// вернуть белый цвет рисования
|
||
u8g2.setDrawColor(1);
|
||
}
|
||
void drawFooterHint(const char* s){
|
||
setFont();
|
||
u8g2.setCursor(0,64-2); // нижняя строка
|
||
u8g2.print(s);
|
||
}
|
||
void drawMenuItem(int y, const String& text, bool sel){
|
||
setFont();
|
||
if (sel){
|
||
u8g2.drawBox(0,y-9,128,11); // выделенная строка
|
||
u8g2.setDrawColor(0); u8g2.setCursor(2,y); u8g2.print(text);
|
||
u8g2.setDrawColor(1);
|
||
} else {
|
||
u8g2.setCursor(2,y); u8g2.print(text);
|
||
}
|
||
}
|
||
String fmtFloat(float v,int p){ char b[20]; dtostrf(v,0,p,b); return String(b); }
|
||
|
||
// -------- INPUT --------
|
||
void pollInputs(){
|
||
encoderPoll();
|
||
encBtn.update();
|
||
bool down = !encBtn.read();
|
||
if (down && !btnWasDown) btnDownAt = ms();
|
||
else if (!down && btnWasDown){
|
||
uint32_t t = ms() - btnDownAt;
|
||
if (t < 1500){
|
||
uint32_t now = ms();
|
||
if (now - lastClickAt < 400 && !lastClickUsed) lastClickUsed = true;
|
||
else lastClickUsed = false;
|
||
lastClickAt = now;
|
||
}
|
||
}
|
||
btnWasDown = down;
|
||
}
|
||
bool isShortClick(){ static uint32_t lh=0; if(!btnWasDown){uint32_t now=ms(); if(now-lastClickAt<80 && !lastClickUsed && now-lh>150){lh=now; return true;}} return false; }
|
||
bool isDoubleClick(){ static uint32_t lh=0; if(!btnWasDown){uint32_t now=ms(); if(now-lastClickAt<120 && lastClickUsed && now-lh>150){lh=now; lastClickUsed=false; return true;}} return false; }
|
||
bool isLongPressReleased(){ static uint32_t lh=0; if(!btnWasDown){uint32_t dur=ms()-btnDownAt; if(dur>=1500 && (ms()-lh>200)){lh=ms(); return true;}} return false; }
|
||
int readRot(int step=1){ int16_t d=encoderReadAndClear(); if(!d) return 0; return d>0?+step:-step; }
|
||
|
||
// -------- SCREENS --------
|
||
void screenHome(){
|
||
u8g2.clearBuffer();
|
||
drawHeader("Главное меню");
|
||
const char* items[] = {"Старт","Профили","Параметры","Сервис"}; int n=4;
|
||
int r=readRot(); if(r){ cursor+=(r>0?1:-1); if(cursor<0) cursor=n-1; if(cursor>=n) cursor=0; }
|
||
for(int i=0;i<n;i++) drawMenuItem(12+(i+1)*11, items[i], i==cursor);
|
||
drawFooterHint("Нажми: выбор | Держи: назад");
|
||
u8g2.sendBuffer();
|
||
|
||
if(isShortClick()){
|
||
if(cursor==0){ui=UI_START_MODE; cursor=0;}
|
||
else if(cursor==1){ui=UI_PROFILES_LIST; cursor=0; topIndex=0;}
|
||
else if(cursor==2){ui=UI_SETTINGS;}
|
||
else {ui=UI_SERVICE;}
|
||
}
|
||
}
|
||
|
||
void screenStartMode(){
|
||
u8g2.clearBuffer();
|
||
drawHeader("Старт: режим");
|
||
const char* items[] = {"Заряд","Разряд (1S)","МиллиОм (1S)"}; int n=3;
|
||
int r=readRot(); if(r){ cursor+=(r>0?1:-1); if(cursor<0) cursor=n-1; if(cursor>=n) cursor=0; }
|
||
for(int i=0;i<n;i++) drawMenuItem(12+(i+1)*11, items[i], i==cursor);
|
||
drawFooterHint("Нажми: далее | Держи: назад");
|
||
u8g2.sendBuffer();
|
||
|
||
if(isShortClick()){ startMode=(StartMode)cursor; ui=UI_START_PROFILE; startProfileIdx=lastProfileIndex; }
|
||
if(isLongPressReleased()){ ui=UI_HOME; cursor=0; }
|
||
}
|
||
|
||
void screenStartProfile(){
|
||
u8g2.clearBuffer();
|
||
drawHeader("Старт: профиль");
|
||
int n=NUM_PROFILES; int r=readRot(); if(r){ startProfileIdx+=(r>0?1:-1); if(startProfileIdx<0) startProfileIdx=n-1; if(startProfileIdx>=n) startProfileIdx=0; }
|
||
if(startProfileIdx<topIndex) topIndex=startProfileIdx; if(startProfileIdx>=topIndex+4) topIndex=startProfileIdx-3;
|
||
|
||
for(int row=0; row<4; row++){
|
||
int i=topIndex+row; if(i>=n) break;
|
||
String line="["+String(i+1)+"] "; line+=chemToStr(profiles[i].chem);
|
||
line+=" S="+String(profiles[i].S); line+=" "+String(profiles[i].capacity_mAh)+"mAh";
|
||
drawMenuItem(12+(row+1)*11, line, i==startProfileIdx);
|
||
}
|
||
drawFooterHint("Нажми: правка | Держи: назад");
|
||
u8g2.sendBuffer();
|
||
|
||
if(isShortClick()){
|
||
Profile &p=profiles[startProfileIdx];
|
||
quickCap_mAh=p.capacity_mAh; quickRateC=p.rateC;
|
||
quickItermA=(p.ItermA>0.001f)?p.ItermA:((p.chem==CHEM_LIION?0.05f:0.02f)*p.capacity_mAh/1000.0f);
|
||
ui=UI_START_QUICK_CAP; saveLastIndex(startProfileIdx);
|
||
}
|
||
if(isLongPressReleased()){ ui=UI_START_MODE; cursor=0; }
|
||
}
|
||
|
||
void editNumberInt(uint16_t &val,uint16_t minV,uint16_t maxV,uint16_t step,const char* title){
|
||
u8g2.clearBuffer(); drawHeader(title);
|
||
int r=readRot(); if(r){ long nv=(long)val + (r>0?step:-step); if(nv<minV) nv=minV; if(nv>maxV) nv=maxV; val=(uint16_t)nv; }
|
||
setFont(); u8g2.setCursor(2, 22+10); u8g2.print(val); u8g2.print(" ");
|
||
drawFooterHint("Нажми: ОК | Держи: отмена");
|
||
u8g2.sendBuffer();
|
||
}
|
||
void editNumberFloat(float &val,float minV,float maxV,float step,const char* title){
|
||
u8g2.clearBuffer(); drawHeader(title);
|
||
int r=readRot(); if(r){ float nv=val+(r>0?step:-step); if(nv<minV) nv=minV; if(nv>maxV) nv=maxV; val=nv; }
|
||
setFont(); u8g2.setCursor(2, 22+10); u8g2.print(fmtFloat(val,(step<0.1f?2:1)));
|
||
drawFooterHint("Нажми: ОК | Держи: отмена");
|
||
u8g2.sendBuffer();
|
||
}
|
||
|
||
void screenStartQuickCap(){ editNumberInt(quickCap_mAh,100,10000,100,"Емкость (mAh)"); if(isShortClick()) ui=UI_START_QUICK_RATEC; if(isLongPressReleased()) ui=UI_START_PROFILE; }
|
||
void screenStartQuickRateC(){ editNumberFloat(quickRateC,0.1f,1.0f,0.1f,"C-rate"); if(isShortClick()) ui=UI_START_QUICK_ITERM; if(isLongPressReleased()) ui=UI_START_PROFILE; }
|
||
void screenStartQuickIterm(){ editNumberFloat(quickItermA,0.01f,5.0f,0.01f,"Iterm (A)"); if(isShortClick()) ui=UI_START_CONFIRM; if(isLongPressReleased()) ui=UI_START_PROFILE; }
|
||
|
||
void screenStartConfirm(){
|
||
u8g2.clearBuffer(); drawHeader("Подтверждение");
|
||
Profile &p=profiles[startProfileIdx];
|
||
setFont();
|
||
u8g2.setCursor(2,12+10); u8g2.print("Режим: "); u8g2.print(startMode==SM_CHARGE?"Заряд":(startMode==SM_DISCHARGE?"Разряд":"МиллиОм"));
|
||
u8g2.setCursor(2,22+10); u8g2.print("Профиль: "); u8g2.print(chemToStr(p.chem)); u8g2.print(" S="); u8g2.print(p.S);
|
||
u8g2.setCursor(2,32+10); u8g2.print("Cap="); u8g2.print(quickCap_mAh); u8g2.print("mAh C="); u8g2.print(fmtFloat(quickRateC,1));
|
||
u8g2.setCursor(2,42+10); u8g2.print("Iterm="); u8g2.print(fmtFloat(quickItermA,2)); u8g2.print("A");
|
||
drawFooterHint("Нажми: ПУСК | Держи: назад");
|
||
u8g2.sendBuffer();
|
||
|
||
if(isShortClick()){ ui=UI_MESSAGE; }
|
||
if(isLongPressReleased()){ ui=UI_START_PROFILE; }
|
||
}
|
||
|
||
void screenMessage(){
|
||
u8g2.clearBuffer(); drawHeader("Сообщение");
|
||
setFont();
|
||
u8g2.setCursor(2,14+8); u8g2.print("Старт (демо).");
|
||
u8g2.setCursor(2,24+8); u8g2.print("Дальше добавим");
|
||
u8g2.setCursor(2,34+8); u8g2.print("алгоритм и логи.");
|
||
drawFooterHint("Нажми: в меню");
|
||
u8g2.sendBuffer();
|
||
|
||
if(isShortClick() || isDoubleClick() || isLongPressReleased()){ ui=UI_HOME; cursor=0; }
|
||
}
|
||
|
||
// Профили
|
||
enum EditField { EF_CHEM=0, EF_S, EF_CAP, EF_RATEC, EF_ITERM, EF_SAVE, EF_CANCEL };
|
||
int profListCursor=0, editProfileIdx=0; EditField editField=EF_CHEM;
|
||
|
||
void screenProfilesList(){
|
||
u8g2.clearBuffer(); drawHeader("Профили");
|
||
int n=NUM_PROFILES; int r=readRot(); if(r){ profListCursor+=(r>0?1:-1); if(profListCursor<0) profListCursor=n-1; if(profListCursor>=n) profListCursor=0; }
|
||
if(profListCursor<topIndex) topIndex=profListCursor; if(profListCursor>=topIndex+4) topIndex=profListCursor-3;
|
||
|
||
for(int row=0; row<4; row++){
|
||
int i=topIndex+row; if(i>=n) break;
|
||
String line="["+String(i+1)+"] "; line+=chemToStr(profiles[i].chem);
|
||
line+=" S="+String(profiles[i].S); line+=" "+String(profiles[i].capacity_mAh)+"mAh";
|
||
drawMenuItem(12+(row+1)*11, line, i==profListCursor);
|
||
}
|
||
drawFooterHint("Нажми: редакт. | Держи: назад");
|
||
u8g2.sendBuffer();
|
||
|
||
if(isShortClick()){ editProfileIdx=profListCursor; editField=EF_CHEM; ui=UI_PROFILE_EDIT_FIELD; }
|
||
if(isLongPressReleased()){ ui=UI_HOME; cursor=0; }
|
||
}
|
||
|
||
void screenProfileEditField(){
|
||
u8g2.clearBuffer(); drawHeader("Редакт.профиля");
|
||
const char* items[]={"Химия","S (банок)","Емкость (mAh)","C-rate","Iterm (A)","Сохранить","Отмена"}; int n=7;
|
||
int r=readRot(); if(r){ int c=(int)editField + (r>0?1:-1); if(c<0) c=n-1; if(c>=n) c=0; editField=(EditField)c; }
|
||
for(int i=0;i<n;i++) drawMenuItem(12+(i+1)*11, items[i], i==(int)editField);
|
||
drawFooterHint("Нажми: выбрать | Держи: назад");
|
||
u8g2.sendBuffer();
|
||
|
||
if(isShortClick()){
|
||
switch(editField){
|
||
case EF_CHEM: ui=UI_EDIT_CHEM; break;
|
||
case EF_S: ui=UI_EDIT_S; break;
|
||
case EF_CAP: ui=UI_EDIT_CAP; break;
|
||
case EF_RATEC: ui=UI_EDIT_RATEC; break;
|
||
case EF_ITERM: ui=UI_EDIT_ITERM; break;
|
||
case EF_SAVE: saveProfile(editProfileIdx); ui=UI_PROFILES_LIST; break;
|
||
case EF_CANCEL:ui=UI_PROFILES_LIST; break;
|
||
}
|
||
}
|
||
if(isLongPressReleased()) ui=UI_PROFILES_LIST;
|
||
}
|
||
|
||
void screenEditChem(){
|
||
u8g2.clearBuffer(); drawHeader("Химия");
|
||
uint8_t &c=profiles[editProfileIdx].chem; int r=readRot(); if(r){ int v=(int)c+(r>0?1:-1); if(v<0) v=2; if(v>2) v=0; c=(uint8_t)v; }
|
||
setFont(); u8g2.setCursor(2, 22+10); u8g2.print(chemToStr(c));
|
||
drawFooterHint("Нажми: ОК | Держи: отмена");
|
||
u8g2.sendBuffer();
|
||
if(isShortClick()||isLongPressReleased()) ui=UI_PROFILE_EDIT_FIELD;
|
||
}
|
||
|
||
void screenEditS(){
|
||
u8g2.clearBuffer(); drawHeader("S (1..4)");
|
||
uint8_t &S=profiles[editProfileIdx].S; int r=readRot(); if(r){ int v=(int)S+(r>0?1:-1); if(v<1) v=4; if(v>4) v=1; S=(uint8_t)v; }
|
||
setFont(); u8g2.setCursor(2,22+10); u8g2.print("S="); u8g2.print(S);
|
||
drawFooterHint("Нажми: ОК | Держи: отмена");
|
||
u8g2.sendBuffer();
|
||
if(isShortClick()||isLongPressReleased()) ui=UI_PROFILE_EDIT_FIELD;
|
||
}
|
||
|
||
void screenEditCap(){ editNumberInt(profiles[editProfileIdx].capacity_mAh,100,10000,100,"Емкость (mAh)"); if(isShortClick()||isLongPressReleased()) ui=UI_PROFILE_EDIT_FIELD; }
|
||
void screenEditRateC(){ editNumberFloat(profiles[editProfileIdx].rateC,0.1f,1.0f,0.1f,"C-rate"); if(isShortClick()||isLongPressReleased()) ui=UI_PROFILE_EDIT_FIELD; }
|
||
void screenEditIterm(){ editNumberFloat(profiles[editProfileIdx].ItermA,0.01f,5.0f,0.01f,"Iterm (A)"); if(isShortClick()||isLongPressReleased()) ui=UI_PROFILE_EDIT_FIELD; }
|
||
|
||
// -------- SETTINGS & SERVICE (заглушки) --------
|
||
void screenSettings(){
|
||
u8g2.clearBuffer(); drawHeader("Параметры");
|
||
setFont();
|
||
u8g2.setCursor(2,14+8); u8g2.print("Позже: лог/экран/сеть");
|
||
drawFooterHint("Держи: назад");
|
||
u8g2.sendBuffer();
|
||
if(isShortClick()||isLongPressReleased()) ui=UI_HOME;
|
||
}
|
||
void screenService(){
|
||
u8g2.clearBuffer(); drawHeader("Сервис");
|
||
setFont();
|
||
u8g2.setCursor(2,14+8); u8g2.print("Позже: тесты/калибровка");
|
||
drawFooterHint("Держи: назад");
|
||
u8g2.sendBuffer();
|
||
if(isShortClick()||isLongPressReleased()) ui=UI_HOME;
|
||
}
|
||
|
||
// -------- SETUP/LOOP --------
|
||
void setup(){
|
||
Serial.begin(115200);
|
||
Wire.begin(21,22);
|
||
Wire.setClock(100000);
|
||
|
||
u8g2.begin();
|
||
u8g2.enableUTF8Print(); // <<< ключевое: печатать UTF-8 (русский)
|
||
u8g2.setI2CAddress(0x3C<<1); // 0x3C из сканера
|
||
u8g2.setBusClock(100000);
|
||
|
||
pinMode(ENC_A_PIN, INPUT_PULLUP);
|
||
pinMode(ENC_B_PIN, INPUT_PULLUP);
|
||
pinMode(ENC_BTN_PIN, INPUT_PULLUP);
|
||
encBtn.attach(ENC_BTN_PIN, INPUT_PULLUP);
|
||
encBtn.interval(5);
|
||
|
||
loadProfiles();
|
||
|
||
u8g2.clearBuffer();
|
||
drawHeader("SmartCharge UI");
|
||
setFont();
|
||
u8g2.setCursor(2,20); u8g2.print("Меню готово.");
|
||
u8g2.setCursor(2,30); u8g2.print("A=32 B=33 BTN=26");
|
||
u8g2.setCursor(2,40); u8g2.print("Крутить/Жать/Держать");
|
||
u8g2.sendBuffer();
|
||
delay(700);
|
||
|
||
ui=UI_HOME; cursor=0; topIndex=0;
|
||
}
|
||
|
||
void loop(){
|
||
pollInputs();
|
||
|
||
switch(ui){
|
||
case UI_HOME: screenHome(); break;
|
||
case UI_START_MODE: screenStartMode(); break;
|
||
case UI_START_PROFILE: screenStartProfile(); break;
|
||
case UI_START_QUICK_CAP: screenStartQuickCap(); break;
|
||
case UI_START_QUICK_RATEC: screenStartQuickRateC(); break;
|
||
case UI_START_QUICK_ITERM: screenStartQuickIterm(); break;
|
||
case UI_START_CONFIRM: screenStartConfirm(); break;
|
||
case UI_PROFILES_LIST: screenProfilesList(); break;
|
||
case UI_PROFILE_EDIT_FIELD: screenProfileEditField(); break;
|
||
case UI_EDIT_CHEM: screenEditChem(); break;
|
||
case UI_EDIT_S: screenEditS(); break;
|
||
case UI_EDIT_CAP: screenEditCap(); break;
|
||
case UI_EDIT_RATEC: screenEditRateC(); break;
|
||
case UI_EDIT_ITERM: screenEditIterm(); break;
|
||
case UI_SETTINGS: screenSettings(); break;
|
||
case UI_SERVICE: screenService(); break;
|
||
case UI_MESSAGE: screenMessage(); break;
|
||
}
|
||
|
||
delay(6);
|
||
}
|