Ejemplo n.º 1
0
def init():
    global __led
    if __led != None or PIN_LED <= 0:
        return
    __led = NeoPixel(Pin(PIN_LED, Pin.OUT), 1)
    __led.fill((0, 0, 0))
    __led.write()
Ejemplo n.º 2
0
class Rgb(NeoPixel):
    def __init__(self, pin, num=1):
        self.pin = pin
        self.num = num
        self.np = NeoPixel(Pin(self.pin, Pin.OUT), self.num)
        # self.np = super().__init__(Pin(self.pin, Pin.OUT), self.num)

    def simpleTest(self, wait_ms=500):
        self.np[0] = RED
        self.np.write()
        sleep_ms(wait_ms)

        self.np[0] = GREEN
        self.np.write()
        sleep_ms(wait_ms)

        self.np[0] = BLUE
        self.np.write()
        sleep_ms(wait_ms)

        self.np[0] = (0, 0, 0)
        self.np.write()

    def color(self, color=RED, i=0):
        self.np[i] = color
        self.np.write()

    def color_chase(self, np, num_pixels, color, wait):
        for i in range(self.num):
            self.np[i] = color
            self.np.write()
            sleep(wait)

    def rainbow_cycle(self, wait=3, intensity=2):
        for j in range(255):
            for i in range(self.num):
                rc_index = (i * 256 // self.num) + j
                self.np[i] = wheel(rc_index & 255, dev=intensity)
            self.np.write()
            sleep_ms(wait)

    def test(self):
        #https://github.com/maxking/micropython/blob/master/rainbow.py
        self.simpleTest()

        self.color_chase(
            self.np, self.num, RED,
            0.1)  # Increase the number to slow down the color chase
        self.color_chase(self.np, self.num, YELLOW, 0.1)
        self.color_chase(self.np, self.num, GREEN, 0.1)
        self.color_chase(self.np, self.num, CYAN, 0.1)
        self.color_chase(self.np, self.num, BLUE, 0.1)
        self.color_chase(self.np, self.num, PURPLE, 0.1)

        self.rainbow_cycle()  # Increase the number to slow down the rainbow
        sleep(1)

        self.np.fill(BLACK)
        self.np.write()
Ejemplo n.º 3
0
 def set_range(cls,
               pixels: NeoPixel,
               range_slice: slice,
               col: RGBBytesColor,
               clear_others: bool = False):
     if clear_others:
         pixels.fill(COL_BLACK)
     pix_range = NeoPixelRange(pixels, range_slice)
     pix_range.set_colors(col)
Ejemplo n.º 4
0
 def blink(self, color=[255, 255, 255], times=3, interval=0.5):
     try:
         self.off()
         for i in range(times):
             NeoPixel.fill(self, color)
             NeoPixel.write(self)
             time.sleep(interval)
             NeoPixel.fill(self, [0, 0, 0])
             NeoPixel.write(self)
             time.sleep(interval)
     finally:
         self.off()
Ejemplo n.º 5
0
def init():
    global left_arm, right_arm, head, lights, display, footpedal, keypad
    left_arm = LazyServo(17, min_angle=90, max_angle=-90)
    right_arm = LazyServo(22)
    head = LazyServo(27)
    lights = NeoPixel(D18, 8)
    lights.fill((255, 0, 0))
    display = CountDisplay(23, 24)
    footpedal = Button(25)
    keypad = Keypad([9, 11, 10, 5], [6, 13, 19, 26])
    for row in keypad.keymap:
        for key in row:
            keypad.callbacks[key] = lambda: print(key)
Ejemplo n.º 6
0
def init_pixels(led_count: int) -> NeoPixel:
    ADDRESSABLE_LEDS = led_count  # (30/m * 5m) / 3 [Addr is Groups of 3]
    print('Setting up neopixel + clearing lights')

    pixels = NeoPixel(board.D18,
                      ADDRESSABLE_LEDS,
                      brightness=1,
                      auto_write=False,
                      pixel_order="BRG")
    pixels.fill(COL_BLACK)
    pixels.show()

    return pixels
Ejemplo n.º 7
0
class Controller():
    def __init__(self, ledsCount, color, brightness):
        self.pixels = NeoPixel(board.D18,
                               ledsCount,
                               auto_write=False,
                               brightness=brightness)

        self.color = color
        self.brightness = brightness
        self.pixels.fill(self.color)
        self.show_pixels()

    def change_color(self, color):
        self.color = color
        self.pixels.fill(self.color)
        self.show_pixels()

    def change_brightness(self, brightness):
        self.brightness = abs(brightness / 100)
        self.pixels.brightness = self.brightness
        self.show_pixels()

    def set_pixels(self, leds, colors=[]):
        self.clear_pixels()
        if len(colors) <= 0:
            for led in leds:
                self.set_pixel(led, self.color)
        else:
            for i, led in enumerate(leds):
                self.set_pixel(led, colors[i])
        self.pixels.show()

    def set_pixel(self, led, color):
        self.pixels[led] = color

    def show_pixels(self):
        self.pixels.show()

    def clear_pixels(self):
        self.pixels.fill((0, 0, 0))

    def turn_off(self):
        self.clear_pixels()
        self.show_pixels()

    def turn_on(self):
        self.pixels.fill(self.color)
        self.show_pixels()
Ejemplo n.º 8
0
                    "b5wld0101-raw-out1", "b5wld0101-raw-out2")
UPLOAD_V_FIELDS = ("b5wld0101-vth", "b5wld0101-vcc")
UPLOAD_CPU_FIELDS = ("cpu-temperature", )
UPLOAD_FIELDS = UPLOAD_PM_FIELDS + UPLOAD_V_FIELDS + UPLOAD_CPU_FIELDS


def d_print(level, *args, **kwargs):
    """A simple conditional print for debugging based on global debug level."""
    if not isinstance(level, int):
        print(level, *args, **kwargs)
    elif debug >= level:
        print(*args, **kwargs)


pixel = NeoPixel(MPP_NEOPIXEL, 1)
pixel.fill(BLACK)

### Initialise the trio of sensors
### Plantower PMS5003 - serial connected
pms5003_en = digitalio.DigitalInOut(PMS5003_EN)
pms5003_en.direction = digitalio.Direction.OUTPUT
pms5003_en.value = True
pms5003_rst = digitalio.DigitalInOut(PMS5003_RST)
pms5003_rst.direction = digitalio.Direction.OUTPUT
pms5003_rst.value = True
serial = busio.UART(PMS5003_TX, PMS5003_RX, baudrate=9600, timeout=15.0)

### Sensirion SPS30 - i2c connected
i2c = busio.I2C(SPS30_SCL, SPS30_SDA)
pms5003 = PM25_UART(serial)
sps30 = SPS30_I2C(i2c, fp_mode=True)
Ejemplo n.º 9
0
from machine import Pin
from neopixel import NeoPixel
from time import sleep

NUM_PIXELS = 14
np = NeoPixel(Pin(16), NUM_PIXELS)
colours = {
    'red': (255, 0, 0),
    'green': (0, 255, 0),
    'blue': (0, 0, 255),
    'orange': (255, 165, 0),
    'yellow': (255, 255, 0),
    'yel_grn': (255, 255, 0),
    'off': (0, 0, 0)
}

while True:
    np.fill(colours['off'])
    for i in range(7):
        np[i] = colours['yellow']
    np.write()
    sleep(1)
    np.fill(colours['off'])
    for i in range(7, 14):
        np[i] = colours['blue']
    np.write()
    sleep(1)
Ejemplo n.º 10
0
from gpiozero import Button
from board import D18
from neopixel import NeoPixel
import time
import numpy
# import threading
from random import randint, choice
# import pdb

pixels = NeoPixel(D18, 16)
pixels.fill((0, 0, 0))
# global jacks_pins

jacks_pins = [13, 22, 6, 8, 3, 10, 20, 27, 19, 24, 23, 25, 16, 11, 12, 9]

jacks_diodes = {
    12: 15,
    9: 14,
    13: 13,
    22: 12,
    6: 11,
    8: 10,
    3: 9,
    10: 8,
    20: 7,
    27: 6,
    19: 5,
    24: 4,
    23: 3,
    25: 2,
    16: 1,
Ejemplo n.º 11
0
import time
from machine import Pin
from neopixel import NeoPixel

np = NeoPixel(Pin(19), 12)
RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)

