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