C++ Blynk (Legacy) - Code Examples for Basic Tasks

1 - Basic ESP8266 & ESP32 based Blynk with OTA template

Let’s start off with a basic starter sketch I use for all my ESP based projects… saves me a bit of typing :stuck_out_tongue:

Nope, I haven’t yet set it up for automatic #ifdef choice of ESP8266 or ESP32… I will leave that for you for now :blush:

#define BLYNK_PRINT Serial // This prints to Serial Monitor
// #define BLYNK_DEBUG  // Optional, this enables more detailed prints

////  Pick one Blynk Device Library group or other 
////----------
// #include <WiFi.h>  // for ESP32
// #include <WiFiClient.h>  // for ESP32
// #include <BlynkSimpleEsp32.h>  // for ESP32
////----------
#include <ESP8266WiFi.h>  // for ESP8266
#include <BlynkSimpleEsp8266.h>  // for ESP8266
////----------

////  Pick one OTA Library or other 
////----------
// #include <ESPmDNS.h>  // For OTA w/ ESP32
////----------
#include <ESP8266mDNS.h>  // For OTA w/ ESP8266
////----------

#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
int port = 8080;


void setup() {
  Serial.begin(9600);  // BLYNK_PRINT data

  WiFi.begin(ssid, pass); 
  Blynk.config(auth, server, port);
  Blynk.connect();

  ArduinoOTA.setHostname("Blynkified ESP Device");  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA
}

void loop() {
  Blynk.run();
  ArduinoOTA.handle();  // For OTA
}
19 Likes

#2 - Using zeRGBa and Slider Widgets to control virtual and physical RGB LED

Next up a favorite of mine… since I like colourful LEDs and stuff :stuck_out_tongue:

This code will allow zeRGBa or individual Red Blue Green Sliders to control the colour of both a Virtual LED (vRGB LED) and any physical one connected to the device.

NOTE: this is NOT for a NeoPixel RGB… Only for a bog standard RGB LED (common Anode/Cathode selectable in code) Please adjust GPIO pins to your needs

This codes primary purpose was to explore the differences in controlling something with multiple Widgets with feedback (e.g. Sliders and zeRGBa) as well as experimenting with the ability for custom Widget colours… thus it incorporates some calculation to convert the 0-255 vPin data for the physical RGB LED to the #HEX data that represents the vRGB LED and Display widget colouring via Blynk.setProperty() command.

//#define BLYNK_PRINT Serial // This prints to Serial Monitor
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// Define your Physical RGB LED pins here
#define RedPin 14  // Set RED RGB pin
#define GrnPin 12  // Set GREEN RGB pin
#define BluPin 13  // Set BLUE RGB pin

// Define your Virtual pins here
#define zeRGBa V0  // Set virtual RGB widget
#define rSlide V1  // Set virtual RGB widget
#define gSlide V2  // Set virtual RGB widget
#define bSlide V3  // Set virtual RGB widget
#define vRed V4  // Set virtual Red LED widget
#define vGreen V5  // Set virtual Green LED widget
#define vBlue V6  // Set virtual Blue LED widget
#define vRGB V7  // Set virtual RGB widget
#define HEXdisplay V8  // Set virtual RGB widget

int rrr, ggg, bbb;  // Set RED BLUE GREEN channels

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;



void setup() {
  //Serial.begin(9600);  // BLYNK_PRINT data

  pinMode(RedPin, OUTPUT);  // Set RED pinMode
  pinMode(GrnPin, OUTPUT);  // Set GREEN pinMode
  pinMode(BluPin, OUTPUT);  // Set BLUE pinMode

  Blynk.virtualWrite(vRGB, 255);  // Activate vRGB
  Blynk.setProperty(vRGB, "color", "#000000");  // Set vRGB to Black

  WiFi.begin(ssid, pass); 
  Blynk.config(auth, server, port);
  Blynk.connect();
}



BLYNK_CONNECTED() {
  Blynk.syncAll();  // Synchronize hardware with App widgets when connected
}



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



//===== RED slider =====
BLYNK_WRITE(rSlide) { // START Blynk Function
  rrr = param.asInt(); // get a RED channel value
  Blynk.virtualWrite(vRed, rrr);  // Red LED intensity
  Blynk.virtualWrite(zeRGBa, rrr, ggg, bbb);  // Sync zeRGBa position
  RGBprocess(); // Run Arduino funtion
}  // END Blynk Function


//===== GREEN slider =====
BLYNK_WRITE(gSlide) { // START Blynk Function
  ggg = param.asInt(); // get a GREEN channel value
  Blynk.virtualWrite(vGreen, ggg);  // Green LED intensity
  Blynk.virtualWrite(zeRGBa, rrr, ggg, bbb);  // Sync zeRGBa position
  RGBprocess(); // Run Arduino funtion
}  // END Blynk Function


//===== BLUE slider =====
BLYNK_WRITE(bSlide) { // START Blynk Function
  bbb = param.asInt(); // get a BLUE channel value
  Blynk.virtualWrite(vBlue, bbb);  // Blue LED intensity
  Blynk.virtualWrite(zeRGBa, rrr, ggg, bbb);  // Sync zeRGBa position
  RGBprocess(); // Run Arduino funtion
}  // END Blynk Function



//===== zeRGBa Widget  =====
BLYNK_WRITE(zeRGBa) { // START Blynk Function
  rrr = param[0].asInt(); // get a RED channel value
  ggg = param[1].asInt(); // get a GREEN channel value
  bbb = param[2].asInt(); // get a BLUE channel value
  Blynk.virtualWrite(rSlide, rrr);  // Sync RED Slider position
  Blynk.virtualWrite(vRed, rrr);  // Red LED intensity
  Blynk.virtualWrite(gSlide, ggg);  // Sync Green slider position
  Blynk.virtualWrite(vGreen, ggg);  // Green LED intensity
  Blynk.virtualWrite(bSlide, bbb);  // Sinc Blue slider position
  Blynk.virtualWrite(vBlue, bbb);  // Blue LED intensity
  RGBprocess(); // Run Arduino funtion
}  // END Blynk Function



//===== Physical RGB LED Control and HEX conversion =====
void RGBprocess() {  // START Arduino funtion

  /*----- Comment out unneeded grouping based on device and RGB type ----- */
  // ESP with Common Anode+ RGB LED
  analogWrite(RedPin, (255 - rrr) * 4 + 4); // Write to RED RGB pin
  analogWrite(GrnPin, (255 - ggg) * 4 + 4); // Write to GREEN RGB pin
  analogWrite(BluPin, (255 - bbb) * 4 + 4); // Write to BLUE RGB pin

  // ESP with Common Cathode- RGB LED
  //analogWrite(RedPin, rrr*4+4);  // Write to RED RGB pin
  //analogWrite(GrnPin, ggg*4+4);  // Write to GREEN RGB pin
  //analogWrite(BluPin, bbb*4+4);  // Write to BLUE RGB pin

  // Arduino with Common Anode+ RGB LED
  //analogWrite(RedPin, 255-rrr);  // Write to RED RGB pin
  //analogWrite(GrnPin, 255-ggg);  // Write to GREEN RGB pin
  //analogWrite(BluPin, 255-bbb);  // Write to BLUE RGB pin

  // Arduino with Common Cathode- RGB LED
  //analogWrite(RedPin, rrr);  // Write to RED RGB pin
  //analogWrite(GrnPin, ggg);  // Write to GREEN RGB pin
  //analogWrite(BluPin, bbb);  // Write to BLUE RGB pin
  /*-----------------------------------------------------------------------*/

  String strRED = String(rrr, HEX);  // Convert RED DEC to HEX
  if (rrr < 16) {
    strRED = String("0" + strRED);  // Buffer with 0 if required
  }  // END if
  String strGRN = String(ggg, HEX);  // Convert GREEN DEC to HEX
  if (ggg < 16)  {
    strGRN = String("0" + strGRN);  // Buffer with 0 if required
  }  // END if
  String strBLU = String(bbb, HEX);  // Convert BLUE DEC to HEX
  if (bbb < 16)  {
    strBLU = String("0" + strBLU);  // Buffer with 0 if required
  }  // END if
  String HEXstring = String("#" + strRED + strGRN + strBLU);  // Combine HEX fragments
  HEXstring.toUpperCase();  // Change HEX value to all upper case for ease of visuals
  Blynk.setProperty(HEXdisplay, "color", HEXstring);  // Change background colour of HEX Data Label
  Blynk.virtualWrite(HEXdisplay, HEXstring);  // Display HEX data
  Blynk.setProperty(vRGB, "color", HEXstring);  // Send formatted HEX colour to vRGB
}  // END Arduino Function

In this QR, you may need to adjust the slider MIN/MAX values to 0-255 for proper function.
image

I hope you enjoy!! :smile:

5 Likes

#3 Dirt simple Zero Centered Negative/Positive data display

Say you need an analog display for a value that could be negative or positive… well, until we get such option for the Gauge Display, here is an alternative that works perfectly.

This is shown along with a ‘normal’ bar graph (in Yellow) of the same data feed from a Potentiometer on an Analog pin.

image

image

image

// ----- Zero Center Split Bar Level Display -- Call this function with a timer -----
void AnalogSensor() {
  LVLval = map(analogRead(pin), 0, 1023, -150, 150); // Mapped data from Arduino analog pin
  Blynk.virtualWrite(V1, LVLval);  // Lefthand bar (MIN/MAX setting 0 to -150, Flip Axis ON)
  Blynk.virtualWrite(V2, LVLval);  // Righthand Bar (MIN/MAX setting 0 to 150, Flip Axis OFF)
}  // END Arduinor Function
8 Likes

#4 Slow & Variable Servo Sweep Without ‘delay()’ (Yay Timers!)

This is one I dug out of my archive and tweaked a bit to make it variable and stable.

I also have another method of varing a timer, shown in a later post: 20 - Easy Variable Timer

This example will allow you to control the sweep speed of a servo motor… normally they run at one speed, from where they are to where you want them to go. Traditional methods to slow that down is move the servo in incremental steps with a delay between each step.

This is that, but without the blocking delay() command. NOTE: Due to the intermittent steps, even at 1ms timing between steps, the sweep will still be much slower then normal.

1st Challenge for you: Use logic to determine if the incremental speed is low enough to skip the intermittent steps all together :thinking:

2nd Challenge for you: This code is a bit clunky and even though starting the same timer again should normal reset it’s instance, I found I needed to use timer delete to keep them from building up same timer instances (once it reached 16 instances, that timer stopped). See if you can devise a cleaner way of processing the timers and the sweeps :thinking:

3rd Challenge for you: When adjusting the speed, the sweep will restart from the beginning… Try to make the adjustment in the timing without needing a reset of the sweep loop :thinking:

For Widgets, you will need:

  • Button in Switch mode (V0) to start and stop the sweep
  • Display (V1) to show the servo position 10-160
  • Slider (V2) to adjust the sweep speed interval in ms - I recommend setting the range from 1-500 for up to a 1/2 second step interval.

Servo motor with signal pin on pin 12 (D6 on Wemos).

//#define BLYNK_PRINT Serial // This prints to Serial Monitor

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Servo.h>

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;

Servo myservo;
BlynkTimer timer;
BlynkTimer UpTimer;
int SrvoPin = 12;
int SrvoPos;
int SrvoButton;
int SrvoSpeed = 30;
int SrvoTimer;  // ID for timer, allows the ability to enable, disable, delete, etc. 



void setup() {
  //Serial.begin(9600);  // BLYNK_PRINT data
  WiFi.begin(ssid, pass); 
  Blynk.config(auth, server, port);
  Blynk.connect();
  Blynk.virtualWrite(V2, SrvoSpeed);
}



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



BLYNK_CONNECTED() {
  Blynk.syncAll();  // Synchronize hardware with App widgets when connected
}



//----- Slow Servo Sweep Button -----
BLYNK_WRITE(V0) {  // START Blynk Function
  SrvoButton = param.asInt();
  if (SrvoButton == 1) {  // If button ON start servo sweep
    myservo.attach(SrvoPin);  // Enable Servo
    SrvoPos = 10;  // Start servo at position 10
    timer.deleteTimer(SrvoTimer);  // Delete timer so it can start over without taking up resources
    SrvoTimer = timer.setTimer(SrvoSpeed, moveServoUP, 160);  // Call moveServoUP() function 160 times
  } else {  // If button OFF stop servo sweep
    myservo.detach();  // Disable Servo - prevents jittering when not activly running
    timer.deleteTimer(SrvoTimer);  // Delete timer so it can start over without taking up resources
  }  // END else
}  // END Blynk Function



//----- Slow Servo Sweep Speed -----
BLYNK_WRITE(V2) {  // START Blynk Function
  timer.deleteTimer(SrvoTimer);  // Delete timer so it can start over without taking up resources
  SrvoSpeed = param.asInt();
  Blynk.syncVirtual(V0);  // Check Button status to restart the loop
}  // END Blynk Function



void moveServoUP() { // START Arduino Function
  myservo.write(SrvoPos);  // tell servo to go to position in variable 'pos'
  SrvoPos++;  // Increment servo position 1 step
  Blynk.virtualWrite(V1, SrvoPos);
  if (SrvoPos >= 160) {  // check if servo has reached endstop
    timer.deleteTimer(SrvoTimer);  // Delete timer so it can start over without taking up resources
    SrvoTimer = timer.setTimer(SrvoSpeed, moveServoDOWN, 160);  // Call moveServoDown() function 160 times
  }  // END else
}  // END Arduino Function



void moveServoDOWN() { // START Arduino Function
  myservo.write(SrvoPos);  // tell servo to go to position in variable 'pos'
  SrvoPos--;  // Decrement servo position 1 step
  Blynk.virtualWrite(V1, SrvoPos);
  if (SrvoPos <= 10) {  // check if servo has reached endstop
    timer.deleteTimer(SrvoTimer);  // Delete timer so it can start over without taking up resources
    Blynk.syncVirtual(V0);  // Check Button status to restart the sweep loop
  }  // END if
}  // END Arduino Function
7 Likes

#5 Matrix of Randomly Flashing & Coloured Virtual RGB LEDs

