Blynk Legacy to Blynk 2.0 for ESP8266 and CNC Shield

Hi all,

Please bear with me as this is my first post and I am new to forum. I haven been working on a project that uses an ESP8266 NodeMCU, CNC Shield, 2 A4988 drivers with 2 NEMA 17s. The goal is to be able to control X and Y motor directions with the joystick on the mobile dashboard. I was able to find an old set of codes for the Blynk Legacy app, but due to issues with the SimpleTimer library I was not able to compile on Arduino IDE. After spending some time with the forum I understand that Blynk does not like the “delay” commands as it stops the MCU from communication with the cloud server? I’ve looked at some FAQs, but none of them seem to easily integrate to my project. What would be the best way to go at fixing this sketch so it can control the 2 NEMA 17s? Thank you for your time.

Jeff


/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

/* Fill-in your Template ID (only if using Blynk.Cloud) */
#define BLYNK_TEMPLATE_ID "*****"
#define BLYNK_DEVICE_NAME "****"
#define BLYNK_AUTH_TOKEN "*****"



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

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "*****";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "******";
char pass[] = "*****";

// X Stepper Motor
int XstepPin = D1; 
int XdirPin  = D2; 
int limitx = 200; // X stepper motor limit
int speedx = 500; 
 
// Y Stepper Motor
int YstepPin = D3; 
int YdirPin  = D4; 
int speedy = 500; 
int Movey = 512; // value from blynk joystick "default value"
 
 
// Manual control X stepper motor
int vresistor = A0; 
int vrdata = 0; 

 
int pinValue1;
int pinValue2;
int pinValue3;
int pinValue4;
 
 
int firstVal, secondVal,thirdVal; // sensors 
// This function sends Arduino's up time every second to Virtual Pin (1).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void myTimerEvent()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V1, millis() / 1000);
}

void setup()
{
  // Debug console
  Serial.begin(115200);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
}

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

// From Blynk application to Nodemcu ESP8266
 
// in Blynk app writes values to the Virtual Pin V2
BLYNK_WRITE(V2) // X stepper Motor limits
{
   pinValue1 = param.asInt(); // assigning incoming value from pin V2 to a variable
   limitx = pinValue1; 
  
}
 
BLYNK_WRITE(V3) // X stepper Motor Speed
{
   pinValue2 = param.asInt(); 
   speedx = pinValue2; 
  
}
 
BLYNK_WRITE(V5) // Y Stepper motor control
{
   pinValue3 = param.asInt(); 
   Movey = pinValue3; 
}

void StepperMotor()
{
  if( digitalRead(D6) == 1 )
  {
   digitalWrite(XdirPin,HIGH); // Enables the motor to move in a particular direction
 for(int x = 0; x < limitx; x++) {
 digitalWrite(XstepPin,HIGH); 
 delayMicroseconds(speedx); 
 digitalWrite(XstepPin,LOW); 
 delayMicroseconds(speedx); 
 }
 delay(500); // half second delay
 
 digitalWrite(XdirPin,LOW); //Changes the rotations direction
 for(int x = 0; x < limitx; x++) {
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
 }
 delay(500);
}
 
 
}
void StepperMotorY()
{
 
    if( digitalRead(D6) == 0 )
  {
    vrdata = analogRead(vresistor); 
 
    if ( vrdata < 100 )
    {
 digitalWrite(XdirPin,LOW);
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
    }
 
        if ( vrdata > 900 )
    {
 digitalWrite(XdirPin,HIGH);
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
    }
  if ( Movey > 512 )
  {
 digitalWrite(YdirPin,HIGH); // Enables the motor to move in a particular direction
 digitalWrite(YstepPin,HIGH); 
 delayMicroseconds(speedy); 
 digitalWrite(YstepPin,LOW); 
 delayMicroseconds(speedy); 
 
  }

    if ( Movey < 512 )
  {
   digitalWrite(YdirPin,LOW); // Enables the motor to move in a particular direction
 digitalWrite(YstepPin,HIGH); 
 delayMicroseconds(speedy); 
 digitalWrite(YstepPin,LOW); 
 delayMicroseconds(speedy); 
  }
 
  }
}
 

An improved version of SimpleTimer, called BlynkTimer, is built in to the the Blynk library, so there is no need to use SimpleTimer with Blynk.

You might want one read this…

Pete.

So in order to fix the below example sketch, “#include <SimpleTimer.h>” can be taken out as BlynkTimer is built into the Blynk library (which is declared “#include <BlynkSimpleEsp8266.h>”) . All “delays()” and “delayMicroseconds(speedx)” can be replaced with "timer.setTimeout(speedx , " etc.? Am I following the FAQ you posted correctly? Thank you for your help.

 * X.step = D1
 * X.DIR = D2
 * Y.Step = D3
 * Y.DIR = D4
 */
#define BLYNK_PRINT Serial


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

char auth[] = "Yz558gb7lZmylfta71ZrxtszvVFPWgYT";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "ZONG MBB-E8231-6E63";
char pass[] = "08659650";

