PDA

View Full Version : [Question(s)] MD23 Motor Driver and Arduino



ROBOTMAN
01-06-2010, 11:54 PM
I was scared to post before thoroughly researching the topic after getting yelled at before but I really can't get this one. I just got an MD23 (http://www.robot-electronics.co.uk/htm/md23tech.htm#change%20address) motor driver and I am trying to interface with my arduino over I2C. I am going off of this sites (http://www.robot-electronics.co.uk/htm/arduino_examples.htm#MD23%20RD01%20Motor%20Control ler) advise on how to hook it up and talk to it. So far I have had to modify the code to get rid of the software that controls the LCD. Also I tried to narrow it down to just the code that spins the motor because my encoders are not hooked up. I have looked for tutorials on i2c communication with google and still come up blank. I can't even get the MD23 to acknowledge that it has received my command. This can be seen because a green light flashes every time a byte is received. The only success I have had is with this code.


#include <Wire.h>

void setup()
{
Wire.begin();
}

void loop()
{
Wire.endTransmission();
}


I assume this is because the end transmission command flushes the line. This causes the green LED to flash. My problem is that I don't know how to send the right data with the arduino. My MD23's address is 0xB0. I don't really know what data type this is so that is the start of my problem. Also thanks to the lack of arduino documentation on i2c I don't know what type of data it sends when I ask it to send 0xB0. All I know is that Wire.send() requires an int data type. If somebody could tell me how to initialize communication with the arduino I would appreciate it. Also the data sheet for the MD23 has lots of tables that show how to check stored information. How would you read register 32 on the MD23? Please help I researched this for 6 hours strait and I can't get anything to work.

lnxfergy
01-07-2010, 12:38 AM
Just about to nod off for the night, but the first thing to check is the Address of the device. Devantech uses 8 bit addresses, and Arduino I2C library uses 7-bit addresses, try shifting the address 1 bit: 0xB0-> 0x58.

-Fergs

ROBOTMAN
01-07-2010, 06:58 PM
The light dosn't blink. Here is my code.

#include <Wire.h>

#define md23Address 0x58

void setup()
{
Wire.begin();
}

void loop()
{
Wire.beginTransmission(0x58);
}

ROBOTMAN
01-07-2010, 07:05 PM
Maybe it is a problem with my setup? I connected it right as far as I can tell but I bypassed the resistors and connected my wire strait to the analog pin 4. Is it possible for this to cause my problem? From what I understood it is just a case of pulsing pins high and low for communication. That brings up another question. How can the arduino send a pulse out of an analog pin? How can I test my circuit to insure the analog pins work correctly?

jes1510
01-07-2010, 07:08 PM
here is a pretty good example of I2C on an Arduino talking to an EEPROM.
http://www.arduino.cc/playground/Code/I2CEEPROM

Edit: here is the reference for the wire library:
http://arduino.cc/en/Reference/Wire

lnxfergy
01-07-2010, 07:25 PM
Have you not seen this page: http://www.robot-electronics.co.uk/files/MD23.pde I'm assuming that's the "code you had to modify to remove the LCD stuff", but then I have to wonder why you were using 0xB0, and not 0x58...

Seems like all the code you could need is there. The reason your code doesn't work is that it's not sending a complete transmission, you're just sending the start bit and the address...

As for not knowing what send does, that's not documented on Arduino because it's part of I2C itself. Everything is byte-oriented, you are reading and writing 8-bit bytes on the device. Therefore, each send() call, converts that int to a byte, and sends it. To write to a register on the motor driver, you have to call beginTransmission(addr), a send(first_register_num_to_write), a number of send(byte_of_data) calls to set the value of the registers, and an endTransmission(). In their code, a good example is:


void encodeReset(){ // This function resets the encoder values to 0
Wire.beginTransmission(md23Address);
Wire.send(cmdByte);
Wire.send(0x20); // Putting the value 0x20 to reset encoders
Wire.endTransmission();
}


Here, they are writing to the cmdByte register (defined earlier in the code as 0x10 -- or decimal 16 in their documentation). The only data sent is 0x20, the value of a command to reset the encoders.

As for reading from Address 32, um, there doesn't appear to be an address 32. But a read is also shown in that code:


long encoder1(){ // Function to read and display value of encoder 1 as a long
Wire.beginTransmission(md23Address); // Send byte to get a reading from encoder 1
Wire.send(encoderOne);
Wire.endTransmission();

Wire.requestFrom(md23Address, 4); // Request 4 bytes from MD23
while(Wire.available() < 4); // Wait for 4 bytes to arrive
long firstByte = Wire.receive(); // Recieve 4 bytes highest byte first
long secondByte = Wire.receive();
long thirdByte = Wire.receive();
long fourthByte = Wire.receive();

long poss1 = (firstByte << 24) + (secondByte << 16) + (thirdByte << 8) + fourthByte; // Put them together

// removed lcd code for clarity...

return(poss1); // returns value of encoder 1 position as a long
}


This looks a bit funky at first, but remember, we are using a register table in the device. The begin/send/end part in the first 3 lines tell the MD03 what register we want to read (encoderOne). We then do a requestFrom for the 4 bytes, and read in the bytes, finally putting them together to get a 32-bit value.

