LOADING

Type to search

Electronics

Mastering Bus Servos with Nvidia Jetson Nano: A Comprehensive Guide


Introduction

Welcome to Tasty Tech Harbour! In today’s post, we’re exploring the intricate yet exciting world of bus servos, specifically focusing on their application in robotic arms. We’ll be leveraging the powerful Nvidia Jetson Nano and a bus servo driver to bring these concepts to life. Whether you’re a seasoned robotics enthusiast or just starting, this guide will provide you with all the necessary steps to understand and control bus servos using the I2C bus


Python Code with Explanation below

             #These are the libraries which we will be using to set the ID and control the servos
import smbus #The smbus library is a Python module that allows for communication with 
             #devices over the I2C (Inter-Integrated Circuit) bus. 
             #It is part of the i2c-tools package and provides an interface for interacting with 
             #I2C devices on Linux systems.
bus = smbus.SMBus(1) #Here we areinitialising the SMBus Class from the smbus library which setsup the communication
                     #with the I2C bus.SMBus(1) the 1 here is the I2C bus number which we found out from the 
                     #the command prompt "I2Cdetect -y -r 1"
                     #y: This option disables interactive mode. Normally, i2cdetect will ask for confirmation 
                     #before scanning each address.Ussing y skips these prompts, making the command non-interactive 
                     #and faster.
                     #r: This option tells i2cdetect to use read byte commands for probing the I2C bus. Normally,
                     #it uses a combination of read and write operations, but the r option forces it to 
                     #use only read operations, which can be safer for some devices.
id = 1 #Here we are creating the id number which has to be set to servo motor, so please enter the ID number you 
       #want to write to the device register address which stores the ID of the Servo.

bus.write_byte_data(0x15, 0x18, id & 0xff)  

#To explain the parameters which We are passing to "write_byte_data".

#write_byte_data(I2CDevice Address, Register address, 
#This is the data byte that you want to write to the specified register).

#In the above line, 0x15 is the I2C Device address.

#Register address/command address(Devices often have multiple registers, 
#each serving different functions (e.g., configuration, data storage). In this case, 0x18 is the specific register you're #targeting which is a command to write the ID of the Servo.

#id & 0xff which is data ( In this case, id & 0xff ensures that only the least significant 8 bits 
#of the id variable are used. The & 0xff operation masks the id to a 
#single byte (0-255 range).
#For example Id = 0001 which is 1, when I do an operation 0000 0001 & 1111 1111 = 0000 0001
#id & 0xff - the Idea behind using such expresion is to keep the data in the range 0 to 255. 
#i.e is to mask the lower bit of the data.
id = 1 #Servo ID to which the command has to be given
angle = 180 #Angle command input value
time = 1000  #The time in which the servo has to reach the target position.

position_scaling = int((3100 - 900) * (angle - 0) / (180 - 0) + 900)
#The above formula maps the angle to a position value suitable for the servo. 
#It linearly scales the angle between 0 and 180 to a position between 900 and 3100.
#The calculation scales the angle from a 0-180 degree range to a 900-3100 position range
print (position_scaling)

#we need to pass 4 data's of 8bits each. [pos_highBit(data1), pos_LowBit(data2), time_Highbit(data3), time_Lowbit(data4)]
#data 1: high 8-bit data of the servo position, 
#data 2: low 8-bit data of the servo position, the two data together are the position data of the servo, 
#        the range is: 96-4000.
#data 3: high 8-bit data of running time high data, 
#data 4: low 8-bit data of running time high data, the two data together are the running time,  
#        the default is 500 (500 milliseconds), and 0 means the fastest speed.

#Hence the bit operations are performed below.
pos_highBit = (position_scaling >> 8) & 0xFF
print (pos_highBit)
pos_LowBit = position_scaling & 0xFF
print (pos_LowBit)
#These lines split the pos integer into high (pos_highBit) and low (pos_LowBit) bytes. This is often 
#necessary for communication with I2C devices, which might expect data in 8-bit chunks.

time_Highbit = (time >> 8) & 0xFF
time_Lowbit = time & 0xFF
bus.write_i2c_block_data(0x15, 0x10 + id, [pos_highBit, pos_LowBit, time_Highbit, time_Lowbit])

#If id is 1, the register address will be 0x10 + 1 = 0x11. Us this as register address for controlling 
#the specific servo motor.
#If id is 2, the register address will be 0x10 + 2 = 0x12.
#And so on, up to id being 6, which would give 0x10 + 6 = 0x16.
#In many implementations, the ID of each servo corresponds directly to its register address. 
#so in this case the Base address is 0x10 to which the id number is address is added.


#[pos_highBit, pos_LowBit, time_Highbit, time_Lowbit] This is the data we sending to control the servo
#he write_i2c_block_data function is used to write a block of data to a specific register of an I2C device. 
#write_i2c_block_data(i2c_addr, register, data),  data=(list of int): The data bytes to write.
#The specific register and data values depend on the servo motor controller you are using and 
#the desired action. I got some information from the servo motor and the driver board supplier 
#which suggest a list of parameter to pass for control the servo motor. 

#1. **Calculate a position value** from the angle, scaling it to a specific range.
#2. **Extract high and low bytes** from the position value for transmission.
#3. **Extract high and low bytes** from the time value for transmission.
#4. **Send the data** to an I2C device using the `write_i2c_block_data` function.

Conclusion

Controlling bus servos using the Nvidia Jetson Nano is a rewarding project that opens up many possibilities in robotics. By understanding the basics of bus servos, setting up the Jetson Nano, integrating a bus servo driver, and using the I2C bus, you’ll be well on your way to creating sophisticated robotic systems.


File

Please find the Download of the Jupyter Notebook File below.


If you found this guide helpful, don’t forget to check out our detailed YouTube video on the same topic. Like, subscribe, and hit the bell icon for more tech tutorials and project guides!


https://youtu.be/ZpJTdnawJNg

Leave a Comment

Your email address will not be published. Required fields are marked *