Esp8266 12e motor shield joystick blynk

Hi i have motor shield with ESP8266 and i need control rccar by blynk.


Motor A use for fluently foward and back and motor B for turn left and right.
https://www.youtube.com/watch?v=RdZYaJCn04M

This sketch working for motorA foward and back. But i dont know how change this sketch for motor B: turn left and right. I try it something but no good.
Thanks.


// Simple WiFi Car using Blynk Joystick Widget
// Pins are based on looking at rear of car.
 
// -- Motor Leads --
// Looking at rear of car, left motor leads, A- -> red, A+ -> black
// Looking at rear of car, right motor leads, B- -> black, B+ -> red
 
// -- Blynk Settings --
// ---Use a Joystick Widget --                                                      
//  ->Merge not Split  should be selected
//  ->Select "Virtual Pin 1"
//  ->Turn autorotate off, use the phone in a portrait not landscape position
//  ->Leave autoreturn on...too hard to control with it off
 
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
 
#define RightMotorSpeed 4
#define RightMotorDir   0  //B
#define LeftMotorSpeed  5  //A
#define LeftMotorDir    2
 
 
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
// Use your own WiFi settings
char auth[] = "b00396c3365b86c5";
char ssid[] = "ASUS";
char pass[] = "Jersin72";
 
// neutral zone settings for x and y
// joystick must move outside these boundary numbers to activate the motors
// makes it a little easier to control the wifi car
int minRange = 312;
int maxRange = 712;
 
// analog speeds from 0 (lowest) - 1023 (highest)
// 3 speeds used -- 0 (noSpeed), 350 (minSpeed), 850 (maxSpeed).
// use whatever speeds you want...too fast made it a pain in the ass to control
int minSpeed = 450;
int maxSpeed = 1023;
int noSpeed = 0;
 
 
void moveControl(int x, int y)
{
  // movement logic
  // move forward

   // y je vetsi jak maxrange a současně x je vetsi jak minRange a současne mensi jak max range 
  if(y >= maxRange && x >= minRange && x <= maxRange) //zataci R
  {
    digitalWrite(RightMotorDir,HIGH);  
    digitalWrite(LeftMotorDir,HIGH);
    analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);
  }
  
  // move forward right
  else if(x >= maxRange && y >= maxRange)   //zataci R
  {
    digitalWrite(RightMotorDir,HIGH);
    digitalWrite(LeftMotorDir,HIGH);
   analogWrite(RightMotorSpeed,minSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);
  }
 
  // move forward left
  else if(x <= minRange && y >= maxRange)
  {
    digitalWrite(RightMotorDir,HIGH);
    digitalWrite(LeftMotorDir,HIGH);
    analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,minSpeed);
  }
 
  // neutral zone
  else if(y < maxRange && y > minRange && x < maxRange && x > minRange)
  {
    analogWrite(RightMotorSpeed,noSpeed); 
    analogWrite(LeftMotorSpeed,noSpeed);
  }
 
 // move back
  else if(y <= minRange && x >= minRange && x <= maxRange)
  {
    digitalWrite(RightMotorDir,LOW);
    digitalWrite(LeftMotorDir,LOW);
   analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);
  }
 
  // move back and right
 else if(y <= minRange && x <= minRange)
  {
   digitalWrite(RightMotorDir,LOW);
    digitalWrite(LeftMotorDir,LOW);
    analogWrite(RightMotorSpeed,minSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);  
  }
 
  // move back and left
  else if(y <= minRange && x >= maxRange)
  {
    digitalWrite(RightMotorDir,LOW);
    digitalWrite(LeftMotorDir,LOW);
    analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,minSpeed);
  }
}
 
void setup()
{
  // initial settings for motors off and direction forward
  pinMode(RightMotorSpeed, OUTPUT);
  pinMode(LeftMotorSpeed, OUTPUT);
  pinMode(RightMotorDir, OUTPUT);
  pinMode(LeftMotorDir, OUTPUT);
  digitalWrite(RightMotorSpeed, LOW);
  digitalWrite(LeftMotorSpeed, LOW);
  digitalWrite(RightMotorDir, HIGH);
  digitalWrite(LeftMotorDir,HIGH);
 
  Blynk.begin(auth, ssid, pass);
 }
 
 
void loop()
{
  Blynk.run();
}
 
 
BLYNK_WRITE(V1)
{
  int x = param[0].asInt();
  int y = param[1].asInt();
  moveControl(x,y); 
}

Is the motorB a Servomotor or a DC Motor at your RC car???

DC motor.

Or output A and B on motor shield working only together? So i will use servo for turn.

Is this sketch good? Thanks.

#define BLYNK_PRINT Serial
#include <SPI.h>
#include <BlynkSimpleEsp8266.h>
#include <Servo.h>
#include <ESP8266WiFi.h>


// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxx";

Servo servo;  


void setup()  
{
  Serial.begin(9600);
  Blynk.begin(auth, "ssid", "password");
  servo.attach(0);

}
BLYNK_WRITE(V1)  
{
  servo.write(param.asInt());  
}

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

Without getting in-depth with the code, I think you are trying to use differential (or tank) drive control. This method will not work for your car.

It looks like you have two DC motors, one for driving the wheels; Forward/Back - with speed being determined by range of signal from mid-to-high (Forward) and mid-to-low (reverse) mid being neutral. The second motor for Steering the car is the same principal, except as Left, Straight, and Right.

Instead of looking at the motor controller (and the code) as RightMotor & LeftMotor, think of them as DriveingMotor & SteeringMotor. Separate them into two loops if that makes it easier to lay out the code, and testing.

Control your DriveingMotor’s speed and direction with just the Y axis of the joystick and the same with the SteeringMotor using the X axis (map the steering speed way down for finer control)

Yes you have right. But i dont find batter code. I need only use motor A for Forward/Back.

For steering the car i used servo.


I use this code and motor B i have no connect. Motor A work good.
But if in this code i delete motor B {Right} so motor A no good working…

Thanks.


// Simple WiFi Car using Blynk Joystick Widget
// Pins are based on looking at rear of car.
 
// -- Motor Leads --
// Looking at rear of car, left motor leads, A- -> red, A+ -> black
// Looking at rear of car, right motor leads, B- -> black, B+ -> red
 
// -- Blynk Settings --
// ---Use a Joystick Widget --                                                      
//  ->Merge not Split  should be selected
//  ->Select "Virtual Pin 1"
//  ->Turn autorotate off, use the phone in a portrait not landscape position
//  ->Leave autoreturn on...too hard to control with it off
 
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Servo.h>
#include <SPI.h>
 
//#define RightMotorSpeed 4
//#define RightMotorDir   0  //B
#define LeftMotorSpeed  5  //A
#define LeftMotorDir    2

 
Servo servo1; 
 
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
// Use your own WiFi settings
char auth[] = "b003999376c3365b86c5";
char ssid[] = "ASUS";
char pass[] = "Jersin72";
 
// neutral zone settings for x and y
// joystick must move outside these boundary numbers to activate the motors
// makes it a little easier to control the wifi car
int minRange = 312;
int maxRange = 712;
 
// analog speeds from 0 (lowest) - 1023 (highest)
// 3 speeds used -- 0 (noSpeed), 350 (minSpeed), 850 (maxSpeed).
// use whatever speeds you want...too fast made it a pain in the ass to control
int minSpeed = 450;
int maxSpeed = 1023;
int noSpeed = 0;
 
 
void moveControl(int x, int y)
{
  // movement logic
  // move forward

   // y je vetsi jak maxrange a současně x je vetsi jak minRange a současne mensi jak max range 
  if(y >= maxRange && x >= minRange && x <= maxRange) //zataci R
  {
   //// digitalWrite(RightMotorDir,HIGH);  
    digitalWrite(LeftMotorDir,HIGH);
   //// analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);
  }
  
  // move forward right
  else if(x >= maxRange && y >= maxRange)   //zataci R
  {
   // digitalWrite(RightMotorDir,HIGH);
    digitalWrite(LeftMotorDir,HIGH);
   //analogWrite(RightMotorSpeed,minSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);
  }
 
  // move forward left
  else if(x <= minRange && y >= maxRange)
  {
   // digitalWrite(RightMotorDir,HIGH);
    digitalWrite(LeftMotorDir,HIGH);
   // analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,minSpeed);
  }
 
  // neutral zone
  else if(y < maxRange && y > minRange && x < maxRange && x > minRange)
  {
   // analogWrite(RightMotorSpeed,noSpeed); 
    analogWrite(LeftMotorSpeed,noSpeed);
  }
 
 // move back
  else if(y <= minRange && x >= minRange && x <= maxRange)
  {
   // digitalWrite(RightMotorDir,LOW);
    digitalWrite(LeftMotorDir,LOW);
   //analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);
  }
 
  // move back and right
 else if(y <= minRange && x <= minRange)
  {
  // digitalWrite(RightMotorDir,LOW);
    digitalWrite(LeftMotorDir,LOW);
   // analogWrite(RightMotorSpeed,minSpeed); 
    analogWrite(LeftMotorSpeed,maxSpeed);  
  }
 
  // move back and left
  else if(y <= minRange && x >= maxRange)
  {
   // digitalWrite(RightMotorDir,LOW);
    digitalWrite(LeftMotorDir,LOW);
   // analogWrite(RightMotorSpeed,maxSpeed); 
    analogWrite(LeftMotorSpeed,minSpeed);
  }
}
 
void setup()
{

 
 servo1.attach(2);
  
  // initial settings for motors off and direction forward
  //pinMode(RightMotorSpeed, OUTPUT);
  pinMode(LeftMotorSpeed, OUTPUT);
 // pinMode(RightMotorDir, OUTPUT);
  pinMode(LeftMotorDir, OUTPUT);
 // digitalWrite(RightMotorSpeed, LOW);
  digitalWrite(LeftMotorSpeed, LOW);
  //digitalWrite(RightMotorDir, HIGH);
  digitalWrite(LeftMotorDir,HIGH);
 
  Blynk.begin(auth, ssid, pass);
 }
 


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


 BLYNK_WRITE(V6)  
{ 
 servo1.write(param.asInt());
}  
 
BLYNK_WRITE(V1)
{
  int x = param[0].asInt();
  int y = param[1].asInt();
  moveControl(x,y); 
}

Ahh, good servo swap… I was going to suggest something like that, but figured that might be too complicated to explain :slight_smile:

Then you can wire both sides of the dual channel controller in parallel, this effectively doubles the current capacity when using one motor (must set each side the same way whenever adjusting values). Or just ignore the one side you are not using (both physically in the wiring and in the code) as if it was a single channel controller. Google around for different wiring and code samples.

And simply use PWM servo control for the steering, based on the input from the joystick’s X axis.

For the joystick to controller conversion, you are looking to take a 0-255 number and if it is 0-127ish, then set direction pin one way and the speed pin mapped from the 0-127 range. The same for the 128-255 range for the other direction and speed. I would suggest adjusting those values to make a buffered middle range i.e 120-137 that represents a neutral zone, in which the motor is fully stopped.

As to how to code that, I don’t have any pre-done snippets to quickly call up (and it’s not directly Blynk application related), you will have to Google around for something to make into your own.

Exactly, you can find below an example at my Lego Car:

Have a look at the code, it could help a bit.

HTH

1 Like

@psoro
Nice car and great job on the DIY shield! I will read up on your project in more detail.

Unfortunately, your car utilizes the same differential drive code that he has tried, and will not (directly) work for his type of drive & steering mechanics :disappointed: But it will give him something to compare with.

@Jiri_Bam
I actually found an old project car chassis, similar to what you have in drive and steering mechanics, that I never got around to working on (need batteries and possibly better motor controller)… but who knows, I might start working on it and will share ideas.

Meanwhile, I did some quick googling and found at least one site with some relevant info and code you might find useful.

http://www.phoenixgarage.org/show_article/128

http://www.bajdi.com/?s=car&submit=Search

1 Like

Ok. Thanks. Now i trying this sketch:

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

#define RightMotorSpeed 5
#define RightMotorDir 0


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


//Servo servo;  
Servo servo1; //D4

void setup()
{
 Serial.begin(9600);
 Blynk.begin(auth, ssid, pass);

 pinMode(RightMotorSpeed, OUTPUT);
 pinMode(RightMotorDir, OUTPUT);

servo1.attach(2);
}

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

void halt()
{
 digitalWrite(RightMotorSpeed, LOW);
 
}

void forward()
{
 digitalWrite(RightMotorDir, HIGH);
 
 digitalWrite(RightMotorSpeed, HIGH);
 
}

void reverse()
{
 digitalWrite(RightMotorDir, LOW);

 digitalWrite(RightMotorSpeed, HIGH);

}



BLYNK_WRITE(V0)
{
 if (param[0])
 forward();
 else
 halt();
}

BLYNK_WRITE(V1)
{
 if (param[0])
 reverse();
 else
 halt();
}

BLYNK_WRITE(V6)  //0-180
{ 
 servo1.write(param.asInt());
}  

But i dont know how change DC motor Right for: from min to max smoothly by joystick.
THanks.

OK, one last assist on something non-Blynk specific :slight_smile:

A quick and dirty fix is, instead of using a digital HIGH and LOW in the MotorSpeed call… use a variable that gets it’s range of 0-255 from the Joystick - call it V for velocity, or whatever, and use analogWrite() with a PWM Pin to control the speed:

analogWrite(RightMotorSpeed, V); // Must use a PWM pin to control this

To get fancier, you would take the range of 0-255 and split it up into thirds, and using map(), split the output between between ‘slow-full reverse’, ‘neutral’ & ‘slow-full forward’.

Keep diggin into the included links (and find others)… your answer lies within :wink:

Ok thank but i am no great programmer with motor control.
Yu mean??:


int V =  map(x, 1, 50, 50, 1);
int y;


void forward(int y)
{
 digitalWrite(RightMotorDir, HIGH);
 
 digitalWrite(RightMotorSpeed, HIGH);

 analogWrite(RightMotorSpeed, V);

}


BLYNK_WRITE(V0)
{
  int y = param[1].asInt();
 if (param[0])
 forward(y);
 else
 halt();
}

Neither am I :wink: I just dig into other’s code until I figure it out, then experiment with my own modifications.

Don’t use both for speed control, just use the analogWrite()