How to program HiTechnic servo with HiTechnic Servo Controller for TETRIX
See original GitHub issue- ev3dev version: 4.4.87-22-ev3dev-ev3
I am trying to program a servo so that is it able to position itself to a number of degree. In order to achieve this, I understand that it first has to connected with a servo controller so that data transmission is possible.
This is my setup. As depicted from the image below, DC Controller is connected to input 2
and Servo Controller is connected to input 3
.
My goal is to manipulate servo
that is connected to channel 1
. I was able to rotate the dc motor
but not the servo.
Code
>>> import smbus
>>> dc = smbus.SMBus(4)
>>> servo = smbus.SMBus(5)
>>> dc.write_i2c_block_data(0x01, 0x46, [0x30]) # motor rotates
>>> servo.write_i2c_block_data(0x01, 0x42, [0x30, 0x55]) # servo did not react
I am confident that the number of addresses and registers are correctly configured. I tried to write and read block data multiple times and it shows that data is being written in the correct channel.
>>> print(servo.read_i2c_block_data(0x01, 0x42))
[48, 85, 90, 91, 128, 128, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
So the question is, how can I control the position of the servo and what exactly does the third parameter array means (180 degree span across 32 bits of character?)
Regards, Rex.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:17 (8 by maintainers)
First, to be clear, I am only talking about hobby-type servo motors here. https://en.wikipedia.org/wiki/Servo_(radio_control)
Actually, you change the duty cycle, not the frequency. These types of motors use a 50Hz signal (one pulse every 20ms) for control. The width of this pulse tells the motor which angle to rotate to. 1.5ms is the “neutral” position. 1.0ms is the minimum rotation and 2.0ms is the maximum rotation.
You can’t know the exact position of the servo motor. It does not have any feedback. You can only know what position you have requested it to move to. It may or may not have yet reached that position though (and may never reach it if it is blocked).
The docs say:
So, you need to do some math to translate. Suppose you have a servo that can travel 180 degrees. We will call the neutral position 0 degrees and the minimum and maximum -90 and 90 degrees respectively (90 - (-90) = 180). Here is a generic scaling function:
So, if we want to go to 30 degrees, that would translate to a 1.67ms pulse width (I trust that you can figure out the math). Then translating that again using the info from the user manual, we get that 1.67ms becomes 170, so we need to write 170 to the controller to get 30 degrees on the motor. (Of course, in your program, you could simplify this to only one conversion instead of calculating the intermediate pulse width).
The reason the controller goes beyond the 1.0 - 2.0ms range I described above is that these motors generally use analog circuits and are not exact. You may need to “calibrate” the motor by telling it to go 90 degrees. If it is not actually 90 degrees, keep adjusting the value you send to the motor controller until you get exactly 90 degrees and save that number to use as
out_max
. Then do the same for -90 degrees to get the minimum value.Hi, I have a problem on moving the servo to a certain value, using ev3dev python too. I tried following OpenRTM’s website but I’m still clueless as to bringing the servo to move like it would on LabVIEW.