Skip to content

Instantly share code, notes, and snippets.

@brooksware2000
Created September 6, 2012 00:27
Show Gist options
  • Save brooksware2000/3648650 to your computer and use it in GitHub Desktop.
Save brooksware2000/3648650 to your computer and use it in GitHub Desktop.
Example menu and relay control sketch for the Wireless Thermostat/Temperature board
/*
Demonstration sketch for the Hobbybotics Wireless Thermostat/Temperature Node.
Creates a LCD menu system and allows ON/OFF control for the relays on the System
Output Controller board.
Sections of code that is not needed for this demonstration is commented out
*/
#include <MCP23008.h> // MCP23008 I/O Expander (I2C)
#include <LCD.h> // I2C LCD
#include <Wire.h> // I2C functions
/*-----------------------------------------------------------------------------------------------
* Menu data type
* ----------------------------------------------------------------------------------------------*/
struct{
int row;
int col;
int index;
int menutype;
} menu;
/*-----------------------------------------------------------------------------------------------
* Enumerated types
* ----------------------------------------------------------------------------------------------*/
// OFF = 0, ON = 1
enum state{
OFF,
ON
};
/*-----------------------------------------------------------------------------------------------
* Create object references
* ----------------------------------------------------------------------------------------------*/
// Default I2C address for LCD is 0
LCD lcd;
// Setup MCP23008 I/O Expander instance to communicate with the menu buttons--address 1
MCP23008 buttons;
// Setup MCP23008 I/O Expander instance to communicate with the relays--address 2
MCP23008 relays;
/*-----------------------------------------------------------------------------------------------
* Button macros
* ----------------------------------------------------------------------------------------------*/
#define up_button buttons.digitalRead(0)
#define select_button buttons.digitalRead(1)
#define down_button buttons.digitalRead(2)
#define left_button buttons.digitalRead(3)
#define right_button buttons.digitalRead(4)
/*-----------------------------------------------------------------------------------------------
* Function: init_buttons
* Description: Initialize buttons. Buttons are connected to MCP23008 I/O Expander (address 1)
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void init_buttons(){
buttons.begin(1);
for(int x = 0; x <= 7; x++){
buttons.pinMode(x, INPUT);
}
}
/*-----------------------------------------------------------------------------------------------
* Function: init_relays
* Description: Initialize relays. Relays are connected to MCP23008 I/O Expander (address 2)
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void init_relays(){
relays.begin(2);
for(int x = 0; x <= 7; x++){
relays.pinMode(x, OUTPUT);
}
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay
* Description: Set relay(ON/OFF)
* Ins: Integer value for relay (0-7)
* Integer value for state (ON = 1/OFF = 0)
*
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay(int relaynum, int state){
relays.digitalWrite(relaynum, state);
}
/*-----------------------------------------------------------------------------------------------
* Function: set_all_relays
* Description: Set all relays(ON/OFF)
* Ins: Integer value for state (ON = 1/OFF = 0)
*
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_all_relays(int state){
for(int x = 0; x <= 7; x++){
relays.digitalWrite(x, state);
}
}
/*-----------------------------------------------------------------------------------------------
* Function: get_relay_state
* Description: Get relay state(ON = 1/OFF = 0)
* Ins: Integer value for relay (0-7)
* Outs: relay state (1 = ON, 0 = OFF)
* ----------------------------------------------------------------------------------------------*/
int get_relay_state(int relaynum){
return relays.digitalRead(relaynum);
}
/*-----------------------------------------------------------------------------------------------
* Function: check_menu_buttons
* Description: Menu navigation buttons
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void check_menu_buttons(){
while (select_button != 0){
if (up_button == 0){
while (up_button == 0) {}
delay(10);
if (up_button == 1)
scroll_up();
}
if (down_button == 0){
while (down_button == 0) {}
delay(10);
if (down_button == 1)
scroll_down();
}
if (left_button == 0){
while (left_button == 0) {}
delay(10);
if (left_button == 1)
scroll_left();
}
if (right_button == 0){
while (right_button == 0) {}
delay(10);
if (right_button == 1)
scroll_right();
}
}
if (select_button == 0){
while (select_button == 0){}
delay(100);
}
}
/*-----------------------------------------------------------------------------------------------
* Function: scroll_up
* Description: Up direction menu button
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void scroll_up(){
// Dual column menu
if (menu.menutype != 1){
switch(menu.index){
case 1: menu.row = 3; menu.col = 12; menu.index = 6; break;
case 2: menu.row = 3; menu.col = 1; menu.index = 5; break;
case 3: menu.row = 1; menu.col = 1; menu.index = 1; break;
case 4: menu.row = 1; menu.col = 12; menu.index = 2; break;
case 5: menu.row = 2; menu.col = 1; menu.index = 3; break;
case 6: menu.row = 2; menu.col = 12; menu.index = 4; break;
}
}
else{
// Single column menu
switch(menu.index){
case 1: menu.row = 3; menu.col = 1; menu.index = 3; break;
case 2: menu.row = 1; menu.col = 1; menu.index = 1; break;
case 3: menu.row = 2; menu.col = 1; menu.index = 2; break;
}
}
set_cursor(menu.col, menu.row);
}
/*-----------------------------------------------------------------------------------------------
* Function: scroll_down
* Description: Down direction menu button
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void scroll_down(){
// Dual column menu
if (menu.menutype != 1){
switch(menu.index){
case 1: menu.row = 2; menu.col = 1; menu.index = 3; break;
case 2: menu.row = 2; menu.col = 12; menu.index = 4; break;
case 3: menu.row = 3; menu.col = 1; menu.index = 5; break;
case 4: menu.row = 3; menu.col = 12; menu.index = 6; break;
case 5: menu.row = 1; menu.col = 12; menu.index = 2; break;
case 6: menu.row = 1; menu.col = 1; menu.index = 1; break;
}
}
else{
// Single column menu
switch(menu.index){
case 1: menu.row = 2; menu.col = 1; menu.index = 2; break;
case 2: menu.row = 3; menu.col = 1; menu.index = 3; break;
case 3: menu.row = 1; menu.col = 1; menu.index = 1; break;
}
}
set_cursor(menu.col, menu.row);
}
/*-----------------------------------------------------------------------------------------------
* Function: scroll_left
* Description: Previous direction menu button
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void scroll_left(){
// Single column vertical menu
if (menu.menutype == 1){
switch(menu.index){
case 1: menu.row = 3; menu.col = 1; menu.index = 3; break;
case 2: menu.row = 1; menu.col = 1; menu.index = 1; break;
case 3: menu.row = 2; menu.col = 1; menu.index = 2; break;
}
}
// Dual column menu
if (menu.menutype == 2){
switch(menu.index){
case 1: menu.row = 3; menu.col = 12; menu.index = 6; break;
case 2: menu.row = 1; menu.col = 1; menu.index = 1; break;
case 3: menu.row = 1; menu.col = 12; menu.index = 2; break;
case 4: menu.row = 2; menu.col = 1; menu.index = 3; break;
case 5: menu.row = 2; menu.col = 12; menu.index = 4; break;
case 6: menu.row = 3; menu.col = 1; menu.index = 5; break;
}
}
set_cursor(menu.col, menu.row);
}
/*-----------------------------------------------------------------------------------------------
* Function: scroll_right
* Description: Next direction menu button
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void scroll_right(){
// Single column vertical menu
if (menu.menutype == 1){
switch(menu.index){
case 1: menu.row = 2; menu.col = 1; menu.index = 2; break;
case 2: menu.row = 3; menu.col = 1; menu.index = 3; break;
case 3: menu.row = 1; menu.col = 1; menu.index = 1; break;
}
}
// Dual column menu
if (menu.menutype == 2){
switch(menu.index){
case 1: menu.row = 1; menu.col = 12; menu.index = 2; break;
case 2: menu.row = 2; menu.col = 1; menu.index = 3; break;
case 3: menu.row = 2; menu.col = 12; menu.index = 4; break;
case 4: menu.row = 3; menu.col = 1; menu.index = 5; break;
case 5: menu.row = 3; menu.col = 12; menu.index = 6; break;
case 6: menu.row = 1; menu.col = 1; menu.index = 1; break;
}
}
set_cursor(menu.col, menu.row);
}
/*-----------------------------------------------------------------------------------------------
* Function: wait_key
* Description: Just a generic pause routine
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void wait_key(){
while (select_button != 0) {}
delay(300);
}
/*-----------------------------------------------------------------------------------------------
* Function: set_cursor
* Description: Set LCD cursor to column and row
* Ins: Integer value for column and row
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_cursor(int col, int row){
lcd.setCursor(col, row);
}
/*-----------------------------------------------------------------------------------------------
* Function: print_string
* Description: Set LCD cursor to column and row and print string
* Ins: Integer value for column and row. Pointer to string to print
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void print_string(char *str, int col, int row){
lcd.setCursor(col, row);
lcd.print(str);
}
/*-----------------------------------------------------------------------------------------------
* Function: print_custom_char
* Description: Set LCD cursor to column and row and print custom LCD character
* Ins: Integer value for column, row and address.
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void print_custom_char(int address, int col, int row){
lcd.setCursor(col, row);
lcd.write(address);
}
/*-----------------------------------------------------------------------------------------------
* Function: print_int
* Description: Set LCD cursor to column and row and print a Integer
* Ins: Integer value for column, row and number
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void print_int(int num, int col, int row){
lcd.setCursor(col, row);
lcd.print(num);
}
/*-----------------------------------------------------------------------------------------------
* Function: main_menu
* Description: Main LCD menu
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void main_menu(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Relay Test Demo--", 0, 0);
print_string("[ ]Set Relay", 0, 1);
print_string("[ ]Set All Relays", 0, 2);
print_string("[ ]Get Status", 0, 3);
set_cursor(menu.col, menu.row);
lcd.blink();
check_menu_buttons();
switch(menu.index){
case 1: set_relay_menu1(); break;
case 2: set_all_relays_menu(); break;
case 3: get_relay_status(); break;
}
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay_menu1
* Description: Set state of relays 1-4
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay_menu1(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 2;
lcd.clear();
print_string("--Set Relay [Page 1]", 0, 0);
print_string("[ ]Relay1 [ ]Relay2", 0, 1);
print_string("[ ]Relay3 [ ]Relay4", 0, 2);
print_string("[ ]Back [ ]Next", 0, 3);
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay1(); break;
case 2: set_relay2(); break;
case 3: set_relay3(); break;
case 4: set_relay4(); break;
case 5: main_menu(); break;
case 6: set_relay_menu2(); break;
}
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay_menu2
* Description: Set state of relays 5-8
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay_menu2(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 2;
lcd.clear();
print_string("--Set Relay [Page 2]", 0, 0);
print_string("[ ]Relay5 [ ]Relay6", 0, 1);
print_string("[ ]Relay7 [ ]Relay8", 0, 2);
print_string("[ ]Back [ ]Exit", 0, 3);
set_cursor(menu.col, menu.row);
lcd.blink();
check_menu_buttons();
switch(menu.index){
case 1: set_relay5(); break;
case 2: set_relay6(); break;
case 3: set_relay7(); break;
case 4: set_relay8(); break;
case 5: set_relay_menu1(); break;
case 6: main_menu(); break;
}
}
/*-----------------------------------------------------------------------------------------------
* Function: set_all_relays_menu
* Description: Set state of all relays
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_all_relays_menu(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set All Relays", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
lcd.blink();
check_menu_buttons();
switch(menu.index){
case 1: set_all_relays(1); break;
case 2: set_all_relays(0); break;
case 3: main_menu(); break;
}
set_all_relays_menu();
}
/*-----------------------------------------------------------------------------------------------
* Function: get_relay_status
* Description:
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void get_relay_status(){
lcd.clear();
print_string("--Relay Status--", 0, 0);
print_string("R1: R2: R3: R4: ", 0, 1);
print_string("S1: S2: S3: S4: ", 0, 2);
print_string("[ ]Back", 0, 3);
print_int(get_relay_state(0), 3, 1);
print_int(get_relay_state(1), 8, 1);
print_int(get_relay_state(2), 13, 1);
print_int(get_relay_state(3), 18, 1);
print_int(get_relay_state(4), 3, 2);
print_int(get_relay_state(5), 8, 2);
print_int(get_relay_state(6), 13, 2);
print_int(get_relay_state(7), 18, 2);
set_cursor(1, 3);
wait_key();
main_menu();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay1
* Description: Turn on/off relay 1
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay1(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 1--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(0, ON); break;
case 2: set_relay(0, OFF); break;
case 3: set_relay_menu1(); break;
}
set_relay1();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay2
* Description: Turn on/off relay 2
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay2(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 2--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(1, ON); break;
case 2: set_relay(1, OFF); break;
case 3: set_relay_menu1(); break;
}
set_relay2();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay3
* Description: Turn on/off relay 3
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay3(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 3--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(2, ON); break;
case 2: set_relay(2, OFF); break;
case 3: set_relay_menu1(); break;
}
set_relay3();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay4
* Description: Turn on/off relay 4
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay4(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 4--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(3, ON); break;
case 2: set_relay(3, OFF); break;
case 3: set_relay_menu1(); break;
}
set_relay4();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay5
* Description: Turn on/off relay 5
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay5(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 5--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(4, ON); break;
case 2: set_relay(4, OFF); break;
case 3: set_relay_menu2(); break;
}
set_relay5();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay6
* Description: Turn on/off relay 6
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay6(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 6--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(5, ON); break;
case 2: set_relay(5, OFF); break;
case 3: set_relay_menu2(); break;
}
set_relay6();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay7
* Description: Turn on/off relay 7
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay7(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 7--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(6, ON); break;
case 2: set_relay(6, OFF); break;
case 3: set_relay_menu2(); break;
}
set_relay7();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay8
* Description: Turn on/off relay 8
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay8(){
menu.col = 1;
menu.row = 1;
menu.index = 1;
menu.menutype = 1;
lcd.clear();
print_string("--Set Relay 8--", 0, 0);
set_relay_dialog();
set_cursor(menu.col, menu.row);
check_menu_buttons();
switch(menu.index){
case 1: set_relay(7, ON); break;
case 2: set_relay(7, OFF); break;
case 3: set_relay_menu2(); break;
}
set_relay8();
}
/*-----------------------------------------------------------------------------------------------
* Function: set_relay_dialog
* Description:
* Ins: none
* Outs: none
* ----------------------------------------------------------------------------------------------*/
void set_relay_dialog(){
print_string("[ ]ON", 0, 1);
print_string("[ ]OFF", 0, 2);
print_string("[ ]Back", 0, 3);
}
/*-----------------------------------------------------------------------------------------------
* Main Routine
* ----------------------------------------------------------------------------------------------*/
void setup() {
lcd.begin(20, 4);
init_buttons();
init_relays();
}
void loop() {
main_menu();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment