I'm working on a project that involves a brushed dc motor RS550. I'm using the vnh5019 motor shield to command my motor with a gearbox that reduces the rpm to 4/5 rpm. I've attached an mpu6050 to the last shaft to measure the inclination of the shaft. I have also connected a load cell with HX711 that is giving no problem fortunately.
Hardware:
I connected the Arduino with vnh5019 with the default pin connections suggested in the vnh5019 datasheet.
You can read at page 10 of this datasheet that many pins are not available because of all the logic connections between vnh5019 and arduino.
So I connected the mpu6050 with arduino (vcc - 3.3V; gnd - gnd; scl - A5; sda - A4).
Software:
I've written a code (badly written, with comments) that runs the motor to a random pwm (from 90 to 120, where the max pwm in vnh5019 is 400) for 0.5s clockwise and after runs counterclockwise with same pwm for 0.5s. After that it generates another random number and repeat the cycle. So basically I'm giving pulses to the motor with a voltage of 12V and a current of 1.5A - 2A
Issues:
When i run the code the motor performs normally for 1-2 minutes with no problem (sometimes 5 minutes). All of the sudden when the motor starts to run again (after a certain amount of time that was working good) FREEZES(the serial communication stop)! It completely stops and the motor keeps running until I unplug the Arduino from its usb.
here below is the code I'm using:
#include "DualVNH5019MotorShield.h"
#include <Wire.h>
#include <MPU6050_light.h>
#include "HX711.h"
HX711 scale(5, 3); //HX711 scale(DOUT,CLK);
float calibration_factor = 5100; // this calibration factor is adjusted according to my load cell //verso il basso "aumenta il peso"..
float units;
float ounces;
//random numbers vars:
int needneg = 0;
int neednum = 1;
int negnum;
int storenum2;
//Gyro:
float X_angle;
float Y_angle;
float Z_angle;
MPU6050 mpu(Wire);
unsigned long timer = 0;
//Insert Integer
int num2 = 10; //setting num2!=oldnum2 to enter the if statement
int oldnum2 = 15;
//time vars
long lastTime = 0;
long time2Wait;
//logic vars
int enterif = 0;
DualVNH5019MotorShield md;
void setup()
{
Serial.begin(9600);
Serial.println("Dual VNH5019 Motor Shield");
md.init();
Wire.begin();
mpu.begin();
scale.set_scale();
scale.tare(); //Reset the scale to 0
long zero_factor = scale.read_average(); //Get a baseline reading
}
void loop() {
//Load Cell Part
scale.set_scale(calibration_factor); //Adjust to this calibration factor
units = scale.get_units(), 10;
if (units < 0)
{
units = 0.00;
}
ounces = units * 0.035274;
//Gyroscope part
mpu.update(); // <-- CREATES PROBLEMS
X_angle = mpu.getAngleX()+2.5;
delay(20);
if((millis()-timer)>50) // print data every 10ms
Serial.print("P: ");
Serial.print(X_angle);
Serial.print("; R: ");
Serial.print(Y_angle);
Serial.print("; Y: ");
Serial.print(Z_angle);
Serial.print("; bilancino: ");
Serial.println(units);
timer = millis();
{
}
//RANDOM NUMBER >= 90 PART:
//if statement to get the negative number of num2
if(num2 > 80) {
needneg = 1; //we need a negative number.
}
//if statement to get a new random number, or the negative number of the previous num2:
if(neednum == 1 && time2Wait - millis() < 80) {
negnum = storenum2; //saving the value of the last number generated
num2 = 90 + abs(random(5,30));
storenum2 = num2; //need to save in another variable because in the ifS below num2 will become 0.
//delay(1000);
if(negnum > 80 && needneg == 1) { //change the number in NEGATIVE number to make the motor go backwards.
num2 = -(negnum); //setting the negative number.
needneg = 0; //we don't need anymore a negative number.
}
neednum = 0; //enter this after two seconds the motor has stopped
}
//we start with num2 != oldnum2 to force the program entering this cycle (VARS DECLARATION)
if(num2 != oldnum2) { //start countdown ONLY IF there's a NEW VALUE incoming...
lastTime = millis() + 500;
oldnum2 = num2; //to not enter the if a second time //and to save the value of speed of the motor (num2)
enterif = 1; //to enter the next if when countdown is finished..
}
if(lastTime - millis() < 50 && enterif == 1) { //one second to stop the motor //need 80 because it SOON become 4592.......
// receivedChars[0] = '\0' ; //empty char array to send integer
num2 = 0;
Serial.println("we are inside lastTime - millis()");
time2Wait = millis() + 2000; //time between two different inputs
neednum = 1; //we need a new number for motor power.
}
//Serial.print("Motor Speed = ");Serial.print(num2); Serial.print(";; lastTime - millis(): ");Serial.println(lastTime - millis());
md.setM1Speed(num2);
stopIfFault();
}
/////////////////////////////////////////////////////////////
//Motor Shield...
void stopIfFault()
{
if (md.getM1Fault())
{
Serial.println("M1 fault");
while(1);
}
}
//Motor Shield...
What I've tried to do:
- Tried to change the power supply for the shield of the motor, Same outcome.
- I protected the shield from RFI with a ceramic capacitor close to the motor, plus I've put some ferrite chokes, some outcome.
- Tried to use different libraries, or codes for the mpu6050, same outcome.
Notes:
As soon as I exclude from the code mpu.update()
the motor runs without problems. Or equivalently if I keep it, but I do NOT connect the mpu6050 the motor will have no problem.
I'm planning to connect another arduino where i will read the values of the mpu6050 (so that i won't have problems) and serial communicate (tx-rx) with the main "Arduino-Shield".
How can I solve this problem? Thanks