F.Ahmed
F.Ahmed

Reputation: 123

Need help merging two codes together

I am trying to make an autonomous car that has a line sensor and a ultrasonic sensor. The car needs to go forwards if the the line sensor on the left and right is activated

if pin16.read_digital == 1 & pin 15.read_digital == 1
   pin2.write_anlog(180)

The above code works fine. I have finished the code which integrates the line sensor and the ultrasonic sensor. The finished code is below :

from microbit import *
from neopixel import NeoPixel
import time
import machine

def setup():
    display.off()
    np = NeoPixel(pin0, 5)
    np.clear()

    pin4.set_pull(pin4.PULL_UP)
    pin1.set_analog_period(20)
    pin2.set_analog_period(20)

    pin15.set_pull(pin15.PULL_UP)
    pin16.set_pull(pin16.PULL_UP)

def distance():
    pin3.write_digital(0)
    time.sleep_us(2)

    pin3.write_digital(1)

    time.sleep_us(10)
    pin3.write_digital(0)

    output = machine.time_pulse_us(pin4, 1)

    return output * 0.034 / 2

def forward():
    pin2.write_analog(1)

def backward():
    pin2.write_analog(180)

def stop():
    pin2.write_analog(90)

def line():
    if pin15.read_digital() == 1 & pin16.read_digital() == 1:
        return True
else:
    return False

setup()
# pin1.write_analog(90)
sleep(200)
# pin1.write_analog(70) right
# pin1.write_analog(150) right


while True:
    if (distance() > 5) & line():
        forward()
    else:
        stop()

This works fine, however when I try to put the left and right in, it does not work. How do I fix this ? The code for left and right is below

while True:
if pin15.read_digital() == 1 & pin16.read_digital() == 0:
    pin1.write_analog(180)
    pin2.write_analog(95)
    time.sleep(500)
    pin2.write_analog(90)
elif pin15.read_digital() == 0 & pin16.read_digital() == 1:
    pin1.write_analog(70)
    pin2.write_analog(180)
    time.sleep(500)
    pin2.write_analog(90)

Upvotes: 1

Views: 104

Answers (2)

tobias_k
tobias_k

Reputation: 82929

You should use and instead of &. & is bitwise and, which binds stronger than ==, whereas and is logical and, which binds weaker than ==.

>>> a, b = 0, 1                                                             
>>> a == 0 and b == 1                                                       
True
>>> a == 0 & b == 1                                                         
False

The latter example, which corresponds to your if statements, is parsed as a == (0 & 1) == 1, i.e. 0 == 0 == 1 (and this, by Python comparison chaining, is not (0 == 0) == 1, which would evaluate to True, but (0 == 0) and (0 == 1)).

For a == 1 & b == 1 this is not a problem, but in all other cases, it will behave unexpectedly.

>>> cases = [(0, 0), (0, 1), (1, 0), (1, 1)]                               
>>> [a == 0 & b == 0 for a, b in cases] # should be [True, False, False, False]
[True, True, False, False]              # but evaluates as "a == 0 == 0"
>>> [a == 0 & b == 1 for a, b in cases] # should be [False, True, False, False]
[False, False, False, False]            # but evaluates as "a == 0 == 1"
>>> [a == 1 & b == 0 for a, b in cases] # should be [False, False, True, False]
[True, False, False, False]             # but evaluates as "a == b == 0"
>>> [a == 1 & b == 1 for a, b in cases] # should be [False, False, False, True]
[False, False, False, True]             # evaluates as "a == b == 1" ("correct")

Upvotes: 1

Asher Atom
Asher Atom

Reputation: 21

I'm not an expert in Arduino nor in the Neopixel library. However, aren't you missing the forward case in your third block of code? Also, it's better to use and instead of &, because & is a bitwise operator and is ranked higher than == in the operator precedence rules, as tobias_k says (you could use parenthesis to work around this if you wanted to, but why would you prefer the bitwise operator?). No need of the == operator, by the way. An integer is automatically evaluated as False in an if statement if it's 0, and True otherwise:

while True:
    read_left, read_right = pin15.read_digital(), pin16.read_digital()
    if read_left and read_right:
        # your code to go forward
    elif read_left and not read_right:
        # your code to turn left
    elif not read_left and read_right:
        # your code to turn right
    else:
        # your code when no line is detected, if you want to handle this case

Upvotes: 1

Related Questions