Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Need a hand with the dual serial controller and arduino


#1

I’m really struggling here, and I could use a hand. I don’t understand the “config byte” or the “motor# and direction byte” as explained in the documentation. Right now I get no leds and no motor motion.

anyway here is my pin setup for the controller
1 positive terminal for 2 AA batteies(3v for motors)
2 ground
3 5v(same as ardunio power, or should this go to 9v/vcc?)
4 to pin 11 my serial tx pin
5 to pin 12, to reset controller
6 motor1 pos
7 motor1 gnd
8 motor2 gnd
9 motor2 pos

of course the battery pack goes to the same ground as everything else on the arduino, and I put a .1uf disk cap between the motor terminals as shown in the manual

my code:

#include <SoftwareSerial.h>

byte motorRxPin = 10;//unused
byte motorTxPin = 11;
byte resetPin = 12;

unsigned char buff[4];

SoftwareSerial motorSerial =  SoftwareSerial(motorRxPin, motorTxPin);

void setup() {
  pinMode(motorTxPin, OUTPUT);
  pinMode(motorRxPin, INPUT);
  pinMode(resetPin, OUTPUT);
  motorSerial.begin(9600);
  
  //config controller  
  buff[0]=0x80;//start byte
  buff[1]=0x02;//config command type byte
  buff[2]=0x02;//motors 2 and 3
  for(int i=0;i<3;i++){
    motorSerial.print(buff[i],BYTE);
  }
  digitalWrite(resetPin, LOW);   // reset motor controller
  delay(200);
  digitalWrite(resetPin, HIGH);
  delay(200);  
  Serial.println("sent config");
  Serial.println("reset controller");  
}

void loop() {
  buff[0]=0x80;//start byte
  buff[1]=0x00;//Device type byte
  buff[2]=0x03;//Motor number and direction byte 1*2+1=3
  buff[3]=0x100;// Motor speed "0 to 128" (100 is 64 in hex)
  
 //send data for motor2
  for(int i=0;i<4;i++){
    motorSerial.print(buff[i],BYTE);
  }
  //send data for motor3
  buff[2]=0x05;//Motor number and direction byte 2*2+1=5
  for(int i=0;i<4;i++) {
    motorSerial.print(buff[i],BYTE);
  }  
  delay(5000); // Wait 5 sec then resend data  
}

sorry for the double post, hopefully the 0 replies on this one will get a response.


Arduino to Micro Dual Serial Motor Controller?
#2

I was already writing this up, but this deserved it’s own thread anyway. It sounds like you have everything wired correctly, and pin3 on the motor controller wants 5V like you have it, NOT anything higher!

As to why the bits are numbered with zero on the right, think back to grade school (maybe Kindergarten?) about how you were taught to break up numbers from right to left in the ones-place, tens-place, hundreds-place, etc., so 253 was 2-hundreds plus 5-tens plus 3-ones. That method actually sets you up really well to think about number systems with different bases. Thinking about numbers a base 10 (i.e. decimal) number system, you could write 253 out as 2*(10^2)+5*(10^1)+3*(10^0). Remember that 10^1 is just 10, and anything^0 is 1 (crazy math!).

253 in binary happens to be 11111101, or 1*(2^7)+1*(2^6)+1*(2^5)+1*(2^4)+1*(2^3)+1*(2^2)+0*(2^1)+1*(2^0). The bit space numbers (0-7, right to left) are the base powers corresponding to the number in that place, and you can generalize this technique to any base. For example, 253 in hexadecimal is FD, or F*(16^1)+D*(16^0). Of course, hex has 16 single digits (0-9,A-E), so F=15 and D=13. Sure enough, 15*(16^1)+13*(16^0)=15*16+13=253.

On a side note, when you enter numbers into the Arduino compiler, it assumes you’re talking in decimal. If you’re writing in hex you need to begin with 0x, as in 0x80 (which I see you’re already doing) and if you’re writing bit by bit in binary, you need to start with 0b. So, 0x80=0b10000000=128.

