0
\$\begingroup\$

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 Datasheet vnh5019 . 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

EDIT: Here's my setup:

Power Supply: 12V 10A(declared), Capacitor 0.4uF

enter image description here

enter image description here

\$\endgroup\$
7
  • \$\begingroup\$ So the motor is going back and forth at different (random) speeds? Maybe instead of random, you check the worst case, full PWM and reverse it. My guess is you'll see your problem much more often. Which will allow you to troubleshoot it easier. \$\endgroup\$
    – Aaron
    Commented May 19, 2021 at 18:16
  • \$\begingroup\$ @Aaron I've worked before with a diy dc brushed motor and it had a lot of rfi, the greater the voltage, the greater the voltage spikes of rfi, sometimes the arduino freezed. I don't think this could be the case because this shield is designed to work with range(5.5-24)V and current 12A continuous. I've checked the rfi with oscilloscope and it's ok. btw let's say I get more often this issue running high PWM. How could I troubleshoot? I do not have big experience, what would you look for? (if I do not have the mpu6050 connected everything will work fine). because i do not have any ideas. \$\endgroup\$
    – Carlo
    Commented May 19, 2021 at 19:44
  • 1
    \$\begingroup\$ When the system is in a broke state is the mpu6050 putting out bad data? Is the mpu6050 hung? You mention that mpu.update(); is causing problems, does it have an infinite wait loop inside it? ie. Is the mpu6050 getting upset from the noise, and then isn't doing something that the mpu.update(); is expecting. \$\endgroup\$
    – Aaron
    Commented May 19, 2021 at 20:06
  • \$\begingroup\$ With full PWM and the motor alternating as you have it, look at the power and signal lines on the mpu6050. If there is noise address it. \$\endgroup\$
    – Aaron
    Commented May 19, 2021 at 20:10
  • \$\begingroup\$ The DC motor should have 3 caps on it (about 0.1uF each): One across the power connections, right at the motor, not on the wire leads. One from each power lead to the motor chassis. Each of these should have as short of leads as possible. If SMT fits, you can use that too. \$\endgroup\$
    – Aaron
    Commented May 19, 2021 at 20:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.