#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define led 13 // ; , ,
#define ADDR_KBRD 0x20
#define ADDR_LCD 0x27
#define PORT_D2 2
#define PORT_D3 3
#define PORT_D4 4
#define POINT_ON_ROOT_MENU_ITEM 0 // 0/1= / (* +)
byte dio_in;
bool b;
byte i;
bool BoolVal[9]={0,0,0, 0,0,0, 0,0,0};
#define ValSvet1 BoolVal[0]
#define ValSvet2 BoolVal[1]
#define ValSvet3 BoolVal[2]
#define ValRozetka1 BoolVal[3]
#define ValRozetka2 BoolVal[4]
#define ValRozetka3 BoolVal[5]
#define ValClapan1 BoolVal[6]
#define ValClapan2 BoolVal[7]
#define ValClapan3 BoolVal[8]
struct STRUCT_KEY{
bool StateCur;
bool StateOld;
bool Imp;
};
STRUCT_KEY Key[5]={0,0,0,
0,0,0,
0,0,0,
0,0,0,
0,0,0
};
String StrNull=" ";
String StrRoot1="COMP-MAN.INFO";
String StrRoot2="PLC-BLOG.COM.UA";
String StrSvet= "";
String StrSvet1=" 1 #01";
String StrSvet2=" 2 #10";
String StrSvet3=" 3 #21";
String StrRozetka="";
String StrRozetka1=" 1 #30";
String StrRozetka2=" 2 #40";
String StrRozetka3=" 3 #50";
String StrClapan="";
String StrClapan1=" 1 #60";
String StrClapan2=" 2 #70";
String StrClapan3=" 3 #80";
struct MENU_ITEM
{
byte KeyUp;
byte KeyDwn;
byte KeyCancel;
byte KeyEnter;
byte KeyEdit;
String *pstr1;
String *pstr2;
};
MENU_ITEM Menu[]={0,0,0,1,0, &StrRoot1,&StrRoot2,
1,8,0,2,0, &StrSvet,&StrRozetka,
2,3,1,2,0, &StrSvet1,&StrSvet2,
2,4,1,3,0, &StrSvet2,&StrSvet3,
3,4,1,4,0, &StrSvet3,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
1,15,0,9,0, &StrRozetka,&StrClapan,
9,10,8,9,0, &StrRozetka1, &StrRozetka2,
9,11,8,10,0, &StrRozetka2, &StrRozetka3,
10,11,8,11,0, &StrRozetka3, &StrNull,
0,0,0,0,0, &StrNull,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
8,15,0,16,0, &StrClapan, &StrNull,
16,17,15,0,0, &StrClapan1,&StrClapan2,
16,18,15,0,0, &StrClapan2,&StrClapan3,
17,18,15,0,0, &StrClapan3,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
0,0,0,0,0, &StrNull,&StrNull,
};
byte PosMenu=0;
LiquidCrystal_I2C lcd(ADDR_LCD,16,2);
void ReadKey(byte dio_in)
{
byte mask=1;
for(i=0; i<5; i++)
{
Key[i].StateCur=!(dio_in & mask);
mask=mask<<1;
Key[i].Imp=!Key[i].StateOld & Key[i].StateCur;
Key[i].StateOld=Key[i].StateCur;
}
}
byte MasRus[33][2]= {
144, 0x41,
145, 0xa0,
146, 0x42,
147, 0xa1,
148, 0xe0,
149, 0x45,
129, 0xa2,
150, 0xa3,
151, 0xa4,
152, 0xa5,
153, 0xa6,
154, 0x4b,
155, 0xa7,
156, 0x4d,
157, 0x48,
158, 0x4f,
159, 0xa8,
160, 0x50,
161, 0x43,
162, 0x54,
163, 0xa9,
164, 0xaa,
165, 0x58,
166, 0xe1,
167, 0xab,
168, 0xac,
169, 0xe2,
170, 0xad,
171, 0xae,
172, 0xc4,
173, 0xaf,
174, 0xb0,
175, 0xb1
};
String RusStrLCD(String StrIn)
{
String StrOut="";
byte b1;
byte y;
byte l=StrIn.length();
for(byte i=0; i<l; i++)
{
b1=StrIn.charAt(i);
if (b1<128)
StrOut=StrOut+char(b1);
else
{
if (b1==208)
{
b1=StrIn.charAt(i+1);
for(y=0; y<33; y++)
if(MasRus[y][0]==b1)
{
StrOut=StrOut+char(MasRus[y][1]);
break;
}
}
i++;
}
}
return StrOut;
}
byte StrHexToByte(char val)
{
byte dec=0;
switch (val) {
case '0':
dec=0;
break;
case '1':
dec=1;
break;
case '2':
dec=2;
break;
case '3':
dec=3;
break;
case '4':
dec=4;
break;
case '5':
dec=5;
break;
case '6':
dec=6;
break;
case '7':
dec=7;
break;
case '8':
dec=8;
break;
case '9':
dec=9;
break;
case 'A':
dec=10;
break;
case 'B':
dec=11;
break;
case 'C':
dec=12;
break;
case 'D':
dec=13;
break;
case 'E':
dec=14;
break;
case 'F':
dec=15;
break;
default:
dec=0;
break;
}
return dec;
}
void WriteLCD(byte num)
{
String str[]={"*"+*Menu[num].pstr1,*Menu[num].pstr2};
if (num==0 && POINT_ON_ROOT_MENU_ITEM==0)
str[0].setCharAt(0,' ');
byte NumVal;
byte l;
for(byte y=0; y<2; y++)
{
l=str[y].length();
for(i=0; i<l; i++)
{
if (str[y].charAt(i)=='#')
{
if(StrHexToByte(str[y].charAt(i+2))==1 && y==0)
str[y].setCharAt(0,'+');
NumVal=StrHexToByte(str[y].charAt(i+1));
str[y]=str[y].substring(0,i)+String(NumVal) ;
if(BoolVal[NumVal]==0)
str[y]=str[y].substring(0,i)+"off" ;
if(BoolVal[NumVal]==1)
str[y]=str[y].substring(0,i)+"ON" ;
}
if (str[y].charAt(i)=='$')
{
;
}
if (str[y].charAt(i)=='~')
{
;
}
}
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(str[0]);
lcd.setCursor(1, 1);
lcd.print(str[1]);
}
byte GoMenu(byte key)
{
byte PosMenuNew=PosMenu;
switch (key) {
case 0:
PosMenuNew=Menu[PosMenu].KeyUp;
break;
case 1:
PosMenuNew=Menu[PosMenu].KeyDwn;
break;
case 2:
PosMenuNew=Menu[PosMenu].KeyCancel;
break;
case 3:
PosMenuNew=Menu[PosMenu].KeyEnter;
break;
case 4:
;
break;
default:
break;
}
return PosMenuNew;
}
void Edit(byte posmenu)
{
byte NumVal;
bool *pval;
String str=*Menu[posmenu].pstr1;
byte l=str.length();
for(i=0; i<l; i++)
if (str.charAt(i)=='#')
{
if(StrHexToByte(str.charAt(i+2))==1)
{
pval= &(BoolVal[StrHexToByte(str.charAt(i+1))]);
*pval=!(*pval);
}
}
}
void ValToPort()
{
digitalWrite(PORT_D2,ValSvet1);
digitalWrite(PORT_D3,ValSvet2);
digitalWrite(PORT_D4,ValSvet3);
}
void setup()
{
pinMode(led, OUTPUT);
pinMode(PORT_D2, OUTPUT);
pinMode(PORT_D3, OUTPUT);
pinMode(PORT_D4, OUTPUT);
StrSvet=RusStrLCD(StrSvet);
StrSvet1=RusStrLCD(StrSvet1);
StrSvet2=RusStrLCD(StrSvet2);
StrSvet3=RusStrLCD(StrSvet3);
StrRozetka=RusStrLCD(StrRozetka);
StrRozetka1=RusStrLCD(StrRozetka1);
StrRozetka2=RusStrLCD(StrRozetka2);
StrRozetka3=RusStrLCD(StrRozetka3);
StrClapan=RusStrLCD(StrClapan);
StrClapan1=RusStrLCD(StrClapan1);
StrClapan2=RusStrLCD(StrClapan2);
StrClapan3=RusStrLCD(StrClapan3);
lcd.init();
lcd.backlight();
WriteLCD(PosMenu);
Wire.begin();
Wire.beginTransmission(ADDR_KBRD);
Wire.write(B11111111);
Wire.endTransmission();
}
void loop()
{
Wire.requestFrom(ADDR_KBRD,1);
while (!Wire.available());
byte dio_in = Wire.read();
ReadKey(dio_in);
int KeyImp=-1;
for (i=0; i<5; i++)
if(Key[i].Imp==1)
{
KeyImp=i;
Key[i].Imp==0;
}
if (KeyImp>-1)
{
if (KeyImp==4)
Edit(PosMenu);
PosMenu=GoMenu((KeyImp));
WriteLCD(PosMenu);
}
b=!b;
digitalWrite(led, b);
ValToPort();
delay(50);
}