Thinking in different number bases is always tricky, so I like to cheat. If you’re using Windows you can always check your numbers in the built in calculator. Load it up and under the “view” menu select “scientific”. You should now have a set of buttons that let you switch the displayed number between Hex, Dec, Oct, and Bin. Play around a little! There’s also a little discussion of how binary/hex/dec counting works in this thread (what do you think of the joke?).

Why the motor numbers go 1 then 0 left to right along the board is just a consequence of how the wiring works out, nothing special. Also, remember that those two motor ports will always respond to motor numbers 0 and 1 respectively, but also whatever other motor numbers you set for them (2 and 3 are default).

Down to the business, your program looks good. It correctly sets up software serial emulation, leaving the hardware serial port free for you to send messages back to the Arduino programming software (nice!). There are a couple of problems with it though. I started thinking about the code from your other post, and I see you’ve made some fixes, but lets go through the original for good measure (and because I already did).

First off, when you set the reset pin to an output, it’s held low by default, so right now your motor controller isn’t even on while you’re trying to send it the configuration byte! You need to set it high, and you need at least a 100ms delay after bringing the reset pin high (each time you do it) to let the motor controller wake up fully. This next one took me forever to figure out when I got my motor controller, you need a short delay after sending your configuration byte before resetting the motor controller for it to process what you just told it. 20ms is orders of magnitude more than enough.

Now lets build your motor number and direction byte. In two motor mode, the controller will always respond to motor numbers 0 and 1, but you want it to also respond to 3 and 4. Here’s the kicker, you can’t set the controller to respond to numbers 3 and 4! In two motor mode, the allowable numbers come in pairs, 0 and 1 (always), 2 and 3 (default), 4 and 5, 6 and 7, you get the picture. If you use an odd number in your configuration byte you’re setting that motor number and the one below it (so 3 means motors 2 and 3), while if you use an even number you’re setting that motor number and the one above it (so 4 means motors 4 and 5). You just can’t have motor numbers 3 and 4, sorry. Lets try 4 and 5:

So, bit by bit (haha, no seriously):