I posted this last year…but am tossing it in here to keep my group of sketches up to date.

Sorry to those not on Local Server… it is not cheap on the energy, however nothing in it is non-recyclable… 72 LED widgets @ 200 energy means you need 14,400 units of energy to load this.

This code is compiled on a Wemos D1 mini with OTA programming functionality built in… but it basically should work on most any ESP8266.

image

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

#define BLYNK_NO_BUILTIN  // Disable built-in analog & digital pin operations
#define BLYNK_MAX_READBYTES 1024
#define BLYNK_MSG_LIMIT 0
#define BLYNK_HEARTBEAT 60

BlynkTimer timer;

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;
String HEXstring;
int randLED;
int randIntensity;
int rrr, ggg, bbb;
int RandomTimer;



void setup() {
  WiFi.begin(ssid, pass); 
  // Preset for use on a Local Server... adjust as required for Cloud Server
  Blynk.config(auth, server, port);
  Blynk.connect();
  for (int i = 0; i <= 71; i++) {
    Blynk.setProperty(i, "label", " ");  // Set LED Label to blank
    Blynk.setProperty(i, "color", "#000000");  // Set LED colour to black
    Blynk.virtualWrite(i, 255);  // Set LED to full intensity
  }
  // You may need to adjust this timer higher, particularly if using Cloud Server
  RandomTimer = timer.setInterval(15L, RGBMatrix); 
 
  ArduinoOTA.setHostname("ESP8266 vRGB Matrix");  // For OTA
  ArduinoOTA.begin();  // For OTA
}



void loop() {
  Blynk.run();
  timer.run();
  ArduinoOTA.handle();
}



void RGBMatrix() {
  randLED = random(72);
  //randIntensity = random(72, 256);
  rrr = random(256);
  ggg = random(256);
  bbb = random(256);
  String strRED = String(rrr, HEX);  // Convert RED DEC to HEX.
  if (rrr < 16) {
    strRED = String("0" + strRED);  // Buffer with 0 if required.
  }  // END if
  String strGRN = String(ggg, HEX);  // Convert GREEN DEC to HEX.
  if (ggg < 16)  {
    strGRN = String("0" + strGRN);  // Buffer with 0 if required.
  }  // END if
  String strBLU = String(bbb, HEX);  // Convert BLUE DEC to HEX.
  if (bbb < 16)  {
    strBLU = String("0" + strBLU);  // Buffer with 0 if required.
  }  // END if
  String HEXstring = String("#" + strRED + strGRN + strBLU);  // Combine HEX fragments.
  Blynk.setProperty(randLED, "color", HEXstring);  // Set LED Label to HEX colour
  //Blynk.virtualWrite(randLED, randIntensity);
}
5 Likes

#6 Matrix of LARGE Randomly Flashing & Coloured Virtual RGB “Super LEDs” (AKA Buttons)

I don’t know why I didn’t do this one sooner… less energy and at about 80% less “LEDs” to flash, it should be theoretically faster… well… it costs less energy at least :stuck_out_tongue: (3200 units of energy)

Challenge Question for the Developers… why is it seem faster to change the colour properties on 71 LEDs compared to 16 Buttons?

Even the QR looks more complex… but then Buttons do have more settings then an LED :stuck_out_tongue:
image

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

#define BLYNK_NO_BUILTIN  // Disable built-in analog & digital pin operations
#define BLYNK_MAX_READBYTES 1024
#define BLYNK_MSG_LIMIT 0
#define BLYNK_HEARTBEAT 60

BlynkTimer timer;

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;
String HEXstring;
int randLED;
int randIntensity;
int rrr, ggg, bbb;
int RandomTimer;



void setup() {
  WiFi.begin(ssid, pass); 
  // Preset for use on a Local Server... adjust as required for Cloud Server
  Blynk.config(auth, server, port);
  Blynk.connect();
  for (int i = 0; i <= 16; i++) {
    Blynk.virtualWrite(i, 1);  // Set Button ON
    Blynk.setProperty(i, "label", " ");  // Set Button Label to blank
    Blynk.setProperty(i, "color", "#000000");  // Set Button colour to black
  }
  RandomTimer = timer.setInterval(30L, RGBMatrix);
  ArduinoOTA.setHostname("ESP8266 BIG vRGB Matrix");  // For OTA
  ArduinoOTA.begin();  // For OTA
}



void loop() {
  Blynk.run();
  timer.run();
  ArduinoOTA.handle();
}



void RGBMatrix() {
  randLED = random(17);
  rrr = random(256);
  ggg = random(256);
  bbb = random(256);
  String strRED = String(rrr, HEX);  // Convert RED DEC to HEX.
  if (rrr < 16) {
    strRED = String("0" + strRED);  // Buffer with 0 if required.
  }  // END if
  String strGRN = String(ggg, HEX);  // Convert GREEN DEC to HEX.
  if (ggg < 16)  {
    strGRN = String("0" + strGRN);  // Buffer with 0 if required.
  }  // END if
  String strBLU = String(bbb, HEX);  // Convert BLUE DEC to HEX.
  if (bbb < 16)  {
    strBLU = String("0" + strBLU);  // Buffer with 0 if required.
  }  // END if
  String HEXstring = String("#" + strRED + strGRN + strBLU);  // Combine HEX fragments.
  Blynk.setProperty(randLED, "color", HEXstring);  // Set LED Label to HEX colour
}
5 Likes

#7 !! NodeJS !! - Pan & Tilt Servo control with Joystick for Raspberry Pi using NodeJS

And now for something different… here is some simple javascript code for using the joystick widget with a couple servos on an RPi for use with a pan and tilt base. More NodeJS stuff here :wink:

Hook up your two servos with 5v, GND and GPIO pins 22 & 23 .
I recommend a dedicated 5v supply and remember to share the GND with the RPi.

Joystick Widget set for vPin 22 & 23 (to match the GPIO just for hookup convenience, they can be any other vPins) and whatever range settings work best for your servos.

const Gpio = require('pigpio').Gpio;
const PAN_PORT = 22;
const TILT_PORT = 23;
const pan = new Gpio(PAN_PORT, {mode: Gpio.OUTPUT});
const tilt = new Gpio(TILT_PORT, {mode: Gpio.OUTPUT});
const Blynk = require('blynk-library');  // Links variable 'Blynk' to the Blynk Library

const AUTH = 'xxxxxxxxxx';

// ----- Use this with Cloud Server.
//  var blynk = new Blynk.Blynk(AUTH, options = { connector : new Blynk.TcpClient()  });

// ----- Use this with Local Server.
var blynk = new Blynk.Blynk(AUTH, options = { connector : new Blynk.TcpClient( options = { addr: "xxx.xxx.xxx.xxx", port: 8080 } ) });

var JoyX = new blynk.VirtualPin(22);  // Setup Joystick X on V22
var JoyY = new blynk.VirtualPin(23);  // Setup Joystick Y on V23

JoyX.on('write', function(panValue) {  // Watches for Joystick X
  pan.servoWrite(panValue);  // Set Servo to value
});

JoyY.on('write', function(tiltValue) {  // Watches for Joystick y
  tilt.servoWrite(tiltValue);  // Set Servo to value
});
7 Likes

