As i explained in the Video, The machine is now working much more stable thanks to the Yolo object Detection Algorithm. The written code on the raspberry pi was not optimized and since Raspberry pi is considered to be server it is very wise to optimize the code otherwise, it will consume the CPU power of the raspberry pi up to 100% and this will lead to complete stop of the program to run. I got a lot of hints and techniques from chat-gpt to optimize this code.
Below is the written the un-optimized code to control the Servo and DC motors and read and write the Push buttons as well as reading temperature sensor and light sensors. We also simultaneously read and write data via OPC-UA protocol in Python:
from opcua import ua, uamethod, Server
from adafruit_motorkit import MotorKit
from adafruit_servokit import ServoKit
import board
import time
import datetime
from gpiozero import Button
import RPi.GPIO as GPIO
import smbus
import sys
import adafruit_dht
server = Server()
url = "opc.tcp://192.168.1.6:4840"
server.set_endpoint(url)
server.secure_channel_timeout = 500000000
server.session_timeout = 500000000
name = "raspberrypi"
addspace = server.register_namespace(name)
node = server.get_objects_node()
Param = node.add_object(addspace, "Parameters")
Move= Param.add_variable(addspace, "Movement", 0, ua.VariantType.Float)
Leftpos = Param.add_variable(addspace, "Leftpos",True, ua.VariantType.Boolean)
Rightpos = Param.add_variable(addspace, "Rightpos",True, ua.VariantType.Boolean)
Middlepos = Param.add_variable(addspace, "Middlepos",True, ua.VariantType.Boolean)
Inmotion = Param.add_variable(addspace, "Inmotion",False, ua.VariantType.Boolean)
Warmup = Param.add_variable(addspace, "Warmup", 0)
ServoBase = Param.add_variable(addspace, "ServoBase",130)
ServoHead = Param.add_variable(addspace, "ServoHead",65)
Roomtemp = Param.add_variable(addspace, "Roomtemperature",0)
MoveHome = Param.add_variable(addspace, "MoveHome",False, ua.VariantType.Boolean)
MoveL = Param.add_variable(addspace, "MoveL",False, ua.VariantType.Boolean)
MoveM = Param.add_variable(addspace, "MoveM",False, ua.VariantType.Boolean)
MoveR = Param.add_variable(addspace, "MoveR",False, ua.VariantType.Boolean)
DEVICE_BUS = 1
bus = smbus.SMBus(DEVICE_BUS)
sensor = adafruit_dht.DHT11(board.D5)
global_variable = False
Homing = False
Motion = False
Lplace = False
Mplace = False
Rplace = False
Move.set_writable()
Warmup.set_writable()
ServoBase.set_writable()
ServoHead.set_writable()
Leftpos.set_read_only()
Rightpos.set_read_only()
Middlepos.set_read_only()
Inmotion.set_read_only()
MoveHome.set_writable()
Roomtemp.set_read_only()
MoveM.set_writable()
MoveL.set_writable()
MoveR.set_writable()
kit = MotorKit(0x61)
kit1 = ServoKit(channels = 16)
buttonl = Button(17)
buttonr = Button(18)
buttonm = Button(13)
def buttonl_pressed():
Leftpos.set_value(False)
print('Leftpos is pressed')
def buttonl_released():
Leftpos.set_value(True)
print('Leftpos is Released')
def buttonr_pressed():
Rightpos.set_value(False)
print('Rightpos is pressed')
def buttonr_released():
Rightpos.set_value(True)
print('Rightpos is released')
def buttonm_pressed():
Middlepos.set_value(False)
print('Leftpos is pressed')
def buttonm_released():
Middlepos.set_value(True)
print('Leftpos is Released')
buttonl.when_pressed = buttonl_pressed
buttonl.when_released = buttonl_released
buttonr.when_pressed = buttonr_pressed
buttonr.when_released = buttonr_released
buttonm.when_pressed = buttonm_pressed
buttonm.when_released = buttonm_released
GPIOpin = -1
def Home_Reset(Movingright = False, Movingleft = False):
while True:
if Middlepos.get_value()== True and Rightpos.get_value() == True and Movingleft == False:
kit.motor2.throttle = 0.7
Movingright = True
elif Middlepos.get_value() == False and Movingright == True:
kit.motor2.throttle = 0
Movingright = False
print('Heater is in Home position')
Motion = False
return Motion
break
elif Rightpos.get_value() == False and Middlepos.get_value()== True :
Movingright = False
Movingleft = True
kit.motor2.throttle = -0.7
elif Middlepos.get_value() == False and Rightpos.get_value() == True:
Movingleft = False
kit.motor2.throttle = 0
print('Heater is in Home position')
Motion = False
return Motion
break
def Move_Middle(Movingright = False, Movingleft = False):
while True:
if Rightpos.get_value() == False:
Movingleft = True
kit.motor2.throttle = -0.7
elif Middlepos.get_value() == False and Movingleft == True:
Movingleft = False
kit.motor2.throttle = 0
print('Heater is in Middle position')
Motion = False
return Motion
break
elif Leftpos.get_value() == False:
Movingright = True
kit.motor2.throttle = 0.7
elif Middlepos.get_value() == False and Movingright == True:
Movingright = False
kit.motor2.throttle = 0
print('Heater is in Middle position')
Motion = False
return Motion
break
def Move_Left(Movingleft = False):
while True:
if Leftpos.get_value() == True:
Movingleft = True
kit.motor2.throttle = -0.7
elif Leftpos.get_value() == False:
Movingleft = False
kit.motor2.throttle = 0
print('Heater is in Left position')
Motion = False
return Motion
break
def Move_Right(Movingright = False):
while True:
if Rightpos.get_value() == True:
Movingright = True
kit.motor2.throttle = 0.7
elif Rightpos.get_value() == False:
Movingright = False
kit.motor2.throttle = 0
print('Heater is in Right position')
Motion = False
return Motion
break
server.start()
print("server has started at {}".format(url))
while True:
#Motion = Inmotion.get_value()
Linear_Motor = Move.get_value()
kit.motor2.throttle = Linear_Motor
#print("Middle sensor =",Middlepos.get_value())
#print("Left sensor =",Leftpos.get_value())
#print("Right sensor =",Rightpos.get_value())
#print('warmup',Warmup.get_value())
i = Warmup.get_value()
if i==1:
bus.write_byte_data(0x11, 0x01, 0xFF)
#print('Warmer is On')
else:
bus.write_byte_data(0x11, 0x01, 0x00)
#print('Warmer is Off')
ServoBasePos = ServoBase.get_value()
kit1.servo[0].angle = ServoBasePos
#print('servobase-position',ServoBasePos)
ServoHeadPos = ServoHead.get_value()
kit1.servo[4].angle = ServoHeadPos
#print('servohead-psoition',ServoHeadPos)
H = MoveHome.get_value()
if H==True:
Motion = True
Home_Reset()
else:
Motion = False
R = MoveR.get_value()
if R==True:
Motion = True
Move_Right()
else:
Motion = False
L = MoveL.get_value()
if L==True:
Motion = True
Move_Left()
else:
Motion = False
M = MoveM.get_value()
if M==True:
Motion = True
Move_Middle()
else:
Motion = False
time.sleep(2)
try:
# Print the values to the serial port
temperature_c = sensor.temperature
Roomtemp.set_value(temperature_c)
#print("Temp={0:0.1f}ΒΊC", Roomtemp.get_value())
time.sleep(2)
except RuntimeError as error:
# Errors happen fairly often, DHT's are hard to read, just keep going
#print(error.args[0])
continue
except Exception as error:
sensor.exit()
raise error
Although the unoptimized Code works but as i said it was too slow and takes alot of resources from the CPU.
Below is the Optimized Version of the code that use functions instead of Conditional statements. This is very optimal version to use your logic in well defined Function and later Call these functions at the required moment instead of using a lot of If-condition statements in a while loop to provide the necessary condition to do a specific job. please take a look at the optimized Version below:
from opcua import ua, Server
from adafruit_motorkit import MotorKit
from adafruit_servokit import ServoKit
import board
import time
from gpiozero import Button
import smbus
import adafruit_dht
# OPC UA Server setup
server = Server()
url = "opc.tcp://192.168.1.6:4840"
server.set_endpoint(url)
server.secure_channel_timeout = 500000000
server.session_timeout = 500000000
name = "raspberrypi"
addspace = server.register_namespace(name)
node = server.get_objects_node()
# Parameters
Param = node.add_object(addspace, "Parameters")
Move = Param.add_variable(addspace, "Movement", 0, ua.VariantType.Float)
Leftpos = Param.add_variable(addspace, "Leftpos", True, ua.VariantType.Boolean)
Rightpos = Param.add_variable(addspace, "Rightpos", True, ua.VariantType.Boolean)
Middlepos = Param.add_variable(addspace, "Middlepos", True, ua.VariantType.Boolean)
Inmotion = Param.add_variable(addspace, "Inmotion", False, ua.VariantType.Boolean)
Warmup = Param.add_variable(addspace, "Warmup", 0)
ServoBase = Param.add_variable(addspace, "ServoBase", 130)
ServoHead = Param.add_variable(addspace, "ServoHead", 65)
Roomtemp = Param.add_variable(addspace, "Roomtemperature", 0)
MoveHome = Param.add_variable(addspace, "MoveHome", False, ua.VariantType.Boolean)
MoveL = Param.add_variable(addspace, "MoveL", False, ua.VariantType.Boolean)
MoveM = Param.add_variable(addspace, "MoveM", False, ua.VariantType.Boolean)
MoveR = Param.add_variable(addspace, "MoveR", False, ua.VariantType.Boolean)
# Set writable/read-only access
Move.set_writable()
Warmup.set_writable()
ServoBase.set_writable()
ServoHead.set_writable()
MoveHome.set_writable()
MoveM.set_writable()
MoveL.set_writable()
MoveR.set_writable()
Leftpos.set_read_only()
Rightpos.set_read_only()
Middlepos.set_read_only()
Inmotion.set_read_only()
Roomtemp.set_read_only()
# Hardware setup
kit = MotorKit(0x61)
kit1 = ServoKit(channels=16)
buttonl = Button(17)
buttonr = Button(18)
buttonm = Button(13)
sensor = adafruit_dht.DHT11(board.D5)
bus = smbus.SMBus(1)
# Button Handlers
def button_handler(button, position_var):
def pressed():
position_var.set_value(False)
print(f"{button} pressed")
def released():
position_var.set_value(True)
print(f"{button} released")
return pressed, released
buttonl.when_pressed, buttonl.when_released = button_handler("Leftpos", Leftpos)
buttonr.when_pressed, buttonr.when_released = button_handler("Rightpos", Rightpos)
buttonm.when_pressed, buttonm.when_released = button_handler("Middlepos", Middlepos)
# Motion functions
def move_motor_to_position(target_pos, motor, speed):
while not target_pos.get_value():
motor.throttle = speed
time.sleep(0.05) # Short delay to reduce CPU usage
motor.throttle = 0
print(f"Reached {target_pos}")
def reset_home():
print("Resetting to Home position...")
if Middlepos.get_value():
move_motor_to_position(Middlepos, kit.motor2, 0.7)
def move_to_position(position_var, speed):
print(f"Moving to {position_var}")
move_motor_to_position(position_var, kit.motor2, speed)
# Main loop
try:
server.start()
print(f"Server started at {url}")
while True:
# Control movement
if MoveHome.get_value():
reset_home()
MoveHome.set_value(False)
if MoveR.get_value():
move_to_position(Rightpos, 0.7)
MoveR.set_value(False)
if MoveL.get_value():
move_to_position(Leftpos, -0.7)
MoveL.set_value(False)
if MoveM.get_value():
move_to_position(Middlepos, 0.7)
MoveM.set_value(False)
# Update servo positions
kit1.servo[0].angle = ServoBase.get_value()
kit1.servo[4].angle = ServoHead.get_value()
# Update room temperature
try:
temperature_c = sensor.temperature
Roomtemp.set_value(temperature_c)
except RuntimeError:
pass # Ignore DHT sensor errors
# Control the warmer
bus.write_byte_data(0x11, 0x01, 0xFF if Warmup.get_value() else 0x00)
# Throttle movement
kit.motor2.throttle = Move.get_value()
time.sleep(0.2) # Reduce CPU usage by adding a delay in the loop
finally:
server.stop()
print("Server stopped")
When you compare the Optimized Code you realize that it is shorter and the quality of the code is higher and every thing is packed in Functions that can be called anytime that is needed. This helped my Project a lot. I hope you enjoyed this Episode. π
Like and leave a comment.

Support Donation.
Please help me to write useful articles for this podcast. Thank you π
β¬1.00





Leave a comment