Over and over again...

Loops are repetitive instructions. Certain instructions are executed again and again until a certain condition is no longer fulfilled. Loops are an essential concept in programming as they make it possible to complete tasks efficiently and with less code.

There are two main types of loops:

A while loop repeats a statement or block of statements as long as a certain condition is true. This loop is useful when the number of repetitions is not known in advance and depends on a condition that can be changed during the execution of the program.

A for loop repeats an instruction or a block of instructions a certain number of times. It is often used to run through a sequence (such as a list, a tuple or a range).

Loops are particularly useful in situations where tasks need to be performed multiple times, such as traversing lists, processing data in a table or repeating calculations until a certain condition is met. By using loops in your programs, you can make your code more efficient and easier to understand.

while-loop

There is a so-called while loop.

This first checks for the condition. In this case, this is the check of the left and right obstacle sensors. As long as the sensor detects something, all instructions that are below it in the make area are executed.

In summary, as long as the obstacle sensors detect an obstacle, the light of the Joy-Car is always switched on.

However, switching the light on every time makes little sense if it does not switch off again at some point. If we add the instruction to switch off the light after our loop, we can directly observe how the light switches between the two states. As long as an obstacle is detected, the instruction block is executed again and again within the loop and is not exited. Only when the condition no longer applies is the loop exited again, the forever block is executed again from the beginning and the light is switched off.

At the beginning, the revision number of the Joy-Car is again defined in the on start block.

basic.forever(function () {
    JoyCar.initJoyCar(RevisionMainboard.OnepThree)
    while (JoyCar.obstacleavoidance(SensorLRSelection.Left) || JoyCar.obstacleavoidance(SensorLRSelection.Right)) {
        JoyCar.light(ToggleSwitch.On)
        basic.pause(1000)
    }
    JoyCar.light(ToggleSwitch.Off)
})

The sample code in MicroPython is there because it is also available in MakeCode. This is super handy because if you're already comfortable with MakeCode, it's much easier to get started with MicroPython. By having sample code in both environments, you can continue learning without much interruption. This will help you understand how programming works and you can see how to do the same things in different programming languages.

# Import necessary libraries
from microbit import *
import neopixel

# Define your Joy-Car mainboard revision
joycar_rev = 1.3

# Define object for the lights
np = neopixel.NeoPixel(pin0, 8)

# Initialization of the I2C interface for the Joy-Car mainboard
i2c.init(freq=400000, sda=pin20, scl=pin19)

# Define values for the lights
# Values which LEDs are to be activated
headlights = (0, 3)
backlights = (5, 6)
indicator_left = (1, 4)
indicator_right = (2, 7)
indicator_warning = (1, 2, 4, 7)

# Values, which color should be displayed on the LEDs
led_white = (60, 60, 60)
led_red = (60, 0, 0)
led_off = (0, 0, 0)
led_red_br = (255, 0, 0)
led_orange = (100, 35, 0)

# method to activate/deactivate lights
def lights(on = True):
    if on:
        for x, y in zip(headlights, backlights):
            # define white for the headlights
            np[x] = led_white
            # define dark red for the backlights
            np[y] = led_red
    else:
        for x, y in zip(headlights, backlights):
            # define black for the headlights and backlights
            np[x] = led_off
            np[y] = led_off
    np.show()