#8 Simple AC Power Monitor (Using ACS712)

This is something I have running on my workbench… simply monitoring the power used by my computer system. So the current adjustments visible on the graph are the difference between my monitors being on or off.

The shading is normal, but I am also using the gradient colour so that it goes from green at its lowest to red at its highest.

image

I have mounted my sensor in an old power tap / spike regulator box…
Not sure I would trust it to the full 15A :zap: :fire::fire:

And yes, it is presently running on a lowly Arduino UNO using the USB Link :stuck_out_tongue_winking_eye:

http://help.blynk.cc/how-to-connect-different-hardware-with-blynk/arduino/usb-serial

I “upgraded” my UNO that runs this AC Current Monitor. Since the UNO only needed one Analog port for the job… and that was all that is left over with these old LCD shields… I added the shield (no not including the merged-into-Blynk Paint code here :wink: ) but eventually I will instead use the display for actual AC current data… maybe even as a clock :thinking:

#include <BlynkSimpleStream.h>  // For USB Link
//#include <ESP8266WiFi.h>  // For WiFi with standalone ESP8266
//#include <BlynkSimpleEsp8266.h>  // For WiFi with ESP8266 as shield for Arduino

char auth[] = "xxxxxxxxxx";
// char ssid[] = "xxxxxxxxxx";  // For WiFi
// char pass[] = "xxxxxxxxxx";  // For WiFi
// char server[] = "10.10.3.13";  // For WiFi - IP for your Local Server
// char server[] = "blynk-cloud.com";  // For WiFi - IP for your Local Server

const int sensorIn = A0;
int mVperAmp = 100; // use 100 for 20A Module and 66 for 30A Module
double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;

BlynkTimer timer;

WidgetTerminal terminal(V1);

void setup() {
  Serial.begin(9600);  // USB Link
  Blynk.begin(Serial, auth);  // For USB Link
  // WiFi.begin(ssid, pass);  // For WiFi
  // Blynk.config(auth, server, port);  // For WiFi
  // Blynk.connect();  // For WiFi
  timer.setInterval(2000L, SensorRead);
}



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



void SensorRead() {
  Voltage = getVPP();
  VRMS = (Voltage / 2.0) * 0.707;
  AmpsRMS = (VRMS * 1000) / mVperAmp;
  Blynk.virtualWrite(V0, 0.9 * AmpsRMS * 110);  // To Gauge Widget @ .9pf and 110vac
  terminal.print(AmpsRMS);  // To Terminal Widget
  terminal.print(" Amps - ");
  terminal.flush();
}



float getVPP() {
  float result;
  int readValue;  //value read from the sensor
  int maxValue = 0;  // store max value here
  int minValue = 1023;  // store min value here
  uint32_t start_time = millis();
  while ((millis() - start_time) < 1500) {  // sample for 1 Sec
    readValue = analogRead(sensorIn);  // see if you have a new maxValue
    if (readValue > maxValue) {
      maxValue = readValue;  // record the maximum sensor value
    }
    if (readValue < minValue) {
      minValue = readValue;  // record the minimum sensor value
    }
  }
  // Subtract min from max
  result = ((maxValue - minValue) * 5.0) / 1023.0;
  return result;
}



void ac_read() {
  int rVal = 0;
  int sampleDuration = 100;  // 100ms
  int sampleCount = 0;
  unsigned long rSquaredSum = 0;
  int rZero = 511;   // For illustrative purposes only - should be measured to calibrate sensor.
  uint32_t startTime = millis();  // take samples for 100ms
  while ((millis() - startTime) < sampleDuration) {
    rVal = analogRead(A0) - rZero;
    rSquaredSum += rVal * rVal;
    sampleCount++;
  }
  double voltRMS = 5.0 * sqrt(rSquaredSum / sampleCount) / 1024.0;
  // x 1000 to convert volts to millivolts
  // divide by the number of millivolts per amp to determine amps measured
  // the 20A module 100 mv/A (so in this case ampsRMS = 10 * voltRMS
  double ampsRMS = voltRMS * 10.0;
}
7 Likes

#9 Basic “Keeps running without WiFi or Blynk Server connection, but reconnects as soon as they are available” sketch

Simply does what the title says… Flashes the built in LED and sends UpTime data to both App and Serial monitor to show operation either way. Also has a lot of serial print commands to show general operation for troubleshooting… Remove them when you are comfortable that everything works for you.

#define BLYNK_PRINT Serial // This prints to Serial Monitor
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for Local Cloud Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;

int DeviceLED = 2;
int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter

BlynkTimer timer;



void setup() {
  Serial.begin(115200);
  pinMode(2, OUTPUT);

  WiFi.begin(ssid, pass);  // Non-blocking if no WiFi available
  Blynk.config(auth, server, port);
  Blynk.connect();

  timer.setInterval(1000L, UpTime);

  ArduinoOTA.setHostname("Loss of connection test");  // For OTA
  ArduinoOTA.begin();  // For OTA
}



BLYNK_CONNECTED() {
  Serial.println("Cconnected");
  ReCnctCount = 0;
}




void UpTime() {
  Blynk.virtualWrite(V0, millis() / 1000);  // Send UpTime seconds to App
  Serial.print("UpTime: ");
  Serial.println(millis() / 1000);  // Send UpTime seconds to Serial
  digitalWrite(DeviceLED, !digitalRead(DeviceLED));  // Blink onboard LED
}



void loop() {
  timer.run();
  ArduinoOTA.handle();  // For OTA

  if (Blynk.connected()) {  // If connected run as normal
    Blynk.run();
  } else if (ReCnctFlag == 0) {  // If NOT connected and not already trying to reconnect, set timer to try to reconnect in 30 seconds
    ReCnctFlag = 1;  // Set reconnection Flag
    Serial.println("Starting reconnection timer in 30 seconds...");
    timer.setTimeout(30000L, []() {  // Lambda Reconnection Timer Function
      ReCnctFlag = 0;  // Reset reconnection Flag
      ReCnctCount++;  // Increment reconnection Counter
      Serial.print("Attempting reconnection #");
      Serial.println(ReCnctCount);
      Blynk.connect();  // Try to reconnect to the server
    });  // END Timer Function
  }
}

NOTE: And here is an enhanced version made by another Blynk Forum member :smiley:

21 Likes

#10 - Basic sketch layout The terms, whys and hows explained… perhaps…

OK, this is just a simple layout of a typical sketch… wherein I will define things like pre-setup, setup(), main loops, functions, etc… these may not be canon in terminology, but it works for me… perhaps for others as well :stuck_out_tongue_winking_eye:

//  This area is what I call pre-setup.  Here you load your libraries, define variables, setup special pin references... basically this is NOT a loop that runs any real code, but some special functions can be placed up here.



// This is the run once per boot loop... here you begin() routines, sensors, etc, initialize timers, set pinMode() etc.
void setup() 
{
  // put your setup code here, to run once:
}



 // Typical Arduino Function... you put specific routines in here and call it from a timer or function call - e.g  myFunction();
void MyFunction()
{ 
  // Generic code functions & stuff here
  // typically called from other functions as needed.
}