// X Stepper Motor
int XstepPin = D1; 
int XdirPin  = D2; 
int limitx = 200; // X stepper motor limit
int speedx = 500; 

// Y Stepper Motor
int YstepPin = D3; 
int YdirPin  = D4; 
int speedy = 500; 
int Movey = 512; // value from blynk joystick "default value"


// Manual control X stepper motor
int vresistor = A0; 
int vrdata = 0; 
SimpleTimer timer;

int pinValue1;
int pinValue2;
int pinValue3;
int pinValue4;


int firstVal, secondVal,thirdVal; // sensors 
// This function sends Arduino's up time every second to Virtual Pin (1).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void myTimerEvent()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V1, millis() / 1000);
  
}



void setup()
{
  // Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode(XstepPin,OUTPUT); 
  pinMode(XdirPin, OUTPUT); 
    pinMode(YstepPin,OUTPUT); 
  pinMode(YdirPin, OUTPUT); 
  pinMode(vresistor, INPUT); 
  timer.setInterval(4000L, StepperMotor); 
    timer.setInterval(300L, StepperMotorY); 


}

void loop()
{

  timer.run(); // Initiates SimpleTimer
  Blynk.run();
}



// From Blynk application to Nodemcu ESP8266

// in Blynk app writes values to the Virtual Pin V2
BLYNK_WRITE(V2) // X stepper Motor limits
{
   pinValue1 = param.asInt(); // assigning incoming value from pin V2 to a variable
   limitx = pinValue1; 
  
}

BLYNK_WRITE(V3) // X stepper Motor Speed
{
   pinValue2 = param.asInt(); 
   speedx = pinValue2; 
  
}

BLYNK_WRITE(V5) // Y Stepper motor control
{
   pinValue3 = param.asInt(); 
   Movey = pinValue3; 
  
}

void StepperMotor()
{
  if( digitalRead(D6) == 1 )
  {
   digitalWrite(XdirPin,HIGH); // Enables the motor to move in a particular direction
 for(int x = 0; x < limitx; x++) {
 digitalWrite(XstepPin,HIGH); 
 delayMicroseconds(speedx); 
 digitalWrite(XstepPin,LOW); 
 delayMicroseconds(speedx); 
 }
 delay(500); // half second delay
 
 digitalWrite(XdirPin,LOW); //Changes the rotations direction
 for(int x = 0; x < limitx; x++) {
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
 }
 delay(500);
}


}