while True:
    np.fill(RED)
    np.write()
    time.sleep(1)
    np.fill(GREEN)
    np.write()
    time.sleep(1)
    np.fill(BLUE)
    np.write()
    time.sleep(1)
    np.fadeinout(PURPLE)
    np.cycle(YELLOW, 30)
    np.bounce(CYAN, 30)
    np.color_chase(RED, 30)
    np.color_chase(YELLOW, 30)
    np.color_chase(GREEN, 30)
    np.color_chase(CYAN, 30)
    np.color_chase(BLUE, 30)
    np.color_chase(PURPLE, 30)
Ejemplo n.º 12
0
#
# Shop: https://shop.mchobby.be/55-leds-neopixels-et-dotstar
# Wiki: https://wiki.mchobby.be/index.php?title=MicroPython-Accueil#ESP8266_en_MicroPython

from machine import Pin
from neopixel import NeoPixel
from time import sleep
from os import urandom

NEOPIXEL_PIN = 2
NEOPIXEL_COUNT = 8
NEOPIXEL_WAIT = 0.010 # 10 ms

# NeoPixel( broche_signal, nbre_de_led )
np = NeoPixel( Pin(NEOPIXEL_PIN), NEOPIXEL_COUNT )
np.fill( (0,0,0) )
np.write()

def wheel( wheel_pos ):
	""" caculate color based on a color wheel. 
	    Color are transistion r - g - b back r based on wheel_pos (0-255) """
	assert 0<= wheel_pos <= 255, "Invalid wheel_pos!"
	
	wheel_pos = 255 - wheel_pos
	if( wheel_pos < 85 ):
		return ( 255-(wheel_pos*3), 0, wheel_pos*3 )
	elif( wheel_pos < 170 ):
		wheel_pos -= 85
		return ( 0, wheel_pos*3, 255-(wheel_pos*3) )
	else:
		wheel_pos -= 170
