address change MD25 etc w/ Arduino code

Motor, Servo, Speech etc.

Moderator: chris

address change MD25 etc w/ Arduino code

Postby slomobile » Thu Nov 10, 2011 2:56 pm

First, a forum issue. Searching for "MD25 I2C address change Arduino" or any other relevant search term for this problem returns 0 results because the search terms are "too common", the entire search phrase is ignored. This is either a problem with the forum search, or changing device address using Arduino is a common problem without an easily locatable solution. Hopefully this thread can become that solution if only people could find it.

The main problem: We're using 2 RD02 sets for our 4wd robot; of course we need to change the address of one of them. I wrote the following code based on MD25 documentation to change the address, but it does not work. There are unknown communication errors writing to the command register. I am able to communicate with the devices and write speed changes if only 1 MD25 is connected. I am using 3.3kOhm pullups on a Teensy++. When running this sketch, a single MD25 is the only device on the bus. I've tried w/ + w/o a shared 5v connection, w/ + w/o power applied to the MD25 battery terminal.
Regardless of what the solution turns out to be, I need clarification on what the right arguments to this line should be.
Code: Select all
changeI2Caddress(0xB0, 0xB4, 16);    // also tried with (0x58, 0x59, 16), (58, 59, 16), (0x58, 0xB4, 16), (176, 178, 16)

Note: there was a bit of not strictly necessary debug and human feedback code added when I realized this wasn't working. The main functionality is in this function.
Code: Select all
void changeI2Caddress(uint8_t oldAddress, uint8_t newAddress, uint8_t commandRegister)

Code: Select all
/*
addressChange.pde
Author: Dustin Maki    11/10/11
Arduino 022 sketch running on Teensy++
Objective: provide universal method to change I2C address on Devantech I2C devices
Devices available for testing: 2x RD02 w/MD25, 1x CMPS10, 1X TPA81, 1X SD20, 1X LCD03 20X4 GREEN, 1X GPIO14
*/
#include <Wire.h>
static const uint8_t BUTTON = 3;// active low
static const uint8_t LED = 6;
uint8_t transmissionStatus = -1;

void setup()
{
    Serial.begin(57600);
    Serial.println("Initialized serial.print");
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);       
    pinMode(BUTTON, INPUT);
    digitalWrite(BUTTON, HIGH);// engage internal pullup resistor
    delay(2000);
    while (HIGH == digitalRead(BUTTON))//button NOT pressed
    {
      delay(1);
        // __asm__("nop\n\t"); //do nothing, just wait for button to be pressed
    }
    digitalWrite(LED, HIGH);//turn led on during address change.
   
    changeI2Caddress(0xB0, 0xB4, 16);    // also tried with (0x58, 0x59, 16), (58, 59, 16), (0x58, 0xB4, 16), (176, 178, 16)
   
    delay(1000);// the function happens fast, keep the LED on a bit so a human perceives something was actually done.
    /*
    TODO: Programatically verify that address has been sucessfully changed.
    Perhaps read firmware version at new address, however that method varies by device.
    */
}

void loop()
{
    //flash LED following sucessful address change
    digitalWrite(LED, LOW);//blink LED when address change complete.
    delay(250);
    digitalWrite(LED, HIGH);
    delay(250);
}




void changeI2Caddress(uint8_t oldAddress, uint8_t newAddress, uint8_t commandRegister) //must be run with ONLY the device whose address is to be changed connected to the I2C bus
{
     Serial.println("Entered changeI2Caddress function");
       
     Wire.beginTransmission(oldAddress);
     Wire.send(commandRegister);
     Wire.send(0xA0);    // also tried changing this arguement to 160
     transmissionStatus = Wire.endTransmission();
     Serial.println("First byte sent");
     printI2Cstatus(transmissionStatus);     
     delay(101);
     
     Wire.beginTransmission(oldAddress);
     Wire.send(commandRegister);
     Wire.send(0xAA);    // also tried changing this arguement to 170
     transmissionStatus = Wire.endTransmission();
     Serial.println("Second byte sent");
     printI2Cstatus(transmissionStatus);     
     delay(101);
     
     Wire.beginTransmission(oldAddress);
     Wire.send(commandRegister);
     Wire.send(0xA5);    // also tried changing this arguement to 165
     transmissionStatus = Wire.endTransmission();
     Serial.println("Third byte sent");
     printI2Cstatus(transmissionStatus);     
     delay(101);
     
     Wire.beginTransmission(oldAddress);
     Wire.send(commandRegister);
     Wire.send(newAddress);
     transmissionStatus = Wire.endTransmission();
     Serial.println("New address sent");
     printI2Cstatus(transmissionStatus);
     delay(1000);
     
     Serial.println("Leaving changeI2Caddress function");
}

