Stepper motor control using WEMOS D1 mini pro + DRV8834

I have done my first stepper motor controller using WEMOS D1 mini pro + DRV8834 Low-Voltage Stepper Motor Driver Carrier

Because it is not possible to user the timer interrupt library I need to find a other solution.
May be it some one find this helpful for his project.

/**************************************************************
   Blynk is a platform with iOS and Android apps to control
   Arduino, Raspberry Pi and the likes over the Internet.
   You can easily build graphic interfaces for all your
   projects by simply dragging and dropping widgets.

     Downloads, docs, tutorials: http://www.blynk.cc
     Blynk community:            http://community.blynk.cc
     Social networks:            http://www.fb.com/blynkapp
                                 http://twitter.com/blynk_app

   Blynk library is licensed under MIT license
   This example code is in public domain.

 **************************************************************
   This example runs directly on ESP8266 chip.
   Used Hardware: 
   WEMOS D1 mini pro + DRV8834 Low-Voltage Stepper Motor Driver Carrier

   Note: This requires ESP8266 support package:
     https://github.com/esp8266/Arduino

   Please be sure to select the right ESP8266 module
   in the Tools -> Board menu!

   Change WiFi ssid, pass, and Blynk auth token to run :)

 **************************************************************/

//#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#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 auth";

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

//*****************************************************
#define DIR_PIN D0
#define STEP_PIN D3
#define ENABLE_PIN D4
#define DISABLE     HIGH
#define ENABLE      LOW
#define int_period 500L // [µsec] time to next interrupt
#define m_step_count_down_time 4 // m_step_count_down_time*int_period[msec] count down timer to disable motor driver minimum time the stepper needs to perform one step keep it low to save current
//********************************************************
int     steps = 0;      // # of steps to be performed
int Periode   = 2000;   // [µsec] !!!  period time to next step
int Next_Step = Periode;// [µsec] !!!  count down timer current step
int m_step_count_down = 0;//[0,5msec]!!!  count down timer to disable motor driver
int RUN=LOW ; //if set t0 HIGH the motor will run for ever
void setup()
{ Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  pinMode (ENABLE_PIN , OUTPUT);
  digitalWrite(ENABLE_PIN, DISABLE); // disable motor driver_2
  pinMode (STEP_PIN , OUTPUT);
  digitalWrite(STEP_PIN, LOW);
  pinMode (DIR_PIN , OUTPUT);
  noInterrupts();
  timer0_isr_init();
  timer0_attachInterrupt(timer0_ISR);
  timer0_write(ESP.getCycleCount() + 80000000L); // 80MHz == 1sec
  interrupts();
}

void loop()
{
  Blynk.run();
  if(RUN==HIGH)steps=100; // Run for ever
}

BLYNK_WRITE(V1)
{
  Periode = param.asInt() ; // assigning incoming value from pin V1 to a variable
  if (Periode<int_period)   Serial.printf("Error Periode lower than int_period  ");
  Next_Step = Periode;
}

BLYNK_WRITE(V2)
{
  steps = param.asInt();// assigning incoming value from pin V2 to a variable
}


BLYNK_WRITE(V3)
{
  RUN = param.asInt(); // assigning incoming value from pin V3 to a variable
}

void timer0_ISR (void)
{
  timer0_write(ESP.getCycleCount() + int_period * 80 ); //40000L); // 80MHz == int_period[msec]
  if (m_step_count_down-- <= 1) digitalWrite(ENABLE_PIN, DISABLE); // disable motor driver when step is performed

  if (steps > 0) // are there steps to be performed ?
  {
    Next_Step -= int_period ; // [µs];
    if (Next_Step <= Periode) //[µsec]period time to next step
    {
      digitalWrite(ENABLE_PIN, ENABLE); // enable motor driver 
      Next_Step += Periode;  //    Next_Step = Next_Step + Periode;
      digitalWrite( STEP_PIN, LOW);
      steps--; // it will decrement two times when performing one single step
      m_step_count_down = m_step_count_down_time ; // m_step_count_down_time*int_period[msec] count down timer to disable motor driver
      digitalWrite( STEP_PIN, HIGH);// perform one step
    }
  }
}

2 Likes

How to post code is covered at In case you see SMTHNG strange in Blynk

1 Like

hello!

my question is not strictly related to blynk. but you mention that [quote=“Brummer, post:1, topic:10562”]
it is not possible to use the timer interrupt library
[/quote]

what do you mean by that?
i’m very beginner with the wemos stuff, but i experienced and read on other forums, that the interrupts are not compatible with wemos wifi. i mean, if i use wifi and interrupts in the same time, it can cause system reset or other undesired behavior.

in my application i need to monitor in real time 2 reed relays (it is a device for special bikes. one sensor is to measure speed and distance, the other one is to monitor the cranks position)

also, i need to display lots of values on the phone, via blynk app. so i can not disable the wifi, nor the interrupts. what is the solution?

thank you!

Hi,
As I know the arduino timer one library is not usable on D1 mini.
Interrupts are usable on D1 mini.
As mentioned here:
All of the IO pins have interrupt/pwm/I2C/one-wire support except D0
https://www.wemos.cc/product/d1-mini-pro.html#

i think youre right, maybe not the interrupt was the problem, but some delays, used to turn a stepper motor…

from here: https://github.com/esp8266/Arduino/blob/master/doc/reference.md

“Remember that there is a lot of code that needs to run on the chip besides the sketch when WiFi is connected. WiFi and TCP/IP libraries get a chance to handle any pending events each time the loop() function completes, OR when delay is called. If you have a loop somewhere in your sketch that takes a lot of time (>50ms) without calling delay, you might consider adding a call to delay function to keep the WiFi stack running smoothly.”

In my example the interrupt runs at 500µsec = 0.5msec !
WIFI and Blynk are running in the main loop.
There is enough reserve to to run the motor close to 2kHz
And to do some blynk sliders and buttons.

I´m not family with the D1 mini but learning a lot with the assistance of this great forum

The interrupt routine MUST be as short as possible to give all the other stuff enough resources to do their job.
Do not use time excessive tasks with in the ISR
avoid Serial.print with in the ISR

1 Like

Hello everybody!
Please let me ask a stupid question as to why timer0_write (ESP.getCycleCount () + 80000000L); // 80MHz == 1sec
(80MHz == 1sec?) Please direct, thanks everyone.

My best guess is because…

Thus the OP apparently used an alternative method to count seconds based on that MCU’s native clock speed of 80MHz

https://wiki.wemos.cc/products:d1:d1_mini_pro

1 Like

Thank you for answering my question!
T = 1 / f = 1 / 80Mhz = 12.5 ns
Timer_0 is 8 bit?

  • timer0 is a special CPU timer that has very high resolution but with limited control.
  • It uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter.
  • It does not support divide, type, or reload flags
  • It is auto-disabled when the compare value matches CCOUNT
  • It is auto-enabled when the compare value changes
    It takes about 80 * 10 ^ 6 cycles to call the ISR corresponding to 1s