[SOLVED][Beginner] Toggle manual/automatic mode on my project!

Hello Blynk community !

I have a very little project I’m working on, here is the idea :

With an LDR, I adjust a light and a servo according to light outside. Very basic as I said !

So I have the prototype working, with all the code etc… extra fine ! But I wanted to go further and add a “manual mode”.

The idea is to have a button on Blynk that allows me to switch between Manual/Auto.

If I’m in auto, the code runs, checking LDR value every 10 sec with a delay.
If in manual, I set the servo/light with a slider and a button !

I got lost when I saw that I had to moove every code into function so that I only had “blynk.run();” in the loop… As far as I understood I shall use “blynk_write” but I have some troubles with it, like the fact that when I press the button it executes 2 times the function set to the virtual pin and apparently the function in blynk_write should be quick to execute (no delay ?? :’( ).

Here is the code I have for automatic mode !

#include <Servo.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
const int LDR = A3; //LDR 
const int LED = 13;
Servo servofenetre; //crée un objet servo



void setup() 
{
  lcd.begin(16,2);
  //Initalisation des pins
  int etat_LDR = LOW;
  float  angle;
  pinMode(LDR, INPUT);
  pinMode(LED, OUTPUT);
 
  //Servo
  servofenetre.attach(10);
  
}

// Loop
void loop() 
{
 unsigned int angle = 0;
 float etat_LDR;
 etat_LDR = analogRead(LDR);
 angle = ((etat_LDR*90)/1023);

 //Display servo angle on LCD
 lcd.setCursor(0,0);
 lcd.print("Angle = ");
 lcd.setCursor(0,1);
 lcd.print(angle);
 
 delay(2000);
 
 servofenetre.write(angle);
      

//LED STATE
 if (etat_LDR > 500)
 {
  digitalWrite(LED, HIGH);
  
 }
 else if (etat_LDR <500)
 {
  digitalWrite(LED,LOW);
 }
}

Thanks a lot in advance ! Hope I made myself understandable and sorry for bad english !

you need simpleTimer in the loop also (search “simpletimer” on here)

you use simpleTimer call the LDR function every 10000 miliseconds.

then to add in manual/auto mode add this ‘variable’ up front and add it to a blynk button

int selectMode;

BLYNK_WRITE(Vx) // button in app where "x" is the virtual pin
  {
    selectMode= param.asInt(); 
    runLDRfunction:
  }

in the LDR function have the first line to say:

void runLDRfunction();
if (selectMode == 1)// in the app the button state is 1 it's "manual"
{
Serial.println(F("manual mode active, ignore LDR function")); // just lets you see what is going on in the serial monitor for debugging
}
else
{
Serial.println(F("automatic mode active, continue to finishing LDR function")); // just lets you see what is going on in the serial monitor for debugging

add in the LDR function etc etc etc 
}

hope this gets you started, give it a go and let us know how far you get…

2 Likes

Hi Dave ! Thanks a lot for that amazing answer ! I thought I was able to do all that by myself but man was I wrong :frowning:

I like to understand things from the beginning so I built a code step by step to make sur that I understand the way BLYNK_WRITE works !

The purpose of the code was to simulate the Manual/Auto mode. In manual an LED blinks fast, in auto the same LED blinks slowly.

When I launch the code, the LED stays LOW all the time… When I put the code in the loop and remove blynk.run it works just fine by adjusting selectMode in the code…

BTW I can’t use serial monitor because I’m using usb cable to transmit internet to the board, therefore the port is busy…

Here is the code I’m using :

#include <BlynkSimpleStream.h>

const int LED2 = 8;
int selectMode;
//Blynk Token
char auth[] = "blablabla";

void setup()
{
  
  
  // Blynk will work through Serial
  Serial.begin(9600);
  Blynk.begin(auth, Serial);
  pinMode(LED2, OUTPUT);

}

 
 void runLDRfunction()
 {
 if (selectMode == 1) //If button MANUAL on app
 { 
  digitalWrite(LED2, LOW); 
  delay(500);
  digitalWrite(LED2,HIGH);
  delay(500);
 }
 else 
 {
 digitalWrite(LED2, LOW); 
  delay(1000);
  digitalWrite(LED2,HIGH);
  delay(1000);
 }
}

BLYNK_WRITE(V3)
 {
  selectMode = param.asInt();
  runLDRfunction;
 }

//loop
void loop()
{
  Blynk.run();
}

I really dont understand why it’s not working like intended, it seems so simple :’(
When adding a button on D8 on blynk I can controll the LED so idk where the problem is !

Thanks in advance for your answer, it’s just awesome to have such a friendly community !

I would find it impossible to code without access to Serial Monitor (SM).

The standard “USB” sketch provided by Blynk gives you access to SM with SoftwareSerial.

I feel really stupid here but you mean that I should use something like SoftwareSerial Serial(2,3); and then put those pins on a physical monitor ?

Is there no way to use the IDE Serial Monitor while using USB cable to transmit internet data ?

By the way I tried to use the terminal widget as a serial monitor (which kinda worked). It displayed “button pushed” when I pressed the button, but it was supposed to display “manual” or “auto” when entering a mode and it never did :’(

Thx a lot for your answers and sorry for being such a noob regarding Blynk ! Controling servos with slider and led with buttons was easy but this is somthing else…

SoftwareSerial does work like that, but you need somewhere to attach them on the computer. E.g. a usb-to-serial convertor or an actual serial port.

you missed the bit where i suggested you search “simpleTimer” on this forum…

(where you find that using delay() is evil for Blynk projects)

to “blink without delay”, read up here:

1 Like

Yes but it will cost you 53 cents https://www.aliexpress.com/item/PL2303-PL2303HX-Chip-USB-Converter-Adapter-Module-To-RS232-TTL-USB-TTL-9-Upgrade-Board-STC/32314781946.html

Thanks for the answers !
I will redo it with the timer !

I will reicive an Arduino UNO WIFI soon so I wont use the serial monitor for now :slight_smile:

I’ll keep you updated here !

Alright Ladies&Gentlemans !

So I just tried with the simpletimer and oh boy it works !!

Here is what’s intended :

There is a switch on blynk. A function that checks switch state is called every second. If switch is on, led is on, and switch off led off. Also it displays “mode 1” or “mode 2” on the terminal that acts as serial monitor.

Here is the code used :

#include <BlynkSimpleStream.h>
#include <SimpleTimer.h>

const int LED2 = 8;
int selectMode;
//Blynk Token
char auth[] = "****";
//Monitor
WidgetTerminal terminal(V1);
//Timer
SimpleTimer timer;


void setup()
{
  // Blynk will work through Serial
  Serial.begin(9600);
  Blynk.begin(auth, Serial);
  pinMode(LED2, OUTPUT);
  
  timer.setInterval(1000, runLDRfunction);
}

 
 void runLDRfunction()
 {
 if (selectMode == 1) //If button MANUAL on app
 { 
  digitalWrite(LED2, LOW); 
  terminal.println("mode 2");
 }
 else 
 {
  digitalWrite(LED2,HIGH);
  terminal.println("mode 1");
 }
}

BLYNK_WRITE(V3)
 {
  selectMode = param.asInt();
  runLDRfunction;
  terminal.println("button pressed");
 }


//loop
void loop()
{
  Blynk.run();
  timer.run();
}

There is still a little thing bothering me !

I expected the “mode 1” or “mode 2” to be desplayed every second, but in fact, nothing is printed on the monitor as long as it doesnt have like 12 elements to print.

So it gets updated every 12 seconds or something like that and I dont know exactly why !

Anyway I’m going to keep digging, thank you so much for the help everyone !

It’s dooooooooooone !

Thanks to you guys I got it to work as planned, many thanks !

I have a light problem with displayin on the lcd but nothing dramatic, should be fixed soon !

I let the working code here so anyone can have a look at it :grin:

#include <BlynkSimpleStream.h>
#include <SimpleTimer.h>
#include <Servo.h>
#include <LiquidCrystal.h>

const int LDR = A3;
const int LED = 13;
int etat_LDR;
float angle;
int selectMode;
Servo servofenetre;

//Blynk Token
char auth[] = "mytoken";

//Monitor
WidgetTerminal terminal(V1);
LiquidCrystal lcd(12,11,5,4,3,2);

//Timer
SimpleTimer timer;


void setup()
{
  // Blynk will work through Serial
  Serial.begin(9600);
  Blynk.begin(auth, Serial);
  pinMode(LDR, INPUT);
  pinMode(LED, OUTPUT);
  servofenetre.attach(10);
  
  timer.setInterval(1000, runLDRfunction);
}

 
 void runLDRfunction()
 {
 if (selectMode == 1) //If button MANUAL on app
 { 
  terminal.println("Manual mode :");
  lcd.clear();
  lcd.print("manual");
 }
 else 
 {
  terminal.println("Automatic mode :");
  etat_LDR = analogRead(LDR);
  angle = ((etat_LDR*90)/1023);

 //Display servo angle on LCD
 lcd.setCursor(0,0);
 lcd.print("Angle = ");
 lcd.setCursor(0,1);
 lcd.print(angle);
 servofenetre.write(angle);

 //LED state
 if (etat_LDR > 500)
 {
  digitalWrite(LED, HIGH);
  
 }
 else if (etat_LDR <500)
 {
  digitalWrite(LED,LOW);
 }
 }
}

BLYNK_WRITE(V2)
 {
  selectMode = param.asInt();
  runLDRfunction;
  terminal.println("button pressed");
 }

BLYNK_WRITE(V3)
{
  servofenetre.write(param.asInt());
}

//loop
void loop()
{
  Blynk.run();
  timer.run();
}

Big shoutout to Dave and Costas on this one !

1 Like

i kinda guessed you’d be able to work it out yourself, some people just can, but others need much more help…

have you read about adding terminal.flush(); after each of the terminal prints?

maybe this will help?

1 Like

It is absolutely essential.

Ok I will try this weekend !

added terminal.flush(); and it works like a charm, thanks a lot everyone !

A post was split to a new topic: Looking to control a servo motor with slider

Can anyone help me?:cry:

@Aizat_Nazih This topic was already solved long ago… I have moved your issue into a new topic. Please be aware, we are not here to write your code for you… you will need to learn how to code for Blynk on your own, but we will help with specific issues as you learn.