Introduction: GiggleBot Light Follower - on Gravel

This time around, we're making the GiggleBot follow a source of light, like the light coming from a flashlight. This will all be done in MicroPython. For that, you'll need to download the GiggleBot MicroPython Runtime.

Step 1: Getting the Required Stuff

Well, just like in other GiggleBot tutorials, you'll need the usual GiggleBot, a set of 3 AA batteries and a BBC micro:bit board.

Apart from these 3, you will also need a flashlight to make the GiggleBot follow it. Or you could just as easily use the smartphone's flash for that matter.

Get the GiggleBot Here!

Step 2: Setting Up the Environment

The GiggleBot MicroPython Runtime is required. This runtime can be downloaded from its documentation here . For that, you'll have to follow the instructions on the Getting Started chapter of the documentation.

Step 3: What Light Sensors (not Actually a Step)

The GiggleBot comes with 2 light sensors that sit right in front of the PCB, next to the 2 NeoPixel LEDs. They are very small and quite hard to spot. They are the size of an ultra-small resistor.

Step 4: Processing the Light Sensor Signals

When integrating their signal, we first run a weighted average on both of them and then make the resulting signal go through a low pass filter. We need to make it go through a low pass filter because both sensors are quite noisy and if we were to also take into account these high-frequency noises, the GiggleBot would have a hard time following the actual light source.

These 2 sensors are especially noisy in low light situations, so if the GiggleBot would be left to go into the dark while there's no strong light source around and no low pass filter is applied, it would then have a choppy trajectory - constantly going to the left and right.

Step 5: Programming It

The following code is the program for the GiggleBot light follower. One thing to keep in mind is that you need to use the GiggleBot Runtime for the GiggleBot, which can be found on its documentation here. At this moment, version v0.4.0 is used, but later versions could be very well used too.

Note: The following script might have missing whitespaces and this seems to be due to some issue in displaying GitHub Gists. Click on the gist to take you to its GitHub page where you can copy-paste the code.

GiggleBot Light Follower w/ Proportional Controller & LPF

from microbit import*
from gigglebot import*
from utime import sleep_ms, ticks_us
motor_speed =100
update_rate =70
setpoint =0.5
Kp =65.0
integral =0.0
tau =0.005
dt =1.0/ update_rate
alpha = tau / (tau + dt)
run =True
deflpf(value):
'''
Low Pass Filter
'''
global integral, alpha
integral = alpha * value + (1- alpha) * integral
return integral
whileTrue:
# if button a is pressed then start following
if button_a.is_pressed():
run =True
# but if button b is pressed stop the light follower
if button_b.is_pressed():
run =False
stop()
sleep_ms(500)
if run isTrue:
start_time = ticks_us()
# read the light sensors
right, left = read_sensor(LIGHT_SENSOR, BOTH)
# light is on the left when position < 0.5
# light is on the right when position > 0.5
# light is in the middle when position = 0.5
# it's a weighted arithmetic mean
try:
position = right /float(left + right)
exceptZeroDivisionError:
position =0.5
if position ==0: position =0.001
if position ==1: position =0.999
# apply low pass filter, then use a P controller
error = lpf(position) - setpoint
correction =-error * Kp
# calculate motor speeds
leftMotorSpeed = motor_speed + correction
rightMotorSpeed = motor_speed - correction
# clipping the motors
if leftMotorSpeed >100:
leftMotorSpeed =100
rightMotorSpeed = rightMotorSpeed - leftMotorSpeed +100
if rightMotorSpeed >100:
rightMotorSpeed =100
leftMotorSpeed = leftMotorSpeed - rightMotorSpeed +100
if leftMotorSpeed <-100:
leftMotorSpeed =-100
if rightMotorSpeed <-100:
rightMotorSpeed =-100
# actuate the motors
set_speed(leftMotorSpeed, rightMotorSpeed)
drive()
# print((position, lpf(position)))
# and maintain the loop frequency
end_time = ticks_us()
delay_diff = (end_time - start_time) /1000
if1000.0/ update_rate - delay_diff >0:
sleep(1000.0/ update_rate - delay_diff)

Step 6: Running It

While running the program, you have at your disposal 2 actions:

  1. Pressing on button A to make the GiggleBot follow the light source.
  2. Pressing on button B to make the GiggleBot stop in its tracks.