# retrieve all sensor data
def fetchSensorData():
    # Since the zfill function is not included in micro:bit Micropython, 
    # it must be inserted as a function
    def zfill(s, width):
        return '{:0>{w}}'.format(s, w=width)

    # Read hexadecimal data and convert to binary data
    data = "{0:b}".format(ord(i2c.read(0x38, 1)))
    # Fill in the data to 8 digits if required
    data = zfill(data, 8)
    # declare bol_data_dict as dictionary
    bol_data_dict = {}
    # Counter for the loop that enters the data from data into bol_data_dict
    bit_count = 7
    # Transfer the data from data to bol_data_dict
    for i in data:
        if i == "0":
            bol_data_dict[bit_count] = False
            bit_count -= 1
        else:
            bol_data_dict[bit_count] = True
            bit_count -= 1

    # As of mainboard revision 1.3, the speed sensors are on separate pins
    if joycar_rev >= 1.3:
        bol_data_dict[8], bol_data_dict[9] = bol_data_dict[0], bol_data_dict[1]
        bol_data_dict[0] = bool(pin14.read_digital())
        bol_data_dict[1] = bool(pin15.read_digital())

    # bit 0 = SpeedLeft, bit 1 = SpeedRight, bit 2 = LineTrackerLeft,
    # bit 3 = LinetrackerCenter, bit 4 = LinetrackerRight,
    # bit 5 = ObstacleLeft, bit 6 = ObstacleRight, bit 7 = free pin(7)
    # (bit 8 = free (pin0) bit 9 = free (pin1)) - only with revision 1.3 or newer
    return bol_data_dict

# an endless loop
while True:
    # Read sensor data from the mainboard
    sensor_data = fetchSensorData()

    # Entry into the loop if no obstacle is detected with the obstacle sensors
    while not sensor_data[5] or not sensor_data[6]:
        # Switch on low beam
        lights()

        # Wait for 1 second
        sleep(1000)

        # Read sensor data from the mainboard
        sensor_data = fetchSensorData()

    lights(on = False)

for loop

However, there are not only while loops, but also the so-called for loops. In for loops, the instructions are executed for a certain number of passes.

Here, two for loops with 8 passes each are run through in order to control all the LEDs of the Joy-Car one after the other. For this purpose, the index variable of the loop is accessed directly in order to obtain and use the current cycle value.

In the following program, an LED strip with the name strip is initialized with 8 LEDs on pin 0 in the on start block after the revision number of the Joy-Car has been defined. In the forever block, LEDs 0-7 (the addressing of the LEDs starts at 0) are then switched on one after the other in the color red in the first for loop. There is a pause of 100 ms (0.1 seconds) after each loop. Once the loop with the number 7 has run through, the second loop starts. In this loop, the LEDs are switched to the color black one after the other. In the case of LEDs, black means off. Once this loop has also run through with the number 7, the forever block starts again from the beginning.


Further information on the use of LEDs can be found in the section on headlights.

JoyCar.initJoyCar(RevisionMainboard.OnepThree)
let strip = neopixel.create(DigitalPin.P0, 8, NeoPixelMode.RGB)
basic.forever(function () {
    for (let Index = 0; Index <= 7; Index++) {
        strip.setPixelColor(Index, neopixel.colors(NeoPixelColors.Red))
        strip.show()
        basic.pause(100)
    }
    for (let Index = 0; Index <= 7; Index++) {
        strip.setPixelColor(Index, neopixel.colors(NeoPixelColors.Black))
        strip.show()
        basic.pause(100)
    }
})

The sample code in MicroPython is there because it is also available in MakeCode. This is super handy because if you're already comfortable with MakeCode, it's much easier to get started with MicroPython. By having sample code in both environments, you can continue learning without much interruption. This will help you understand how programming works and you can see how to do the same things in different programming languages.

# Import necessary libraries
from microbit import *
import neopixel

# Define your Joy-Car mainboard revision
joycar_rev = 1.3

# Define object for the lights
np = neopixel.NeoPixel(pin0, 8)

# Define an endless loop
while True:
    # Loop with index 1 to 7 (8 not included)
    for index in range(0,8):
        # Set LED with index red
        np[index] = (255, 0, 0)
        # Display color on the LED
        np.show()
        # wait 100 ms
        sleep(100)

    # Loop with index 1 to 7 (8 not included)
    for index in range(0,8):
        # Set LED with index to black
        np[index] = (0, 0, 0)
        # Display color on the LED
        np.show()
        # wait 100 ms
        sleep(100)