Help with Wemos D1 Motor shield project

Hi, I’m hoping this is something obvious that I’m missing but I can’t see why this isn’t working for me.

I was inspired by another project to make a motorised pet feeder. The original is here: http://home.btconnect.com/brettoliver1/Cat_Feeder/Pet_Feeder.htm

Mine is not as complex, theres no video feed and I’m using a simple DC motor not a stepper.

The problem: I have a command to the motor telling it to activate. Then theres a setTimeout calling a command for it to stop. The function the motor command is in IS being called as I the serial.prints are coming through. If I take the motor on instruction and put it in void loop, it works.

I know the varTimer = pinValue is probably wrong but it was a way of taking the integer from one virtual pin and using it another function. The idea being the slider will define the timeout period.



/*************************************************************
  Download latest Blynk library here:
    https://github.com/blynkkk/blynk-library/releases/latest

  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
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  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 sketch shows how to read values from Virtual Pins

  App project setup:
    Slider widget (0...100) on Virtual Pin V1
 *************************************************************/

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include "WEMOS_Motor.h"
#include <SimpleTimer.h>

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

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "ssid";
char pass[] = "password";
SimpleTimer timer;
int varTimer;
 Motor M1(0x30,_MOTOR_A, 1000);//Motor A

// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin V1
BLYNK_WRITE(V1)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("V1 Slider value is: ");
  Serial.println(pinValue);
  varTimer = pinValue;
}

BLYNK_WRITE(V3) 
{
{
  if(param.asInt() == 0) { 
    FeedStart();
  }
  }
} 
 void FeedStart() // Rotate the rotor
 {
        M1.setmotor( _CW, 100);
        Serial.print(" FEEDING ");
        Serial.print(" for ");
        Serial.println(varTimer);
        timer.setTimeout(5000, FeedStop); //After 5 seconds call the FeedStop function
        
 }
 void FeedStop() // stop the rotor
 {
        M1.setmotor(_STANDBY); 
        Serial.println("END OF FEEDING ");
        
       
 }
 
void setup()
{
  // Debug console
  Serial.begin(9600);
Blynk.begin(auth, ssid, pass);

}

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

Does the feeding start but not stop or does neither function work?

Neither works. When you press the button linked to V3 you get the serial messages, so the function appears to be getting called.

The second function is triggered after the timeout, again going by the serial output.

Is it an actual WeMos motor shield you are using and which pins on the WeMos are you using for the shield?

The only way the motor will start is from V3 going LOW. Is V3 a button?
Put button in switch mode and it would be normal to use == 1 not == 0 in V3.

Yes its the wemos motor shield stacked on top of a D1 so all the headers are populated. Its a 12v motor connected to A1 and A2

V3 is a button in push mode. V3 gets updated on press and again on release so yes, when it goes back to 0 then FeedStart is called - which appears to be the case, I am getting the “FEEDING” message and the “END OF FEEDING” message 5 seconds later.

If I change V3 to a switch it calls FeedStart on the second press, which is consistent. The motor does not activate on either press.

That suggests a hardware issue. Do you know that the Motor shield and motor are working i.e. have you used them previously in other projects?

I’ve only tried the example sketches which work and if I move M1.setmotor( _CW, 100) into Void Loop it starts immediately on booting

Change the button to switch and the V3 if statement to == 1 just as a test.
Do you know what the 100 does in setMotor()? 100ms / 100 degrees etc.
If it’s 100ms then it would work in loop() as it keeps repeating but you probably wouldn’t notice a single 100ms movement from pressing V3.

Its PWM, so 100% duty cycle.

Going back the the project I’m basing mine off - If I change the ode to the following it works as it should. Which is ok but it’d be better to know why it doesn’t work the other way…

void loop()
{
  
  Blynk.run();
  timer.run();
      // get the man switch value
  if (digitalRead(V3) > 0) // feeds and updates the hopper level/man trigger count on manual trigger
 {
 
FeedStart();
   
 }
}

You can’t do a digital read of a virtual pin.

Even more odd that it works in that case!

It does seem like I can’t specify the timeout using a variable but I guess that’s a separate issue.

I think it’s because you haven’t declared the timeout correctly but I would be more interested in starting the motor in the first place than stopping it.

Definitely agree.

Does the motor start with:

bool motorhasStarted = true;

void loop()
{
  Blynk.run();
  timer.run();
     
  if (motorhasStarted == true)  
 {
    motorhasStarted = false;
    FeedStart();
 }
}

Motor runs on startup for the duration set in the timeout. I’ve moved

 Motor M1(0x30,_MOTOR_A, 1000);//Motor A

into Void Setup() and that seems to work, still testing

Good so timeout and motor etc are fine.

For slider operation all you need to do is define a global variable:

int feedSeconds = 5;

BLYNK_WRITE(V1)
{
 feedSeconds = param.asInt(); // assigning incoming value from pin V1 to a variable
  Serial.print("V1 Slider value is: ");
  Serial.println(feedSeconds);
}

 void FeedStart() // Rotate the rotor
 {
        M1.setmotor( _CW, 100);
        Serial.print(" FEEDING ");
        Serial.print(" for ");
        Serial.println(varTimer);
        timer.setTimeout(feedSeconds * 1000, FeedStop); //Slider set feeding time in ms      
 }

Not sure why V3 is not starting the motor but I would change it to normal logic of switch and 1 rather than push and 0.

You shouldn’t need Motor M1() in setup().

youre right it makes no difference.

For the V3 logic could you explain a bit more?

Put the button in switch mode and this

BLYNK_WRITE(V3) 
{
  if(param.asInt() == 1) { 
    FeedStart();
  }
}

You can always add this to the last line of FeedStop() so the button is in sync with the motor state.

Blynk.virtualWrite(V3, 0);

Okay I’ll try that now.

One more thing, is there a simple change to replace serial.print to have everything printed to the in app console instead?