/*
Copyright Giuseppe Di Cillo (www.coagula.org)
Contact: dicillo@coagula.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
IMPORTANT: to use the menubackend library by Alexander Brevig download it at http://www.arduino.cc/playground/uploads/Profiles/MenuBackend_1-4.zip and add the next code at line 195
void toRoot() {
setCurrent( &getRoot() );
}
*/
#include "DHT.h"
#include <EEPROM.h>
#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig
#include <LiquidCrystal.h> //this library is included in the Arduino IDE
#define DHTPIN 10 // what digital pin we're connected to
// Uncomment whatever type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
unsigned long previousMillis=0;
int intervalDHT = 1000;
const int buttonPinLeft = 6; // pin for the Up button
const int buttonPinRight = 7; // pin for the Down button
const int buttonPinEsc = 8; // pin for the Esc button
const int buttonPinEnter = 9; // pin for the Enter button
const int PinRelay = 13; // pin for the Relay
int lastButtonPushed = 0;
int lastButtonEnterState = LOW; // the previous reading from the Enter input pin
int lastButtonEscState = LOW; // the previous reading from the Esc input pin
int lastButtonLeftState = LOW; // the previous reading from the Left input pin
int lastButtonRightState = LOW; // the previous reading from the Right input pin
long lastEnterDebounceTime = 0; // the last time the output pin was toggled
long lastEscDebounceTime = 0; // the last time the output pin was toggled
long lastLeftDebounceTime = 0; // the last time the output pin was toggled
long lastRightDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 500; // the debounce time
int flag1 = 0;
const int addrMinNote=5; //address in EEPROM to store minimum note
const int addrMaxNote=6; //address in EEPROM to store maximum note
const int addrPlayMode=8; //address in EEPROM to store the play mode
//constants to identify different status
const int statusPlayMode1=1;
const int statusRun=2;
//constants to identify different status
const int statusSetMinNote=7;
const int statusSetMaxNote=8;
char strSetMinimumNote[17] = "Set minimum ";
char strSetMaximumNote[17] = "Set maximum ";
int currentStatusMode;
int lastPlayingMode;
int minNoteSetting;
int maxNoteSetting;
int minNote=0;
int maxNote=100;
// LiquidCrystal display with:
// rs on pin 7
// rw on ground
// enable on pin 6
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
MenuItem menu1Item1 = MenuItem("Item1");
MenuItem menuItem1SubItem1 = MenuItem("Item1SubItem1");
MenuItem menuItem1SubItem2 = MenuItem("Item1SubItem2");
MenuItem menu1Item2 = MenuItem("Item2");
MenuItem menuItemMinNote = MenuItem("menuItemMinNote");
MenuItem menuItemMaxNote = MenuItem("menuItemMaxNote");
MenuItem menuItem3SubItem3 = MenuItem("Item2SubItem3");
MenuItem menu1Item3 = MenuItem("Item3");
void setup()
{
pinMode(PinRelay,OUTPUT);
digitalWrite(PinRelay, HIGH);
pinMode(buttonPinLeft, INPUT);
pinMode(buttonPinRight, INPUT);
pinMode(buttonPinEnter, INPUT);
pinMode(buttonPinEsc, INPUT);
dht.begin();
lcd.begin(16, 2);
minNoteSetting=EEPROM.read(addrMinNote);
if (minNoteSetting==255){
currentStatusMode=statusPlayMode1;//default
EEPROM.write(addrMinNote, minNote);
EEPROM.write(addrMaxNote, maxNote);
EEPROM.write(addrPlayMode, currentStatusMode);
}else{
minNote=EEPROM.read(addrMinNote); //read fromm EEPROM the stored minimum note
maxNote=EEPROM.read(addrMaxNote); //read fromm EEPROM the stored maximum note
currentStatusMode=EEPROM.read(addrPlayMode); //read fromm EEPROM the stored play mode
}
//configure menu
menu.getRoot().add(menu1Item1);
menu1Item1.addRight(menu1Item2).addRight(menu1Item3);
menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
menu1Item2.add(menuItemMinNote).addRight(menuItemMaxNote).addRight(menuItem3SubItem3);
//menu.toRoot();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("LOADING..");
lcd.noDisplay();
delay(500);
lcd.display();
delay(500);
lcd.noDisplay();
delay(500);
lcd.display();
delay(500);
lcd.noDisplay();
delay(500);
lcd.display();
delay(500);
currentStatusMode = statusRun;
} // setup()...
void loop()
{
unsigned long currentMillis = millis();
// Read temperature as Fahrenheit (isFahrenheit = true)
readButtons(); //I splitted button reading and navigation in two procedures because
char strSetting[21] = "CC ";
char sett[4];
switch(currentStatusMode){
case statusPlayMode1: //playing mode 1
navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings)
break;
case statusRun: //playing mode 1
// time to toggle LED on Pin 12?
if ((unsigned long)(currentMillis - previousMillis) >= intervalDHT) {
float h1;
h1 =dht.readHumidity();
// Read temperature as Celsius (the default)
float t1;
t1 = dht.readTemperature();
// save current time to pin 12's previousMillis
if(t1<=minNote){
digitalWrite(PinRelay, HIGH);
}
if(t1>=maxNote){
digitalWrite(PinRelay, LOW);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Hum: ");
lcd.setCursor(8,0);
lcd.print(h1);
lcd.setCursor(0,1);
lcd.print("Temp: ");
lcd.setCursor(8,1);
lcd.print(t1);
previousMillis = currentMillis;
}
// Wait a few seconds between measurements.
// delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
if(lastButtonPushed==buttonPinEsc){
currentStatusMode = statusPlayMode1;
menu.toRoot();
}
break;
case statusSetMinNote: //set min note
switch (lastButtonPushed){
case buttonPinEnter://set the new minimum note and go back to the main screen
minNote=minNoteSetting;
currentStatusMode=lastPlayingMode;
EEPROM.write(addrMinNote, minNote);
menu.toRoot();
break;
case buttonPinEsc://go back to the main screen
minNoteSetting=minNote;
currentStatusMode=lastPlayingMode;
menu.toRoot();
break;
case buttonPinRight://increase minimum note
if(minNoteSetting<100&&minNoteSetting<maxNote){
minNoteSetting=minNoteSetting+1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(strSetMinimumNote);
lcd.setCursor(0,1);
lcd.print(minNoteSetting);
}
break;
case buttonPinLeft://decrease minimum note
if(minNoteSetting>0){
minNoteSetting=minNoteSetting-1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(strSetMinimumNote);
lcd.setCursor(0,1);
lcd.print(minNoteSetting);
}
break;
}
break;
case statusSetMaxNote: //set max note
switch (lastButtonPushed){
case buttonPinEnter://set the new maximum note and go back to the main screen
maxNote=maxNoteSetting;
currentStatusMode=lastPlayingMode;
EEPROM.write(addrMaxNote, maxNote);
menu.toRoot();
break;
case buttonPinEsc://go back to the main screen
maxNoteSetting=maxNote;
currentStatusMode=lastPlayingMode;
menu.toRoot();
break;
case buttonPinRight://increase maximum note
if(maxNoteSetting<100){
maxNoteSetting=maxNoteSetting+1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(strSetMaximumNote);
lcd.setCursor(0,1);
lcd.print(maxNoteSetting);
}
break;
case buttonPinLeft://decrease maximum note
if(maxNoteSetting>0&&maxNoteSetting>minNote){
maxNoteSetting=maxNoteSetting-1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(strSetMaximumNote);
lcd.setCursor(0,1);
lcd.print(maxNoteSetting);
}
break;
}
break;
}
} //loop()...
void menuChanged(MenuChangeEvent changed){
MenuItem newMenuItem=changed.to; //get the destination menu
lcd.clear();
lcd.setCursor(0,0);
// lcd.setCursor(0,1); //set the start position for lcd printing to the second row
if(newMenuItem.getName()==menu.getRoot()){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Main Menu ");
}else if(newMenuItem.getName()=="Item1"){
lcd.print("Item1 <");
lcd.setCursor(0,1);
lcd.print("Item2 ");
}else if(newMenuItem.getName()=="Item1SubItem1"){
lcd.print("Item1SubItem1 <");
lcd.setCursor(0,1);
lcd.print("Item1SubItem2 ");
}else if(newMenuItem.getName()=="Item1SubItem2"){
lcd.print("Item1SubItem1 ");
lcd.setCursor(0,1);
lcd.print("Item1SubItem2 <");
}else if(newMenuItem.getName()=="Item2"){
lcd.print("Item2 <");
lcd.setCursor(0,1);
lcd.print("Run.. ");
}else if(newMenuItem.getName()=="menuItemMinNote"){
lcd.print("Set minimum <");
lcd.setCursor(0,1);
lcd.print(strSetMaximumNote);
}else if(newMenuItem.getName()=="menuItemMaxNote"){
lcd.print(strSetMinimumNote);
lcd.setCursor(0,1);
lcd.print("Set maximum <");
}else if(newMenuItem.getName()=="Item2SubItem3"){
lcd.print("Item2SubItem3 <");
}else if(newMenuItem.getName()=="Item3"){
lcd.print("Run.. <");
}
}
void menuUsed(MenuUseEvent used){
if( used.item == menu1Item1 ){
currentStatusMode = statusPlayMode1;
EEPROM.write(addrPlayMode, statusPlayMode1);
menu.toRoot();
}else if( used.item == menuItemMinNote ){
minNoteSetting=minNote;
lastPlayingMode=currentStatusMode;
currentStatusMode = statusSetMinNote;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(strSetMinimumNote);
lcd.setCursor(0,1);
lcd.print(minNote);
}else if( used.item == menuItemMaxNote ){
maxNoteSetting=maxNote;
lastPlayingMode=currentStatusMode;
currentStatusMode = statusSetMaxNote;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(strSetMaximumNote);
lcd.setCursor(0,1);
lcd.print(maxNote);
}
else if( used.item == menu1Item3 ){
currentStatusMode = statusRun;
// menu.toRoot();
}
}
void readButtons(){ //read buttons status
int reading;
int buttonEnterState=LOW; // the current reading from the Enter input pin
int buttonEscState=LOW; // the current reading from the input pin
int buttonLeftState=LOW; // the current reading from the input pin
int buttonRightState=LOW; // the current reading from the input pin
//Enter button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEnter);
// check to see if you just pressed the enter button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonEnterState) {
// reset the debouncing timer
lastEnterDebounceTime = millis();
}
if ((millis() - lastEnterDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEnterState=reading;
lastEnterDebounceTime=millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEnterState = reading;
//Esc button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinEsc);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonEscState) {
// reset the debouncing timer
lastEscDebounceTime = millis();
}
if ((millis() - lastEscDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonEscState = reading;
lastEscDebounceTime=millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonEscState = reading;
//Down button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinRight);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonRightState) {
// reset the debouncing timer
lastRightDebounceTime = millis();
}
if ((millis() - lastRightDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonRightState = reading;
lastRightDebounceTime =millis();
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonRightState = reading;
//Up button
// read the state of the switch into a local variable:
reading = digitalRead(buttonPinLeft);
// check to see if you just pressed the Down button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonLeftState) {
// reset the debouncing timer
lastLeftDebounceTime = millis();
}
if ((millis() - lastLeftDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonLeftState = reading;
lastLeftDebounceTime=millis();;
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonLeftState = reading;
//records which button has been pressed
if (buttonEnterState==HIGH){
lastButtonPushed=buttonPinEnter;
}else if(buttonEscState==HIGH){
lastButtonPushed=buttonPinEsc;
}else if(buttonRightState==HIGH){
lastButtonPushed=buttonPinRight;
}else if(buttonLeftState==HIGH){
lastButtonPushed=buttonPinLeft;
}else{
lastButtonPushed=0;
}
}
void navigateMenus() {
MenuItem currentMenu=menu.getCurrent();
switch (lastButtonPushed){
case buttonPinEnter:
if(!(currentMenu.moveDown())){ //if the current menu has a child and has been pressed enter then menu navigate to item below
menu.use();
}else{ //otherwise, if menu has no child and has been pressed enter the current menu is used
menu.moveDown();
}
break;
case buttonPinEsc:
menu.toRoot(); //back to main
break;
case buttonPinRight:
menu.moveRight();
break;
case buttonPinLeft:
menu.moveLeft();
break;
}
lastButtonPushed=0; //reset the lastButtonPushed variable
}
ไม่มีความคิดเห็น:
แสดงความคิดเห็น