// This is called a Blynk Function... basically runs like an Arduino Function, but using App triggered widgets, linked to the same vPin to "call' it whenever a Widget, set to PUSH changes state.
BLYNK_WRITE(vPin) 
{  
  //  Blynk function stuff here
  //  called whenever the associated widget or vPin changes state
}



// this is the loop that constantly runs as fast as it can... with Blynk we try to keep it as clear as possible.
void loop() 
{
  // continuously looping stuff here... like Blynk.run(); and timer.run();
}
8 Likes

#11 - The simple, but mystifyingly complex, Bridge

The Bridge is meant to allow totally separate projects to share data, and/or control things between themselves. You can also have just one project with multiple devices, but have any of the 1st device’s Blynk functions triggered directly by Bridge code in the 2nd device… bypassing the App.

As long as the Auth tokens were generated on the same server, then this can even share between different accounts… I think? :thinking:

Basically, Blynk Bridge is a way of emulating a receiving device’s App input, triggering a Physical Pin or Virtual Pin (using a BLYNK_WRITE() function), but the triggering action came from another transmitting device’s code, not the App… say all that five times fast :stuck_out_tongue:

OK, here is a simple bidirectional Bridge network between two identical sketches/devices… (does not have to be identical, but this is for demonstration :stuck_out_tongue_winking_eye: )

This example has two projects/devices. On each project you can toggle the ‘Local’ project’s device’s LED with Button V0 or the ‘remote’ project’s device’s LED with Button V1… and visa versa.

NOTE for each device’s sketch, comment out the Upper OR Lower AUTH and Bridge tokens, depending on which project you are flashing this sketch to.

For example… use these top settings for Project/device A, and the bottom ones for Project/device B

image

For the App projects, simply add in two buttons, Local LED (V0) and Remote LED (V1) for each project.

*** Don’t forget to add in the Bridge Widget to each project that sends data to another

Also, when using Built In LED’s they are usually triggered LOW, so to make that make visual sense, simply reverse each Button’s settings as such…

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "aaaaaaaaaa";  // Token for Device A
//char auth[] = "bbbbbbbbbb";  // Token for Device B

char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;
#define DeviceLED 2 // Built in LED for Wemos or NodeMCU v3, Or 16 for NodeMCU v1

WidgetBridge bridge1(V127); //  Initiating Bridge Widget on V127 (this is just as holding pin for the bridge, can be any unused vPin and each bridge needs its own)


void setup() {
  pinMode(DeviceLED, OUTPUT);
  WiFi.begin(ssid, pass);
  Blynk.config(auth, server, port);
  Blynk.connect();
}



BLYNK_CONNECTED() {
  bridge1.setAuthToken("bbbbbbbbbb"); // Token of the Device B
  //bridge1.setAuthToken("aaaaaaaaaa"); // Token of the Device A
}



BLYNK_WRITE(V0) { // Local LED
  digitalWrite(DeviceLED, param.asInt()); // take the state of the Button and send it to the Local LED
}



BLYNK_WRITE(V1) { // Remote LED
  bridge1.virtualWrite(V0, param.asInt()); // take the state of the Button and send it to the Remote LED
}

This concept is completely upgradable to anything else you want to control via Bridge.


NOTE: When using Blynk Functions on the receiving side, you MUST have a widget for the receiving vPin in that devices project… just use the same vPin for both the Blynk Function and the Widget’s Blynk.virtualWrite() command…

Sending Project…

void MEGAupdate() { //  Timed Function
  bridge1.virtualWrite(V43, t);  // Solar DHT22 Temperature to receiving project
  bridge1.virtualWrite(V44, h);  // Solar DHT22 Humidity to receiving project
  bridge1.virtualWrite(V47, current_mA);  // Solar Panel Current to receiving project
  bridge1.virtualWrite(V48, busvoltage);  // Solar Battery Voltage to receiving project
}

Receiving Project…

BLYNK_WRITE(V43) { // Solar DHT22 Temperature from sending project
  Blynk.virtualWrite(V43, param.asFloat());
}

BLYNK_WRITE(V44) { // Solar DHT22 Humidity from sending project
  Blynk.virtualWrite(V44, param.asFloat());
}

BLYNK_WRITE(V47) { // Solar Panel Current from sending project
  Blynk.virtualWrite(V47, param.asFloat());
}

BLYNK_WRITE(V48) { // Solar Battery Voltage from sending project
  Blynk.virtualWrite(V48, param.asFloat());
}

NOTE: When initiating the bridges, you can use any name and available (unused) vPin on the “transmitter” project’s side… but each separately defined bridge (AKA for seperate MCUs) does need a different vPin.

These "holding’ vPins are NOT the same as whatever vPins you are trying to control on the receiving side… so there is NO need to make them the same unless you really like it that way…

For example…

WidgetBridge MyNodeMCU(V125); //  Initiating Bridge Widget on V125 (this is just as holding pin for the bridge, can be any unused vPin and each bridge needs its own)

WidgetBridge MyWemos(V126); //  Initiating Bridge Widget on V126 (this is just as holding pin for the bridge, can be any unused vPin and each bridge needs its own)

WidgetBridge MyUNO(V127); //  Initiating Bridge Widget on V127 (this is just as holding pin for the bridge, can be any unused vPin and each bridge needs its own)
BLYNK_CONNECTED() {
  MyNodeMCU.setAuthToken("AuthToken of NodeMCU"); // Token of the hardware A
  MyWemos.setAuthToken("AuthToken of Wemos"); // Token of the hardware B
  MyUNO.setAuthToken("AuthToken of UNO"); // Token of the hardware C
}
BLYNK_WRITE(V0) {
  MyNodeMCU.virtualWrite(V3, param.asInt()); // take the state of this transmitting MCU's virtual V0 button and send it to the receiving MCU's V3 vPin
}

BLYNK_WRITE(V1) { 
  MyWemos.virtualWrite(V8, param.asInt()); // take the state of this transmitting MCU's virtual button on V1 and send it to the receiving MCU's V8 vPin
}

BLYNK_WRITE(V2) { 
  MyUNO.digitalWrite(13, param.asInt()); // take the state of this transmitting MCU's virtual button on V2 and send it to the receiving MCU's GPIO13
}
9 Likes

#12 - Timers simplified… perhaps… :slight_smile:

Some have a difficult time understanding timers… and since this is a fundamental building block of Blynk… I buried this reference in the middle of this entire topic :innocent: Well anyhow…

This is a “real world” timer example where i am using two timers to alternately turn ON and OFF an LED… yes, there are many ways to do this, but this example is all about timers.

  • The first timer will run it’s assigned function 500ms (1/2 second) after bootup, and every 500ms after.

  • The second timer will run it’s assigned function 1000ms (1 second) after bootup and every 1000ms after

This in effect will cause the LED to blink ON and OFF every 1/2 second.

In this case I used both timers for the same LED action, but normally you would run one timer to run a function that flashes the LED on and off (we will look a various ways to do that later), while the 2nd would run a function that gets sensor data and sends it to the App… and so on.

I did it this way to show that you can have multiple timers running (up to 16 per instance)… in this case the instance is called timer… but could have easily been called blinker, flasher or fred… just be sure to declare the timer name and use it accordingly in the setup… E.g.