bit 7: 0 - always zero (except for the start 0x80 start byte
bit 6: 0 - zero for two motor mode
bits 0-5: 000100 - four in binary, as in motors number 4 and 5 (you could also use 5)

So your configuration routine should be:

	buff[0]=0x80;//start byte
	buff[1]=0x02;//config command type byte
	buff[2]=0b00000100;//Motor number and direction byte

You could also write buff[2]=0x04 or buff[2]=4, in the end it’s all the same number.

Now finally to the motor commands. First, you have a little typo when you build your second motor command you write buff[1]=0x01;, but buff[1] is the device type byte, you want buff[2] the motor number byte (incidentally, device type 1 is the code for Pololu serial servo controllers). The trick to the motor number is to ignore the byte building part and use this formula (also from the user guide): motor number and direction byte=motor number2+direction, where direction=1 is forward, and direction=0 is reverse. So, motor four forward would be (42+1)=9, while motor 5 in reverse would be (5*2+0)=10. Sweet!

So, with all the changes, your code ends up looking like this:

#include <SoftwareSerial.h>

byte motorRxPin = 10;//unused
byte motorTxPin = 11;
byte resetPin = 12;

unsigned char buff[4];

SoftwareSerial motorSerial =  SoftwareSerial(motorRxPin, motorTxPin);

void setup() {
  pinMode(motorTxPin, OUTPUT);
  pinMode(motorRxPin, INPUT);
  pinMode(resetPin, OUTPUT);
  motorSerial.begin(9600);

  digitalWrite(resetPin, HIGH);//start motor controller up
  delay(100);//let motor controller wake up
 
  buff[0]=0x80;//start byte
  buff[1]=0x02;//config command type byte
  buff[2]=4;//Motor number and mode byte, motors 4 and 5, two motor mode
  for(int i=0;i<3;i++){
    motorSerial.print(buff[i],BYTE);
  }
  delay(20);//give the controller a chance to remember what you told it

  Serial.println("sent config");

  digitalWrite(resetPin, LOW);//reset motor controller
  delay(1);//reset delay (it doesn't have to be long at all)
  digitalWrite(resetPin, HIGH);
  Serial.println("reset controller"); 
  delay(200);//wakeup delay again
}

void loop() {
  buff[0]=0x80;//start byte
  buff[1]=0x00;//Device type byte
  buff[2]=9;//Motor number and direction byte, motor 4 forward (4*2+1)
  buff[3]=0x64;// Motor speed "0 to 128" (100 is 64 in hex)
 
  //send data for motor0
  for(int i=0;i<4;i++){
    motorSerial.print(buff[i],BYTE);
  }
  //send data for motor1
  buff[2]=10; //Motor number and direction byte, motor 5, reverse (5*2+0)
  for(int i=0;i<4;i++) {
    motorSerial.print(buff[i],BYTE);
  } 
  delay(5000); // Wait 5 sec then resend data
}

And here’s the real kicker, the motor number settings are stored in non-volatile (i.e. permanent) memory, so you don’t have to (and really shouldn’t) send the motor configuration command every time. How sweet is that?

I just tested this code with the Arduino compiler and a Baby Orangutan (not really an Arduino board, but the same processor) and it worked great, so let me know how it works out for you.

-Adam


#3

First off thanks for the detailed explanation, I really appreciate it.

so if I understand correctly

for configuration
bits 0-5 are 000010 (for motor 2 and 3)
bit 6 is 0(2 motors)
bit 7 is 0(always 0)

so my config byte should be 00000010, or 2, or 0x02

for motor control
bit 0 is 1(forward)
bits 1-6 are 000010 (for motor2, and 000011 for motor3)
bit 7 is 0(always 0)

so my control byte should be
00000100(motor 2 forward), 0x64, or 100
00000110(motor 3 forward), 0x6e, or 110

your program did not work for me, I changed the for loops back to 4 iterations, and it seems to be better, each motor moves forward just a hair… and then it all stops again… any idea what to try next? I can attach an image if it will help.


#4

I was way off here

00000101(motor2, forward), 0x05, or 5
00000111(motor2, forward), 0x07, or 7


#5

My latest code. I think this should work, but I only get one green led…, then two green with a forward blip on both motors.

I’m getting close… sooo close. love that mac calculator it has a “programmer” view that converts, hex, octal, decimal, and binary

#include <SoftwareSerial.h>

byte motorRxPin = 10;//unused
byte motorTxPin = 11;
byte resetPin = 12;

unsigned char buff[4];

SoftwareSerial motorSerial =  SoftwareSerial(motorRxPin, motorTxPin);

void setup() {
  pinMode(motorTxPin, OUTPUT);
  pinMode(motorRxPin, INPUT);
  pinMode(resetPin, OUTPUT);
  motorSerial.begin(9600);
  Serial.begin(9600);
  
  digitalWrite(resetPin, HIGH);//start motor controller up
  delay(200);//let motor controller wake up

  buff[0]=0x80;//start byte
  buff[1]=0x02;//config command type byte
  buff[2]=0x02;//Motor number and mode byte, motors 2 and 3, two motor mode
  for(int i=0;i<3;i++){
    motorSerial.print(buff[i],BYTE);
  }
  delay(20);//give the controller a chance to remember what you told it

  Serial.println("sent config");

  digitalWrite(resetPin, LOW);//reset motor controller
  delay(2);//reset delay (it doesn't have to be long at all)
  digitalWrite(resetPin, HIGH);
  Serial.println("reset controller");
  delay(200);//wakeup delay again

  buff[0]=0x80;//start byte
  buff[1]=0x00;//Device type byte
  buff[3]=0x40;// Motor speed 1/2 full
}

void loop() {
  buff[2]=0x05;//Motor number and direction byte, motor 2 forward (2*2+1)
  //send data for motor2
  for(int i=0;i<4;i++){
    motorSerial.print(buff[i],BYTE);
  }
  //send data for motor3
  buff[2]=0x07; //Motor number and direction byte, motor 3, forward (3*2+1)
  for(int i=0;i<4;i++) {
    motorSerial.print(buff[i],BYTE);
  }
  delay(5000); // Wait 5 sec then resend data
}

#6

Your code works just fine for me, which is baffling, but I’m also a little confused about these LEDs you keep mentioning.

The other thread, the one you posted in first, was talking about using an Arduino with the micro dual serial motor controller, this guy:

Are you using the low voltage dual serial motor controller? This guy:

I’ll assume you are, since it’s the only Pololu dual serial motor controller with LEDs. The pinout and control protocol are conveniently the same as the uDSMC, so it should work too, but I have no direct experience with that particular controller, so I don’t know any of it’s quirks. Maybe someone from Pololu can clue us in tomorrow (well, later today).

Have you tried leaving the configuration command out of your program all together? It should still respond to motor numbers 2 and 3 (or whatever the last motor numbers you configured are), and it should always respond to motor numbers 0 and 1.

Also, skimming the manual, I see this note (highlighted in red) about the configuration command, at the top of page 6:

I’m not sure if that’s because of a potential electronics issue, or just in case your motors pulsing unexpectedly could do something bad, like drive your robot off the table, but it’s worth trying too. You could also add a long delay after your configuration command to see if the LEDs pulse the number you set the motor to.

-Adam


#7

well I removed the initilization code, and changed the speed to 0x10… and guess what it runs for about 10 seconds now before it dies?

2 green leds for forward, and everythign looks ok, and then a full stop.

how much power does this controller consume?


#8

Hello,

My original reply got lost when our forum went down, but your last reply indicates that you saw the post. The motor controller internal circuitry alone draws somewhere around 10 mA, but the LEDs can draw more than that if they are turned on brightly enough. Given that you are seeing longer operation with lower power settings, I do think that this is a power or noise issue.

The following is my original post from yesterday:

The micro dual serial motor controller is not being discontinued. What was changed was the chassis completion kit, which now includes the low-voltage motor controller instead of the micro one.

The motor controller isn’t intended to be configured every time, so I recommend taking that configuration code out of your main program. You should use a separate program, run it and confirm that the LEDs flash as expected, and then run different programs with your main code after that.

As for the main problem, it’s almost always a power or noise issue. As soon as the motors kick in, you get a lot more noise in the system that might do things such as reset the controller or cause communications to get messed up. What is your power supply for the 5V logic supply, and are you sure it can provide the necessary current?

- Jan


#9

arduino can supply about 40mA on any pin, and I’m powering this on the 5v rail, so I think it will supply 40mA at a minimum, probably more. I’ll check into it. What is the power consumption of the leds?

I already commented the configuration. I also have .1 uf caps from terminal to terminal on the motors to reduce noise. Is it possible the 2AA batteries can not supply enough current?

anyway here is my latest code

#include <SoftwareSerial.h>

byte motorRxPin = 10;//unused
byte motorTxPin = 11;
byte resetPin = 12;

unsigned char buff[4];

SoftwareSerial motorSerial =  SoftwareSerial(motorRxPin, motorTxPin);

void setup() {
  pinMode(motorTxPin, OUTPUT);
  pinMode(motorRxPin, INPUT);
  pinMode(resetPin, OUTPUT);
  motorSerial.begin(9600);
  Serial.begin(9600);
  
  digitalWrite(resetPin, HIGH);//start motor controller up
  delay(200);//let motor controller wake up
/*
  buff[0]=0x80;//start byte
  buff[1]=0x02;//config command type byte
  buff[2]=0x02;//Motor number and mode byte, motors 2 and 3, two motor mode
  for(int i=0;i<3;i++){
    motorSerial.print(buff[i],BYTE);
  }
  delay(20);//give the controller a chance to remember what you told it

  Serial.println("sent config");
*/
  digitalWrite(resetPin, LOW);//reset motor controller
  delay(2);//reset delay (it doesn't have to be long at all)
  digitalWrite(resetPin, HIGH);
  Serial.println("reset controller");
  delay(200);//wakeup delay again

  buff[0]=0x80;//start byte
  buff[1]=0x00;//Device type byte
  buff[3]=0x10;// Motor speed 1/2 full
}

void loop() {
  buff[2]=0x05;//Motor number and direction byte, motor 2 forward (2*2+1)
  //send data for motor2
  for(int i=0;i<4;i++){
    motorSerial.print(buff[i],BYTE);
  }
  //send data for motor3
  buff[2]=0x07; //Motor number and direction byte, motor 3, forward (3*2+1)
  for(int i=0;i<4;i++) {
    motorSerial.print(buff[i],BYTE);
  }
  delay(5000); // Wait 5 sec then resend data
}

#10

The 40 mA on any pin is just the microcontroller spec, right? The bigger question is, what is powering that 5V rail, and what else do you have connected to it?

The LEDs draw a bit under 5 mA each at 5 V. The problem is that the load fluctuates, and if you have many devices that also vary in their power consumption (e.g. sonar or IR rangefinders that have to emit some sort of burst every time they make a measurement), your peak requirement might be quite a bit higher than the average. Capacitors (of different sizes since they tend to have different frequency responses) across the power line should help a lot, provided your supply can deliver enough current.

Do you have access to an oscilloscope? It might be helpful to look at the various lines you think are just DC since there are often small glitches there that can do things like reset microcontrollers, causing the kind of behavior you are seeing.

- Jan


#11

No I don’t have an oscilliscope, or access to one… and I think they tend to cost a bit more than my budget will allow :frowning:

The only thing currently hooked up to my arduino is this controller, which is why I’m having a hard time understanding what is going on.


#12

Which Arduino board are you using (sorry if you already mentioned it somewhere)? I looked at the Diecimila version, and that looks like it should have plenty of power, but I’ve also seen small units with smaller regulators.

I’m also not clear on what your latest symptoms are. I think I remember seeing that you were having unexpected behavior even without motors connected (i.e. just the LEDs); is that still the case? Can you give us a better indication of if the problems happen randomly? For instance, does the motor run for 10 seconds one time and 3 seconds the next time? It looks like your are repeating your command every 5 seconds; what happens if you don’t repeat it?

- Jan


#13

appreciate you sticking with me here, I do have a multimeter, so I’ll try to get some testing done tonight…

It is pretty consistent now, it is an arduino decimilia, when i run the program above, it will run forward, very slow for 5-10 seconds… then stop… it does not restart.

If I turn it off, and back on it will run again, but for a shorter time… until on and off do nothing.

Then if I “let it cool” for a bit, and try again, it seems to work, again for 5-10 seconds… on and off, on and off… eventually nothing again.

Nothing ever gets hot, I’m starting to think the fets are fried… but there is no evidence of me letting the smoke out on any of the chips, and I know I never over volted anything.


#14

That is strange. At this point, it might be quickest for you to send the unit back for us to inspect. You can send it to us with RMA #38434.

- Jan


#15

Ok one last shot. Maybe I am just doing something terribly stupid, so here is a picture of my setup. I’m using ladyadas protoshield on top of a decimilia.

http://www.jesandari.com/junk/DSC00075.JPG


#16

It generally looks okay, but breadboards aren’t that great for higher currents. Since I think it’s a noise problem, I really need to know what the behavior is with and without the motors attached. You should try to get just the on-board LEDs to respond the way you expect, and then you can try adding smaller loads such as smaller motors or LEDs (with resistors!) to see if the motor controller is operating correctly. If adding the motors then makes things break, it’s probably a noise problem, and we can work on resolving that once we know if the board is working.

- Jan


#17

you want me to send it back, or run a few tests first?


#18

It’s up to you. I thought you wanted to try some more, so I suggested how you should go about it.

- Jan


#19

yeah I’ll run some tests tomorrow, I should have time then.


#20

ok I tested today with a brand new boarduino, from ladyada… exact same problem… I’ll send it back.