from machine import Pin,PWM
import neopixel
import utime
trig = 27
state_value = 0
mode_value = 0
IR_Pin  = Pin(19,Pin.IN,Pin.PULL_UP)
button = Pin(18, Pin.IN)
RGB_pin = Pin(26, Pin.OUT)
np = neopixel.NeoPixel(RGB_pin, n=6, bpp=3, timing=1)
buzzer = PWM(Pin(33))
buzzer.duty_u16(0)
N=0

speed = 1023  #Speed range:0~1023
def motor(L12,L13,R14,R15):
    PWM(Pin(12)).duty(L12) 
    PWM(Pin(13)).duty(L13) 
    PWM(Pin(14)).duty(R14) 
    PWM(Pin(15)).duty(R15)
def getDistance(trig):
    trig = Pin(27,Pin.OUT)
    trig.value(0)
    utime.sleep_us(2)
    trig.value(1)
    utime.sleep_us(10)
    trig.value(0)
    trig = Pin(27,Pin.IN)
    while trig.value() == 0:
        start = utime.ticks_us()
    while trig.value() == 1:
        end = utime.ticks_us()
    d = (end - start) * 0.0343 / 2 
    return d
def motor(A1,A2,B1,B2):
    motor1.duty_u16(A1) 
    motor2.duty_u16(A2) 
    motor3.duty_u16(B1) 
    motor4.duty_u16(B2)
    
def Advance():
    distance = getDistance(trig)
    if distance < 20:
        motor(0,0,0,0)
        for n in range(0,6):
            np[n] = (255,0,0)
        np.write()
        buzzer.duty_u16(2000)
        buzzer.freq(262)
        utime.sleep(0.3)
        for n in range(0,6):
            np[n] = (0,0,0)
        np.write()
        buzzer.duty_u16(0)
        utime.sleep(0.3)
    else:
        motor(0,speed,0,speed)
        for n in range(0,6):
            np[n] = (0,255,0)
        np.write()
        
def IR_remote_control(key_val):
    global state_value
    global mode_value
    if(key_val==0x45):
        mode_value = 1
    elif(key_val==0x46):
        mode_value = 0
    if(key_val==0x18):
        if(mode_value==1):
            Advance()
            state_value = 1
        elif(mode_value==0):
            state_value = 0
            motor(0,speed,0,speed)
#         motor(speed,0,speed,0) # Go forward
    elif(key_val==0x08):
        state_value = 0
        motor(speed,0,0,speed) # Turn left
    elif(key_val==0x5a):
        state_value = 0
        motor(0,speed,speed,0) # Turn right
    elif(key_val==0x52):
        state_value = 0
        motor(speed,0,speed,0) # Go back
    else:
        state_value = 0
        motor(0,0,0,0) # Stop
    if(state_value==0):
        for n in range(0,6):
            np[n] = (0,255,0)
        np.write()
            
if __name__ == '__main__':    
    while True:
        if IR_Pin.value() == 0:
            count = 0
            while IR_Pin.value() == 0 and count < 200:
                count += 1
                utime.sleep_us(60)
            count = 0
            while IR_Pin.value() == 1 and count < 80:
                count += 1
                utime.sleep_us(60)
            idx = 0
            cnt = 0
            data = [0,0,0,0]
            for i in range(0,32):
                count = 0
                while IR_Pin.value() == 0 and count < 15:
                    count += 1
                    utime.sleep_us(60)
                count = 0
                while IR_Pin.value() == 1 and count < 40:
                    count += 1
                    utime.sleep_us(60)
                if count > 8:
                    data[idx] |= 1<<cnt
                if cnt == 7:
                    cnt = 0
                    idx += 1
                else:
                    cnt += 1
            if data[0]+data[1] == 0xFF and data[2]+data[3] == 0xFF:
#                 print("Retrieve key: 0x%02x" %data[2])
                N=data[2]
        if IR_Pin.value() == 1:
            motor(0,0,0,0)     # Stop
        else:
            IR_remote_control(N)

        
