[HELP] How will this be handled?

Forums:

Dear piBorg community,

I have a couple of questions where I am struggling with.
First of all, I am writing an API for the UltraBorg motorcontroller and I2C in global.

In the linux kernel, it is required to have a I2C address.
The UltraBorg is connected at address 0x36. (See picture)

But the devices that are connected to the UltraBorg does not have their own I2C SLAVE address.
How are we still able to communicate with these slaves?

As far as I can see we need an address to communicate with a device.
https://www.kernel.org/doc/Documentation/i2c/dev-interface

Also, i2c_read_word_data prints out 218 in any case for the UltraBord motorcontroller.
But what does this number means?

I hope someone can clear out some things.
Thanks anyway ;)

Images: 
piborg's picture

I think there is a little bit of confusion here :)

The UltraBorg is at address 0x36 is you have said above.
All of the attached servos and ultrasonic sensors are controlled by talking to the UltraBorg at address 0x36 and sending different commands.

If you find the UltraBorg.h code on this page you can see the various command codes.
https://www.piborg.org/ultraborg/examples#code
The commands all start with UB_COMMAND_

Further down the page is UltraBorg.cpp, this is the source for an Arduino and is fairly similar to what you need to do.
For example the UbSetServoPosition1 function changes the position for a servo connected in the #1 slot.

The setup ready to talk is quite simple:

unsigned char writeBuffer[UB_I2C_MAX_LEN];
unsigned char readBuffer[UB_I2C_MAX_LEN];
int address;
int ultraBorg;

// Open I2C communications
ultraBorg= open("/dev/i2c-1", O_RDWR);
address= 0x36;
ioctl(ultraBorg, I2C_SLAVE, address);

The commands themselves are fairly simple, they work by sending the command byte first followed by any data bytes.
For example to set the servo #1 position we can simply use the write function like this:

// We need the following values here:
// * float position <- the servo position between -1 and +1
// * int UbServo1Min <- the lowest allowed value, the default is UB_DEFAULT_PWM_MIN
//                     read the tuned value using UbGetServoMinimum1
// * int UbServo1Max<- the highest allowed value, the default is UB_DEFAULT_PWM_MAX
//                     read the tuned value using UbGetServoMaximum1

// Work out the PWM setting from the position value
float powerOut = (position + 1.0) / 2.0;
unsigned int pwmDuty = (unsigned int)((powerOut * (UbServo1Max - UbServo1Min)) + UbServo1Min);

// Build the command
int length = 3;
writeBuffer[0] = UB_COMMAND_SET_PWM1;  // The command to set the position on servo #1 
writeBuffer[1] = (unsigned char)((pwmDuty >> 8) & 0xFF);
writeBuffer[2] = (unsigned char)(pwmDuty & 0xFF);

// Send the command
if (write(ultraBorg, writeBuffer, length) != length) {
    // Failed to send correctly !
}

Reading we need to use both write and read.
For example this would read the first ultrasonic sensor (UbGetDistance1):

unsigned int time_us;

// Build the command
int length = 1;
writeBuffer[0] = UB_COMMAND_GET_FILTER_USM1;  // The command to read the distance on ultrasonic #1

// Send the command
if (write(ultraBorg, writeBuffer, length) != length) {
    // Failed to send correctly !
}

// Read the reply
length = UB_I2C_MAX_LEN;
if (read(ultraBorg, readBuffer, length ) == length ) {
    // We read the data reply
    time_us = ((unsigned int)readBuffer[1] << 8) + (unsigned int)readBuffer[2];
    if (time_us == 65535) time_us = 0; // Check for an error value
} else {
    // Something went wrong !
    time_us = 0;
}

// Work out the distance
float distance1 = (float)time_us * UB_USM_US_TO_MM;
Subscribe to Comments for &quot;[HELP] How will this be handled?&quot;