Sunday 11 November 2018

[Tutorial] Use three Micro:bits to control the car, under the supervision of traffic lights

1. Brief introduction of BBC micro:bit


Image result for microbits bbc

The Micro Bit (also referred to as BBC Micro Bit, stylized as micro:bit) is an open source hardware ARM-based embedded system designed by the BBC for use in computer education in the UK. You can start your journey from the plenty of online tutorials: https://microbit-micropython.readthedocs.io/en/latest/tutorials/introduction.html.

Editors: there are two editors for you, MU editor and Python editor. Mu editor (https://codewith.mu/) is an offline platform which you need to install in your computer. Python editor (https://python.microbit.org/v/1.1) is an online version that brings you much convenience. Both editors are based on Python.

micro:bit Micropython API: Before coding, you need to look through the built-in APIs (https://microbit-micropython.readthedocs.io/en/latest/microbit_micropython_api.html). Though there are not many APIs, you will have no trouble in using micro:bit to practice your idea.

2. The equipment

Three micro:bits, some jumper wires, LEDs (green, yellow, and red), a toy car, power banks (optional)



3. Equipment assembly and system structure

The system is divided into three parts: light_control (traffic lights), car_control (driver), receiver (car).
light_control: (The green LED, far away from red LED, acts as the yellow.)
car_control:

receiver:


Micro:bit plays a role of instruction transmission. The work process is:

  • Light_control changes the status of lights-when the green lights, allowing move; when the yellow lights, awaiting for the red; when the red lights, stopping. 
  • Car_control controls the movement of the toy car. Depending on the built-in the accelerometer, tilting the micro:bit to make the toy car move forward, backward, left and right.
  • Receiver controls the motor pins to let the toy car move as instructed.     

4. Source code and explanation


  • Light_control end (directly copy and paste in your project)
from microbit import *
import radio

radio.on()
radio.config(group=255) 

anchor_up = Image("00900:09990:90909:00900:00900")
anchor_down = Image("00900:00900:90909:09990:00900")
anchor_left = Image("00900:09000:99999:09000:00900")
anchor_right = Image("00900:00090:99999:00090:00900")
anchor_stop = Image("90009:09090:00900:09090:90009")
anchor_wait = Image("00000:00000:99999:00000:00000")

while True:
    #the default status of light is green.
    display.show(anchor_up)
    pin1.write_digital(1)
    pin0.write_digital(0)
    pin2.write_digital(0)
    sleep(60000)

    radio.send('b')  #yellow lights
    display.show(anchor_wait)
    pin1.write_digital(0)
    pin2.write_digital(0)
    for i in range(10):
        pin0.write_digital(1)
        sleep(200)
        pin0.write_digital(0)
        sleep(200)
    
    radio.send('c')  #red lights
    display.show(anchor_stop)
    pin1.write_digital(0)
    pin0.write_digital(0)
    pin2.write_digital(1)
    sleep(15000)

To make you better follow my idea, please have a look at this small video below:

From the video, we can see when the green lights, the image shown in the microbit is a forward arrow; when the yellow (I use a green LED temporarily) flashes, the image shown in the microbit is a horizontal line; when the red lights, the image shown in the microbit is a cross.
light end                                                 micro:bit end 
green light                                             forward arrow
yellow light                                           horizontal line
red light                                                          cross
    
  • Car_control end
from microbit import *
import radio
import microbit as m

radio.on()
radio.config(group=255) 

status = False

anchor_up = Image("00900:09990:90909:00900:00900")
anchor_down = Image("00900:00900:90909:09990:00900")
anchor_left = Image("00900:09000:99999:09000:00900")
anchor_right = Image("00900:00090:99999:00090:00900")
anchor_stop = Image("90009:09090:00900:09090:90009")
anchor_wait = Image("00000:00000:99999:00000:00000")

while True:    
    incoming = radio.receive()    
    if incoming == 'b':
        status=False
        display.show(anchor_wait)
        sleep(2000)
    elif incoming == 'c':
        status=False
        display.show(anchor_stop)
        sleep(15000)
    else:
        status=True

    if button_a.was_pressed():
        display.clear()
        radio.config(group=255) 
    
    if button_b.was_pressed() and status:
        display.clear()
        radio.config(group=25)  
    
    # get data from accelerometer
    x = m.accelerometer.get_x()
    y = m.accelerometer.get_y()
    
    # based on different situation to send different data and visualise what kind of data you are sending
    # only when green lights, the car can go
    if (x >= 400) and status:
        display.show(anchor_right)
        # 'r' means right
        radio.send('r')
        sleep(1)
    
    elif (x <= -400) and status:
        display.show(anchor_left)
        # 'l' means left
        radio.send('l')
        sleep(1)

    elif (y <= -400) and status:
        display.show(anchor_up)
        # 'u' means up
        radio.send('u')
        sleep(1)
    
    elif (y >= 400) and status:
        display.show(anchor_down)
        # 'd' means down
        radio.send('d')
        sleep(1)
    
    elif (x <= 400) and (x > -400) and (y <= 400) and (y > -400) and status:
        display.clear()
        radio.send('s')
        sleep(1) 

In this code, I use the accelerometer sensor. Four instructions are set depending on the tilt direction (forth, back, left and right). Meanwhile, the images shown in the micro:bit are four-direction arrows.
The actions conducted in this end resemble the actions you would do when you're driving. Let's go to the details. 
  • When the green lights, time for driving and four-direction arrows shown in your micro:bit board to show the signal of free-driving, you need to push the button B (built-in button) to control your car. It is a very necessary step because it changes the group "radio.config(group=25)" which means let the car_control end and receiver be in the same group then they can communicate or they can't.
  • When the yellow flashes, time for waiting and a horizontal line shown in your micro:bit board, now you need to push the button A (built-in button) to follow the rule of traffic lights (the red will light soon after the yellow flash). The function of this button is to reset the radio group "radio.config(group=255) "  which lets the light_control end and car_control end communicate again. If you miss pushing or don't push in time the button A when the yellow is flashing, you are in high risk of rushing the red light in that there needs some time for system response.    
  • When the red lights, time for stopping and a cross shown in your micro:bit board, now you cannot do anything but wait. 
  
  • Receiver end
from microbit import *
import radio

radio.on()
radio.config(group=25) 

anchor_up = Image("00900:09990:90909:00900:00900")
anchor_down = Image("00900:00900:90909:09990:00900")
anchor_left = Image("00900:09000:99999:09000:00900")
anchor_right = Image("00900:00090:99999:00090:00900")

while True:
    # listening the radio data from sender 
    incoming = radio.receive()
        
    # if received data == 'u', your car will move forward  
    if incoming == 'u':
        display.show(anchor_up)
        pin8.write_digital(0)
        pin16.write_digital(1)
        pin0.write_digital(0)
        pin12.write_digital(1)
        
    if incoming == 'd':
        display.show(anchor_down)
        pin8.write_digital(1)
        pin16.write_digital(0)
        pin0.write_digital(1)
        pin12.write_digital(0)
    
    if incoming == 'r':
        display.show(anchor_right)
        pin8.write_digital(0)
        pin16.write_digital(0)
        pin0.write_digital(0)
        pin12.write_digital(1)
    
    if incoming == 'l':
        display.show(anchor_left)
        pin8.write_digital(0)
        pin16.write_digital(1)
        pin0.write_digital(0)
        pin12.write_digital(0)
    
    if incoming == 's':
        display.show('T')
        pin8.write_digital(0)
        pin16.write_digital(0)
        pin0.write_digital(0)
        pin12.write_digital(0)

This code shows you how the car is controlled by its motor. There are four pins Pin0, pin8, pin12 and pin16 to operate. when each action is conducted, the corresponding image will show in the micro:bit board.

4. Demonstration




2 comments:

  1. could you implement such an environment, where many running cars send their real-time sensor data to IoV Gateway. One monitor is listening these data from gateway and broadcast corresponding control message to the network. The proxy agent on each car could listen the broadcast message and do correct reaction, in order to achieve some goals like running in specific order or in specific speed/direction, or avoid some bad things like collision. I am focusing on deep reinforcement neutral network for pretty a while, which I think could benefit the monitor of this scenario. If you could be responsible for the environment, maybe we could cooperate together to make this real.

    ReplyDelete
    Replies
    1. Hi, it sounds interesting. This is our IoT (Internet of Things) lab: http://iot.eecs.qmul.ac.uk/. we are happy to hear your voice on email.

      Delete

[Research] Recurrent Neural Network (RNN)

1. Introduction As we all know, forward neural networks (FNN) have no connection between neurons in the same layer or in cross layers. Th...