Ошибка в коде
- Войдите на сайт для отправки комментариев
Сб, 07/01/2017 - 22:10
Ребят, нашел в инете код, подходящий для моего проекта, но попытавшись скопмелировать его, напоролся на ошибки, которые уже битых 4 часа не могу осмыслить и убрать. Помогите пожалуйста, а то руки опускаются
Arduino: 1.8.0 (Windows 7), Плата:"Arduino/Genuino Uno"
C:\Users\Р?лья\Desktop\water\water.ino: In function 'void setup()':
water:311: error: a function-definition is not allowed here before '{' token
water:619: error: expected '}' at end of input
exit status 1
a function-definition is not allowed here before '{' token
#include <EEPROM.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#define LEFT 0
#define CENTER 1
#define RIGHT 2
#define RelayModesCount 4
#define KeyFirst 2
#define KeyLast 6
LiquidCrystal_I2C lcd (0x27,20,4);
RTC_DS1307 RTC; // RTC Modul
DHT dht(7, DHT21); // pin, type
volatile boolean Blinker = true;
volatile long BlinkerTime;
volatile byte ButtonPress[8];
const String RelayModeNames[] = {"OFF", "ON", "Once", "Daily"};
int aKey1 = 0;
int aKey2 = 0;
DateTime NowDate;
boolean DoBlink(void)
{
boolean Result = false;
long NBlinkerTime = millis();
if (Blinker)
{
if (NBlinkerTime - BlinkerTime > 200)
{
digitalWrite(8, HIGH);
BlinkerTime = NBlinkerTime;
Blinker = false;
Result = true;
}
}
else
{
if (NBlinkerTime - BlinkerTime > 300 )
{
digitalWrite(8, LOW);
BlinkerTime = NBlinkerTime;
Blinker = true;
}
}
return Result;
}
String BlinkString(String string, byte Cur, byte ItemsCount)
{
String result = string;
byte len = string.length();
if (!Blinker && Cur == ItemsCount)
{
for (byte i = 0; i < len; i++) result.setCharAt(i, ' ');
}
return result;
}
/********************************************************************************************************/
/********************************** Объявление классов *********************************************/
/********************************************************************************************************/
class TMenu
{
public:
byte _ItemsCount;
TMenu *Parent;
String *MenuName;
boolean ItemIsValue;
byte CurrentItem;
TMenu **Items;
String *ItemsName;
// byte ItemsCount(void);
byte ItemsCount(void) {
return _ItemsCount;
};
bool AddItem(TMenu *NewItem);
virtual void Print(void);
void OnKey(byte KeyNum);
void ChangeItem(byte value);
virtual void Increment(void);
virtual void Decrement(void);
virtual void OnSet(void);
DateTime CheckDateTime(DateTime OldDate, int Increment, byte DatePart);
};
class TNoMenu: public TMenu
{
public:
void Print(void);
TNoMenu(TMenu *ParentMenu) {
MenuName = 0;
CurrentItem = 0;
_ItemsCount = 0;
Parent = ParentMenu;
Items = 0;
ItemsName = 0;
ItemIsValue = false;
};
void Increment(void) {};
void Decrement(void) {};
void OnSet(void) {};
};
class TSelectMenu: public TMenu
{
public:
void Print(void);
TSelectMenu(TMenu *ParentMenu, String NewName) {
MenuName = new String(NewName);
CurrentItem = 0;
_ItemsCount = 0;
Parent = ParentMenu;
Items = 0;
ItemsName = 0;
ItemIsValue = false;
};
void Increment(void) {};
void Decrement(void) {};
void OnSet(void) {};
};
class TTimeMenu: public TMenu
{
public:
void Print(void);
DateTime *SetDateTime;
long OldDateTime;
TTimeMenu(TMenu *ParentMenu, String NewName, DateTime *ParamDate) {
MenuName = new String(NewName);
CurrentItem = 0; _ItemsCount = 6; Parent = ParentMenu; Items = 0; ItemsName = 0;
ItemIsValue = true; OldDateTime = millis();
SetDateTime = ParamDate;
};
void Increment(void) {
*SetDateTime = CheckDateTime (*SetDateTime, 1, CurrentItem);
};
void Decrement(void) {
*SetDateTime = CheckDateTime (*SetDateTime, -1, CurrentItem);
};
void OnSet(void) {
RTC.adjust(*SetDateTime);
};
void SecondTimer(void) {
long TmpDateTime = millis(); if (TmpDateTime - OldDateTime > 1000) {
OldDateTime = TmpDateTime;
*SetDateTime = *SetDateTime + 1;
};
};
};
class TRelayMenu: public TMenu
{
public:
byte RelayNumber;
byte RelayMode;
// byte Shedule=0;
boolean OnceBit;
DateTime RelayOn;
DateTime RelayOff;
TRelayMenu(TMenu *ParentMenu, byte NewNumber, String NewName) {
MenuName = new String(NewName);
CurrentItem = 0; _ItemsCount = 11; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = true, OnceBit = false;
RelayNumber = NewNumber;
RelayMode = 0;
RelayOn = DateTime(2015, 1, 1, 23, 00, 00);
RelayOff = DateTime(2015, 1, 1, 07, 00, 00);
};
void Print(void);
void Increment(void) {
if (!CurrentItem) {
RelayMode++;
if ( RelayMode >= RelayModesCount) RelayMode = 0;
}
else if (CurrentItem < 6) RelayOn = CheckDateTime (RelayOn, 1, CurrentItem - 1);
else RelayOff = CheckDateTime (RelayOff, 1, CurrentItem - 6);
};
void Decrement(void) {
if (!CurrentItem) {
RelayMode--;
if ( RelayMode > 127) RelayMode = RelayModesCount - 1;
}
else if (CurrentItem < 6) RelayOn = CheckDateTime (RelayOn, -1, CurrentItem - 1);
else RelayOff = CheckDateTime (RelayOff, -1, CurrentItem - 6);
};
boolean CheckDaily(void);
void OnSet(void) {
///// здесь надо записать реле в память
byte p_address = RelayNumber * 16;
EEPROM.write(p_address, RelayMode);
EEPROM.write(p_address + 1, byte(RelayOn.year() - 2000));
EEPROM.write(p_address + 2, byte(RelayOn.month() ));
EEPROM.write(p_address + 3, byte(RelayOn.day() ));
EEPROM.write(p_address + 4, byte(RelayOn.hour() ));
EEPROM.write(p_address + 5, byte(RelayOn.minute() ));
EEPROM.write(p_address + 6, byte(RelayOff.year() - 2000));
EEPROM.write(p_address + 7, byte(RelayOff.month() ));
EEPROM.write(p_address + 8, byte(RelayOff.day() ));
EEPROM.write(p_address + 9, byte(RelayOff.hour() ));
EEPROM.write(p_address + 10, byte(RelayOff.minute() ));
};
};
/********************************************************************************************************/
/******************************** Конец объявления классов ******************************************/
/********************************************************************************************************/
TMenu *CurrentMenu = 0;
TNoMenu *NoMenu = 0;
TSelectMenu *SelectMenu;
TTimeMenu *TimeMenu;
TRelayMenu *RelayMenu[4];
/********************************************************************************************************************************************/
/********************************************************************************************************************************************/
/********************************************************************************************************************************************/
void setup()
{
NoMenu = new TNoMenu(0);
SelectMenu = new TSelectMenu (NoMenu, "NoMenu");
TimeMenu = new TTimeMenu(SelectMenu, "Time Setup", &NowDate);
SelectMenu->AddItem(TimeMenu);
byte p_address;
DateTime DTFlesh;
for (int i = 0; i < 4; i++)
{
// здесь надо добавить загрузку параметров из флеша
RelayMenu[i] = new TRelayMenu (SelectMenu, i, "Relay " + String(i + 1));
SelectMenu->AddItem(RelayMenu[i]);
p_address = i * 16;
RelayMenu[i]->RelayMode = EEPROM.read(p_address);
DTFlesh = DateTime(int(EEPROM.read(p_address + 1) + 2000), EEPROM.read(p_address + 2), EEPROM.read(p_address + 3), EEPROM.read(p_address + 4), EEPROM.read(p_address + 5), 0 );
RelayMenu[i]->RelayOn = RelayMenu[i]->CheckDateTime(DTFlesh, 0, 0);
DTFlesh = DateTime(int(EEPROM.read(p_address + 6) + 2000), EEPROM.read(p_address + 7), EEPROM.read(p_address + 8), EEPROM.read(p_address + 9), EEPROM.read(p_address + 10), 0 );
RelayMenu[i]->RelayOff = RelayMenu[i]->CheckDateTime(DTFlesh, 0, 0);
}
for (byte i = KeyFirst; i < KeyLast; i++)
{
pinMode(i, INPUT); //Keypad 2-«menu» 3-"-" 4-"+" 5-«SET»
digitalWrite(i, HIGH); //setup Resistor input2Vcc
ButtonPress[i] = true;
}
pinMode(8, OUTPUT); //LED
pinMode(9, OUTPUT);
for (byte i = 10; i < 14; i++)
{
pinMode(i, OUTPUT); // relay i
digitalWrite(i, HIGH);
}
pinMode (A2, INPUT_PULLUP);
pinMode (A3, INPUT_PULLUP);
Serial.begin(9600); // Used to type in characters
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines and turn on backlight
RTC.begin();
lcd.noBacklight();
delay(150);
lcd.backlight();
NowDate = RTC.now();
//проверка времени
if ( NowDate.year() > 2000 && NowDate.year() < 2114 &&
NowDate.month() > 0 && NowDate.month() < 13 &&
NowDate.day() > 0 && NowDate.day() < 32 &&
NowDate.hour() >= 0 && NowDate.hour() < 24 &&
NowDate.minute() >= 0 && NowDate.minute() < 60 &&
NowDate.second() >= 0 && NowDate.second() < 60 )
{
CurrentMenu = NoMenu;
}
else
{
lcd.setCursor(2, 1);
lcd.print("Clock Failure!");
delay(700);
RTC.adjust(DateTime(2015, 1, 1, 00, 00, 00));
CurrentMenu = TimeMenu;
}
void loop()
{
/********* KEYPAD BUNCLE, 5 keys, from 2 to 6 *********/
byte NButtonPress[8] = {0, 0, 0, 0, 0, 0, 0, 0};
byte NButtonRelease[8] = {0, 0, 0, 0, 0, 0, 0, 0};
const byte ButtonTry = 3;
aKey1 = analogRead (2);
aKey2 = analogRead (3);
byte aKeyNum=0;
/**************** check for key pressed or released ****************/
for (byte i = 0; i < 3; i++)
{
delay(15);
if (aKey1< 64) aKeyNum=2;//AnalogKey 1 = Dig2
else if (aKey1<128) aKeyNum=6;//Analog key 3 = D4
else if (aKey1<256) aKeyNum=4;//key 5=d6
else if (aKey2< 64) aKeyNum=1;//key 6 = menu
else if (aKey2<128) aKeyNum=3;//analogkey 2 = D3
else if (aKey2<256) aKeyNum=5;//key 4 =d5
else aKeyNum=0; // no key
for (byte j = KeyFirst; j < KeyLast; j++) // Read ports 2...6
{
if (digitalRead(j) == LOW || aKeyNum==j)
{
NButtonPress[j]++;
NButtonRelease[j] = 0;
}
else
{
NButtonPress [ j ] = 0;
NButtonRelease[j]++;
delay(5);
}
}
/*************** Do key process ******************/
// byte m;
for (byte j = KeyFirst; j < KeyLast; j++)
{
if (NButtonPress[ j ] >= ButtonTry ButtonPress[ j ] == false)
{
ButtonPress[j] = true;
CurrentMenu->OnKey(j);
}
else
{
if (NButtonRelease[j] >= ButtonTry && ButtonPress[j] == true)
{
ButtonPress[j] = false;
}
}
}
/***************** Relay Check *********************/
CurrentMenu->Print();
DoBlink();
}
void LcdPrint(byte string, String str, byte Align)
{
byte StrTrim1;
byte StrTrim2;
lcd.setCursor(0, string); //Start at character 0 on line 0
switch (Align)
{
case RIGHT:
break;
case CENTER:
StrTrim1 = byte((20 - str.length()) / 2);
StrTrim2 = 20 - str.length() - StrTrim1;
for (byte k = 0; k < StrTrim1; k++) lcd.print(" ");
lcd.print(str);
for (byte k = 0; k < StrTrim2; k++) lcd.print(" ");
break;
default:
lcd.print(str);
StrTrim1 = 20 - str.length();
for (byte k = 0; k < StrTrim1; k++) lcd.print(" ");
}
}
void TNoMenu::Print(void)
{
NowDate = RTC.now();
String Ddate;
Ddate = " R1-" + RelayModeNames[RelayMenu[0]->RelayMode] + " R2-" + RelayModeNames[RelayMenu[1]->RelayMode];
LcdPrint(0, Ddate, CENTER);
Ddate = " R3-" + RelayModeNames[RelayMenu[2]->RelayMode] + " R4-" + RelayModeNames[RelayMenu[3]->RelayMode];
LcdPrint(1, Ddate, CENTER);
Ddate = String (NowDate.year()) + "/" + String(NowDate.month()) + "/" + String(NowDate.day()) + " " + String (NowDate.hour()) + ":" + String(NowDate.minute()) + ":" + String(NowDate.second());
LcdPrint(2, Ddate, CENTER);
Ddate = "Temp " + String (int(dht.readTemperature())) + "C, Hum " + String(int(dht.readHumidity())) + "%";
LcdPrint(3, Ddate, CENTER);
RelayCheck();
}
void TTimeMenu::Print(void)
{
SecondTimer();
String Ddate = BlinkString(String((*SetDateTime).year()), CurrentItem, 0) + "/" +
BlinkString(String( (*SetDateTime).month()), CurrentItem, 1) + "/" +
BlinkString(String((*SetDateTime).day()), CurrentItem, 2) + " ";
LcdPrint(1, Ddate, CENTER);
Ddate = BlinkString(String ((*SetDateTime).hour()), CurrentItem, 3) + ":" +
BlinkString(String((*SetDateTime).minute()), CurrentItem, 4) + ":" +
BlinkString(String((*SetDateTime).second()), CurrentItem, 5);
LcdPrint(2, Ddate, CENTER);
LcdPrint(3, " ", CENTER);
RelayCheck();
}
void TMenu::OnKey(byte KeyNum)
{
switch (KeyNum)
{
case 3: // — if (ItemIsValue) Decrement();
else ChangeItem(-1);
break;
case 4: // +
if (ItemIsValue) Increment();
else ChangeItem(1);
break;
case 5: // SET
if (ItemIsValue)
{
OnSet();
ChangeItem(+1);
}
else // вход в подменю
{
if (Items && ItemsCount())
{
if (CurrentMenu->ItemsCount())
{
CurrentMenu = CurrentMenu->Items[CurrentMenu->CurrentItem];
CurrentMenu->CurrentItem = 0;
}
}
}
break;
default: // 2 -menu
if (Parent) CurrentMenu = CurrentMenu->Parent; //(TMenu *) &NoMenu;
else
{
CurrentMenu = SelectMenu;
CurrentMenu->CurrentItem = 0;
}
}
}
void TMenu::ChangeItem(byte value)
{
CurrentItem += value;
if (CurrentItem > 128) CurrentItem = ItemsCount() - 1;
else if (CurrentItem > ItemsCount() - 1) CurrentItem = 0;
}
boolean TMenu::AddItem(TMenu *NewItem)
{
if (!Items) Items = new TMenu *[_ItemsCount = 1];
else Items = (TMenu **)realloc((void *)Items, (_ItemsCount = _ItemsCount + 1) * sizeof(void *));
Items[_ItemsCount - 1] = NewItem;
}
DateTime TMenu::CheckDateTime(DateTime OldDate, int Increment, byte DatePart)
{
int DTmin[6] = {2000, 1, 1, 0, 0, 0};
int DTmax[6] = {2199, 12, 31, 23, 59, 59};
int DT[6];
int diff;
DT[0] = OldDate.year();
DT[1] = OldDate.month();
DT[2] = OldDate.day();
DT[3] = OldDate.hour();
DT[4] = OldDate.minute();
DT[5] = OldDate.second();
DT[DatePart] = DT[DatePart] + Increment;
if (DT[1] == 1 || DT[1] == 3 || DT[1] == 5 || DT[1] == 7 || DT[1] == 8 || DT[1] == 10 || DT[1] == 12) DTmax[2] = 31;
else if (DT[1] == 2)
{
if ((DT[0] % 4 == 0 && DT[0] % 100 != 0) || (DT[0] % 400 == 0)) DTmax[2] = 29;
else DTmax[2] = 28;
}
else DTmax[2] = 30;
for (byte i = 0; i < 6; i++)
{
if (DT[i] > DTmax[i]) DT[i] = DTmin[i];
else if (DT[i] < DTmin[i]) DT[i] = DTmax[i];
}
return DateTime(DT[0], DT[1], DT[2], DT[3], DT[4], DT[5]);
}
void TSelectMenu::Print(void)
{
NowDate = RTC.now();
byte shift = 0;
if (CurrentItem > 3) shift = CurrentItem - 3;
for (byte i = 0; i < 4; i++)
{
if ((CurrentItem - shift) == i) //Blinker
{
LcdPrint(i, ">> " + * (Items[i + shift]->MenuName) + " <<", CENTER);
}
else LcdPrint(i, *(Items[i + shift]->MenuName), CENTER);
}
RelayCheck();
}
void TRelayMenu::Print(void)
{
String DData;
NowDate = RTC.now();
LcdPrint(0, (*MenuName) + "[" + BlinkString(RelayModeNames[RelayMode], CurrentItem, 0) + "]", CENTER);
DData = "On:";
switch (RelayMode)
{
case 3: //Daily
// DData = DData + " ";
if (CurrentItem > 0 && CurrentItem < 4) CurrentItem = 4;
break;
default:
DData = DData + BlinkString(String(RelayOn.year(), DEC), CurrentItem, 1) + "/" + BlinkString(String( RelayOn.month(), DEC), CurrentItem, 2) +
"/" + BlinkString(String( RelayOn.day(), DEC), CurrentItem, 3);
}
DData = DData + " " + BlinkString(String (RelayOn.hour(), DEC), CurrentItem, 4) + ":" + BlinkString(String(RelayOn.minute(), DEC), CurrentItem, 5);
LcdPrint(1, DData, CENTER);
DData = "Off:";
switch (RelayMode)
{
case 3: //Daily
// DData = DData + " ";
if (CurrentItem > 5 && CurrentItem < 9) CurrentItem = 9;
break;
default:
DData = DData + BlinkString(String(RelayOff.year(), DEC), CurrentItem, 6) + "/" + BlinkString(String( RelayOff.month(), DEC), CurrentItem, 7) +
"/" + BlinkString(String( RelayOff.day(), DEC), CurrentItem, 8);
}
DData = DData + " " + BlinkString(String (RelayOff.hour(), DEC), CurrentItem, 9) + ":" + BlinkString(String(RelayOff.minute(), DEC), CurrentItem, 10);
LcdPrint(2, DData, CENTER);
LcdPrint(3, " ", CENTER);
}
boolean TRelayMenu::CheckDaily(void)
{
int TimeOn = 60 * int(RelayOn.hour()) + int(RelayOn.minute());
int TimeOff = 60 * int(RelayOff.hour()) + int(RelayOff.minute());
int NowTime = 60 * int(NowDate.hour()) + int(NowDate.minute());
boolean result; // true = время включения больше времени выключения
if ( TimeOn > TimeOff )
{
if (NowTime <= TimeOff || NowTime >= TimeOn ) result = true;
else result = false;
}
else
{
if (NowTime <= TimeOff && NowTime >= TimeOn ) result = true;
else result = false;
};
return result;
}
void RelayCheck (void)
{
boolean OnceBitCheck;
for (byte i = 0; i < 4; i++)
{
switch (RelayMenu[i]->RelayMode)
{
case 1: //relay 0n
digitalWrite(i + 10, LOW);
break;
case 2: //Once;
OnceBitCheck = (NowDate.unixtime() > RelayMenu[i]->RelayOn.unixtime() && NowDate.unixtime()<RelayMenu[i]->RelayOff.unixtime());
if (OnceBitCheck) RelayMenu[i]->OnceBit = true;
else if (RelayMenu[i]->OnceBit)
{
RelayMenu[i]->RelayMode = 0;
byte p_address = RelayMenu[i]->RelayNumber * 16;
EEPROM.write(p_address, RelayMenu[i]->RelayMode);
}
digitalWrite(i + 10, !OnceBitCheck);
break;
case 3: //Daily
digitalWrite(i + 10, !(RelayMenu[i]->CheckDaily()));
break;
default: //relay 0ff
digitalWrite(i + 10, HIGH);
}
}
}
Перед
поставьте
и будет Вам счастье (наверное).
выдает это
В строке 372 тоже поставте скобку закрывающую.
И Crt-T в IDE почаще нажимайте.
Ребята. Подскажите что за ошибка. "C:\Users\Dmitriy\AppData\Local\Temp\arduino_modified_sketch_784566\sketch_apr10c.ino: In member function 'virtual void TNoMenu::Print()':
#include <EEPROM.h> #include <DHT.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <RTClib.h> #define LEFT 0 #define CENTER 1 #define RIGHT 2 #define RelayModesCount 4 #define KeyFirst 2 #define KeyLast 6 LiquidCrystal_I2C lcd (0x3F, 20, 4); RTC_DS1307 RTC; // RTC Modul DHT dht(7, DHT21); // pin, type volatile boolean Blinker = true; volatile long BlinkerTime; volatile byte ButtonPress[8]; const String RelayModeNames[] = {"OFF", "ON", "Once", "Daily"}; int aKey1 = 0; int aKey2 = 0; DateTime NowDate; boolean DoBlink(void) { boolean Result = false; long NBlinkerTime = millis(); if (Blinker) { if (NBlinkerTime - BlinkerTime > 200) { digitalWrite(8, HIGH); BlinkerTime = NBlinkerTime; Blinker = false; Result = true; } } else { if (NBlinkerTime - BlinkerTime > 300 ) { digitalWrite(8, LOW); BlinkerTime = NBlinkerTime; Blinker = true; } } return Result; } String BlinkString(String string, byte Cur, byte ItemsCount) { String result = string; byte len = string.length(); if (!Blinker && Cur == ItemsCount) { for (byte i = 0; i < len; i++) result.setCharAt(i, ' '); } return result; } /********************************************************************************************************/ /********************************** Объявление классов *********************************************/ /********************************************************************************************************/ class TMenu { public: byte _ItemsCount; TMenu *Parent; String *MenuName; boolean ItemIsValue; byte CurrentItem; TMenu **Items; String *ItemsName; // byte ItemsCount(void); byte ItemsCount(void) { return _ItemsCount; }; bool AddItem(TMenu *NewItem); virtual void Print(void); void OnKey(byte KeyNum); void ChangeItem(byte value); virtual void Increment(void); virtual void Decrement(void); virtual void OnSet(void); DateTime CheckDateTime(DateTime OldDate, int Increment, byte DatePart); }; class TNoMenu: public TMenu { public: void Print(void); TNoMenu(TMenu *ParentMenu) { MenuName = 0; CurrentItem = 0; _ItemsCount = 0; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = false; }; void Increment(void) {}; void Decrement(void) {}; void OnSet(void) {}; }; class TSelectMenu: public TMenu { public: void Print(void); TSelectMenu(TMenu *ParentMenu, String NewName) { MenuName = new String(NewName); CurrentItem = 0; _ItemsCount = 0; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = false; }; void Increment(void) {}; void Decrement(void) {}; void OnSet(void) {}; }; class TTimeMenu: public TMenu { public: void Print(void); DateTime *SetDateTime; long OldDateTime; TTimeMenu(TMenu *ParentMenu, String NewName, DateTime *ParamDate) { MenuName = new String(NewName); CurrentItem = 0; _ItemsCount = 6; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = true; OldDateTime = millis(); SetDateTime = ParamDate; }; void Increment(void) { *SetDateTime = CheckDateTime (*SetDateTime, 1, CurrentItem); }; void Decrement(void) { *SetDateTime = CheckDateTime (*SetDateTime, -1, CurrentItem); }; void OnSet(void) { RTC.adjust(*SetDateTime); }; void SecondTimer(void) { long TmpDateTime = millis(); if (TmpDateTime - OldDateTime > 1000) { OldDateTime = TmpDateTime; *SetDateTime = *SetDateTime + 1; }; }; }; class TRelayMenu: public TMenu { public: byte RelayNumber; byte RelayMode; // byte Shedule=0; boolean OnceBit; DateTime RelayOn; DateTime RelayOff; TRelayMenu(TMenu *ParentMenu, byte NewNumber, String NewName) { MenuName = new String(NewName); CurrentItem = 0; _ItemsCount = 11; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = true, OnceBit = false; RelayNumber = NewNumber; RelayMode = 0; RelayOn = DateTime(2015, 1, 1, 23, 00, 00); RelayOff = DateTime(2015, 1, 1, 07, 00, 00); }; void Print(void); void Increment(void) { if (!CurrentItem) { RelayMode++; if ( RelayMode >= RelayModesCount) RelayMode = 0; } else if (CurrentItem < 6) RelayOn = CheckDateTime (RelayOn, 1, CurrentItem - 1); else RelayOff = CheckDateTime (RelayOff, 1, CurrentItem - 6); }; void Decrement(void) { if (!CurrentItem) { RelayMode--; if ( RelayMode > 127) RelayMode = RelayModesCount - 1; } else if (CurrentItem < 6) RelayOn = CheckDateTime (RelayOn, -1, CurrentItem - 1); else RelayOff = CheckDateTime (RelayOff, -1, CurrentItem - 6); }; boolean CheckDaily(void); void OnSet(void) { ///// здесь надо записать реле в память byte p_address = RelayNumber * 16; EEPROM.write(p_address, RelayMode); EEPROM.write(p_address + 1, byte(RelayOn.year() - 2000)); EEPROM.write(p_address + 2, byte(RelayOn.month() )); EEPROM.write(p_address + 3, byte(RelayOn.day() )); EEPROM.write(p_address + 4, byte(RelayOn.hour() )); EEPROM.write(p_address + 5, byte(RelayOn.minute() )); EEPROM.write(p_address + 6, byte(RelayOff.year() - 2000)); EEPROM.write(p_address + 7, byte(RelayOff.month() )); EEPROM.write(p_address + 8, byte(RelayOff.day() )); EEPROM.write(p_address + 9, byte(RelayOff.hour() )); EEPROM.write(p_address + 10, byte(RelayOff.minute() )); }; }; /********************************************************************************************************/ /******************************** Конец объявления классов ******************************************/ /********************************************************************************************************/ TMenu *CurrentMenu = 0; TNoMenu *NoMenu = 0; TSelectMenu *SelectMenu; TTimeMenu *TimeMenu; TRelayMenu *RelayMenu[4]; /********************************************************************************************************************************************/ /********************************************************************************************************************************************/ /********************************************************************************************************************************************/ void setup() { NoMenu = new TNoMenu(0); SelectMenu = new TSelectMenu (NoMenu, "NoMenu"); TimeMenu = new TTimeMenu(SelectMenu, "Time Setup", &NowDate); SelectMenu->AddItem(TimeMenu); byte p_address; DateTime DTFlesh; for (int i = 0; i < 4; i++) { // здесь надо добавить загрузку параметров из флеша RelayMenu[i] = new TRelayMenu (SelectMenu, i, "Relay " + String(i + 1)); SelectMenu->AddItem(RelayMenu[i]); p_address = i * 16; RelayMenu[i]->RelayMode = EEPROM.read(p_address); DTFlesh = DateTime(int(EEPROM.read(p_address + 1) + 2000), EEPROM.read(p_address + 2), EEPROM.read(p_address + 3), EEPROM.read(p_address + 4), EEPROM.read(p_address + 5), 0 ); RelayMenu[i]->RelayOn = RelayMenu[i]->CheckDateTime(DTFlesh, 0, 0); DTFlesh = DateTime(int(EEPROM.read(p_address + 6) + 2000), EEPROM.read(p_address + 7), EEPROM.read(p_address + 8), EEPROM.read(p_address + 9), EEPROM.read(p_address + 10), 0 ); RelayMenu[i]->RelayOff = RelayMenu[i]->CheckDateTime(DTFlesh, 0, 0); } for (byte i = KeyFirst; i < KeyLast; i++) { pinMode(i, INPUT); //Keypad 2-«menu» 3-"-" 4-"+" 5-«SET» digitalWrite(i, HIGH); //setup Resistor input2Vcc ButtonPress[i] = true; } pinMode(8, OUTPUT); //LED pinMode(9, OUTPUT); for (byte i = 10; i < 14; i++) { pinMode(i, OUTPUT); // relay i digitalWrite(i, HIGH); } pinMode (A2, INPUT_PULLUP); pinMode (A3, INPUT_PULLUP); Serial.begin(9600); // Used to type in characters digitalWrite(8, LOW); digitalWrite(9, HIGH); lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines and turn on backlight RTC.begin(); lcd.noBacklight(); delay(150); lcd.backlight(); NowDate = RTC.now(); //проверка времени if ( NowDate.year() > 2000 && NowDate.year() < 2114 && NowDate.month() > 0 && NowDate.month() < 13 && NowDate.day() > 0 && NowDate.day() < 32 && NowDate.hour() >= 0 && NowDate.hour() < 24 && NowDate.minute() >= 0 && NowDate.minute() < 60 && NowDate.second() >= 0 && NowDate.second() < 60 ) { CurrentMenu = NoMenu; } else { lcd.setCursor(2, 1); lcd.print("Clock Failure!"); delay(700); RTC.adjust(DateTime(2015, 1, 1, 00, 00, 00)); CurrentMenu = TimeMenu; } } void loop() { /********* KEYPAD BUNCLE, 5 keys, from 2 to 6 *********/ byte NButtonPress[8] = {0, 0, 0, 0, 0, 0, 0, 0}; byte NButtonRelease[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const byte ButtonTry = 3; aKey1 = analogRead (2); aKey2 = analogRead (3); byte aKeyNum = 0; /**************** check for key pressed or released ****************/ for (byte i = 0; i < 3; i++) { delay(15); if (aKey1 < 64) aKeyNum = 2; //AnalogKey 1 = Dig2 else if (aKey1 < 128) aKeyNum = 6; //Analog key 3 = D4 else if (aKey1 < 256) aKeyNum = 4; //key 5=d6 else if (aKey2 < 64) aKeyNum = 1; //key 6 = menu else if (aKey2 < 128) aKeyNum = 3; //analogkey 2 = D3 else if (aKey2 < 256) aKeyNum = 5; //key 4 =d5 else aKeyNum = 0; // no key for (byte j = KeyFirst; j < KeyLast; j++) // Read ports 2...6 { if (digitalRead(j) == LOW || aKeyNum == j) { NButtonPress[j]++; NButtonRelease[j] = 0; } else { NButtonPress [ j ] = 0; NButtonRelease[j]++; delay(5); } } /*************** Do key process ******************/ // byte m; for (byte j = KeyFirst; j < KeyLast; j++) { if (NButtonPress[j] >= ButtonTry && ButtonPress[j] == false) { ButtonPress[j] = true; CurrentMenu->OnKey(j); } else { if (NButtonRelease[j] >= ButtonTry && ButtonPress[j] == true) { ButtonPress[j] = false; } } } /***************** Relay Check *********************/ CurrentMenu->Print(); DoBlink(); } } void LcdPrint(byte string, String str, byte Align) { byte StrTrim1; byte StrTrim2; lcd.setCursor(0, string); //Start at character 0 on line 0 switch (Align) { case RIGHT: break; case CENTER: StrTrim1 = byte((20 - str.length()) / 2); StrTrim2 = 20 - str.length() - StrTrim1; for (byte k = 0; k < StrTrim1; k++) lcd.print(" "); lcd.print(str); for (byte k = 0; k < StrTrim2; k++) lcd.print(" "); break; default: lcd.print(str); StrTrim1 = 20 - str.length(); for (byte k = 0; k < StrTrim1; k++) lcd.print(" "); } } void TNoMenu::Print(void) { NowDate = RTC.now(); String Ddate; Ddate = " R1-" + RelayModeNames[RelayMenu[0]->RelayMode] + " R2-" + RelayModeNames[RelayMenu[1]->RelayMode]; LcdPrint(0, Ddate, CENTER); Ddate = " R3-" + RelayModeNames[RelayMenu[2]->RelayMode] + " R4-" + RelayModeNames[RelayMenu[3]->RelayMode]; LcdPrint(1, Ddate, CENTER); Ddate = String (NowDate.year()) + "/" + String(NowDate.month()) + "/" + String(NowDate.day()) + " " + String (NowDate.hour()) + ":" + String(NowDate.minute()) + ":" + String(NowDate.second()); LcdPrint(2, Ddate, CENTER); Ddate = "Temp " + String (int(dht.readTemperature())) + "C, Hum " + String(int(dht.readHumidity())) + "%"; LcdPrint(3, Ddate, CENTER); RelayCheck(); } void TTimeMenu::Print(void) { SecondTimer(); String Ddate = BlinkString(String((*SetDateTime).year()), CurrentItem, 0) + "/" + BlinkString(String( (*SetDateTime).month()), CurrentItem, 1) + "/" + BlinkString(String((*SetDateTime).day()), CurrentItem, 2) + " "; LcdPrint(1, Ddate, CENTER); Ddate = BlinkString(String ((*SetDateTime).hour()), CurrentItem, 3) + ":" + BlinkString(String((*SetDateTime).minute()), CurrentItem, 4) + ":" + BlinkString(String((*SetDateTime).second()), CurrentItem, 5); LcdPrint(2, Ddate, CENTER); LcdPrint(3, " ", CENTER); RelayCheck(); } void TMenu::OnKey(byte KeyNum) { switch (KeyNum) { case 3: // — if (ItemIsValue) Decrement(); else ChangeItem(-1); break; case 4: // + if (ItemIsValue) Increment(); else ChangeItem(1); break; case 5: // SET if (ItemIsValue) { if OnSet(); else ChangeItem(+1); } else // вход в подменю { if (Items && ItemsCount()) { if (CurrentMenu->ItemsCount()) { CurrentMenu = CurrentMenu->Items[CurrentMenu->CurrentItem]; CurrentMenu->CurrentItem = 0; } } } break; default: // 2 -menu if (Parent) CurrentMenu = CurrentMenu->Parent; //(TMenu *) &NoMenu; else { CurrentMenu = SelectMenu; CurrentMenu->CurrentItem = 0; } } void TMenu::ChangeItem(byte value) { CurrentItem += value; if (CurrentItem > 128) CurrentItem = ItemsCount() - 1; else if (CurrentItem > ItemsCount() - 1) CurrentItem = 0; } boolean TMenu::AddItem(TMenu * NewItem) { if (!Items) Items = new TMenu *[_ItemsCount = 1]; else Items = (TMenu **)realloc((void *)Items, (_ItemsCount = _ItemsCount + 1) * sizeof(void *)); Items[_ItemsCount - 1] = NewItem; } DateTime TMenu::CheckDateTime(DateTime OldDate, int Increment, byte DatePart) { int DTmin[6] = {2000, 1, 1, 0, 0, 0}; int DTmax[6] = {2199, 12, 31, 23, 59, 59}; int DT[6]; int diff; DT[0] = OldDate.year(); DT[1] = OldDate.month(); DT[2] = OldDate.day(); DT[3] = OldDate.hour(); DT[4] = OldDate.minute(); DT[5] = OldDate.second(); DT[DatePart] = DT[DatePart] + Increment; if (DT[1] == 1 || DT[1] == 3 || DT[1] == 5 || DT[1] == 7 || DT[1] == 8 || DT[1] == 10 || DT[1] == 12) DTmax[2] = 31; else if (DT[1] == 2) { if ((DT[0] % 4 == 0 && DT[0] % 100 != 0) || (DT[0] % 400 == 0)) DTmax[2] = 29; else DTmax[2] = 28; } else DTmax[2] = 30; for (byte i = 0; i < 6; i++) { if (DT[i] > DTmax[i]) DT[i] = DTmin[i]; else if (DT[i] < DTmin[i]) DT[i] = DTmax[i]; } return DateTime(DT[0], DT[1], DT[2], DT[3], DT[4], DT[5]); } void TSelectMenu::Print(void) { NowDate = RTC.now(); byte shift = 0; if (CurrentItem > 3) shift = CurrentItem - 3; for (byte i = 0; i < 4; i++) { if ((CurrentItem - shift) == i) //Blinker { LcdPrint(i, ">> " + * (Items[i + shift]->MenuName) + " <<", CENTER); } else LcdPrint(i, *(Items[i + shift]->MenuName), CENTER); } RelayCheck(); } void TRelayMenu::Print(void) { String DData; NowDate = RTC.now(); LcdPrint(0, (*MenuName) + "[" + BlinkString(RelayModeNames[RelayMode], CurrentItem, 0) + "]", CENTER); DData = "On:"; switch (RelayMode) { case 3: //Daily // DData = DData + " "; if (CurrentItem > 0 && CurrentItem < 4) CurrentItem = 4; break; default: DData = DData + BlinkString(String(RelayOn.year(), DEC), CurrentItem, 1) + "/" + BlinkString(String( RelayOn.month(), DEC), CurrentItem, 2) + "/" + BlinkString(String( RelayOn.day(), DEC), CurrentItem, 3); } DData = DData + " " + BlinkString(String (RelayOn.hour(), DEC), CurrentItem, 4) + ":" + BlinkString(String(RelayOn.minute(), DEC), CurrentItem, 5); LcdPrint(1, DData, CENTER); DData = "Off:"; switch (RelayMode) { case 3: //Daily // DData = DData + " "; if (CurrentItem > 5 && CurrentItem < 9) CurrentItem = 9; break; default: DData = DData + BlinkString(String(RelayOff.year(), DEC), CurrentItem, 6) + "/" + BlinkString(String( RelayOff.month(), DEC), CurrentItem, 7) + "/" + BlinkString(String( RelayOff.day(), DEC), CurrentItem, 8); } DData = DData + " " + BlinkString(String (RelayOff.hour(), DEC), CurrentItem, 9) + ":" + BlinkString(String(RelayOff.minute(), DEC), CurrentItem, 10); LcdPrint(2, DData, CENTER); LcdPrint(3, " ", CENTER); } boolean TRelayMenu::CheckDaily(void) { int TimeOn = 60 * int(RelayOn.hour()) + int(RelayOn.minute()); int TimeOff = 60 * int(RelayOff.hour()) + int(RelayOff.minute()); int NowTime = 60 * int(NowDate.hour()) + int(NowDate.minute()); boolean result; // true = время включения больше времени выключения if ( TimeOn > TimeOff ) { if (NowTime <= TimeOff || NowTime >= TimeOn ) result = true; else result = false; } else { if (NowTime <= TimeOff && NowTime >= TimeOn ) result = true; else result = false; }; return result; } void RelayCheck (void) { boolean OnceBitCheck; for (byte i = 0; i < 4; i++) { switch (RelayMenu[i]->RelayMode) { case 1: //relay 0n digitalWrite(i + 10, LOW); break; case 2: //Once; OnceBitCheck = (NowDate.unixtime() > RelayMenu[i]->RelayOn.unixtime() && NowDate.unixtime() < RelayMenu[i]->RelayOff.unixtime()); if (OnceBitCheck) RelayMenu[i]->OnceBit = true; else if (RelayMenu[i]->OnceBit) { RelayMenu[i]->RelayMode = 0; byte p_address = RelayMenu[i]->RelayNumber * 16; EEPROM.write(p_address, RelayMenu[i]->RelayMode); } digitalWrite(i + 10, !OnceBitCheck); break; case 3: //Daily digitalWrite(i + 10, !(RelayMenu[i]->CheckDaily())); break; default: //relay 0ff digitalWrite(i + 10, HIGH); } } }"
1. 589-619 (RelayCheck) перенесите в 398 строку перед TNoMenu::Print
2. 436 - else без конструкции if.
3. 445 - ???? что за странный if?
1. 589-619 (RelayCheck) перенесите в 398 строку перед TNoMenu::Print
2. 436 - else без конструкции if.
3. 445 - ???? что за странный if?
Теперь вот такая ошибка. "C:\Users\Dmitriy\AppData\Local\Temp\arduino_modified_sketch_427514\sketch_apr10c.ino: In member function 'void TMenu::OnKey(byte)':
"
ну... смотрим внимательно TMenu::onKey около 468 строки. Мне чёй-то, не очень видно :(
ну... смотрим внимательно TMenu::onKey около 468 строки. Мне чёй-то, не очень видно :(
#include <EEPROM.h> #include <DHT.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <RTClib.h> #define LEFT 0 #define CENTER 1 #define RIGHT 2 #define RelayModesCount 4 #define KeyFirst 2 #define KeyLast 6 LiquidCrystal_I2C lcd (0x3F, 20, 4); RTC_DS1307 RTC; // RTC Modul DHT dht(7, DHT21); // pin, type volatile boolean Blinker = true; volatile long BlinkerTime; volatile byte ButtonPress[8]; const String RelayModeNames[] = {"OFF", "ON", "Once", "Daily"}; int aKey1 = 0; int aKey2 = 0; DateTime NowDate; boolean DoBlink(void) { boolean Result = false; long NBlinkerTime = millis(); if (Blinker) { if (NBlinkerTime - BlinkerTime > 200) { digitalWrite(8, HIGH); BlinkerTime = NBlinkerTime; Blinker = false; Result = true; } } else { if (NBlinkerTime - BlinkerTime > 300 ) { digitalWrite(8, LOW); BlinkerTime = NBlinkerTime; Blinker = true; } } return Result; } String BlinkString(String string, byte Cur, byte ItemsCount) { String result = string; byte len = string.length(); if (!Blinker && Cur == ItemsCount) { for (byte i = 0; i < len; i++) result.setCharAt(i, ' '); } return result; } /********************************************************************************************************/ /********************************** Объявление классов *********************************************/ /********************************************************************************************************/ class TMenu { public: byte _ItemsCount; TMenu *Parent; String *MenuName; boolean ItemIsValue; byte CurrentItem; TMenu **Items; String *ItemsName; // byte ItemsCount(void); byte ItemsCount(void) { return _ItemsCount; }; bool AddItem(TMenu *NewItem); virtual void Print(void); void OnKey(byte KeyNum); void ChangeItem(byte value); virtual void Increment(void); virtual void Decrement(void); virtual void OnSet(void); DateTime CheckDateTime(DateTime OldDate, int Increment, byte DatePart); }; class TNoMenu: public TMenu { public: void Print(void); TNoMenu(TMenu *ParentMenu) { MenuName = 0; CurrentItem = 0; _ItemsCount = 0; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = false; }; void Increment(void) {}; void Decrement(void) {}; void OnSet(void) {}; }; class TSelectMenu: public TMenu { public: void Print(void); TSelectMenu(TMenu *ParentMenu, String NewName) { MenuName = new String(NewName); CurrentItem = 0; _ItemsCount = 0; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = false; }; void Increment(void) {}; void Decrement(void) {}; void OnSet(void) {}; }; class TTimeMenu: public TMenu { public: void Print(void); DateTime *SetDateTime; long OldDateTime; TTimeMenu(TMenu *ParentMenu, String NewName, DateTime *ParamDate) { MenuName = new String(NewName); CurrentItem = 0; _ItemsCount = 6; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = true; OldDateTime = millis(); SetDateTime = ParamDate; }; void Increment(void) { *SetDateTime = CheckDateTime (*SetDateTime, 1, CurrentItem); }; void Decrement(void) { *SetDateTime = CheckDateTime (*SetDateTime, -1, CurrentItem); }; void OnSet(void) { RTC.adjust(*SetDateTime); }; void SecondTimer(void) { long TmpDateTime = millis(); if (TmpDateTime - OldDateTime > 1000) { OldDateTime = TmpDateTime; *SetDateTime = *SetDateTime + 1; }; }; }; class TRelayMenu: public TMenu { public: byte RelayNumber; byte RelayMode; // byte Shedule=0; boolean OnceBit; DateTime RelayOn; DateTime RelayOff; TRelayMenu(TMenu *ParentMenu, byte NewNumber, String NewName) { MenuName = new String(NewName); CurrentItem = 0; _ItemsCount = 11; Parent = ParentMenu; Items = 0; ItemsName = 0; ItemIsValue = true, OnceBit = false; RelayNumber = NewNumber; RelayMode = 0; RelayOn = DateTime(2015, 1, 1, 23, 00, 00); RelayOff = DateTime(2015, 1, 1, 07, 00, 00); }; void Print(void); void Increment(void) { if (!CurrentItem) { RelayMode++; if ( RelayMode >= RelayModesCount) RelayMode = 0; } else if (CurrentItem < 6) RelayOn = CheckDateTime (RelayOn, 1, CurrentItem - 1); else RelayOff = CheckDateTime (RelayOff, 1, CurrentItem - 6); }; void Decrement(void) { if (!CurrentItem) { RelayMode--; if ( RelayMode > 127) RelayMode = RelayModesCount - 1; } else if (CurrentItem < 6) RelayOn = CheckDateTime (RelayOn, -1, CurrentItem - 1); else RelayOff = CheckDateTime (RelayOff, -1, CurrentItem - 6); }; boolean CheckDaily(void); void OnSet(void) { ///// здесь надо записать реле в память byte p_address = RelayNumber * 16; EEPROM.write(p_address, RelayMode); EEPROM.write(p_address + 1, byte(RelayOn.year() - 2000)); EEPROM.write(p_address + 2, byte(RelayOn.month() )); EEPROM.write(p_address + 3, byte(RelayOn.day() )); EEPROM.write(p_address + 4, byte(RelayOn.hour() )); EEPROM.write(p_address + 5, byte(RelayOn.minute() )); EEPROM.write(p_address + 6, byte(RelayOff.year() - 2000)); EEPROM.write(p_address + 7, byte(RelayOff.month() )); EEPROM.write(p_address + 8, byte(RelayOff.day() )); EEPROM.write(p_address + 9, byte(RelayOff.hour() )); EEPROM.write(p_address + 10, byte(RelayOff.minute() )); }; }; /********************************************************************************************************/ /******************************** Конец объявления классов ******************************************/ /********************************************************************************************************/ TMenu *CurrentMenu = 0; TNoMenu *NoMenu = 0; TSelectMenu *SelectMenu; TTimeMenu *TimeMenu; TRelayMenu *RelayMenu[4]; /********************************************************************************************************************************************/ /********************************************************************************************************************************************/ /********************************************************************************************************************************************/ void setup() { NoMenu = new TNoMenu(0); SelectMenu = new TSelectMenu (NoMenu, "NoMenu"); TimeMenu = new TTimeMenu(SelectMenu, "Time Setup", &NowDate); SelectMenu->AddItem(TimeMenu); byte p_address; DateTime DTFlesh; for (int i = 0; i < 4; i++) { // здесь надо добавить загрузку параметров из флеша RelayMenu[i] = new TRelayMenu (SelectMenu, i, "Relay " + String(i + 1)); SelectMenu->AddItem(RelayMenu[i]); p_address = i * 16; RelayMenu[i]->RelayMode = EEPROM.read(p_address); DTFlesh = DateTime(int(EEPROM.read(p_address + 1) + 2000), EEPROM.read(p_address + 2), EEPROM.read(p_address + 3), EEPROM.read(p_address + 4), EEPROM.read(p_address + 5), 0 ); RelayMenu[i]->RelayOn = RelayMenu[i]->CheckDateTime(DTFlesh, 0, 0); DTFlesh = DateTime(int(EEPROM.read(p_address + 6) + 2000), EEPROM.read(p_address + 7), EEPROM.read(p_address + 8), EEPROM.read(p_address + 9), EEPROM.read(p_address + 10), 0 ); RelayMenu[i]->RelayOff = RelayMenu[i]->CheckDateTime(DTFlesh, 0, 0); } for (byte i = KeyFirst; i < KeyLast; i++) { pinMode(i, INPUT); //Keypad 2-«menu» 3-"-" 4-"+" 5-«SET» digitalWrite(i, HIGH); //setup Resistor input2Vcc ButtonPress[i] = true; } pinMode(8, OUTPUT); //LED pinMode(9, OUTPUT); for (byte i = 10; i < 14; i++) { pinMode(i, OUTPUT); // relay i digitalWrite(i, HIGH); } pinMode (A2, INPUT_PULLUP); pinMode (A3, INPUT_PULLUP); Serial.begin(9600); // Used to type in characters digitalWrite(8, LOW); digitalWrite(9, HIGH); lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines and turn on backlight RTC.begin(); lcd.noBacklight(); delay(150); lcd.backlight(); NowDate = RTC.now(); //проверка времени if ( NowDate.year() > 2000 && NowDate.year() < 2114 && NowDate.month() > 0 && NowDate.month() < 13 && NowDate.day() > 0 && NowDate.day() < 32 && NowDate.hour() >= 0 && NowDate.hour() < 24 && NowDate.minute() >= 0 && NowDate.minute() < 60 && NowDate.second() >= 0 && NowDate.second() < 60 ) { CurrentMenu = NoMenu; } else { lcd.setCursor(2, 1); lcd.print("Clock Failure!"); delay(700); RTC.adjust(DateTime(2015, 1, 1, 00, 00, 00)); CurrentMenu = TimeMenu; } } void loop() { /********* KEYPAD BUNCLE, 5 keys, from 2 to 6 *********/ byte NButtonPress[8] = {0, 0, 0, 0, 0, 0, 0, 0}; byte NButtonRelease[8] = {0, 0, 0, 0, 0, 0, 0, 0}; const byte ButtonTry = 3; aKey1 = analogRead (2); aKey2 = analogRead (3); byte aKeyNum = 0; /**************** check for key pressed or released ****************/ for (byte i = 0; i < 3; i++) { delay(15); if (aKey1 < 64) aKeyNum = 2; //AnalogKey 1 = Dig2 else if (aKey1 < 128) aKeyNum = 6; //Analog key 3 = D4 else if (aKey1 < 256) aKeyNum = 4; //key 5=d6 else if (aKey2 < 64) aKeyNum = 1; //key 6 = menu else if (aKey2 < 128) aKeyNum = 3; //analogkey 2 = D3 else if (aKey2 < 256) aKeyNum = 5; //key 4 =d5 else aKeyNum = 0; // no key for (byte j = KeyFirst; j < KeyLast; j++) // Read ports 2...6 { if (digitalRead(j) == LOW || aKeyNum == j) { NButtonPress[j]++; NButtonRelease[j] = 0; } else { NButtonPress [ j ] = 0; NButtonRelease[j]++; delay(5); } } /*************** Do key process ******************/ // byte m; for (byte j = KeyFirst; j < KeyLast; j++) { if (NButtonPress[j] >= ButtonTry && ButtonPress[j] == false) { ButtonPress[j] = true; CurrentMenu->OnKey(j); } else { if (NButtonRelease[j] >= ButtonTry && ButtonPress[j] == true) { ButtonPress[j] = false; } } } /***************** Relay Check *********************/ CurrentMenu->Print(); DoBlink(); } } void LcdPrint(byte string, String str, byte Align) { byte StrTrim1; byte StrTrim2; lcd.setCursor(0, string); //Start at character 0 on line 0 switch (Align) { case RIGHT: break; case CENTER: StrTrim1 = byte((20 - str.length()) / 2); StrTrim2 = 20 - str.length() - StrTrim1; for (byte k = 0; k < StrTrim1; k++) lcd.print(" "); lcd.print(str); for (byte k = 0; k < StrTrim2; k++) lcd.print(" "); break; default: lcd.print(str); StrTrim1 = 20 - str.length(); for (byte k = 0; k < StrTrim1; k++) lcd.print(" "); } } void RelayCheck (void) { boolean OnceBitCheck; for (byte i = 0; i < 4; i++) { switch (RelayMenu[i]->RelayMode) { case 1: //relay 0n digitalWrite(i + 10, LOW); break; case 2: //Once; OnceBitCheck = (NowDate.unixtime() > RelayMenu[i]->RelayOn.unixtime() && NowDate.unixtime() < RelayMenu[i]->RelayOff.unixtime()); if (OnceBitCheck) RelayMenu[i]->OnceBit = true; else if (RelayMenu[i]->OnceBit) { RelayMenu[i]->RelayMode = 0; byte p_address = RelayMenu[i]->RelayNumber * 16; EEPROM.write(p_address, RelayMenu[i]->RelayMode); } digitalWrite(i + 10, !OnceBitCheck); break; case 3: //Daily digitalWrite(i + 10, !(RelayMenu[i]->CheckDaily())); break; default: //relay 0ff digitalWrite(i + 10, HIGH); } } } void TNoMenu::Print(void) { NowDate = RTC.now(); String Ddate; Ddate = " R1-" + RelayModeNames[RelayMenu[0]->RelayMode] + " R2-" + RelayModeNames[RelayMenu[1]->RelayMode]; LcdPrint(0, Ddate, CENTER); Ddate = " R3-" + RelayModeNames[RelayMenu[2]->RelayMode] + " R4-" + RelayModeNames[RelayMenu[3]->RelayMode]; LcdPrint(1, Ddate, CENTER); Ddate = String (NowDate.year()) + "/" + String(NowDate.month()) + "/" + String(NowDate.day()) + " " + String (NowDate.hour()) + ":" + String(NowDate.minute()) + ":" + String(NowDate.second()); LcdPrint(2, Ddate, CENTER); Ddate = "Temp " + String (int(dht.readTemperature())) + "C, Hum " + String(int(dht.readHumidity())) + "%"; LcdPrint(3, Ddate, CENTER); RelayCheck(); } void TTimeMenu::Print(void) { SecondTimer(); String Ddate = BlinkString(String((*SetDateTime).year()), CurrentItem, 0) + "/" + BlinkString(String( (*SetDateTime).month()), CurrentItem, 1) + "/" + BlinkString(String((*SetDateTime).day()), CurrentItem, 2) + " "; LcdPrint(1, Ddate, CENTER); Ddate = BlinkString(String ((*SetDateTime).hour()), CurrentItem, 3) + ":" + BlinkString(String((*SetDateTime).minute()), CurrentItem, 4) + ":" + BlinkString(String((*SetDateTime).second()), CurrentItem, 5); LcdPrint(2, Ddate, CENTER); LcdPrint(3, " ", CENTER); RelayCheck(); } void TMenu::OnKey(byte KeyNum) { switch (KeyNum) { case 3: // — if (ItemIsValue) Decrement(); else ChangeItem(-1); break; case 4: // + if (ItemIsValue) Increment(); else ChangeItem(1); break; case 5: // SET if (ItemIsValue) { if OnSet(); else ChangeItem(+1); } else // вход в подменю { if (Items && ItemsCount()) { if (CurrentMenu->ItemsCount()) { CurrentMenu = CurrentMenu->Items[CurrentMenu->CurrentItem]; CurrentMenu->CurrentItem = 0; } } } break; default: // 2 -menu if (Parent) CurrentMenu = CurrentMenu->Parent; //(TMenu *) &NoMenu; else { CurrentMenu = SelectMenu; CurrentMenu->CurrentItem = 0; } } } void TMenu::ChangeItem(byte value) { CurrentItem += value; if (CurrentItem > 128) CurrentItem = ItemsCount() - 1; else if (CurrentItem > ItemsCount() - 1) CurrentItem = 0; } boolean TMenu::AddItem(TMenu * NewItem) { if (!Items) Items = new TMenu *[_ItemsCount = 1]; else Items = (TMenu **)realloc((void *)Items, (_ItemsCount = _ItemsCount + 1) * sizeof(void *)); Items[_ItemsCount - 1] = NewItem; } DateTime TMenu::CheckDateTime(DateTime OldDate, int Increment, byte DatePart) { int DTmin[6] = {2000, 1, 1, 0, 0, 0}; int DTmax[6] = {2199, 12, 31, 23, 59, 59}; int DT[6]; int diff; DT[0] = OldDate.year(); DT[1] = OldDate.month(); DT[2] = OldDate.day(); DT[3] = OldDate.hour(); DT[4] = OldDate.minute(); DT[5] = OldDate.second(); DT[DatePart] = DT[DatePart] + Increment; if (DT[1] == 1 || DT[1] == 3 || DT[1] == 5 || DT[1] == 7 || DT[1] == 8 || DT[1] == 10 || DT[1] == 12) DTmax[2] = 31; else if (DT[1] == 2) { if ((DT[0] % 4 == 0 && DT[0] % 100 != 0) || (DT[0] % 400 == 0)) DTmax[2] = 29; else DTmax[2] = 28; } else DTmax[2] = 30; for (byte i = 0; i < 6; i++) { if (DT[i] > DTmax[i]) DT[i] = DTmin[i]; else if (DT[i] < DTmin[i]) DT[i] = DTmax[i]; } return DateTime(DT[0], DT[1], DT[2], DT[3], DT[4], DT[5]); } void TSelectMenu::Print(void) { NowDate = RTC.now(); byte shift = 0; if (CurrentItem > 3) shift = CurrentItem - 3; for (byte i = 0; i < 4; i++) { if ((CurrentItem - shift) == i) //Blinker { LcdPrint(i, ">> " + * (Items[i + shift]->MenuName) + " <<", CENTER); } else LcdPrint(i, *(Items[i + shift]->MenuName), CENTER); } RelayCheck(); } void TRelayMenu::Print(void) { String DData; NowDate = RTC.now(); LcdPrint(0, (*MenuName) + "[" + BlinkString(RelayModeNames[RelayMode], CurrentItem, 0) + "]", CENTER); DData = "On:"; switch (RelayMode) { case 3: //Daily // DData = DData + " "; if (CurrentItem > 0 && CurrentItem < 4) CurrentItem = 4; break; default: DData = DData + BlinkString(String(RelayOn.year(), DEC), CurrentItem, 1) + "/" + BlinkString(String( RelayOn.month(), DEC), CurrentItem, 2) + "/" + BlinkString(String( RelayOn.day(), DEC), CurrentItem, 3); } DData = DData + " " + BlinkString(String (RelayOn.hour(), DEC), CurrentItem, 4) + ":" + BlinkString(String(RelayOn.minute(), DEC), CurrentItem, 5); LcdPrint(1, DData, CENTER); DData = "Off:"; switch (RelayMode) { case 3: //Daily // DData = DData + " "; if (CurrentItem > 5 && CurrentItem < 9) CurrentItem = 9; break; default: DData = DData + BlinkString(String(RelayOff.year(), DEC), CurrentItem, 6) + "/" + BlinkString(String( RelayOff.month(), DEC), CurrentItem, 7) + "/" + BlinkString(String( RelayOff.day(), DEC), CurrentItem, 8); } DData = DData + " " + BlinkString(String (RelayOff.hour(), DEC), CurrentItem, 9) + ":" + BlinkString(String(RelayOff.minute(), DEC), CurrentItem, 10); LcdPrint(2, DData, CENTER); LcdPrint(3, " ", CENTER); } boolean TRelayMenu::CheckDaily(void) { int TimeOn = 60 * int(RelayOn.hour()) + int(RelayOn.minute()); int TimeOff = 60 * int(RelayOff.hour()) + int(RelayOff.minute()); int NowTime = 60 * int(NowDate.hour()) + int(NowDate.minute()); boolean result; // true = время включения больше времени выключения if ( TimeOn > TimeOff ) { if (NowTime <= TimeOff || NowTime >= TimeOn ) result = true; else result = false; } else { if (NowTime <= TimeOff && NowTime >= TimeOn ) result = true; else result = false; }; return result; }ну блииииин. ну там же else без if!!!!!!!
У Вас "if" закоментирован . см: case 3:
это сознательно?
ну блииииин. ну там же else без if!!!!!!!
У Вас "if" закоментирован . см: case 3:
это сознательно?
УПС. Не заметил.
СПАСИБО.