Ejemplo n.º 13
0
class Glock(object):
    def __init__(self):
        self.code = utils.get_code()
        print("CURRENT KP CODE:", self.code)

        self.result_count = 0
        self.last = -1
        self.names = [
            "Joel", "Obed", "Malcolm", "Omar", "Matt", "Chris", "Chinny"
        ]

        #thread variables
        self.kp_thread = None
        self.camera_thread = None
        self.stream_thread = None
        self.main_thread = None
        self.idle_thread = None

        #thread event signals
        self.kp_stop_signal = None
        self.camera_stop_signal = None
        self.stream_stop_signal = None
        self.main_stop_signal = None
        self.idle_stop_signal = None
        self.idle_blue_signal = Event()

        #system variables
        self.camera = None
        self.system_active_idle = False
        self.ran_validation = False
        self.keypad = None
        self.killed = False
        self.stream_process = None
        self.stream = None
        self.result_count = None
        self.init_done = False
        self.bytes = None
        self.key = None
        self.fps = None
        self.kp_active = False
        self.result_count = None
        self.frame_counter = 0
        self.verification_frame_count = 0

        # NeoPixel Setup
        self.pixel_pin = board.D21
        self.num_pixels = 60
        self.ORDER = GRB
        self.pixels = NeoPixel(self.pixel_pin,
                               self.num_pixels,
                               brightness=0.2,
                               auto_write=False,
                               pixel_order=self.ORDER)

        #setup GPIO pins
        self.GPIO_TRIGGER = 13
        self.GPIO_ECHO = 19
        self.GPIO_STRIKE = 20
        self.LED_PIN = 25

        #set GPIO direction (IN / OUT)
        #GPIO SETUP
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        GPIO.setup(self.GPIO_TRIGGER, GPIO.OUT)
        GPIO.setup(self.GPIO_ECHO, GPIO.IN)
        GPIO.setup(self.GPIO_STRIKE, GPIO.OUT)
        GPIO.setup(self.LED_PIN, GPIO.OUT)  # LED pin

    def detect_face_frame(self, image):
        final = []
        cascPath = "haarcascade_frontalface_default.xml"
        # Create the haar cascade
        faceCascade = opencv.CascadeClassifier(cascPath)
        gray = opencv.cvtColor(image, opencv.COLOR_BGR2GRAY)

        print("frame processing...")
        # cv2.destroyAllWindows()
        # Detect faces in the image
        faces = faceCascade.detectMultiScale(gray,
                                             scaleFactor=1.3,
                                             minNeighbors=5)

        #If no faces were found tweak parameters
        if len(faces) == 0:
            faces = faceCascade.detectMultiScale(gray,
                                                 scaleFactor=1.2,
                                                 minNeighbors=5)
        if len(faces) == 0:
            faces = faceCascade.detectMultiScale(gray,
                                                 scaleFactor=1.1,
                                                 minNeighbors=5)

        # Draw a rectangle around the faces
        for (x, y, w, h) in faces[::-1]:
            print("Found a face!")
            #Resize image to 120 pixels
            cropped = gray[y - 20:y + h + 20, x:x + w]
            final = np.array(opencv.resize(cropped, (100, 100)))

            opencv.imshow("Display WIndow", final)
            opencv.waitKey(0)
            opencv.destroyAllWindows()
        return final

    def find_face(self, img):
        global model_sigmoid
        global model_softmax
        global sig_input_details
        global soft_input_details
        global sig_output_details
        global soft_output_details

        face = self.detect_face_frame(img)
        #If no face found
        if face == []:
            return 0, -1

        #Sigmoid output
        sig_input_data = np.reshape(np.array(face, dtype=np.float32),
                                    sig_input_details[0]['shape'])
        model_sigmoid.set_tensor(sig_input_details[0]['index'], sig_input_data)
        model_sigmoid.invoke()
        sig_output = model_sigmoid.get_tensor(sig_output_details[0]['index'])

        #Softmax Output
        soft_input_data = np.divide(
            np.reshape(np.array(face, dtype=np.float32),
                       soft_input_details[0]['shape']), 255.0)
        model_softmax.set_tensor(soft_input_details[0]['index'],
                                 soft_input_data)
        model_softmax.invoke()
        soft_output = model_softmax.get_tensor(soft_output_details[0]['index'])

        sig = np.argmax(sig_output)
        soft = np.argmax(soft_output)
        print("Sig Raw Value: ", sig_output)
        print("Soft Raw Value: ", soft_output)
        print("Person: ", self.names[sig])
        #If 2 differnt people
        if sig != soft:
            return -1, -1
        #If not above threshold
        #elif
        else:
            return 1, sig

    def distance(self):
        #set Trigger to HIGH
        GPIO.output(self.GPIO_TRIGGER, True)

        # set Trigger after 0.01ms to LOW
        sleep(0.00001)
        GPIO.output(self.GPIO_TRIGGER, False)

        StartTime = time()
        StopTime = time()

        # save StartTime
        while GPIO.input(self.GPIO_ECHO) == 0:
            StartTime = time()

        # save time of arrival
        while GPIO.input(self.GPIO_ECHO) == 1:
            StopTime = time()

        # time difference between start and arrival
        TimeElapsed = StopTime - StartTime
        # multiply with the sonic speed (34300 cm/s)
        # and divide by 2, because there and back
        distance = (TimeElapsed * 34300) / 2
        return distance

    def led_unlock_success(self):
        #stop idle led to allow for GREEN light
        if self.idle_stop_signal != None:
            self.idle_stop_signal.set()
            self.idle_thread.join()

        #start with green flash and then pulse
        self.pixels.fill((0, 225, 0))
        for i in range(60):
            self.pixels[i] = (0, 125, 0)
            self.pixels.show()
            sleep(.01)

        for i in range(60):
            self.pixels[60 - i - 1] = (0, 50, 0)
            self.pixels.show()
            sleep(.01)

    def led_unlock_fail(self):
        #stop idle led to allow for RED light
        if self.idle_stop_signal != None:
            self.idle_stop_signal.set()
            self.idle_thread.join()
        #pluse in red
        for eek in range(3):
            for i in range(20):
                self.pixels.fill((225 - i, 0, 0))
                self.pixels.show()
                sleep(.0005)
        sleep(.5)

    def restart_idle(self):
        #Function to restart IDLE LED Thread
        sleep(1)

        self.idle_stop_signal = Event()
        self.idle_blue_signal.clear()
        self.idle_thread = Thread(target=self.idle)

        self.idle_thread.start()

    def idle(self):
        print("starting IDLE LED thread")
        #Process to  pulse either white or blue
        #will plulse in blue if signal is sent by keypad handler
        while not self.idle_stop_signal.wait(0):
            if self.idle_blue_signal.isSet():
                for i in range(60):
                    self.pixels[i] = (0, 0, 125)
                    self.pixels.show()
                    sleep(.01)

                for i in range(60):
                    self.pixels[60 - i - 1] = (0, 0, 50)
                    self.pixels.show()
                    sleep(.01)
            else:
                for i in range(60):
                    self.pixels[i] = (125, 125, 125)
                    self.pixels.show()
                    sleep(.01)

                for i in range(60):
                    self.pixels[60 - i - 1] = (50, 50, 50)
                    self.pixels.show()
                    sleep(.01)

    def Validated(self):
        #add mutex on gpio ops?
        #activate strike for 10 sec
        GPIO.output(self.GPIO_STRIKE, GPIO.HIGH)
        print("GLOCK STRIKE ACTIVATED")
        sendText(True)

        self.led_unlock_success()  #unlock strike and wait
        sleep(16)
        GPIO.output(self.GPIO_STRIKE, GPIO.LOW)
        self.ran_validation = True  #send signal to restaart idle thread

    def Invalidated(self):
        #add mutex on gpips?
        print("GLOCK INVALID")
        sendText(False)
        self.led_unlock_fail()
        self.ran_validation = True

    def setup_stream(self):
        global output
        #loop to send cameera feed to streaming output class
        while not self.stream_stop_signal.wait(0):
            with PiCamera(resolution='1024x768', framerate=24) as self.camera:
                output = StreamingOutput()
                self.camera.start_recording(output,
                                            format='mjpeg',
                                            splitter_port=1,
                                            quality=0)
                sleep(_ONE_DAY_IN_SECONDS)
        self.camera.stop_recording()

    def CameraHandler(self):
        #Load models
        global model_sigmoid
        global model_softmax
        global sig_input_details
        global soft_input_details
        global sig_output_details
        global soft_output_details

        model_sigmoid = tf.lite.Interpreter(model_path="sigmoid.tflite")
        model_sigmoid.allocate_tensors()
        sig_input_details = model_sigmoid.get_input_details()
        sig_output_details = model_sigmoid.get_output_details()

        model_softmax = tf.lite.Interpreter(model_path="softmax.tflite")
        model_softmax.allocate_tensors()
        soft_input_details = model_softmax.get_input_details()
        soft_output_details = model_softmax.get_output_details()

        self.init_done = True
        print("Enter CameraHandler...")
        log_handler.emit("Enter CameraHandler...")
        self.result_count = 0

        while not self.camera_stop_signal.wait(0):
            #if no one infrom of door or keypad currently in use then skip processing frame
            if self.system_active_idle == False or self.kp_active:
                # print("loop until motion")
                continue
            #grab every third frame from the camera to verfiy face
            if (self.verification_frame_count % 3 == 0):
                #capture image in array and send to ML suite
                rawCapture = PiRGBArray(self.camera, size=(1024, 768))
                sleep(0.1)
                self.camera.capture(rawCapture,
                                    format="bgr",
                                    use_video_port=True,
                                    splitter_port=2)
                image = rawCapture.array

                result, person = self.find_face(image)

                rawCapture.truncate(0)
                if result == 0:  #no face found in image
                    print("NO FACE FOUND")
                    log_handler.emit("NO FACE FOUND")
                    continue
                elif (result == 1
                      and self.last == -1) or (result == 1 and self.last
                                               == person):  #corect face found
                    self.result_count += 1
                    last = person
                    print("RESIDENT FACE FOUND")
                    log_handler.emit("RESIDENT FACE FOUND")
                else:  #face found but incorrect
                    self.result_count -= 1
                    print("INCORRECT FACE FOUND")
                    log_handler.emit("INCORRECT FACE FOUND")

                #need to see the same face twice in order to verify resident
                if (self.result_count == 2):
                    self.Validated()
                    self.result_count = 0  #reset "correct score"
                    self.last = -1
                #same logic..if two wrong faces then signal invalid
                elif (self.result_count == -2):
                    self.Invalidated()
                    self.result_count = 0
                    self.last = -1
                else:
                    continue
            self.verification_frame_count += 1
            # count +=1
            # #call verification on captured image

    def KeypadHandler(self):
        print("Enter KeypadHandler")
        log_handler.emit("Enter KeypadHandler")

        code_as_list = list(self.code)
        print("code as list: ", code_as_list)
        log_handler.emit("code as list: ", code_as_list)
        #create empty buffer for entered code
        entered_code = list()
        new_code_list = list()
        code_active = False  # flag for signaling when input seq ready
        reset_active = False
        self.kp_active = False
        looking_new_code = False

        while not self.kp_stop_signal.wait(0):
            keys = self.keypad.pressed_keys  #grab key pressed
            if len(keys) != 1:
                #eliminate multi press for keypad
                continue

            if keys == ["#"] and looking_new_code:
                #clear newcode being entered while in "enter code state"
                new_code_list = list()

            elif keys == ['*']:  #input is reset and now look for code
                entered_code = list()
                new_code_list = list()

                code_active = True
                reset_active = False
                self.kp_active = True
                looking_new_code = False

                self.idle_blue_signal.clear()
            #reset master key code (usual '#' case)
            elif keys == ['#']:
                self.idle_blue_signal.set()

                entered_code = list()
                new_code_list = list()
                code_active = False
                reset_active = True
                self.kp_active = True
                looking_new_code = False

            elif reset_active:
                #regualar number is pressed while setting new key code ]
                #or to verifty old code for kp code change
                new_code_list += keys
                if looking_new_code:  #if case will short to here if alrady entered old code to change to new
                    if len(code_as_list) == len(new_code_list):  #get new code
                        print("new_code", new_code_list)
                        log_handler.emit("new_code", new_code_list)

                        as_string = [str(elem) for elem in new_code_list]
                        as_string = ''.join(as_string)

                        #update code variavles
                        self.code = as_string
                        utils.change_code(as_string)
                        code_as_list = new_code_list

                        #flash blue
                        new_code_list = list()
                        entered_code = list()
                        looking_new_code = False
                        reset_active = False

                        self.idle_blue_signal.clear()
                        self.kp_active = False

                elif len(code_as_list) == len(
                        new_code_list):  #submit old code for verification
                    verification_res = (new_code_list == [
                        int(i) for i in code_as_list
                    ])  #verify list
                    print("old_code", new_code_list, "verified:",
                          str(verification_res))
                    log_handler.emit("old_code", new_code_list, "verified:",
                                     str(verification_res))

                    if verification_res:
                        #flash blue
                        # time.sleep(1)
                        # time.sleep(1)
                        looking_new_code = True

                        self.led_unlock_success()

                    else:
                        #flash red
                        reset_active = False
                        self.kp_active = False
                        self.Invalidated()

                    new_code_list = list()
                    entered_code = list()

            elif code_active:
                entered_code += keys  #add key to code
                if len(code_as_list) == len(
                        entered_code):  #submit code for verification
                    code_active = False
                    self.kp_active = False

                    print("code", entered_code)
                    log_handler.emit("code", entered_code)
                    verification_res = (entered_code == [
                        int(i) for i in code_as_list
                    ])  #verify list
                    if verification_res == True:
                        print("Validated")
                        log_handler.emit("Validated")
                        self.Validated()
                    else:
                        print("Invalidated")
                        log_handler.emit("Invalidated")
                        self.Invalidated()

            else:
                continue

            print("code", entered_code)
            print("reset_code", new_code_list)

            sleep(0.3)

    def MainHandler(self):
        print("Enter Main MainHandler...")
        # distances = [1000,1000,1000] #track last three disances

        #create queue of seen distances
        distances = [0, 0, 0]
        d_count = 0
        d_max = 0
        while not self.init_done:
            continue
        while not self.main_stop_signal.wait(0):
            sleep(0.5)
            distance = self.distance()
            distances[d_count % 3] = distance
            d_count += 1
            print("Measured Distance = %.1f cm" % distance)
            # print(self.system_active_idle)
            # print(self.ran_validation)
            if (max(distances) < 90 and self.system_active_idle
                    == False):  #start process for camera and LED
                print("idlewake")

                self.system_active_idle = True

                self.restart_idle()

                self.kp_stop_signal = Event()
                self.kp_thread = Thread(target=self.KeypadHandler)
                self.kp_thread.start()

            elif (self.ran_validation == True):
                print("ran validation, restarting idle")
                log_handler.emit("ran validation, restarting idle")

                #clear pixels
                self.pixels.fill((0, 0, 0))
                self.pixels.show()

                #restart the killed idle thread if person in front of sensor
                if max(distances) < 90:
                    self.restart_idle()
                    self.system_active_idle = True
                else:

                    self.system_active_idle = False
                self.ran_validation = False
            elif (min(distances) > 90 and self.system_active_idle
                  == True):  #close ML and turn off LED
                print("no motion detected...close idle")
                log_handler.emit("no motion detected...close idle")
                self.system_active_idle = False

                self.idle_blue_signal.clear()
                self.idle_stop_signal.set()
                self.kp_stop_signal.set()

                self.idle_thread.join()

                self.kp_thread.join()
                print("kp joined")

                self.pixels.fill((0, 0, 0))
                self.pixels.show()

                self.ran_validation = False
        try:
            self.camera_stop_signal.set()
            self.camera_thread.join()
            print("camera joined")
            self.idle_stop_signal.set(
            )  #stop self.idle_thread when main function exits
            self.idle_thread.join()
        except:
            return

    def run(self):

        #clear pixels
        self.pixels.fill((0, 0, 0))
        self.pixels.show()

        self.stream_stop_signal = Event()
        self.stream_thread = Thread(target=self.setup_stream)
        self.stream_thread.start()

        self.keypad = keypad.keypad_setup()

        self.camera_stop_signal = Event()
        self.camera_thread = Thread(target=self.CameraHandler)
        self.camera_thread.start()

        self.main_stop_signal = Event()
        self.main_thread = Thread(target=self.MainHandler)
        self.main_thread.start()

        print("G_LOCK HAS BEEN STARTED")
        log_handler.emit("G_LOCK HAS BEEN STARTED")

    # def stream_serve(self):
    #     p0 = subprocess.call(['sudo', 'pkill', 'uv4l']) #exit any hanging uv4l processes

    #     command = "sudo uv4l -nopreview --auto-video_nr --driver raspicam --encoding mjpeg --width 640 --height 480 --framerate 20 --server-option '--port=2020' --server-option '--max-queued-connections=30' --server-option '--max-streams=25' --server-option '--max-threads=29'"
    #     args = shlex.split(command)
    #     p1 = subprocess.Popen(args) #start streaming server

    #     print("BEGIN UV4L STREAMING")

    def kill(self):
        self.killed = True

        print("GLOCK KILL: Stopping threads")

        self.main_stop_signal.set()
        self.stream_stop_signal.set()

        self.stream_thread.join()
        self.main_thread.join()

        #clear pixels
        self.pixels.fill((0, 0, 0))
        self.pixels.show()
