You might have noticed that it was difficult to hold the tilt transmitting micro:bit to make the cyber:bot stay still. We can fix that by adding a stop range to the tilt values.
The scripts will check if the micro:bit accelerometer’s y-axis is close to zero. The transmitter micro:bit will display a diamond to indicate that it’s nearly level in the forward/backward direction. The receiver script will also make the cyber:bot stay still when the diamond indicator is displayed.
The only thing that needs to be added to the transmitter radio_tilt_transmit_rapid script is an if... block that displays one of two things:
Let’s try it!
# radio_tilt_controller_w_stop_range from microbit import * import math import radio radio.on() radio.config(channel=7, queue=1, length=64) while True: x = accelerometer.get_x() y = accelerometer.get_y() angle = round( math.degrees( math.atan2(y, x) ) ) needle = ( angle + 90 + 15 ) // 30 if abs(y) > 80: display.show(Image.ALL_CLOCKS[needle]) else: display.show(Image.DIAMOND_SMALL) dictionary = { } dictionary['x'] = x dictionary['y'] = y dictionary['needle'] = needle packet = str(dictionary) radio.send(packet) sleep(50)
The radio_tilt_controller_w_stop_range script is just radio_tilt_transmit_rapid with an if…else… statement added.
When the absolute value of y is greater than 80, it displays the tilt direction needle, just like it has up to this point. But, if the y value is anywhere in the -80 to 80 range, it instead displays a small diamond to tell you that your forward/backward tilt is pretty close to level.
if abs(y) > 80: display.show(Image.ALL_CLOCKS[needle]) else: display.show(Image.DIAMOND_SMALL)
The if abs(y) function returns the positive-only version of any value y might store. So, if y stores -20, abs(y) returns 20. If y stores 20, abs(y) doesn’t change anything and just returns 20. So, if abs(y) > 80 is a concise way to check if y is outside the -80…80 range. Another way to check if y is outside that range would be if y > 80 or y < -80.
In addition to displaying the diamond when the y-axis tilt is close to level, the radio_tilt_bot_fb_with_stop_range script also makes the cyber:bot stay still.
# radio_tilt_bot_fb_with_stop_range from cyberbot import * import radio radio.on() radio.config(channel=7, queue=1, length=64) while True: packet = radio.receive() if packet: dictionary = eval(packet) x = dictionary.get('x') y = dictionary.get('y') needle = dictionary.get('needle') fb = y / 10 if abs(fb) > 8: display.show(Image.ALL_CLOCKS[needle]) vL = fb vR = -fb else: display.show(Image.DIAMOND_SMALL) vL = None vR = None bot(18).servo_speed(vL) bot(19).servo_speed(vR)
While still holding the transmitter micro:bit level, does the cyber:bot stay still?
As you tilt the tilt transmitter away from and then toward you, does it make the cyber:bot roll forward and backward?
Here is the portion of radio_tilt_bot_fb_with_stop_range that’s different from the previous radio_tilt_bot_fb_only that it’s based on.
if abs(fb) > 8: display.show(Image.ALL_CLOCKS[needle]) vL = fb vR = -fb else: display.show(Image.DIAMOND_SMALL) vL = None vR = None
Keep in mind that fb is y / 8, so instead of looking for y being outside the +/- 80 range, this program checks if fb is outside the +/- 8 range. When the absolute value of fb is greater than 8, the script displays the tilt needle and sets the vL and vR variables just like it did in the previous radio_tilt_bot_fb_only script. But when fb falls inside the -8 to 8 range, it displays the diamond and sets vL and vR to None.
Whenever the else block sets vL and vR to None, it makes the servos stay still. It’s actually better than setting vL and vR to zero because None causes servo_speed to stop sending control signals. This prevents any slow wheel rotation that might otherwise occur when the servos are slightly out of calibration and the speeds are set to 0.
bot(18).servo_speed(vL) bot(19).servo_speed(vR)