void printI2Cstatus(uint8_t I2Cstatus)
{
    switch (I2Cstatus)
    {
    case 0:
      Serial.println("0 Success");
      break;
    case 1:
      Serial.println("1 data too long to fit in transmit buffer");
      break;
    case 2:
      Serial.println("2 received NACK on transmit of address");
      break;
    case 3:
      Serial.println("3 received NACK on transmit of data");
      break;
    case 4:
      Serial.println("4 other error");
      break;
    default:
      // if nothing else matches, do the default
      Serial.print("unrecognized value: ");
      Serial.println(I2Cstatus);
    }
}

Output from the serial monitor looks like this:

Initialized serial.print
Entered changeI2Caddress function
First byte sent
4 other error
Second byte sent
4 other error
Third byte sent
4 other error
New address sent
4 other error
Leaving changeI2Caddress function

I then remove and reconnect power to the MD25 to see if that green 'communication' LED on MD25 will flash more than once. It never does. FYI, it seems to be a fairly brief flash, well under 1 second. Is that the length of the single 'long' flash indicating the default 0xB0 address?
slomobile
 
Posts: 7
Joined: Sun Oct 30, 2011 1:14 pm

Re: address change MD25 etc w/ Arduino code

Postby chris » Fri Nov 11, 2011 12:19 pm

The correct numbers to send to the function are: 0x58, 0xB4, 16

I can't see Wire.begin(); being called to join the I2C bus system as a master....
User avatar
chris
 
Posts: 172
Joined: Wed Nov 08, 2006 3:13 pm
Location: Norfolk, England

Re: address change MD25 etc w/ Arduino code

Postby slomobile » Sat Nov 12, 2011 9:39 pm

Thank you for that. I've had 5 sets of experienced eyeballs look at this code and none of them found that very basic omission. Wire.begin(); was in the code previously; not sure how it went walkabout. Will retest on Monday when I have access to the bot. BTW, anyone is welcome to use this code.
slomobile
 
Posts: 7
Joined: Sun Oct 30, 2011 1:14 pm

Re: address change MD25 etc w/ Arduino code

Postby slomobile » Mon Nov 14, 2011 8:16 pm

Still does not work. Called changeAddress(0x58, 0xB4, 16); Added Wire.begin(); to setup. The serial monitor output instead of "4 other error" displays "2 received NACK on transmit of address". Any idea why?
slomobile
 
Posts: 7
Joined: Sun Oct 30, 2011 1:14 pm

Re: address change MD25 etc w/ Arduino code

Postby chris » Tue Nov 15, 2011 4:57 pm

Are the jumpers on the MD25 set for I2C?
Can you talk to the MD25 to read the software version, is it possible the board has been changed to address 0xb4 at some stage?
There is an example for the Arduino with a MD25 here: http://www.robot-electronics.co.uk/acat ... mples.html
User avatar
chris
 
Posts: 172
Joined: Wed Nov 08, 2006 3:13 pm
Location: Norfolk, England

Re: address change MD25 etc w/ Arduino code

Postby slomobile » Wed Nov 16, 2011 7:44 am

Mission accomplished. I'm not sure exactly what went wrong when, but we had multiple people trying to troubleshoot simultaneously. I'm guessing that more than once, one person decided to try one change that would have fixed it at the same time someone else tried something that broke it leading to a wild goose chase. Lesson learned(yet again)- only perform 1 change at a time, then test. repeat as necessary. The last thing we changed that made it work was correcting the SDA/SCL lines at the processor. I know they were correct for most of the troubleshooting I performed but at some point after I described i2c as a serial protocol someone assumed that because Rx and Tx are normally swapped in one type of serial protocol that our 2 wires should be swapped too. Wrong. Thanks for the help.
slomobile
 
Posts: 7
Joined: Sun Oct 30, 2011 1:14 pm


Return to Drivers

Who is online

Users browsing this forum: No registered users and 0 guests