8 Channel Servo Controller Mindsensors


#1

Hi,

does anybody get the Mindsensors 8 Channel Servocontroller to work with the BrickPi and Python?

Basically the documentation (http://www.mindsensors.com/index.php?module=documents&JAS_DocumentManager_op=downloadFile&JAS_File_id=1263)
says that if you want to set the servo 1 to 2000, you need to set the register 0x5A to 1/10 of that value, which would be 200. I think at this point my biggest problem is, that Iam not experienced in how to use the I2C function of the BrickPi Api.

This is what i did:

BrickPi.SensorType[PORT_1] = TYPE_SENSOR_I2C
BrickPi.SensorI2CSpeed[PORT_1] = 0
BrickPi.SensorI2CDevices[PORT_1] = 1

BrickPi.SensorI2CAddr[PORT_1][0] = 0x5A # the register for the first servo
BrickPi.SensorSettings[I2C_PORT][I2C_DEVICE] = BIT_I2C_SAME

BrickPi.SensorI2CWrite[I2C_PORT][I2C_DEVICE] = 1 # write one byte
BrickPi.SensorI2CRead[I2C_PORT][I2C_DEVICE] = 0 # dont read anything
BrickPi.SensorI2COut[I2C_PORT][I2C_DEVICE][0] = 200 # send the 200 to the buffer
BrickPiUpdateValues() # send everything to the BrickPi

The Programm does not throw exceptions, but there is no response from the servos at all.


#2

Have a look through the notes here: https://github.com/DexterInd/BrickPi_Python/blob/master/Developer%20Notes%20-%20BrickPi%20I2C.txt about BrickPi I2C.
Looking at the code you have, this line:
BrickPi.SensorI2CAddr[PORT_1][0] = 0x5A # the register for the first servo
Should be setting the address of the device itself on the I2C bus, which according to the docs you link is 0xB0.
The way I2C works (in this context at least) is you then send an array of 2 bytes - the first byte contains the address of the register you want to write to (in this case, 0x5A), the second byte is the value you wish to set that register to (200). If I’m not mistaken, the correct way to do that would be:

BrickPi.SensorI2CAddr[PORT_1][0] = 0xB0 # Tell the BrickPi that device 1 on port 1 uses I2C address 0xB0
BrickPi.SensorSettings[PORT_1][0] = BIT_I2C_SAME
BrickPi.SensorI2CWrite[PORT_1][0] = 2 # We'll be sending 2 bytes - the register address and the value
BrickPi.SensorI2CRead[PORT_1][0] = 0 # don't read anything
BrickPi.SensorI2COut[PORT_1][0][0] = 0x5A; Set the first byte to the address of the register to write to
BrickPi.SensorI2COut[PORT_1][0][1] = 200 # Set the second byte to the value we wish that register to have
BrickPiUpdateValues() # send everything to the BrickPi

Hope that helps.


#3

Thanks for this description, it realy helped me out to understand how I2C on the BrickPi should work.

Unfortunately the Servo Controller is still not working at all. I will test it the days on the NXT to check if I messed up the controller due to my attempts to get this little bastard to work. If someone get the controller to work in the meantime, I would be happy to see some code :slight_smile:

Thanks a lot Shao for your help


#4

Thanks Shao!

Mstrehse, do you have a logic analyzer you can take a look at the data going back and forth with? It might help to figure out what’s going wrong. Just an idea.


#5

Hi,

sorry for the late awnser. I do not have an logic analyzer, so iam not able to figure out, whats going wrong here.

At this point I can say, that the servo controller is working with the original NXT and the Address of the controller is still the 0xB0. I also know, what you have to do, to get the controller to work. We dont need fancy reverse engeneering at this point, because all you need (i think) is written in the manual (http://www.mindsensors.com/index.php?module=documents&JAS_DocumentManager_op=downloadFile&JAS_File_id=1263)

The sourcecode from Shao is in my opinion absolutely right and makes sense to me, but it is not working. I think it would be less painfull to work with the BrickPi, if we would have a better documentation of how to send some data to a bit over the I2C Protocoll with an example or two. All I can see at this moment is a very confusing txt file in the git repository :frowning:

Lets say for instance I want to send the data 250 to the bit 0x5A on the only device on port one with the address 0xB0. How should the complete sourcecode of my application look like?

At this point I have the following:

from BrickPi import *

BrickPi.SensorType[PORT_1] = TYPE_SENSOR_I2C
BrickPi.SensorI2CSpeed[PORT_1] = 0
BrickPi.SensorI2CDevices[PORT_1] = 1

BrickPiSetup()

BrickPi.SensorSettings[PORT_1][0] = BIT_I2C_SAME
BrickPi.SensorI2CAddr[PORT_1][0] = 0xB0

BrickPi.SensorI2CWrite[PORT_1][0] = 2
BrickPi.SensorI2CRead[PORT_1][0] = 0
BrickPi.SensorI2COut[PORT_1][0][0] = 0x52
BrickPi.SensorI2COut[PORT_1][0][1] = 250
BrickPiSetupSensors()

I hope that helps to figure out, why it doesnt work.


#6

Ok after some research i found the problem. The Servo Controller definitly needs aditional power supply on the BrickPi. After I attached a 9V Block to the pi, the controller works as expected.

I will build a python class for the communication with the servo controller upload it here when iam finished.

Here is the way to get the servo controller work with the BrickPi:

  1. Make sure the RaspberryPi has 9V on its USB Port
  2. Connect a 9V battery to the BrickPi, because the servo controller needs power supply to work.
  3. connect your servos to the controller (make sure the yellow wire of the servo is on the side where the controller has a white stripe)
  4. Use the following code to set the servo on port 1 to 2000 µS

from BrickPi import *

General port settings for port 1

BrickPi.SensorType[PORT_1] = TYPE_SENSOR_I2C
BrickPi.SensorI2CSpeed[PORT_1] = 0
BrickPi.SensorI2CDevices[PORT_1] = 1

BrickPiSetup()

settings for the controller

BrickPi.SensorI2CAddr[PORT_1][0] = 0xB0
BrickPi.SensorSettings[PORT_1][0] = BIT_I2C_MID #BIT_I2C_SAME wont work

write 2 bytes, read none

BrickPi.SensorI2CWrite[PORT_1][0] = 2
BrickPi.SensorI2CRead[PORT_1][0] = 0

Set the position of the servo

Servo:

0x5A - Servo 1

0x5B - Servo 2

Position:

The values for the positions are between 50 and 250.

A value of 150 is the center position

Example: Servo 1 to 200

BrickPi.SensorI2COut[PORT_1][0][0] = 0x5A
BrickPi.SensorI2COut[PORT_1][0][1] = 200
BrickPiUpdateValues()

Hope that helps :wink:


#7
from BrickPi import *

# General port settings for port 1
BrickPi.SensorType[PORT_1] = TYPE_SENSOR_I2C
BrickPi.SensorI2CSpeed[PORT_1] = 0
BrickPi.SensorI2CDevices[PORT_1] = 1

BrickPiSetup()

# settings for the controller
BrickPi.SensorI2CAddr[PORT_1][0] = 0xB0
BrickPi.SensorSettings[PORT_1][0] = BIT_I2C_MID #BIT_I2C_SAME wont work

# write 2 bytes, read none
BrickPi.SensorI2CWrite[PORT_1][0] = 2
BrickPi.SensorI2CRead[PORT_1][0] = 0

# Set the position of the servo
#
# Servo:
# 0x5A – Servo 1
# 0x5B – Servo 2
# …
#
# Position:
# The values for the positions are between 50 and 250.
# A value of 150 is the center position
#
# Example: Servo 1 to 200
BrickPi.SensorI2COut[PORT_1][0][0] = 0x5A
BrickPi.SensorI2COut[PORT_1][0][1] = 200
BrickPiSetupSensors()
BrickPiUpdateValues()

#8

Fantastic! Thanks for sharing!