void StepperMotorY()
{

    if( digitalRead(D6) == 0 )
  {
    vrdata = analogRead(vresistor); 

    if ( vrdata < 100 )
    {
 digitalWrite(XdirPin,LOW);
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
    }

        if ( vrdata > 900 )
    {
 digitalWrite(XdirPin,HIGH);
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
    }
  if ( Movey > 512 )
  {
 digitalWrite(YdirPin,HIGH); // Enables the motor to move in a particular direction
 digitalWrite(YstepPin,HIGH); 
 delayMicroseconds(speedy); 
 digitalWrite(YstepPin,LOW); 
 delayMicroseconds(speedy); 

  }

    if ( Movey < 512 )
  {
   digitalWrite(YdirPin,LOW); // Enables the motor to move in a particular direction
 digitalWrite(YstepPin,HIGH); 
 delayMicroseconds(speedy); 
 digitalWrite(YstepPin,LOW); 
 delayMicroseconds(speedy); 
  }
 
  }
} ```

Correct. You also need to change:

to:

BlynkTimer timer;

Not exactly.
BlynkTimer works in milliseconds, not microseconds. however, a 500 microsecond delay won’t cause any issues with Blynk.

Also, the whole idea of using BlynkTimer or SimpleTimer is that they are non-blocking - they don’t block other code execution once they are triggered.
So, if you want to wait x milliseconds before doing the next action then you’ll need to use a lambda timeout timer, with the next action to be performed inside the lambda function.
This could lead to cascaded lambda timers though!

Also, I think you might need to give some thought to exactly how Blynk is used in this sketch.
Processes like CNC, 3D Printing, Laser engraving etc rely on critical timing.
Blynk also complains if it isn’t given access to processor time on a regular basis, and the two can be conflicting.
If you wanted to use Blynk to input some parameters then start a CNC process running then you might be better disconnecting from Blynk and allowing the device to be 100% CNC focussed, then re-connect to Blynk once the CNC operation has finished.
I guess it depends on your aims, and on how critical the CNC operations are.

Another option is to use an ESP32 and use multi-threading, with the Blynk operations running on one core and the CNC on another.

Pete.

I edited the code to what it is below. It compiled and uploaded without any hiccups. The device show online. Now, I think my issue is with setting up the datastreams for the joystick. For the joystick on the mobile dashboard, I have set up two datastreams for X and Y. X is Virtual Pin 4, Double, #, and Min/Max 0/1023. Y is Virtual Pin 5, Double, #, and Min/Max 0/1023. For “limit” slider I have Virtual Pin 2, Double, #, Min/Max 0/200. For “speed” slider I have Virtual Pin 3, Double, #, Min/Max 400/300. I’m not getting any responses to my motors. I’m not sure how to reply to certain parts of your posts, but in regards to the CNC and 3D printing, I’m just using the motors to control a little Nerf gun turret toy, nothing for CNC operations.

Thanks

Jeff

/*
 * X.step = D1
 * X.DIR = D2
 * Y.Step = D3
 * Y.DIR = D4
 */
 
#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "***"
#define BLYNK_DEVICE_NAME "***"
#define BLYNK_AUTH_TOKEN "***"

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




char auth[] = "***";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "***";
char pass[] = "***";

// X Stepper Motor
int XstepPin = D1; 
int XdirPin  = D2; 
int limitx = 200; // X stepper motor limit
int speedx = 500; 

// Y Stepper Motor
int YstepPin = D3; 
int YdirPin  = D4; 
int speedy = 500; 
int Movey = 512; // value from blynk joystick "default value"


// Manual control X stepper motor
int vresistor = A0; 
int vrdata = 0; 
BlynkTimer timer;

int pinValue1;
int pinValue2;
int pinValue3;
int pinValue4;


int firstVal, secondVal,thirdVal; // sensors 
// This function sends Arduino's up time every second to Virtual Pin (1).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void myTimerEvent()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V1, millis() / 1000);
  
}



void setup()
{
  // Debug console
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode(XstepPin,OUTPUT); 
  pinMode(XdirPin, OUTPUT); 
  pinMode(YstepPin,OUTPUT); 
  pinMode(YdirPin, OUTPUT); 
  pinMode(vresistor, INPUT); 
  timer.setInterval(4000L, StepperMotor); 
  timer.setInterval(300L, StepperMotorY); 


}

void loop()
{

  timer.run(); // Initiates SimpleTimer
  Blynk.run();
}



// From Blynk application to Nodemcu ESP8266

// in Blynk app writes values to the Virtual Pin V2
BLYNK_WRITE(V2) // X stepper Motor limits
{
   pinValue1 = param.asInt(); // assigning incoming value from pin V2 to a variable
   limitx = pinValue1; 
  
}

BLYNK_WRITE(V3) // X stepper Motor Speed
{
   pinValue2 = param.asInt(); 
   speedx = pinValue2; 
  
}

BLYNK_WRITE(V5) // Y Stepper motor control
{
   pinValue3 = param.asInt(); 
   Movey = pinValue3; 
  
}

void StepperMotor()
{
  if( digitalRead(D6) == 1 )
  {
   digitalWrite(XdirPin,HIGH); // Enables the motor to move in a particular direction
 for(int x = 0; x < limitx; x++) {
 digitalWrite(XstepPin,HIGH); 
 delayMicroseconds(speedx); 
 digitalWrite(XstepPin,LOW); 
 delayMicroseconds(speedx); 
 }
 delayMicroseconds(500); 
 
 digitalWrite(XdirPin,LOW); //Changes the rotations direction
 for(int x = 0; x < limitx; x++) {
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
 }
 delayMicroseconds(500);
}


}

void StepperMotorY()
{

    if( digitalRead(D6) == 0 )
  {
    vrdata = analogRead(vresistor); 

    if ( vrdata < 100 )
    {
 digitalWrite(XdirPin,LOW);
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
    }

        if ( vrdata > 900 )
    {
 digitalWrite(XdirPin,HIGH);
 digitalWrite(XstepPin,HIGH);
 delayMicroseconds(speedx);
 digitalWrite(XstepPin,LOW);
 delayMicroseconds(speedx);
    }
  if ( Movey > 512 )
  {
 digitalWrite(YdirPin,HIGH); // Enables the motor to move in a particular direction
 digitalWrite(YstepPin,HIGH); 
 delayMicroseconds(speedy); 
 digitalWrite(YstepPin,LOW); 
 delayMicroseconds(speedy); 

  }

    if ( Movey < 512 )
  {
   digitalWrite(YdirPin,LOW); // Enables the motor to move in a particular direction
 digitalWrite(YstepPin,HIGH); 
 delayMicroseconds(speedy); 
 digitalWrite(YstepPin,LOW); 
 delayMicroseconds(speedy); 
  }
 
  }
}

I’m not really clear about what your sketch is meant to do.

You appear to be doing a digitalRead on pin D6, but it doesn’t have a pinMode statement declaring it as an INPUT, and I have no idea what D6 is connected to.

You’re using timers to call StepperMotor and StepperMotorY, but I’m not clear why they aren’t called by the joystick BLYNK_WRITE routines.

The BLYNK_WRITE routines are very messy,

would be better written as this:

BLYNK_WRITE(V2) // X stepper Motor limits
{
   limitx = param.asInt(); // assigning incoming value from pin V2 to a variable
}

You’re doing something with a variable resistor attached to pin A0, but I have no idea what this is for.

I’d suggest that you tidy-up your code and add some narrative about how it’s meant to work.

Pete.