Devantech also has an I2C tutorial that you may want to look at (or google around for another, there's quite a few, this was just one that I knew the address of): http://www.robot-electronics.co.uk/acatalog/using_the_i2c_bus.htm

-Fergs

ROBOTMAN
01-07-2010, 07:31 PM
That is helpful but I got most of that already. I think my problem is hardware not software. I try and begin transmission with the device but I don't get a light like I should. All the jumpers are connected so the address must be right. Everything is wired but the resistors and when the transmission is ended the light flashes but that is the only time.

Edit:
Sorry didn't see your message I'll check it out.

lnxfergy
01-07-2010, 07:36 PM
Everything is wired but the resistors... .

You mean the 1K8 resistors? Yeah you NEED those... it's also I2C spec. (1k8 is really quite low, making me really think they need them. The Arduino is equivalent to a 10-30k pullup, so it's not getting enough current to bounce back possibly).

EDIT: Oh, and I just noticed that their schematic is WRONG. You need a 1k8 between VCC and SCL, and another between VCC and SDA, not two on SDA.

-Fergs

ROBOTMAN
01-07-2010, 07:48 PM
Nothing seems to work. I can't tell if the encoder reset works and because my encoders are not connected I can't run the other code. I made this program based on what I learned and it wont work.

#include <Wire.h>

#define md23Address 0x58 // Address of the MD22
#define softwareReg 0x0D // Byte to read the software version
#define speed1 0x00 // Byte to send speed to first motor
#define speed2 0x01 // Byte to send speed to second motor
#define cmdByte 0x10 // Command byte
#define encoderOne 0x02 // Byte to read motor encoder 1
#define encoderTwo 0x06 // Byte to read motor encoder 2



void setup()
{
Wire.begin();
}

long encoder1;

void loop()
{
int x = 0;
x = 255;
Wire.beginTransmission(md23Address);
Wire.send(speed1);
Wire.send(x); // Putting the value 0x20 to reset encoders
Wire.endTransmission();
delay(100);
}

Because it is a loop you would think the light would keep blinking but it only blinks once and nothing happens.

Edit:
Again missed the post I'll work on it.

ROBOTMAN
01-07-2010, 08:16 PM
I rewired everything and connected it the way you told me. Still nothing. I tested the motors and they work. Could accidentally attaching the resistors to 9v instead of 5v have broken the controller? I assume vcc means regulated 5v right? No deadly blue smoke came out so I thought I was fine. Also the 1k8 resistor would be BROWN, GRAY, RED and 1.700ish k right?

ROBOTMAN
01-07-2010, 10:32 PM
I attached my multimeter to ground and the SCL line. I picked up a voltage of positive 3.72 volts unchanging. Doing the same thing to the SDA line resulted in what appeared to be a solid positive .16 volts unchanging. From what I understand if done properly this should fluctuate between 5v and 0v right? It is in a loop as well so I would expect to see it keep happening. Also the Wire.endTransmit(); command that causes the light to blink only works once even in a loop. I need help asap because I wont be able to work on this much longer. Please help. Here is a picture of my circuit that feeds positive 5v to the resistors and provides the connection between the arduino and the MD23. I am trying to give as much information as possible.


http://forums.trossenrobotics.com/gallery/files/2/6/4/3/circut.jpg

Click here (http://forums.trossenrobotics.com/gallery/files/2/6/4/3/circut_original.jpg) and zoom for a detailed image. The wite wire is power the four yellow wires are SDA, SCL, connection to arduino analog pin 4, and connection to analog pin 5. The resistors are I believe the right ones.

lnxfergy
01-07-2010, 11:01 PM
I rewired everything and connected it the way you told me. Still nothing. I tested the motors and they work. Could accidentally attaching the resistors to 9v instead of 5v have broken the controller? I assume vcc means regulated 5v right? No deadly blue smoke came out so I thought I was fine. Also the 1k8 resistor would be BROWN, GRAY, RED and 1.700ish k right?

I'm out of ideas, the code is, in theory, correct. The hardware assembly is pretty straight-forward. You might try contacting whoever you bought it from, or robot electronics.

Without putting a scope or a logic analyzer on it, can't say for sure, but 9V into a 5V circuit could probably be bad even with a limit resistor in place. It's not a matter of blue smoke (doubt you would kill the whole processor), but you might have popped an I/O line.

EDIT: out of curiousity, how long are your wires? I2C requires a low-capacitance bus, those 1k8 resistors are pretty high current (compared to a 10k), so they could handle quite a bit of bus capacitance.

-Fergs

ROBOTMAN
01-07-2010, 11:07 PM
That would make sense I guess. I am curious about the voltage not moving however. I do have a oscilloscope sort of thing could that may help. I think I should start at the source and that is to check and make sure I am getting 0v and 5v pulses because right now I am pretty sure I am not. I don't know what that means.

lnxfergy
01-07-2010, 11:17 PM
That would make sense I guess. I am curious about the voltage not moving however. I do have a oscilloscope sort of thing could that may help. I think I should start at the source and that is to check and make sure I am getting 0v and 5v pulses because right now I am pretty sure I am not. I don't know what that means.

The I2C clock signal is running at 100khz... that's way faster than your meter is gonna do, you need a scope to see that. Your meter is showing something along the lines of an average voltage...

-Fergs

ROBOTMAN
01-08-2010, 12:13 AM
I emailed robot shop. I'm betting it is broken for anyone with the same problem. I will post the final results when I know. That just goes to show always buy from trossen!