Ejemplo n.º 14
0
class RFIDDoorUnlockClient:
    """Client class. Interacts directly with the MFRC522 RFID reader."""

    def __init__(self, room_num, mfrc_reader, remote_addr, mqtt_obj, aes_key, aes_iv):
        self.room = room_num
        self.rdr = mfrc_reader
        self.server_addr = remote_addr
        self.mqtt = mqtt_obj
        self.__key = aes_key
        self.__iv = aes_iv
        # Only using the neopixel instance for showing visually if the RFID tag was valid
        self.np = NeoPixel(Pin(17,Pin.OUT),32)
        print("RFID Door Unlock Client created")
        self.__running_thread = _thread.start_new_thread(self.run, tuple())

    def __str__(self):
        return ("Room: " + self.room + ", Verification Server: "
                + self.server_addr[0] + ":" + self.server_addr[1]
                + "\nAES 256 CBC Key: " + str(self.__key)
                + "\nAES 256 CBC IV: " + str(self.__iv))

    def __repr__(self):
        return (self.room, repr(self.rdr), self.server_addr,
                repr(self.mqtt), self.__key, self.__iv)

    # TODO: Implement __del__ method as soon as MicroPython supports it
    # for user created classes

    def run(self):
        """Constantly running on a thread once the instance is created

        Based heavily off of the do_read method from Tasmi Devil's
        MFRC522 examples.
        """
        while True:
            sleep_ms(100)  # Small lag for the RFID reader
            uid_hash = ''
            (stat, tag_type) = self.rdr.request(self.rdr.REQIDL)
            if stat == self.rdr.OK:
                print("reader status OK")
                (stat, raw_uid) = self.rdr.anticoll()
                if stat == self.rdr.OK:
                    print("reader status OK after anticoll")
                    h = sha256()
                    h.update(bytes(raw_uid))
                    uid_hash = h.digest()
                    print("RFID tag UID SHA-256 hash:")
                    print(uid_hash)
                    secure_packet, n = self.make_secure_packet(uid_hash)
                    print("Secure packet created")
                    client = socket(AF_INET, SOCK_STREAM)
                    client.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
                    client.connect(self.server_addr)
                    print("Connected to server")
                    client.sendall(secure_packet)  # 64-byte packet
                    print("Sent secure packet to server")
                    # TODO: set up a timeout here. Only wait for so long
                    response = client.recv(64)
                    print("Received response from server")
                    try:
                        client.close()
                        del client
                        print("Disconnected from server")
                    except AttributeError:
                        print("Connection closed on server side")
                    if self.verify(response, n):
                        print("Passed verification")
                        self.unlock_door()
                    else:
                        print("Failed verification")
                        self.blink_fail_lights()

    def make_secure_packet(self, h):
        """Encrypts and returns plaintext appended with a 32B nonce (also returned)

        AES 256 CBC is used (as opposed to EBC which would not be secure
        in this implementation)
        """
        nonce = urandom(32)
        plaintext = h + nonce
        e = aes(self.__key, 2, self.__iv)
        print("AES encrypter created")
        return e.encrypt(plaintext), nonce

    def verify(self, pkt, n):
        """Verifies the packet received has the same nonce as the one sent"""
        d = aes(self.__key, 2, self.__iv)
        plaintext = d.decrypt(pkt)
        payload = plaintext[:32]
        nonce = plaintext[32:]
        if n == nonce:
            print("Valid nonce")
            h = sha256()
            h.update(b'valid')  # the string that is hashed on the server side
            if payload == h.digest():
                print("Valid payload")
                return True
        return False

    def unlock_door(self):
        """Handles whatever things must be done to unlock the door

        In the specific version used for this project, this means
          1: Publishing the unlocked status to the MQTT broker
          2: Turning on the green LEDs
          3: Physically unlocking the door
          4: Waiting 5 seconds
          5: Physically locking the door
          6: Turning off the LEDs
          7: Publishing the locked status to the MQTT broker
        """
        #self.mqtt.connect()
        #print("Connected to MQTT broker")
        #self.mqtt.publish('/'+self.room_num+'/lock', 'unlocked')
        #print("'unlocked' sent to MQTT broker")
        #self.mqtt.disconnect()
        #print("Disconnected from MQTT broker")
        self.np.fill((0,10,0))
        self.np.write()
        # TODO: Physically unlock the door
        sleep_ms(5000)
        # TODO: Physically lock the door
        self.np.fill((0,0,0))
        self.np.write()
        #self.mqtt.connect()
        #print("Connected to MQTT broker")
        #self.mqtt.publish('/'+self.room_num+'/lock', 'locked')
        #print("'locked' sent to MQTT broker")
        #self.mqtt.disconnect()
        #print("Disconnected from MQTT broker")
        return

    def blink_fail_lights(self):
        """Blink the light pattern for a failed verification"""
        self.np.fill((10,0,0))
        self.np.write()
        sleep_ms(100)
        self.np.fill((0,0,0))
        self.np.write()
        sleep_ms(100)
        self.np.fill((10,0,0))
        self.np.write()
        sleep_ms(100)
        self.np.fill((0,0,0))
        self.np.write()
        sleep_ms(100)
        self.np.fill((10,0,0))
        self.np.write()
        sleep_ms(100)
        self.np.fill((0,0,0))
        self.np.write()
        sleep_ms(1000)