BlynkTimer fred;

fred.setInterval(500L, blinkMyLEDon); 

But for this example, lets stick with the name timer :wink:

NOTE Because both these timers initialize at the same time (at boot) it is important to stagger timers (more info below) enough to allow their associated functions to complete their task… otherwise you can get some interesting stuttering and lockups in your sketch.

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "xxxxxxxxxx";  // Token for Device A
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;

#define DeviceLED 2 // Built in LED for Wemos or NodeMCU v3, Or 16 for NodeMCU v1



void setup() {
  pinMode(DeviceLED, OUTPUT);
  WiFi.begin(ssid, pass);
  Blynk.config(auth, server, port);
  Blynk.connect();

  timer.setInterval(500L, blinkMyLEDon);  // This will call the Arduino Function 'void blinkMyLEDon()' every 500ms (1/2 second)

  timer.setInterval(1000L, blinkMyLEDoff);  // This will call the Arduino Function 'void blinkMyLEDoff()' every 1000ms (1 second)
}



void blinkMyLEDon() {
  digitalWrite(DeviceLED, LOW); // Turn ON built in LED (triggered LOW)
}

void blinkMyLEDoff() {
  digitalWrite(DeviceLED, HIGH); // Turn OFF built in LED (triggered LOW)
}



void loop() {
  Blynk.run();
  timer.run(); // This keeps checking the timers to see if then need to be processed
}

  • Latch & indicator Here is another example with the timers that, with a press of a button, you can trigger a relay on for 10 seconds, while flashing an indicator LED the entire time.

NOTE: This “time” :stuck_out_tongue_winking_eye: the timers are NOT initialized in the void setup() since they do not need to run all the time from boot. These timers setTimer() and setTimout() just run when called, and for as long as told to, and that is it.

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;
int Latch;
int Flag;
#define DeviceLED 2 // Built in LED for Wemos or NodeMCU v3, Or 16 for NodeMCU v1
#define LatchRelay 12 //  GPIO12 or D6

BlynkTimer timer;



void setup() {
  pinMode(DeviceLED, OUTPUT);
  pinMode(LatchRelay, OUTPUT);
  WiFi.begin(ssid, pass);
  Blynk.config(auth, server, port);
  Blynk.connect();
}



//===== LATCH(Relay) & LED PULSE - BLYNK Functions =====
BLYNK_WRITE(V0)  // Virtual button on V0 to activate Relay_LED pulses
{
  //Serial.println("Latch LED");
  Latch = param.asInt();
  if (Latch == 1 && Flag == 0) {
    Flag = 1;  // Keeps from allowing button press more then once while relay activated
    digitalWrite(LatchRelay, HIGH); // Activate Relay
    timer.setTimer(1000L, blinkMyLEDon, 10);  // Pulse LED routine (LedON/LedOFF) 10 times
    timer.setTimeout(10000L, RelayOFF);  // Deactivare Relay after 10 seconds
  }  // END if
}  // END Blynk Function

void RelayOFF() {
  digitalWrite(LatchRelay, LOW);
  Flag = 0;  // reset flag after relay disables
}  // END Function

void blinkMyLEDon() {
  digitalWrite(DeviceLED, LOW); // Turn ON built in LED (triggered LOW)
  timer.setTimeout(500L, blinkMyLEDoff);  // Run LED OFF routine once in 1/2 second
}  // END Function

void blinkMyLEDoff() {
  digitalWrite(DeviceLED, HIGH); // Turn OFF built in LED (triggered LOW)
}  // END Function



void loop() {
  Blynk.run();
  timer.run(); // This keeps checking the timers to see if then need to be processed
}

Staggering Timers:

Stagger the timers so that each one starts a little later then the prior one… but also giving its function time to complete.

Also try not to have timers match on alternating cycles… like a timer every 1 second another every 5 seconds and a third every 60 seconds… as some and/or all will eventually try to run at the same time every few cycles.

For example… eight timed functions, running all timers within 200 ms from start to finish, and repeating the process every second… assuming 20 ms is enough time for each function to complete its task before the next one runs…

  timer.setInterval(1000L, myFunction1);
  timer.setInterval(1020L, myFunction2);
  timer.setInterval(1040L, myFunction3);
  timer.setInterval(1080L, myFunction4);
  timer.setInterval(1100L, myFunction5);
  timer.setInterval(1120L, myFunction6);
  timer.setInterval(1140L, myFunction7);
  timer.setInterval(1160L, myFunction8);

NOTE: While each timer starts counting at the same time (as is the way it should be) , they run each of their respective first functions 20ms later then it’s predecessor, and thus each subsequent function call continues to run at a different time hence forth. any eventual overlap (because I am using evenly divisible timers in this example) is few and far between. I have actual projects running like this without issues.

You can test if 20ms is enough by having print statements at the beginning and end of each function… then if one function starts before the other ends, you will see the print statements out of order. Be aware that the print statements themselves will take a small amount of time to process.

If the actual time between individual timers is more important then having them all start at the same time (AKA they all MUST be one second intervals, but still not running at the same time), you can also stagger timers this way…

  timer.setInterval(1000L, myFunction1);
  delay(20);
  timer.setInterval(1000L, myFunction2);
  delay(20);
  timer.setInterval(1000L, myFunction3);
  delay(20);
  timer.setInterval(1000L, myFunction4);
  delay(20);
  timer.setInterval(1000L, myFunction5);
  delay(20);
  timer.setInterval(1000L, myFunction6);
  delay(20);
  timer.setInterval(1000L, myFunction7);
  delay(20);
  timer.setInterval(1000L, myFunction8);
8 Likes

#13 - The All-in-One Timer Function (AKA Lambda Function) - No, I don’t entirely understand it… but it works :stuck_out_tongue_winking_eye:

I like this for it’s relative simplicity… no separate function to call (or write in the code) I just copy/paste my most used into my new sketches…


in your pre-setup…

BlynkTimer timer;

And in your void setup()

  // Timed Lambda Function - UpTime counter
  timer.setInterval(1000L, []() {  // Run every second
    Blynk.virtualWrite(V0, millis() / 60000);  // Display the UpTime in Minutes
  });  // END Timer Function

  • Lambda routine for the DHT sensor. With the Lambda, you you can combine commands and even add in some logic, just like normal… just more compact. Here is a simple example…
    In your pre-setup…
#include <DHT.h>  // For DHT22
#define DHTPIN 0  // GPIO0(D3) on Wemos D1 Mini
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
float h, t;

And in your void setup()

  // Timed Lambda Function - DHT22 Temp & Humidity sensor
  timer.setInterval(300000L, []() {  // Run every 5 minutes
    h = dht.readHumidity();
    t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
    if (isnan(h) || isnan(t)) {  // Check if any reads failed and try once more this cycle.
      delay(250);  // short delay before recheck
      h = dht.readHumidity();
      t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
    }
    Blynk.virtualWrite(V1, h);  // Display Humidity
    Blynk.virtualWrite(V2, t);  // Display Temperature
  });  // END Timer Function
5 Likes

#14 - ESP32 - Alternate way to control PWM pins for Servos and/or LEDs

