Hi All,
I am currently creating a menu system for my blynk controlled smart home,
I am having a struggle with implementing bridges(not really main concern at this moment.)
my main concern is i cant get my code to write a value to a virtual pin, and then have that virtual pin display said value in on the switch widget in the mobile app:
i am not a coder by any means, i have basically butchered together code to get things working as they should,
i am now hitting a brick wall and can’t seem to figure out how to get it to work.
Hardware:
1 x Arduino uno via usb,
1 x D1Robot LCD Shield
2 x nodemcu clones running DHT11 & relay boards.
code below:
> /* Comment this out to disable prints and save space */
> #define BLYNK_PRINT SwSerial
>
>
> #include <SoftwareSerial.h>
> SoftwareSerial SwSerial(10, 11); // RX, TX
>
> #include <BlynkSimpleStream.h>
>
> // You should get Auth Token in the Blynk App.
> // Go to the Project Settings (nut icon).
> char auth[] = "noneofyabeezwax";
>
>
>
> int vswitch1, vswitch2, vswitch3, vswitch4, vswitch5 , vswitch6, vswitch7, vswitch8;
>
>
> int switch1;
>
>
> // Attach virtual serial terminal to Virtual Pin V1
> WidgetTerminal terminal(V0);
>
> // You can send commands from Terminal to your hardware. Just use
> // the same Virtual Pin as your Terminal Widget
> BLYNK_WRITE(V1)
> {
> int pinValue1 = param.asInt();
> vswitch1 = pinValue1;
>
> }
>
> BLYNK_WRITE(V2) // V5 is the number of Virtual Pin
> {
> int pinValue2 = param.asInt();
> vswitch2 = pinValue2;
> }
> BLYNK_WRITE(V3) // V5 is the number of Virtual Pin
> {
> int pinValue3 = param.asInt();
> vswitch3 = pinValue3;
> }
> BLYNK_WRITE(V4) // V5 is the number of Virtual Pin
> {
> int pinValue4 = param.asInt();
> vswitch4 = pinValue4;
> }
> BLYNK_WRITE(V5) // V5 is the number of Virtual Pin
> {
> int pinValue5 = param.asInt();
> vswitch5 = pinValue5;
> }
> BLYNK_WRITE(V6) // V5 is the number of Virtual Pin
> {
> int pinValue6 = param.asInt();
> vswitch6 = pinValue6;
> }
> BLYNK_WRITE(V7) // V5 is the number of Virtual Pin
> {
> int pinValue7 = param.asInt();
> vswitch7 = pinValue7;
> }
> BLYNK_WRITE(V8) // V5 is the number of Virtual Pin
> {
> int pinValue8 = param.asInt();
> vswitch8 = pinValue8;
> }
>
> ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
>
>
> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
>
>
> /*
> This program is designed to get you as close as possible to a finished menu for the standard Arduino Uno LCD/button shield. The only required modifications
> are to add as menu items to the master menu (menuItems array) and then modify/adjust the void functions below for each of those selections.
> */
>
> // You can have up to 10 menu items in the menuItems[] array below without having to change the base programming at all. Name them however you'd like. Beyond 10 items, you will have to add additional "cases" in the switch/case
> // section of the operateMainMenu() function below. You will also have to add additional void functions (i.e. menuItem11, menuItem12, etc.) to the program.
> String menuItems[] = {"Kitchen", "Stove", "Livingroom", "Bathroom", "Hallway", "Bedroom"};
>
> // Navigation button variables
> int readKey;
> int savedDistance = 0;
>
> // Menu control variables
> int menuPage = 0;
> int maxMenuPages = round(((sizeof(menuItems) / sizeof(String)) / 2) + .5);
> int cursorPosition = 0;
> // Creates 3 custom characters for the menu display
> byte downArrow[8] = {
> 0b00100, // *
> 0b00100, // *
> 0b00100, // *
> 0b00100, // *
> 0b00100, // *
> 0b10101, // * * *
> 0b01110, // ***
> 0b00100 // *
> };
>
> byte upArrow[8] = {
> 0b00100, // *
> 0b01110, // ***
> 0b10101, // * * *
> 0b00100, // *
> 0b00100, // *
> 0b00100, // *
> 0b00100, // *
> 0b00100 // *
> };
>
> byte menuCursor[8] = {
> B01000, // *
> B00100, // *
> B00010, // *
> B00001, // *
> B00010, // *
> B00100, // *
> B01000, // *
> B00000 //
> };
>
> #include <Wire.h>
> #include <LiquidCrystal.h>
>
> // Setting the LCD shields pins
> LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
>
>
> void setup()
> {
> // Debug console
> SwSerial.begin(9600);
>
> // Blynk will work through Serial
> // Do not read or write this serial manually in your sketch
> Serial.begin(9600);
> Blynk.begin(Serial, auth);
>
> // This will print Blynk Software version to the Terminal Widget when
> // your hardware gets connected to Blynk Server
> terminal.println(F("Blynk v" BLYNK_VERSION ": Device started"));
> terminal.println(F("-------------"));
> terminal.println(F("Type 'Marco' and get a reply, or type"));
> terminal.println(F("anything else and get it printed back."));
> terminal.flush();
>
> // Initializes serial communication
>
>
> // Initializes and clears the LCD screen
> lcd.begin(16, 2);
> lcd.clear();
>
> // Creates the byte for the 3 custom characters
> lcd.createChar(0, menuCursor);
> lcd.createChar(1, upArrow);
> lcd.createChar(2, downArrow);
> }
> //void loop goes here
>
> // This function will generate the 2 menu items that can fit on the screen. They will change as you scroll through your menu. Up and down arrows will indicate your current menu position.
> void mainMenuDraw() {
> Serial.print(menuPage);
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print(menuItems[menuPage]);
> lcd.setCursor(1, 1);
> lcd.print(menuItems[menuPage + 1]);
> if (menuPage == 0) {
> lcd.setCursor(15, 1);
> lcd.write(byte(2));
> } else if (menuPage > 0 and menuPage < maxMenuPages) {
> lcd.setCursor(15, 1);
> lcd.write(byte(2));
> lcd.setCursor(15, 0);
> lcd.write(byte(1));
> } else if (menuPage == maxMenuPages) {
> lcd.setCursor(15, 0);
> lcd.write(byte(1));
> }
> }
>
> // When called, this function will erase the current cursor and redraw it based on the cursorPosition and menuPage variables.
> void drawCursor() {
> for (int x = 0; x < 2; x++) { // Erases current cursor
> lcd.setCursor(0, x);
> lcd.print(" ");
> }
>
> // The menu is set up to be progressive (menuPage 0 = Item 1 & Item 2, menuPage 1 = Item 2 & Item 3, menuPage 2 = Item 3 & Item 4), so
> // in order to determine where the cursor should be you need to see if you are at an odd or even menu page and an odd or even cursor position.
> if (menuPage % 2 == 0) {
> if (cursorPosition % 2 == 0) { // If the menu page is even and the cursor position is even that means the cursor should be on line 1
> lcd.setCursor(0, 0);
> lcd.write(byte(0));
> }
> if (cursorPosition % 2 != 0) { // If the menu page is even and the cursor position is odd that means the cursor should be on line 2
> lcd.setCursor(0, 1);
> lcd.write(byte(0));
> }
> }
> if (menuPage % 2 != 0) {
> if (cursorPosition % 2 == 0) { // If the menu page is odd and the cursor position is even that means the cursor should be on line 2
> lcd.setCursor(0, 1);
> lcd.write(byte(0));
> }
> if (cursorPosition % 2 != 0) { // If the menu page is odd and the cursor position is odd that means the cursor should be on line 1
> lcd.setCursor(0, 0);
> lcd.write(byte(0));
> }
> }
> }
>
>
> void operateMainMenu() {
> int activeButton = 0;
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 0: // When button returns as 0 there is no action taken
> break;
> case 1: // This case will execute if the "forward" button is pressed
> button = 0;
> switch (cursorPosition) { // The case that is selected here is dependent on which menu page you are on and where the cursor is.
> case 0:
> menuItem1();
> break;
> case 1:
> menuItem2();
> break;
> case 2:
> menuItem3();
> break;
> case 3:
> menuItem4();
> break;
> case 4:
> menuItem5();
> break;
> case 5:
> menuItem6();
> break;
> case 6:
> menuItem7();
> break;
> case 7:
> menuItem8();
> break;
> case 8:
> menuItem9();
> break;
> case 9:
> menuItem10();
> break;
> }
> activeButton = 1;
> mainMenuDraw();
> drawCursor();
> break;
> case 2:
> button = 0;
> if (menuPage == 0) {
> cursorPosition = cursorPosition - 1;
> cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
> }
> if (menuPage % 2 == 0 and cursorPosition % 2 == 0) {
> menuPage = menuPage - 1;
> menuPage = constrain(menuPage, 0, maxMenuPages);
> }
>
> if (menuPage % 2 != 0 and cursorPosition % 2 != 0) {
> menuPage = menuPage - 1;
> menuPage = constrain(menuPage, 0, maxMenuPages);
> }
>
> cursorPosition = cursorPosition - 1;
> cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
>
> mainMenuDraw();
> drawCursor();
> activeButton = 1;
> break;
> case 3:
> button = 0;
> if (menuPage % 2 == 0 and cursorPosition % 2 != 0) {
> menuPage = menuPage + 1;
> menuPage = constrain(menuPage, 0, maxMenuPages);
> }
>
> if (menuPage % 2 != 0 and cursorPosition % 2 == 0) {
> menuPage = menuPage + 1;
> menuPage = constrain(menuPage, 0, maxMenuPages);
> }
>
> cursorPosition = cursorPosition + 1;
> cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
> mainMenuDraw();
> drawCursor();
> activeButton = 1;
> break;
> }
> }
> }
>
> // This function is called whenever a button press is evaluated. The LCD shield works by observing a voltage drop across the buttons all hooked up to A0.
> int evaluateButton(int x) {
> int result = 0;
> if (x < 50) {
> result = 1; // right
> } else if (x < 195) {
> result = 2; // up
> } else if (x < 380) {
> result = 3; // down
> } else if (x < 790) {
> result = 4; // left
> }
> return result;
> }
>
> // If there are common usage instructions on more than 1 of your menu items you can call this function from the sub
> // menus to make things a little more simplified. If you don't have common instructions or verbage on multiple menus
> // I would just delete this void. You must also delete the drawInstructions()function calls from your sub menu functions.
> void drawInstructions() {
> lcd.setCursor(0, 1); // Set cursor to the bottom line
> lcd.print("Use ");
> lcd.write(byte(1)); // Up arrow
> lcd.print("/");
> lcd.write(byte(2)); // Down arrow
> lcd.print(" buttons");
> }
>
> void menuItem1() { // Function executes when you select the 2nd item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
>
>
> lcd.clear();
> lcd.setCursor(3, 0);
>
> if (vswitch1 == 1)
> {
> lcd.print("ON/off");
> }
>
> if(vswitch1 == 0)
> {
> lcd.print("OFF/on");
>
> }
>
>
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 2:
> vswitch1 = 0;
> switch1 = 1;
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned Off");
> delay(1000);
> activeButton = 1;
> break;
> case 3:
> vswitch1 = 1;
> switch1 =0;
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned On");
> delay(1000);
> activeButton = 1;
> break;
> case 4:// This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
>
> }
> BLYNK_READ(V1) // Widget in the app READs Virtal Pin V5 with the certain frequency
> {
> // This command writes Arduino's uptime in seconds to Virtual Pin V5
> Blynk.virtualWrite(V1, switch1);
> }
>
> void menuItem2() { // Function executes when you select the 2nd item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> if (vswitch2 == 1)
> {
> lcd.print("ON/off");
> }
>
> if(vswitch2 == 0)
> {
> lcd.print("OFF/on");
>
> }
>
>
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 2:
> vswitch2 = 0;
> Blynk.virtualWrite(V2,0);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned Off");
> delay(1000);
> activeButton = 1;
> break;
> case 3:
> vswitch2 = 1;
> Blynk.virtualWrite(V2,1);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned On");
> delay(1000);
> activeButton = 1;
> break;
> case 4:// This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
> void menuItem3() { // Function executes when you select the 3rd item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> if (vswitch3 == 1)
> {
> lcd.print("ON/off");
> }
>
> if(vswitch3 == 0)
> {
> lcd.print("OFF/on");
>
> }
>
>
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 2:
> vswitch3 = 0;
> Blynk.virtualWrite(V3,0);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned Off");
> delay(1000);
> activeButton = 1;
> break;
> case 3:
> vswitch3 = 1;
> Blynk.virtualWrite(V3,1);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned On");
> delay(1000);
> activeButton = 1;
> break;
> case 4:// This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
>
> void menuItem4() { // Function executes when you select the 4th item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> if (vswitch4 == 1)
> {
> lcd.print("ON/off");
> }
>
> if(vswitch4 == 0)
> {
> lcd.print("OFF/on");
>
> }
>
>
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 2:
> vswitch4 = 0;
> Blynk.virtualWrite(4,LOW);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned Off");
> delay(1000);
> activeButton = 1;
> break;
> case 3:
> vswitch4 = 1;
> Blynk.virtualWrite(V4,1);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned On");
> delay(1000);
> activeButton = 1;
> break;
> case 4:// This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
> void menuItem5() { // Function executes when you select the 5th item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> if (vswitch5 == 1)
> {
> lcd.print("ON/off");
> }
>
> if(vswitch5 == 0)
> {
> lcd.print("OFF/on");
>
> }
>
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 2:
> vswitch5 = 0;
> Blynk.virtualWrite(V5,0);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned Off");
> delay(1000);
> activeButton = 1;
> break;
> case 3:
> vswitch5 = 1;
> Blynk.virtualWrite(V5,1);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned On");
> delay(1000);
> activeButton = 1;
> break;
> case 4:// This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
> void menuItem6() { // Function executes when you select the 6th item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> if (vswitch6 == 1)
> {
> lcd.print("ON/off");
> }
>
> if(vswitch6 == 0)
> {
> lcd.print("OFF/on");
>
> }
>
>
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 2:
> vswitch6 = 0;
> Blynk.virtualWrite(V6,0);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned Off");
> delay(1000);
> activeButton = 1;
> break;
> case 3:
> vswitch6 = 1;
> Blynk.virtualWrite(V6,1);
> button = 0;
> lcd.clear();
> lcd.setCursor(1, 0);
> lcd.print("Turned On");
> delay(1000);
> activeButton = 1;
> break;
> case 4:// This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
> void menuItem7() { // Function executes when you select the 7th item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> lcd.print("Sub Menu 7");
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 4: // This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
>
> void menuItem8() { // Function executes when you select the 8th item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> lcd.print("Sub Menu 8");
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 4: // This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
>
> void menuItem9() { // Function executes when you select the 9th item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> lcd.print("Sub Menu 9");
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 4: // This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
>
> void menuItem10() { // Function executes when you select the 10th item from main menu
> int activeButton = 0;
>
> lcd.clear();
> lcd.setCursor(3, 0);
> lcd.print("Sub Menu 10");
>
> while (activeButton == 0) {
> int button;
> readKey = analogRead(0);
> if (readKey < 790) {
> delay(100);
> readKey = analogRead(0);
> }
> button = evaluateButton(readKey);
> switch (button) {
> case 4: // This case will execute if the "back" button is pressed
> button = 0;
> activeButton = 1;
> break;
> }
> }
> }
>
> void loop() {
> mainMenuDraw();
> drawCursor();
> operateMainMenu();
> Blynk.run();
> }