With ifs and buts....

In principle, the JavaScript programming language is represented by the blocks. This also allows you to use queries and dependencies that you may already be familiar with. For example, you can check whether a certain condition is fulfilled. One such dependency in the following example is the if block.

Similar to the loops, the if condition is checked first. If this applies, the corresponding statement block is executed once. The rest of the program is then continued directly. If the condition does not apply, the statement block is simply skipped.

TIP: While loops “block” the rest of the execution until the condition is no longer fulfilled, the rest of the program can still be executed with if-conditions.

If ... else

In the following example, we check the left-hand obstacle sensor and switch the light on when the sensor detects an obstacle and then switch the light off again without pausing.

JoyCar.initJoyCar(RevisionMainboard.OnepThree)
basic.forever(function () {
    if (JoyCar.obstacleavoidance(SensorLRSelection.Left)) {
        JoyCar.light(ToggleSwitch.On)
    }
    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

# Switch off low beam
lights(on = False)

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

    # Check left-hand obstacle sensor
    if not sensor_data[5]:
        # Switch on low beam
        lights()

	# Switch off low beam
    lights(on = False)

If so ..., else

If conditions can optionally be extended by an otherwise block. Either the program statement from the first block is executed, if the condition applies, or an alternative block is executed. This principle can be imagined as a fork in the road, where you can either turn left or right. Depending on whether the condition applies, a decision is made as to which road to take.

In the following code, the if block permanently checks whether the left-hand obstacle sensor has detected an obstacle or not. The light is only switched on if the sensor detects an obstacle. In all other cases, the otherwise block is executed, i.e. the light is switched off.

JoyCar.initJoyCar(RevisionMainboard.OnepThree)
basic.forever(function () {
    if (JoyCar.obstacleavoidance(SensorLRSelection.Left)) {
        JoyCar.light(ToggleSwitch.On)
    } else {
        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

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

    # Check left-hand obstacle sensor
    if not sensor_data[5]:
        # Switch on low beam
        lights()
    else:
        # Switch off low beam
        lights(on = False)

2x If so ..., else

Of course, it can also be tested for several different conditions in succession in one program. In the next step, we first check the left-hand obstacle sensor to switch on the headlights and then the right-hand obstacle sensor to switch on the reversing light.

In this case, we use a total of two if conditions. This means that both conditions can apply at the same time and therefore both the headlights and the reversing light can light up at the same time.

JoyCar.initJoyCar(RevisionMainboard.OnepThree)
basic.forever(function () {
    if (JoyCar.obstacleavoidance(SensorLRSelection.Left)) {
        JoyCar.light(ToggleSwitch.On)
    } else {
        JoyCar.light(ToggleSwitch.Off)
    }
    if (JoyCar.obstacleavoidance(SensorLRSelection.Right)) {
        JoyCar.reversinglight(ToggleSwitch.On)
    } else {
        JoyCar.reversinglight(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()

# Activate/deactivate the light for reversing
def lightsBack(on = True):
    if on:
        # Set left rear light to white
        np[backlights[0]] = led_white
        np.show()
    else:
        # Set left rear light to black
        np[backlights[0]] = 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

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

    # Check left-hand obstacle sensor
    if not sensor_data[5]:
        # Switch on low beam
        lights()
    else:
        # Switch off low beam
        lights(on = False)

    # Check right-hand obstacle sensor
    if not sensor_data[6]:
        # Activate reversing light
        lightsBack()
    else:
        # Deactivate reversing light
        lightsBack(on = False)

else if

But that is not always what is wanted. Sometimes an either-or is simply not enough. In this case, the if condition can be extended by any number of additional blocks. In this case, several if queries are set one after the other. The big difference here, however, is that no matter how many queries are set in succession, only one condition can apply. As soon as a condition is fulfilled, the corresponding statement block is executed and all other conditions are skipped.

In the following example, we check the two obstacle sensors again. However, in this case the query is realized via a coherent if condition and not via two individual ones. This means that only either the headlights or the reversing light can light up, but never both at the same time.

If both conditions are met, i.e. in this case an obstacle has been detected with the left and right sensors, the first applicable query is always executed for an if - else if - else query. In these cases, this is always the function that is assigned to the query of the left-hand obstacle sensor.

JoyCar.initJoyCar(RevisionMainboard.OnepThree)
basic.forever(function () {
    if (JoyCar.obstacleavoidance(SensorLRSelection.Left)) {
        JoyCar.light(ToggleSwitch.On)
    } else if (JoyCar.obstacleavoidance(SensorLRSelection.Right)) {
        JoyCar.reversinglight(ToggleSwitch.On)
    } else {
        JoyCar.light(ToggleSwitch.Off)
        JoyCar.reversinglight(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()

# Activate/deactivate the light for reversing
def lightsBack(on = True):
    if on:
        # Set left rear light to white
        np[backlights[0]] = led_white
        np.show()
    else:
        # Set left rear light to black
        np[backlights[0]] = 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

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

    # Check left-hand obstacle sensor
    if not sensor_data[5]:
        # Switch on low beam
        lights()
    # Check right-hand obstacle sensor
    elif not sensor_data[6]:
        # Activate reversing light
        lightsBack()
    else:
        # Switch off low beam & reversing light
        lights(on = False)
        lightsBack(on = False)