@@ -107,26 +107,17 @@ function apply_motor_output!(hw::HardwareContext, pwm_left::Float32, pwm_right::
107107end
108108
109109function (@main )(args):: Cint
110- println (Core. stdout , " hello world! " )
110+ println (Core. stdout , " Balance car starting... " )
111111
112112 # Initialize GPIO controller
113113 gpio = GPIO. open_gpio (" /dev/gpiochip0" )
114- println (Core. stdout , " gpio opened" )
115114
116115 # Setup GPIO output pins for motor direction
117116 ain1 = GPIO. request_output (gpio, AIN1, " motor_ain1" , 0 )
118- println (Core. stdout , " ain1 configured" )
119-
120117 bin1 = GPIO. request_output (gpio, BIN1, " motor_bin1" , 0 )
121- println (Core. stdout , " bin1 configured" )
122-
123118 stby = GPIO. request_output (gpio, STBY_PIN, " motor_stby" , 0 )
124- println (Core. stdout , " stby configured" )
125-
126119 ltrans_oe = GPIO. request_output (gpio, LTRANS_OE, " ltrans_oe" , 0 )
127- println (Core. stdout , " ltrans_oe configured" )
128-
129- println (Core. stdout , " gpio pins configured" )
120+ println (Core. stdout , " GPIO configured" )
130121
131122 # Setup hardware PWM via sysfs
132123 pwm_chip = PWM. open_chip (0 )
@@ -140,61 +131,75 @@ function (@main)(args)::Cint
140131 PWM. set_period_hz (pwm_right, PWM_FREQ_HZ)
141132 PWM. set_duty_cycle_ns (pwm_right, 0 )
142133 PWM. enable (pwm_right)
143-
144- println (Core. stdout , " pwm startup done" )
134+ println (Core. stdout , " PWM configured" )
145135
146136 # Create hardware context
147137 hw = HardwareContext (gpio, ain1, bin1, stby, ltrans_oe, pwm_chip, pwm_left, pwm_right)
148138
149- # Initialize I2C for IMU (bus 1, address 0x68)
139+ # Initialize IMU (I2C bus 1, address 0x68)
150140 imu = MPU6000 (1 , 0x68 )
151- println (Core. stdout , " i2c startup done" )
152-
153141 wake! (imu)
154- println (Core. stdout , " imu startup done " )
142+ println (Core. stdout , " IMU initialized " )
155143
156- timu = ThreadedMPU6000 (imu)
157- tenc_1a = ThreadedEncoder (Encoder (gpio, M1A))
158- tenc_2a = ThreadedEncoder (Encoder (gpio, M2A))
144+ # Initialize encoders (single-threaded, poll-based)
145+ enc_left = Encoder (gpio, M1A)
146+ enc_right = Encoder (gpio, M2A)
147+ println (Core. stdout , " Encoders initialized" )
159148
160- GPIO. set_value (ltrans_oe, 1 )
161- GPIO. set_value (stby, 1 ) # take the motor controller out of standby
149+ # Initialize balance controller
162150 ctrl = BalanceController. BalanceController ()
163151
164- ml_update_rate_ns = 50000000
165- imu_read_margin = 12600000
166- println (Core. stdout , " start loop!" )
167- start = time_ns ()
152+ # Enable hardware
153+ GPIO. set_value (ltrans_oe, 1 )
154+ GPIO. set_value (stby, 1 )
155+
156+ # Control loop timing (5ms = 200Hz)
157+ loop_period_ns = 5_000_000
158+
159+ println (Core. stdout , " Starting control loop..." )
168160 Base. exit_on_sigint (false )
161+ loop_start = time_ns ()
162+
169163 try
170164 while true
171- wait_until (start + ml_update_rate_ns - imu_read_margin)
172- println (Core. stdout , " wait 1" )
173- put! (timu. request, true ) # trigger the IMU request
174- wait_until (start + ml_update_rate_ns)
175- println (Core. stdout , " wait 2" )
176- imu_data = take! (timu. response)
177- println (Core. stdout , " IMU response: $(imu_data. accel_x) " )
178- enc_1_cnts = reset! (tenc_1a)
179- enc_2_cnts = reset! (tenc_2a)
180- command = BalanceController. balance_car! (ctrl, enc_1_cnts, enc_2_cnts,
181- imu_data. accel_x, imu_data. accel_y, imu_data. accel_z,
182- imu_data. gyro_x, imu_data. gyro_y, imu_data. gyro_z)
183- start = time_ns ()
165+ # Wait for next loop iteration
166+ wait_until (loop_start + loop_period_ns)
167+ loop_start = time_ns ()
168+
169+ # Read IMU (synchronous, ~1.3ms at 100kHz SMBus for 14 bytes)
170+ imu_data = read_all_raw (imu)
171+
172+ # Drain encoder events that occurred since last loop
173+ drain_events! (enc_left)
174+ drain_events! (enc_right)
175+ enc_left_cnt = enc_left. count
176+ enc_right_cnt = enc_right. count
177+ reset! (enc_left)
178+ reset! (enc_right)
179+
180+ # Run balance controller
181+ command = BalanceController. balance_car! (ctrl,
182+ enc_left_cnt, enc_right_cnt,
183+ imu_data. accel_x, imu_data. accel_y, imu_data. accel_z,
184+ imu_data. gyro_x, imu_data. gyro_y, imu_data. gyro_z)
185+
186+ # Apply motor output
184187 if isnothing (command)
185188 car_stop! (hw)
186- println (Core. stdout , " motors stopped!" )
187189 else
188190 left, right = command
189191 apply_motor_output! (hw, left, right)
190- println (Core. stdout , " motors run!" )
191192 end
192193 end
193194 catch e
194- rethrow ()
195+ if e isa InterruptException
196+ println (Core. stdout , " \n Ctrl-C received" )
197+ else
198+ println (Core. stdout , " Error: " , e)
199+ rethrow ()
200+ end
195201 finally
196- GPIO. set_value (ltrans_oe, 0 )
197- GPIO. set_value (stby, 0 )
202+ shutdown! (hw)
198203 end
199204 return 0
200205end
0 commit comments