Grove I2C Motor Driver Setup and Example Code
After much deliberation I was finally able to get my Grove I2C motor driver and its example code working. I had originally had problems compiling a set of example code that I found online but now I have fixed the code. Also I have made a drawing showing how to connect the Grove I2C Motor Driver to an Arduino Uno. It seems that very few people have made tutorials on this controller other than the wiki page which has just a lot of technical information which is great but for people who don't want all that extra information I have made this short tutorial. I kept it short sweet and to the point so hopefully if you are trying to use one of these controllers you will be able to use the information on this page.
Setup:
The example code bellow should simply make the motor spin and then reverse directions repeatedly.
Additional help can be found here:
http://www.seeedstudio.com/wiki/index.php?title=Grove_-_I2C_Motor_Driver
http://www.seeedstudio.com/forum/viewtopic.php?f=17&t=2935
http://www.arduino.cc/en/Reference/Wire
Additional help can be found here:
http://www.seeedstudio.com/wiki/index.php?title=Grove_-_I2C_Motor_Driver
http://www.seeedstudio.com/forum/viewtopic.php?f=17&t=2935
http://www.arduino.cc/en/Reference/Wire
Working Code Example:
#include <Wire.h> //#define MOTORSHIELDaddr 0x0f #define SETPWMAB 0x82 #define SETFREQ 0x84 #define CHANGEADDR 0x83 #define CHANNELSET 0xAA #define MOTOR1 0xA1 #define MOTOR2 0xA5 #define SAVEADDR 'S' #define NOTSAVEADDR 'N' byte val = 0; // I put this here to replace the "Wire.write(0);" static unsigned char MOTORSHIELDaddr = 0x28; void speedAB(unsigned char spda , unsigned char spdb) { Wire.beginTransmission(MOTORSHIELDaddr); // transmit to device MOTORSHIELDaddr Wire.write(SETPWMAB); //set pwm header Wire.write(spda); // send pwma Wire.write(spdb); // send pwmb Wire.endTransmission(); // stop transmitting } void fre_pre(unsigned char pres) { Wire.beginTransmission(MOTORSHIELDaddr); // transmit to device MOTORSHIELDaddr Wire.write(SETFREQ); // set frequence header Wire.write(pres); // send prescale Wire.write(val); // need to send this byte as the third byte(no meaning) Wire.endTransmission(); } void change_adr(unsigned char new_adr, unsigned char save_or_not) { Wire.beginTransmission(MOTORSHIELDaddr); // transmit to device MOTORSHIELDaddr Wire.write(CHANGEADDR); // change address header Wire.write(new_adr); // send new address Wire.write(save_or_not); // save the new address or not Wire.endTransmission(); // delayMicroseconds(100); //this command needs at least 6 us } void channel(unsigned char i4) //0b 0000 I4 I3 I2 I1 { delayMicroseconds(4); Wire.beginTransmission(MOTORSHIELDaddr); // transmit to device MOTORSHIELDaddr Wire.write(CHANNELSET); // channel control header Wire.write(i4); // send channel control information Wire.write(val); // need to send this byte as the third byte(no meaning) Wire.endTransmission(); } void motorAndspd( unsigned char motor_s,unsigned char Mstatus, unsigned char spd) { Wire.beginTransmission(MOTORSHIELDaddr); // transmit to device MOTORSHIELDaddr Wire.write(motor_s); // motor select information Wire.write(Mstatus); // motor satus information Wire.write(spd); // motor speed information Wire.endTransmission(); } void setup() { Wire.begin(); // join i2c bus (address optional for master) delayMicroseconds(10); //wait for motor driver to initialization } void loop() { motorAndspd(0xA1,0B01,225); motorAndspd(0xA5,0B01,30); delay(2000); motorAndspd(0xA5,0B10,225); motorAndspd(0xA1,0B10,30); delay(2000); change_adr(0x12, NOTSAVEADDR ); MOTORSHIELDaddr = 0x12; for( int i = 0;i< 16;i++) { fre_pre(i); channel(i); delay(100); } speedAB(100 , 100); // was 0 , 0 change_adr(0x28,NOTSAVEADDR ); MOTORSHIELDaddr = 0x28; while(1) { channel(0b00001010); delay(500); channel(0b00000101); delay(500); } } |
Hello,
ReplyDeleteI have been studying the code for the Grove I2C because we are building a robot in school and i understand it all except for the fre_pre void, could somebody explain it to me!
Thank You!
:D
Hi, It has been a while since I have looked at this code. My goal was to get the motor driver to work with the example code that I found online because Arduino had made a change to their syntax since the program was written. I haven't had a chance to go any further with the code since then. Luckily I know some people who are very good with Arduino and I will confer with them about it and then get back to you. Sorry I'm unable to provide you with an answer right away but I at least wanted to let you know that your comment was not being ignored. I will reply back as soon as I can.
ReplyDeleteOK, This is what I have come up with. The
ReplyDelete"void fre_pre(unsigned char pres)" seems to be initializing a variable called 'pres'. However, the 'fre_pre' part may specifically serve the purpose of declaring a calibration method for this particular function. I will let you know if I find out anything more in the next few days.
Also, "fre_pre" stands for frequency prescaler. This code sends the frequency prescaler to the motor controller. I was informed of the following: A frequency prescaler is one of two arguments required to set the operating speed of the Atmel chip. The other is the crystal or internal clock. The basic version is prescaler x frequency gives final frequency. I think with the right prescaler one can clock the Atmel right down to 33KHz. This is important for power saving and if specific frequency matching is required.
ReplyDeleteI hope this is more help to you.