Ejemplo n.º 15
0
class ConfigManager:
  def __init__(self, config={}):
    self.config = config
    self.np = NeoPixel(Pin(5, Pin.OUT), 1, timing = True)
    self.np.fill((255, 0, 0)); self.np.write()

    self.wlan_ap = network.WLAN(network.AP_IF)
    self.wlan_sta = network.WLAN(network.STA_IF)

    # setup for ssid
    if self.config.get('device_name'):
      self.ap_name= self.config['device_name']
    else:
      self.ap_name= "BlockyWifi_" + binascii.hexlify(machine.unique_id()).decode('ascii')
    self.ap_password = "******"

    self.wifi_status = 0
    
  def connect(self, ssid, password):
    self.wlan_sta.active(True)
    self.wlan_sta.connect(ssid, password)
    a=0
    print('Connecting to wifi')
    while not self.wlan_sta.isconnected() | (a > 99) :
      time.sleep(0.1)
      a+=1
      print('.', end='')
    
    if self.wlan_sta.isconnected():
      print('\nConnected. Network config:', self.wlan_sta.ifconfig())
      self.wifi_status = 1
      return True
    else : 
      print('\nProblem. Failed to connect to :' + ssid)
      self.wifi_status = 2
      self.wlan_sta.active(False)
      return False

  def _httpHandlerIndexGet(self, httpClient, httpResponse):
    print('Get index request')  
    htmlFile = open('index.html', 'r')
    content = ''
    for line in htmlFile:
      content = content + line
    httpResponse.WriteResponseOk( headers = None,
      contentType	 = "text/html",	contentCharset = "UTF-8",	content = content)
    
    '''
    available_networks = []
    for nw in wlan_sta.scan():
      available_networks.append({'ssid': nw[0].decode('utf-8'), 'rssi': nw[3]})
      
    available_networks_str = ujson.dumps(networks)
    '''
  
  def _httpHandlerCheckStatus(self, httpClient, httpResponse):
    print('Get check status request')
    if self.wifi_status == 1:
      content = 'OK'
    elif self.wifi_status == 2:
      content = 'Failed'
    else:  
      content = ''
    
    httpResponse.WriteResponseOk(headers = None,
      contentType	 = "text/html",
      contentCharset = "UTF-8",
      content = content)
      
    if self.wifi_status == 1:
      print('Wait for rebooting')
      time.sleep(5)
      print('Rebooting')
      machine.reset()

  def _httpHandlerSaveConfig(self, httpClient, httpResponse):
    print('Get save config request')
    request_json = ujson.loads(httpClient.ReadRequestContent().decode('ascii'))
    self.wifi_status = 0
    print(request_json)
    httpResponse.WriteResponseOk(headers = None,
      contentType	 = "text/html",
      contentCharset = "UTF-8",
      content = 'OK')
    
    if self.connect(request_json['ssid'], request_json['password']):
      # save config
      if not self.config.get('known_networks'):
        self.config['known_networks'] = [{'ssid': request_json['ssid'], 'password': request_json['password']}]
      else:
        exist_ssid = None
        for n in self.config['known_networks']:
          if n['ssid'] == request_json['ssid']:
            exist_ssid = n
            break
        if exist_ssid:
          exist_ssid['password'] = request_json['password'] # update WIFI password
        else:
          # add new WIFI network
          self.config['known_networks'].append({'ssid': request_json['ssid'], 'password': request_json['password']})
      
      self.config['device_name'] = request_json['deviceName']
      self.config['auth_key'] = request_json['authKey']
      f = open('config.json', 'w')
      f.write(ujson.dumps(self.config))
      f.close()
    
  def _httpHandlerScanNetworks(self, httpClient, httpResponse) :
    print('Receive request to scan networks')
    self.wlan_sta.active(True)
    networks = []
    for nw in self.wlan_sta.scan():
      networks.append({'ssid': nw[0].decode('ascii'), 'rssi': nw[3]})
    
    content = ujson.dumps(networks)
   
    httpResponse.WriteResponseOk(headers = None,
      contentType	= "application/json",
      contentCharset = "UTF-8",
      content = content)
                   
  def start(self):    
    self.wlan_sta.active(True)
    self.wlan_ap.active(True)

    self.wlan_ap.config(essid=self.ap_name, password=self.ap_password)

    routeHandlers = [
      ("/", "GET", self._httpHandlerIndexGet),
      ("/aplist", "GET", self._httpHandlerScanNetworks),
      ("/status", "GET", self._httpHandlerCheckStatus),
      ("/save", "POST",	self._httpHandlerSaveConfig)
    ]

    srv = MicroWebSrv(routeHandlers=routeHandlers)
    srv.Start(threaded=True)

    print('Now enter config mode')
    print('Connect to Wifi ssid :' + self.ap_name + ' , default pass: '******'And connect to Blocky via at 192.168.4.1')

    gc.collect()
    print(gc.mem_free())

    return True
Ejemplo n.º 16
0
def delegate_format(pixel: neopixel.NeoPixel, input_item: any) -> None:
    item = input_item[0]
    pixel.fill((100, 100, 100))
Ejemplo n.º 17
0
Archivo: main.py Proyecto: joram/steps
def start_worker():
    thread = threading.Thread(target=drive_leds)
    thread.daemon = True                            # Daemonize thread
    thread.start()                                  # Start the execution


def stop_leds():
    global done
    done = True
    pixels.fill((0, 0, 0))


def button_callback():
    date_time = datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S")
    post_message_to_lack(f"@here button pressed! `{date_time}`")
    set_state({"mode": "nyan_cat"})
    time.sleep(10)
    set_state({"mode": "per_step"})


if __name__ == '__main__':
    if os.getenv('WERKZEUG_RUN_MAIN') == 'true':
        post_message_to_lack("stairs pi has booted")
        # register_button(button_callback)
        pixels.fill((255, 255, 255))
        atexit.register(stop_leds)
        start_worker()

    app.run(host="0.0.0.0", debug=True)
Ejemplo n.º 18
0
# couleur des autres pixels
np[1] = (0, 255, 0)  # vert
np[2] = (0, 0, 128)  # bleu (1/2 brillance)

# Voir aussi HTML Color Picker
# https://www.w3schools.com/colors/colors_picker.asp
np[3] = (255, 102, 0)  # Orange
np[4] = (255, 0, 102)  # Rose bonbon
np[5] = (153, 51, 255)  # Violet
np[6] = (102, 153, 255)  # bleu pastel
np[7] = (153, 255, 153)  # vert pastel

# Envoyer l'info au NeoPixels
np.write()

sleep(2)

# fill() permet de remplir tout
# le NeoPixel avec une seule couleur
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 128), (255, 102, 0), (255, 0, 102),
          (153, 51, 128), (102, 153, 128), (153, 255, 128)]

for color in colors:
    np.fill(color)
    np.write()
    sleep(2)

# Eteindre les NeoPixels
np.fill((0, 0, 0))
np.write()
Ejemplo n.º 19
0
import bme280
class LedStatus():

    INDEX_COLOURS = [
        0x9CFF9C, 0x31FF00, 0x31CF00, 0xF0F000, 0xFFCF00, 0xFF9A00, 0xFF6464,
        0xFF0000, 0x900000, 0xCE30FF
    ]

    def __init__(self):
        self.neo = NeoPixel(board.NEOPIXEL, 1, brightness=0.1)
        self.neo.fill(0)

    def show_air_quality(self, reading):
        # From: https://uk-air.defra.gov.uk/air-pollution/daqi?view=more-info&pollutant=pm25#pollutant
        if reading >= 71:
            self.neo.fill(self.INDEX_COLOURS[9])
        elif reading >= 65 and reading <= 70:
            self.neo.fill(self.INDEX_COLOURS[8])
        elif reading >= 59 and reading <= 64:
            self.neo.fill(self.INDEX_COLOURS[7])
        elif reading >= 54 and reading <= 58:
            self.neo.fill(self.INDEX_COLOURS[6])
        elif reading >= 48 and reading <= 53:
            self.neo.fill(self.INDEX_COLOURS[5])
        elif reading >= 42 and reading <= 47:
            self.neo.fill(self.INDEX_COLOURS[4])
        elif reading >= 36 and reading <= 41:
            self.neo.fill(self.INDEX_COLOURS[3])
        elif reading >= 24 and reading <= 35:
            self.neo.fill(self.INDEX_COLOURS[2])
        elif reading >= 12 and reading <= 23:
            self.neo.fill(self.INDEX_COLOURS[1])
        else:
            self.neo.fill(self.INDEX_COLOURS[0])
