[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 ;)
- Log in to post comments



piborg
Thu, 04/14/2016 - 11:45
Permalink
UltraBorg I2C communications
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
UbSetServoPosition1function 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
writefunction 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
writeandread.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;