Projets:Perso:2011:Motorshield:use

From Electrolab
Jump to: navigation, search

Motorshield use it page

add links to get back
add a descriptive header...

Things you should know

Remember, YMMV: this is a prototype, not a commercial product.

  • PWM frequency shall be under 11 kHz according to datasheet. It can be selected when you create a AF_DCMotor object: "AF_DCMotor motor_1_or_2(1,MOTOR12_2KHZ);" or "AF_DCMotor motor_3_or_4(3,MOTOR34_2KHZ);"
  • I think I ended up messing with signals, that is motor x forward/backward isn't 100% garanteed to be the same as for Adafruit's version. That's lame, but it seems okay to me, given that it is a prototype. One can still pilot all four DC motors, you just have to figure out which one is where and goes which way - or wait for the final HW revision, or the specific SW library.
  • because of previous issue, stepper support most probably won't work out of the box.
  • speed value is messed up, see below.
  • you can read each H-bridge status flags (see datasheet: indicates if everything's fine), if you have the right 0 ohm resistor soldered.

Setting speed for DC motors

The PWMing for speed is an active low on the MC33932 vs an active high on the L293D. I have been lazy to implement a HW thing to compensate for that. I suppose I'll have to decide what I end up doing: either keep the hw simple or respect full pin/sw compatibility. Anyway, on this prototype, speed values are inversed ! that means, "motorX.setSpeed(255);" will stop the motor and "motorX.setSpeed(0);" will have it go fullspeed.

Current feedback feature

To use the current feedback feature, you should:

  • have the right 0 ohm (eg, bridge) resistors in place (check schematic)
  • do something like "analogRead(MOTORX_FBPIN)" with "const int M1_FB = A0;//M1 current feedback","const int M2_FB = A1;//M2 current feedback","const int M3_FB = A3;//M3 current feedback","const int M4_FB = A4; //M4 current feedback".
  • use the datasheet, schematic and your brain to find the value ! Or read below.

How to find the right code to have a meaningful value:

  • The current mirror on feedback pin is 0.24% of load current.
  • The resistor in place has a value of 270 ohm (standard precision).
  • Therefore, a 5A current will achieve 5*0.0024*270 = 3.24 volts seen on the ADC
  • The ADC is 10bits with a 5v reference, so this 5A current will result in 3.24/5*1024 = 664 approx.
  • Then 5/664 (or 0.00753) is the factor to have a value in amps.
  • An almost correct code might be something like "value_miliamps = 8*analogRead(MOTORX_FBPIN);". Remember that the Arduino doesn't like floating point variables nor making divisions (no dedicated hw) and there are imprecisions here and there, so a x8 factor should be good enough.
  • Note that at 6.5A the overcurrent protection kicks in, so the ADC should be fine in any case.

Code example

formating sucks, sorry ! // Adafruit Motor shield library // copyright Adafruit Industries LLC, 2009 // this code is public domain, enjoy! // adapted for Electrolab Motorshield prototype #include <AFMotor.h> const int STATUS_FLAG_1 = A2;//H-bridge1 status flag const int STATUS_FLAG_2 = A5;//H-bridge2 status flag const int M1_FB = A0; //M1 current feedback const int M2_FB = A1; //M2 current feedback const int M3_FB = A3; //M3 current feedback const int M4_FB = A4; //M4 current feedback //we need PWM freq < 11kHz AF_DCMotor motor1(1,MOTOR12_8KHZ); AF_DCMotor motor2(2,MOTOR12_8KHZ); AF_DCMotor motor3(3,MOTOR34_8KHZ); AF_DCMotor motor4(4,MOTOR34_8KHZ); void setup() { Serial.begin(9600); Serial.println("Motor test! Everyone full forward !"); //enable status flag reading pinMode(STATUS_FLAG_1, INPUT);//Status flag1 pinMode(STATUS_FLAG_2, INPUT);//Status flag2 // turn off (!!) all motors motor1.setSpeed(255); motor2.setSpeed(255); motor3.setSpeed(255); motor4.setSpeed(255); motor1.run(RELEASE); motor2.run(RELEASE); motor3.run(RELEASE); motor4.run(RELEASE); // turn on (!!) all motors motor1.setSpeed(0); motor2.setSpeed(0); motor3.setSpeed(0); motor4.setSpeed(0); motor1.run(FORWARD); motor2.run(FORWARD); motor3.run(FORWARD); motor4.run(FORWARD); } void loop() { int tempval; Serial.print("motor1 current(mA):"); tempval = 3*analogRead(M1_FB);//check the datasheet & schematic, value in mA Serial.println(tempval); Serial.print("motor2 current(mA):"); tempval = 3*analogRead(M2_FB);//check the datasheet & schematic, value in mA Serial.println(tempval); Serial.print("motor3 current(mA):"); tempval = 3*analogRead(M3_FB);//check the datasheet & schematic, value in mA Serial.println(tempval); Serial.print("motor4 current(mA):"); tempval = 3*analogRead(M4_FB);//check the datasheet & schematic, value in mA Serial.println(tempval); Serial.print("status flag1:"); if(HIGH==digitalRead(STATUS_FLAG_1)) Serial.println("ok"); else Serial.println("nok"); Serial.print("status flag2:"); if(HIGH==digitalRead(STATUS_FLAG_2)) Serial.println("ok"); else Serial.println("nok"); Serial.println(""); delay(1000); }