Ejemplo n.º 21
0
 def off(self):
     NeoPixel.fill(self, (0, 0, 0))
     NeoPixel.write(self)
     self._on = False
Ejemplo n.º 22
0
class ArtNeoPixel(ArtPart):
    def __init__(self,
                 pin=15,
                 n=30,
                 bpp=3,
                 name=None,
                 duration=10000,
                 director=None):

        super().__init__(name=name, duration=duration, director=director)

        if type(pin) is not Pin:
            pin = Pin(pin, Pin.OUT)
        self.np = NeoPixel(pin, n, bpp)
        self.refresh_rate = 15
        self.need_update = True
        self.running = True
        self.duration = duration  # ms
        log.debug("{} lights on {}".format(self.np.n, self.np.pin))
        self.cmds['random'] = self.random
        self.cmds['fade'] = self.fade
        self.cmds['bounce'] = self.bounce
        self.cmds['chase'] = self.chase
        self.cmds['clear'] = self.clear

    def __getitem__(self, key):
        return self.np[key]

    def __setitem__(self, key, value):
        self.np[key] = value

    def do_update(self):
        self.np.write()
        self.need_update = False
        return False

    def get_sublights(self, lights):
        if lights is None:
            lights = [j for j in range(self.np.n)]
        return len(lights), lights

    async def random(self,
                     brightness=0.1,
                     duration=5000,
                     beat=300,
                     start=0,
                     lights=None,
                     **kwargs):
        n, lights = self.get_sublights(lights)
        while self.running:
            await self.wait_for_start(start)
            begin_ms = ticks_ms()
            while duration is None or (ticks_diff(ticks_ms(), begin_ms) <
                                       duration):
                for j in lights:
                    col = [int(c * brightness) for c in os.urandom(3)]
                    self.np[j] = col
                self.need_update = True
                await asyncio.sleep_ms(beat)
            else:
                await self.clear(lights)
                return

    async def chase(self,
                    color=(255, 255, 255),
                    bgcolor=(0, 0, 0),
                    cycles=4,
                    duration=None,
                    beat=200,
                    start=0,
                    lights=None,
                    **kwargs):
        n, lights = self.get_sublights(lights)
        while self.running:
            await self.wait_for_start(start)
            begin_ms = ticks_ms()
            if duration is None:
                duration = cycles * beat * n
            else:
                cycles = duration // (beat * n)
            for i in range(cycles * n):
                if ticks_diff(ticks_ms(), begin_ms) > duration:
                    await self.clear(lights)
                    return
                self.np[lights[(i - 1) % n]] = bgcolor
                self.np[lights[i % n]] = color
                self.need_update = True
                await asyncio.sleep_ms(beat)
        await self.clear(lights)

    async def bounce(self,
                     color=(255, 255, 255),
                     bgcolor=(0, 0, 0),
                     cycles=4,
                     duration=None,
                     beat=100,
                     start=0,
                     lights=None,
                     **kwargs):
        await self.wait_for_start(start)
        n, lights = self.get_sublights(lights)
        if duration is None:
            duration = cycles * beat * n
        else:
            cycles = duration // (beat * n)
        begin_ms = ticks_ms()

        while self.running:
            for i in range(cycles * 2 * n):
                if ticks_diff(ticks_ms(), begin_ms) > duration:
                    await self.clear(lights)
                    return
                for j in lights:
                    self.np[j] = bgcolor
                if (i // n) % 2 == 0:
                    self.np[lights[i % n]] = color
                else:
                    self.np[lights[n - 1 - (i % n)]] = color
                self.need_update = True
                await asyncio.sleep_ms(beat)

    async def fade(self,
                   color=(255, 255, 255),
                   cycles=3,
                   step=8,
                   beat=30,
                   duration=None,
                   start=0,
                   lights=None,
                   **kwargs):
        await self.wait_for_start(start)
        n, lights = self.get_sublights(lights)
        if duration is None:
            duration = cycles * beat * n
        begin_ms = ticks_ms()
        while self.running and ticks_diff(ticks_ms(), begin_ms) <= duration:
            log.debug("start fade, ticks==%d",
                      ticks_diff(ticks_ms(), begin_ms))
            for val in range(0, 256, step):
                # log.info("val={}".format(val))
                for j in range(n):
                    self.np[lights[j]] = [val & v for v in color]
                self.need_update = True
                await asyncio.sleep_ms(beat)
                if ticks_diff(ticks_ms(), begin_ms) > duration:
                    await self.clear(lights)
                    return
            for val in range(255, -1, -step):
                # log.info("val={}".format(val))
                for j in range(n):
                    self.np[lights[j]] = [val & v for v in color]
                self.need_update = True
                await asyncio.sleep_ms(beat)
                if ticks_diff(ticks_ms(), begin_ms) > duration:
                    await self.clear(lights)
                    return
            for j in range(n):
                self.np[lights[j]] = (0, 0, 0)
            log.debug("stop fade, ticks==%d", ticks_diff(ticks_ms(), begin_ms))
            self.need_update = True
        await self.clear(lights)

    async def clear(self, lights=None, start=0, **kwargs):
        await self.wait_for_start(start)
        if lights is None:
            self.np.fill((0, 0, 0))
        else:
            for i in range(len(lights)):
                self.np[lights[i]] = (0, 0, 0)
        self.np.write()

    async def stop(self, clear=True, **kwargs):
        if clear:
            self.np.fill((0, 0, 0))
            self.np.write()
        self.running = False
        log.info("{}: stopping".format(self.name))
Ejemplo n.º 23
0
def color_wheel(pixel: neopixel.NeoPixel, input_item: colorify.Color) -> None:
    c = input_item
    pixel.fill(c.get_rgb())
    c.change_hue(1)
Ejemplo n.º 24
0
neo = NeoPixel(28, n=8, brightness=0.3, autowrite=False)

RED = (255, 0, 0)
YELLOW = (255, 150, 0)
GREEN = (0, 255, 0)
CYAN = (0, 255, 255)
BLUE = (0, 0, 255)
PURPLE = (180, 0, 255)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
COLORS = (RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE, BLACK)

# fill
for color in COLORS:
    neo.fill(color)
    neo.show()
    time.sleep(0.25)

# chase
for color in COLORS:
    for i in range(neo.n):
        neo[i] = color
        neo.show()
        time.sleep(0.025)

# rainbow
for i in range(255):
    neo.rainbow_cycle(i)
    neo.show()
    time.sleep(0.0025)
Ejemplo n.º 25
0
        try:
            while True:
                network.process()
                time.sleep_ms(100)
        except:
            pass  #machine.reset()


config_btn = Pin(CONFIG_PIN, Pin.IN)

status_led = NeoPixel(Pin(LED_PIN, Pin.OUT), 1, timing=True)

if config_btn.value():
    print('config button is pressed')
    # turn on config led
    status_led.fill((255, 0, 0))
    status_led.write()

    # start while loop until btn is released
    press_begin = time.ticks_ms()
    press_duration = 0
    while config_btn.value():
        press_end = time.ticks_ms()
        press_duration = time.ticks_diff(press_end, press_begin)
        print(press_duration)
        if press_duration > 2000:
            break
        time.sleep_ms(100)

    # check how long it was pressed
    if press_duration > 2000:
Ejemplo n.º 26
0
class LOLRGB:
    def __init__(self):
        self._pin = Pin(DATA_PIN, Pin.OUT)
        self._np = NeoPixel(self._pin, WIDTH * HEIGHT)
        self._delay_ms = MEDIUM_PAUSE
        self._color = RED
        self._boundary = CHAR_BOUNDARY

    def set_delay_ms(self, delay_ms, persist=True):
        # number of ms between each column of pixels drawn to the display
        delay_ms = int(delay_ms)
        if delay_ms < 0:
            raise ValueError('Please provide a delay >= 0')
        if persist:
            self._delay_ms = delay_ms
        else:
            return delay_ms

    def set_color(self, color, persist=True):
        # tuple (r,g,b) = one colour
        # list of tuples = cycle through colours
        color = self._colorify(color)
        if persist:
            self._color = color
        else:
            return color

    def set_boundary(self, boundary, persist=True):
        # when to move onto the next colour when cycling through colours
        if not CHAR_BOUNDARY <= boundary <= WORD_BOUNDARY:
            raise ValueError('Please provide a boundary (0-1)')
        if persist:
            self._boundary = boundary
        else:
            return boundary

    def write(self, string, color=None, delay_ms=None, boundary=None):
        try:
            self._write(string, color, delay_ms, boundary)
        except KeyboardInterrupt:
            self._np.fill(BLACK)
            self._np.write()

    def _colorify(self, color, top=True):
        # ensures its a valid single colour tuple or a list of colour tuples
        if top and isinstance(color, list):
            for c in color:
                self._colorify(c, False)
            if len(color) == 1:
                return color[0]
        elif not isinstance(color, tuple) or len(color) != 3:
            raise ValueError(
                'Invalid color. Must be a tuple (r,g,b) or list of tuples [(r,g,b),(r,g,b)]'
            )
        return color

    def _stringify(self, string):
        # ensures the string is printable
        if isinstance(string, str):
            return string
        if isinstance(string, (int, float)):
            return str(string)
        if isinstance(string, (bytearray, bytes)):
            return string.decode("utf-8")
        raise TypeError('Could not interpret string')

    def _write(self, string, color=None, delay_ms=None, boundary=None):
        string = self._stringify(string)

        #if len(string) == 0:
        # raise ValueError('Please provide a non-empty string')

        if color is None:
            color = self._color
        else:
            color = self.set_color(color, False)
        num_colors = 1 if isinstance(color, tuple) else len(color)

        if delay_ms is None:
            delay_ms = self._delay_ms
        else:
            delay_ms = self.set_delay_ms(delay_ms, False)

        if boundary is None:
            boundary = self._boundary
        else:
            boundary = self.set_boundary(boundary, False)

        # number of columns to be drawn
        str_len_with_space = len(string) * _CHAR_AND_SPACE

        # number of frames to draw, starting with the string offscreen right
        # and ending offscreen left
        frames = WIDTH + str_len_with_space

        # for colour cycling
        num_spaces = 0

        for frame in range(frames):
            self._np.fill(BLACK)

            # which column of pixels is currently being drawn
            # starts offscreen on the right and moves left on each frame
            cursor = WIDTH - frame

            # loop over each column that needs to be drawn
            column_from = max(cursor, 0)
            column_to = min(WIDTH, cursor + str_len_with_space)

            for column in range(column_from, column_to):
                # column number relative to the string
                str_column = column - cursor

                # which char of the string is being drawn
                char_index = str_column // _CHAR_AND_SPACE

                # column of font character including space (1-4)
                column_in_char = str_column % _CHAR_AND_SPACE

                # if multiple colours, detect word boundaries
                if num_colors > 1:
                    num_spaces = string.count(' ', 0, char_index)

                # 0=48, A=65, a=97
                ascii_code = ord(string[char_index])

                # font only supports chars 32-127, anything more or less gets a
                # hollow rect (zero) or a filled rect (del)
                if ascii_code < _SPACE_CHAR:
                    ascii_code = _ZERO_CHAR  # hollow rect
                elif ascii_code > _DEL_CHAR:
                    ascii_code = _DEL_CHAR  # filled rect

                # ascii_code 32 (space), nothing to draw, skip ahead to the next char
                if ascii_code == _SPACE_CHAR:
                    continue

                # only output font columns, skip spaces
                if column_in_char < _CHAR_WIDTH:
                    # which char offset in the font
                    font_position = ascii_code - _SPACE_CHAR

                    # offset of the column in the font
                    font_col = (font_position * _CHAR_WIDTH) + column_in_char

                    # the page in the font that contains this char column
                    # note: some chars span multiple bytes in the font
                    # so its calculated at a column level
                    font_page = font_position // _FONT_CHARS_PER_ROW

                    # which byte in the font contains this char column
                    font_index = (font_col // 8) + (font_page * 4 *
                                                    _BYTES_PER_ROW)

                    # how many bits to shift the byte to get this char column
                    shift = 7 - (font_col % 8)

                    # determine the colour for this column
                    if num_colors == 1:
                        char_color = color
                    elif boundary == CHAR_BOUNDARY:
                        char_color = color[(char_index - num_spaces) %
                                           num_colors]
                    elif boundary == WORD_BOUNDARY:
                        char_color = color[num_spaces % num_colors]

                    # write column of pixel data
                    for h in range(HEIGHT):
                        self._np[column + WIDTH * h] = char_color if _TOMTHUMB[
                            font_index +
                            _BYTES_PER_ROW * h] >> shift & 1 else BLACK

            # draw the pixels
            self._np.write()

            # pause between each frame
            if delay_ms > 0:
                sleep_ms(delay_ms)
Ejemplo n.º 27
0
        return (0, 85 - pos, pos)
    pos = pos - 170
    return (pos, 0, 85 - pos)


# Raimbow
from machine import Pin
from neopixel import NeoPixel
nf = NeoPixel(Pin(26), 192)

for i in range(192):
    nf[i] = wheel(i)
nf.write()

# Turn off
nf.fill((0, 0, 0))
nf.write()

# Demo 5.3 - PIR
from machine import Pin
from time import sleep

PIR = Pin(36, Pin.IN)
while True:
    if PIR.value():
        print('Movement detected !')
    else:
        print('Everything quiet...')
    sleep(1)

# Demo 5.4 - External interrupts
Ejemplo n.º 28
0
PERIOD_MS = 500

colors = [(0, 0, 255), (16, 0, 128), (32, 0, 64), (64, 0, 32), (128, 0, 16),
          (255, 0, 0)]

colors.extend(list(reversed(colors))[1:-1])


def solid():
    elapsed = ticks_ms() // PERIOD_MS
    current = elapsed % len(colors)
    np.fill(colors[current])
    np.write()


def chase():
    elapsed = ticks_ms() // PERIOD_MS
    for i in range(PIXEL_COUNT):
        current = (elapsed + 1) % len(colors)
        np[i] = colors[current]
    np.write()


np = NeoPixel(PIXEL_PIN, PIXEL_COUNT)
np.fill((0, 0, 0))
np.write()

while True:
    chase()
    sleep(0.01)
Ejemplo n.º 29
0
from machine import Pin
from neopixel import NeoPixel
from time import sleep

PIXEL_PIN = Pin(5, Pin.OUT)
PIXEL_COUNT = 8

np = NeoPixel(PIXEL_PIN, PIXEL_COUNT)
np.fill((0, 0, 0))
np.write()

np.fill((255, 0, 0))
np.write()
sleep(2)

np.fill((0, 255, 0))
np.write()
sleep(2)

np.fill((0, 0, 255))
np.write()
sleep(2)

np.fill((0, 0, 0))
np.write()
Ejemplo n.º 30
0
class MainApp(IoTApp):
    """
    This is your custom class that is instantiated as the main app object instance,
    it inherits from the supplied IoTApp class found in the libs/iot_app.py module
    which is copied when the Huzzah32 is prepared.
    This IoTApp in turn encapsulates an instance of the ProtoRig class (which is 
    found in libs/proto_rig.py) and exposes a number of properties of this ProtoRig
    instance so you do not have to do this yourself.
    Also, the IoTApp provides an execution loop that can be started by calling the
    run() method of the IoTApp class (which is of course inherited into your custom
    app class). All you have to do is define your program by providing implementations
    of the init(), loop() and deinit() methods.
    Looping of your program can be controlled using the finished flag property of
    your custom class.
    """

    AP_SSID = "DCETLocalVOIP"
    AP_PSWD = ""
    AP_TOUT = 5000
    MQTT_ADDR = "192.168.."  # Your desktop PC Wi-Fi dongle IP address
    MQTT_PORT = 1883
    NTP_PORT = 123  # NTP server port number (by default this is port 123)
    # Literal string values can be converted to binary representation by using a b prefix
    MQTT_TEST_TOPIC_1 = b"cet235/test/ticks"
    MQTT_TEST_TOPIC_2 = b"cet235/test/secs"

    def init(self):
        """
        The init() method is designed to contain the part of the program that initialises
        app specific properties (such as sensor devices, instance variables etc.)
        """
        self.message = "None"
        self.gap = " "
        self.active = False
        self.topic_1_count = 0
        self.topic_1_colour = 0

        self.wifi_msg = "No WIFI"
        connect_count = 0
        # Try to connect to WiFi 5 times, if unsuccessful then only try again if button A on
        # the OLED is pressed
        while connect_count < 5 and not self.is_wifi_connected():
            self.oled_clear()
            self.wifi_msg = "Connect WIFI:{0}".format(connect_count + 1)
            self.oled_text(self.wifi_msg, 0, 0)
            self.oled_display()
            self.connect_to_wifi(wifi_settings=(self.AP_SSID, self.AP_PSWD,
                                                True, self.AP_TOUT))
            connect_count += 1

        if self.is_wifi_connected():
            self.wifi_msg = "WIFI"
            self.ntp_msg = "NTP - RTC good"
            # Register with the MQTT broker and link the method mqtt_callback() as the callback
            # when messages are recieved
            self.set_rtc_by_ntp(ntp_ip=self.MQTT_ADDR, ntp_port=self.NTP_PORT)
            self.register_to_mqtt(server=self.MQTT_ADDR,
                                  port=self.MQTT_PORT,
                                  sub_callback=self.mqtt_callback)
            # Subscribe to topic "cet235/test/ticks"
            self.mqtt_client.subscribe(self.MQTT_TEST_TOPIC_1)

            # Subscribe to topic "cet235/test/secs"
            self.mqtt_client.subscribe(self.MQTT_TEST_TOPIC_2)

            self.oled_clear()
            self.oled_display()
        else:
            self.wifi_msg = "No WIFI"
            self.oled_clear()
            self.oled_display()

        self.neopixel_pin = self.rig.PIN_21

        # Set pin 21 to be a digital output pin that is initially pulled down (off)
        self.neopixel_pin.init(mode=Pin.OUT, pull=Pin.PULL_DOWN)

        self.npm = NeoPixel(self.neopixel_pin, 32, bpp=3, timing=1)

        # self.rtc.datetime((2019, 3, 5, 1, 9, 0, 0, 0))

        # Instantiate a BME680 object and configure it using the obtain_sensor_bme680()
        # method
        self.obtain_sensor_bme680()

        # Name of the file to write to the Huzzah32's root file system
        self.file_name = "access_data.csv"

        if self.file_exists(self.file_name):
            os.remove(self.file_name)

        self.file = open(self.file_name, "w+")

        self.access = False
        self.access_str = ""

        self.off = False
        self.count = 0
        self.lightcount = 0

        self.npm.fill((5, 5, 5))
        self.npm.write()

        self.npm.write()

    def loop(self):
        """
        The loop() method is called after the init() method and is designed to contain
        the part of the program which continues to execute until the finished property
        is set to True
        """

        yr, mn, dy, dn, hr, mi, se, ms = self.rtc.datetime()
        self.oled_clear()
        output = "{0} {1:02d}-{2:02d}-{3}".format(self._DAY_NAMES[dn][0:3], dy,
                                                  mn, yr)
        self.oled_text(output, 0, 12)
        output = "{0:02d}:{1:02d}:{2:02d}".format(hr, mi, se)
        self.oled_text(output, 0, 22)

        self.oled_display()

        sleep(0.1)
        if self.is_wifi_connected():
            # Check for any messages received from the MQTT broker, note this is a non-blocking
            # operation so if no messages are currently present the loop() method continues
            self.mqtt_client.check_msg()

        # If sensor readings are available, read them once a second or so
        if self.sensor_bme680.get_sensor_data():
            tm_reading = self.sensor_bme680.data.temperature  # In degrees Celsius
            rh_reading = self.sensor_bme680.data.humidity  # As a percentage (ie. relative humidity)

            self.oled_text("{0}c".format(tm_reading), 0, 0)
            self.oled_text("{0}%".format(rh_reading), 60, 0)
            self.oled_display()

            sleep(0.5)

            # Current date and time taken from the real-time clock
            now = self.rtc.datetime()
            year = now[0]
            month = now[1]
            day = now[2]
            hour = now[4]
            minute = now[5]
            second = now[6]

            if self.access:

                if self.count == 0:
                    date_str = "{0}/{1}/{2}".format(day, month, year)
                    time_str = "{0}:{1}:{2}".format(hour, minute, second)

                    # Write to file
                    self.file.write("{0},{1},{2},{3} \n".format(
                        "ACCESS-STARTED", date_str, time_str, self.message))

                # Format timestamp

                timestamp = "{0}-{1}-{2}|{3}:{4}:{5}".format(
                    year, month, day, hour, minute, second)

                # Format line of data
                data_line = "{0},{1:.2f},{2:.2f},{3}\n".format(
                    timestamp, tm_reading, rh_reading, self.message)

                # Write data line to the access_data.csv file
                if self.message != "None":
                    self.file.write(data_line)

                # Set correct colour for NeoPixel matrix LEDS and correct access warning string

                if self.lightcount == 0:
                    self.npm.fill((0, 0, 0))
                    self.npm.write()
                elif self.lightcount <= 5:
                    self.npm.fill((0, 10, 0))
                    self.npm.write()
                elif self.lightcount > 5 and self.lightcount <= 10:
                    self.npm.fill((10, 10, 0))
                    self.npm.write()
                elif self.lightcount > 10:
                    self.npm.fill((10, 0, 0))
                    self.npm.write()
                # Increment seconds counter
                self.count += 1
                self.lightcount += 1

    def mqtt_callback(self, topic, msg):

        topic = self.MQTT_TEST_TOPIC_2

        sleep(1)

        # decode the message
        self.message = (str(bytes(msg), "utf-8"))

        # statment to manage the type of message that it's receive
        if (self.message != "None"):
            self.access = True
        else:
            self.lightcount = 0

    def deinit(self):
        """
        The deinit() method is called after the loop() method has finished, is designed
        to contain the part of the program that closes down and cleans up app specific
        properties, for instance shutting down sensor devices. It can also be used to
        display final information on output devices (such as the OLED FeatherWing)
        """
        # Clear the NeoPixel matrix
        self.npm.fill((0, 0, 0))
        self.npm.write()

        # If an access period is currently active then write to the access_data.csv file that it
        # is now stopped and also the length of the access period in seconds
        if self.access:
            # Current date and time taken from the real-time clock to record as stop date and time
            # for this access period

            now = self.rtc.datetime()
            year = now[0]
            month = now[1]
            day = now[2]
            hour = now[4]
            minute = now[5]
            second = now[6]

            date_str = "{0}/{1}/{2}".format(day, month, year)
            time_str = "{0}:{1}:{2}".format(hour, minute, second)

            # Write to file, note: self.count is approximately the number of seconds that this access
            # period lasted
            self.file.write("{0},{1},{2},{3}\n".format("ACCESS-STOPPED",
                                                       date_str, time_str,
                                                       self.count))

        # Make sure the access_data.csv file is closed
        self.file.close()

    def obtain_sensor_bme680(self):

        self.sensor_bme680 = BME680(i2c=self.rig.i2c_adapter, i2c_addr=0x76)
        self.sensor_bme680.set_temperature_oversample(OS_8X)
        self.sensor_bme680.set_humidity_oversample(OS_2X)
        self.sensor_bme680.set_filter(FILTER_SIZE_3)

    def file_exists(self, file_name):
        file_names = os.listdir()

        return file_name in file_names

    def btnA_handler(self, pin):

        if not self.access:
            # Current date and time taken from the real-time clock to record as start date and time
            # for this access period
            now = self.rtc.datetime()
            year = now[0]
            month = now[1]
            day = now[2]
            hour = now[4]
            minute = now[5]
            second = now[6]

            date_str = "{0}/{1}/{2}".format(day, month, year)
            time_str = "{0}:{1}:{2}".format(hour, minute, second)

            # Write to file
            self.file.write("{0},{1},{2}\n".format("ACCESS-STARTED", date_str,
                                                   time_str))

            # Update access information

            self.access = True
            self.access_str = "ACCESS"
            self.count = 0

    def btnB_handler(self, pin):
        if self.access:

            now = self.rtc.datetime()
            year = now[0]
            month = now[1]
            day = now[2]
            hour = now[4]
            minute = now[5]
            second = now[6]

            date_str = "{0}/{1}/{2}".format(day, month, year)
            time_str = "{0}:{1}:{2}".format(hour, minute, second)

            # Write to file, note: self.count is approximately the number of seconds that this access
            # period lasted
            self.file.write("{0},{1},{2},{3}\n".format("ACCESS-STOPPED",
                                                       date_str, time_str,
                                                       self.count))

            # Update access information
            self.access = False
            self.access_str = ""

            # Clear the NeoPixel matrix
            self.npm.fill((0, 0, 0))
            self.npm.write()