At the time of this posting, the ESP32 Arduino Core does not support the handy analogWrite() command. So how do we do the PWM dodo we want to do?

Well, a little G :eyes: gling later and I found a few different websites that describe in more detail then I will get into here. How profoundly customisable the ESP32 GPIO pins are :smiley:

First you need this library…

And here is just a couple of sites with usage examples…

Basicly the GPIO pins can be linked to 16 independent channels, with configurable duty cycles and wave periods. The accuracy of the duty cycle can be configured up to 16 bits of resolution.

I am using 50Hz and 16-bits for the Servo control. for my servo 2000-8000 was a good range in the settings, without pushing the limits of the servo.

And for the RGB LED I am using 5000Hz but only 8-bits to give the range of 0-255 in the settings

For those that like to visually see results right darn now!!.. here is a small project that you can use… and even if you don’t have a servo motor or a 4 lead RGB LED, you will see the results on the App (OK a Gauge Widget is a poor substitute for a Servo :blush: but the HEX data that shows the corresponding colour is useful)

image

//#define BLYNK_PRINT Serial // This prints to Serial Monitor

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

#include <ESPmDNS.h>  // For OTA - ESP32
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

#include "esp32-hal-ledc.h" // For Servo & RGB PWM control

char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";  // URL for Blynk Cloud Server
int port = 8080;

int rrr, ggg, bbb;  // Set RED BLUE GREEN channe
int ServoPos;



void setup() {
  //Serial.begin(115200);  // BLYNK_PRINT data

  //===== Servo pin setup for ESP32 =====
  ledcSetup(1, 50, 16); // For Servo - channel 1, 50 Hz, 16-bit width
  ledcAttachPin(2, 1);   // For Servo - GPIO 2 assigned to channel 1

  //===== RGB LED pin setup for ESP32 =====
  ledcSetup(2, 5000, 8); // For RGB-Red - channel 2, 5000 Hz, 8-bit width
  ledcAttachPin(25, 2);   // For RGB-Red - GPIO 25 assigned to channel 2

  ledcSetup(3, 5000, 8); // For RGB-Green - channel 3, 5000 Hz, 8-bit width
  ledcAttachPin(27, 3);   // For RGB-Green - GPIO 27 assigned to channel 3

  ledcSetup(4, 5000, 8); // For RGB-Blue - channel 4, 5000 Hz, 8-bit width
  ledcAttachPin(26, 4);   // For RGB-Blue - GPIO 26 assigned to channel 4


  WiFi.begin(ssid, pass);
  Blynk.config(auth, server, port);
  Blynk.connect();

  ArduinoOTA.setHostname("ESP32 Servo RGB");  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA
}



//===== Servo Control Widgets =====
BLYNK_WRITE(V1) {  // Slider for selective servo positioning
  ServoPos = param.asInt();  // Get position data
  ledcWrite(1, ServoPos);  // Move servo to position
  Blynk.virtualWrite(V0, ServoPos);  // Display servo position
  Blynk.virtualWrite(V5, ServoPos);  // Show servo position
}  // END Blynk Function


BLYNK_WRITE(V2) {  // Button for servo endstop positioning
  ServoPos = param.asInt();  // Get position data (pre set in MIN/MAX settings
  ledcWrite(1, ServoPos);  // Move servo to position
  Blynk.virtualWrite(V0, ServoPos);  // Display servo position
  Blynk.virtualWrite(V5, ServoPos);  // Show servo position
  Blynk.virtualWrite(V1, ServoPos);  // Sync slider position
}  // END Blynk Function



//===== zeRGBa Widget =====
BLYNK_WRITE(V4) { // START Blynk Function
  rrr = param[0].asInt(); // get a RED channel value
  ggg = param[1].asInt(); // get a GREEN channel value
  bbb = param[2].asInt(); // get a BLUE channel value
  RGBprocess(); // Run Arduino funtion
}  // END Blynk Function


//===== Physical RGB LED Control and HEX conversion =====
void RGBprocess() {  // START Arduino funtion

  // For Common Anode+ RGB LED
  ledcWrite(2, 256 - rrr); // Write to RED RGB pin
  ledcWrite(3, 256 - ggg); // Write to GREEN RGB pin
  ledcWrite(4, 256 - bbb); // Write to BLUE RGB pin

  // For Common Cathode- RGB LED
  //  ledcWrite(2, rrr); // Write to RED RGB pin
  //  ledcWrite(3, ggg); // Write to GREEN RGB pin
  //  ledcWrite(4, bbb); // Write to BLUE RGB pin

  // zeRGBa pin to #HEX conversion
  String strRED = String(rrr, HEX);  // Convert RED DEC to HEX
  if (rrr < 16) {
    strRED = String("0" + strRED);  // Buffer with 0 if required
  }  // END if
  String strGRN = String(ggg, HEX);  // Convert GREEN DEC to HEX
  if (ggg < 16)  {
    strGRN = String("0" + strGRN);  // Buffer with 0 if required
  }  // END if
  String strBLU = String(bbb, HEX);  // Convert BLUE DEC to HEX
  if (bbb < 16)  {
    strBLU = String("0" + strBLU);  // Buffer with 0 if required
  }  // END if
  String HEXstring = String("#" + strRED + strGRN + strBLU);  // Combine HEX fragments
  HEXstring.toUpperCase();  // Change HEX value to all upper case for ease of visuals.
  Blynk.setProperty(V3, "color", HEXstring);  // Change background colour of HEX Data Label
  Blynk.virtualWrite(V3, HEXstring);  // Display HEX data
}  // END Arduino Function



void loop() {
  Blynk.run();
  ArduinoOTA.handle();  // For OTA
}
6 Likes

#15 - Dual Blynk sliders for High Range High Precision values

And for all those precision slider fanatics who want their cake and eat it too (PS the cake is a lie :wink: )…

I introduce the solution for High Range AND High Precision using only sliders (no ugly step widgets for analog purists :stuck_out_tongue: ) Good luck trying to do both with a single slider.

int FullRange;
float Precision;

BLYNK_WRITE(V0) {  // Higher Range slider 0 to 255
  Blynk.virtualWrite(V1, 0);  // Zero out Precision slider
  FullRange = param.asInt();
  Blynk.virtualWrite(V2, FullRange);  // Display widget
}

BLYNK_WRITE(V1) {  // High Precision slider -0.99 to 0.99
  Precision = param.asFloat();
  Blynk.virtualWrite(V2, FullRange + Precision);  // Display widget
}

image

image

image

image

10 Likes

#16 - Ultrasonic Distance Sensor with Servo

This little project used the HC-SR04 Ultrasonic sensor… but instead of boring old distance numbers, it will also position a servo within a range of selected distances.

This sketch demonstrates a timer that can be enabled and disabled, so as not to be running something like the Ultrasonic sensor if other critical timing functions need to run.

And also demonstrates enabling and disabling the servo, so that there is no jitter or fluttering when it is not supposed to be moving, as can sometimes be caused by other timer routines.

Sensor and Servo need 5v, so best to draw from a separate 5v PSU than the Wemos’s 5v pin… particularly for the servo.

Wire the sensor and servo pins as shown in the sketch.

int trigPin = 12;  // D5 on Wemos D1 Mini
int echoPin = 13;  // D6 on Wemos D1 Mini
int servoPin = 4;  // D2 on Wemos D1 Mini

As a precaution, I wired a 1K resistor in series between the ECHO pin of the sensor and Pin 13 (D7) of the Wemos… this drops the current potential down, so that the 5v signal will not hurt the Wemos.

//#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

#include <Servo.h>

char auth[] = "xxxxxxxxxx";  // Local Server
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";
int port = 8080;

int trigPin = 12;  // D5 on Wemos D1 Mini
int echoPin = 13;  // D6 on Wemos D1 Mini
int servoPin = 4;  // D2 on Wemos D1 Mini

int PingTimer; // TimerID
int SrvoPos;  // Servo position
long duration, distance;  // For Ping sensor 

BlynkTimer timer;
Servo myservo;



void setup() {
  //Serial.begin(115200);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(servoPin, OUTPUT);

  WiFi.begin(ssid, pass);
  Blynk.config(auth, server, port);
  Blynk.connect();

  // ===== Timer Setup =====
  PingTimer = timer.setInterval(250L, PingSensor);  // Ping distance routine - Button Controlled
  timer.disable(PingTimer);  // Disable timer until needed

  ArduinoOTA.setHostname("Wemos D1 Mini");  // For OTA - Use your own device identifying name
  ArduinoOTA.begin();  // For OTA
}



BLYNK_CONNECTED() {
    Blynk.syncVirtual(V2)
}



void loop() {
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
  ArduinoOTA.handle();  // For OTA
}



BLYNK_WRITE(V2) { // Button to Enable/Disable Ultrasonic Sensor Routine
  if (param.asInt() == 1) {  // If button state is 1 (HIGH) then...
    timer.enable(PingTimer);  // Enable timer
    myservo.attach(servoPin);  // Connect survo
  } else {  // If button state is 0 (LOW) then...
    timer.disable(PingTimer);  // Disable timer
    myservo.write(5);  // Set servo at 0 position
    Blynk.virtualWrite(V1, 0);  // Reset Gauge for servo position
    Blynk.virtualWrite(V0, "N/A");  // Reset Display for Ultrasonic Sensor status
    delay(500);  // Small delay to allow servo reposition before disabling it.
    myservo.detach();  // Disconnect survo
  }
}



void PingSensor() {  // Ultrasonic (Ping) Distance Sensor
    // Pulse
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // End Pulse & Calculate didtance
    duration = pulseIn(echoPin, HIGH);
    distance = (duration / 2) / 29.1;

    // Map and constrain the Ultrasonic range 1-50cm to the servo position of 10-160
    SrvoPos = constrain(map(distance, 1, 50, 10, 160), 10, 160);  

    // Show results
    myservo.write(SrvoPos);  // Position servo
    Blynk.virtualWrite(V0, distance);  // To Display Widget
    Blynk.virtualWrite(V1, SrvoPos);  // To Gauge Widget
}
5 Likes

#17 - Dual Temperature Sensors running on ESP-01

This is a simple example of running both a DHTxx (in this case DHT11) and DS18B20 1-wire sensors on the lowly ESP-01

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

char auth[] = "xxxxxxxxxx";  // Local Server
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx";  // IP for your Local Server
char server[] = "blynk-cloud.com";
int port = 8080;

BlynkTimer timer;

// DHT22 Sensor setup
#include <DHT.h>
#define DHTPIN 0  // GPIO0 - pin5 on ESP-01
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float h;
float t;

// DS18B20 Sensor setup
#include <OneWire.h>
#include<DallasTemperature.h>
#define ONE_WIRE_BUS 2  // GPIO2 - pin3 on ESP-01
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float DS18B20Temp;




void setup()
{
  DS18B20.begin();

  Blynk.connectWiFi(ssid, pass);
  Blynk.config(auth, server, 8080);
  Blynk.connect();

  timer.setInterval(1000L, UpTime);
  timer.setInterval(60000L, DS18B20TempSensor);
  timer.setInterval(10050L, DHTTempHumSensor);

  Blynk.virtualWrite(2, BLYNK_VERSION);
  Blynk.virtualWrite(6, ESP.getCoreVersion());

  ArduinoOTA.setHostname("ESP-01 Multi-temp");  // For OTA
  ArduinoOTA.begin();  // For OTA
}



void DS18B20TempSensor()  // DS18B20 sensor reading
{
  DS18B20.requestTemperatures();
  delay(500);  // Yes, the evil delay... but only for a really short time every 10s .  Alternative options are avail with timers.
  Blynk.virtualWrite(V3, DS18B20.getTempCByIndex(0));
}



void DHTTempHumSensor()  // DHT sensor reading
{
  h = dht.readHumidity();
  t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit
  Blynk.virtualWrite(V4, h);
  Blynk.virtualWrite(V5, t);
}



BLYNK_WRITE(V1) {  // Quick test read.  Clears all values and reloads
  if (param.asInt()) {
    Blynk.virtualWrite(V0, 0);
    Blynk.virtualWrite(V3, 0);
    Blynk.virtualWrite(V4, 0);
    Blynk.virtualWrite(V5, 0);
    DS18B20TempSensor();
    DHTTempHumSensor();
  }
}



void UpTime()
{
  Blynk.virtualWrite(V0, millis() / 1000);
  Blynk.virtualWrite(V7, WiFi.RSSI());
}



void loop()
{
  Blynk.run();
  timer.run();
  ArduinoOTA.handle();  // For OTA
}
8 Likes

#18 - Multi Colour Button, one color for ON one for OFF

NOTE - This has been rendered obsolete with the new Styled Button :+1:


The button (in switch mode) is essentially ON all the time, but pressing it toggles a variable (buttonState) between 0 & 1 so you can still control things outside the Blynk Function if you want.

You can also change the small labeling… However, there is no current way, that I am aware of, to change the buttons center text from within code.

You can make both ON and OFF colours whatever you want… just use my zeRGBa examples above to get the #HEX code you need for the colour you want.

In pre-setup…

int buttonToggle = 1;  // Set buttonToggle to 1 to start buttonState in OFF mode
int buttonState = 0;  // Set buttonState variable OFF

In setup after connection…

Blynk.virtualWrite(V0, 1); // set coloured button to default ON state
BLYNK_WRITE(V0) {
  if (param.asInt() == 0 && buttonToggle == 1) {
    buttonToggle = 0;
    buttonState = 1;
    Blynk.setProperty(V0, "color", "#23C48E"); // GREEN
    Blynk.setProperty(V0, "label", "ON"); // ON
  } else if (param.asInt() == 0 && buttonToggle == 0) {
    buttonToggle = 1;
    buttonState = 0;
    Blynk.setProperty(V0, "color", "#D3435C"); // RED
    Blynk.setProperty(V0, "label", "OFF"); // OFF
  }
  Blynk.virtualWrite(V1, buttonState);  // Display buttons usable state
  Blynk.virtualWrite(V0, 1);  // reset button widget to ON
}

5 Likes

A post was merged into an existing topic: Blynk.setProperty() command not changing button color

A post was split to a new topic: How to repeat the same activity or stop the activity form a function that is called by a BLYNK_WRITE(V?) function