Exemplo n.º 1
0
class TheTapper():
    """
    Illuminate the neopixels in a counter-clockwise fashion with randomly generated colors.
    When you tap the playground express, the neopixels will stop changing and the
    program pauses. Tap again and the neopixels will start again.
    """
    def __init__(self):
        # create an instance of the API
        self.p = PyMataCpx()

        print('Tap the playground express to stop the neopixels from moving.')
        print('Tap again, to start them up')
        print('The tap state will be printed to the console')

        # Start monitoring for tap events and
        # send event notifications to the tapped method.
        self.p.cpx_tap_start(self.tapped)
        self.go = True

        while True:

            try:
                # run the light show
                for neopixel in range(0, 10):
                    if self.go:
                        self.p.cpx_pixels_clear()
                        self.p.cpx_pixels_show()
                        r = random.randint(0, 254)
                        g = random.randint(0, 254)
                        b = random.randint(0, 254)
                        self.p.cpx_pixel_set(neopixel, r, g, b)
                        self.p.cpx_pixels_show()
                        time.sleep(.2)
                    else:
                        self.p.cpx_pixels_clear()
                        self.p.cpx_pixels_show()
                        time.sleep(.001)
            except KeyboardInterrupt:
                # If you press control-C, cleanly exit
                self.p.cpx_pixels_clear()
                self.p.cpx_pixels_show()
                self.p.cpx_close_and_exit()

    def tapped(self, data):
        """
        :param data: data[0] = data type (analog = 2, digital =32)
                     data[1] = pin for device 27
                     data[2] = tap data - list of booleans.
                               First value for 1 tap
                               Second value for 2 taps
        """
        # for any taps, toggle the go flag
        # print out the current tap state
        if data[2] != [False, False]:
            self.go = not self.go
            print(self.go)
Exemplo n.º 2
0
class TheClapper:
    """
    Turn LEDs in a counter-clockwise fashion with randomly generated colors.
    When you clap your hand loudly, the pixels will stop changing and the
    program exits. Clap again and they start moving again.
    """
    def __init__(self):
        self.p = PyMataCpx()

        print('Clap your hands loudly to stop the neopixels from moving.')
        print('Clap again, to start them up')

        self.p.cpx_microphone_start(self.listen)
        self.go = True

        while True:
            try:
                # run the light show
                for neopixel in range(0, 10):
                    if self.go:

                        self.p.cpx_pixels_clear()
                        self.p.cpx_pixels_show()
                        r = random.randint(0, 254)
                        g = random.randint(0, 254)
                        b = random.randint(0, 254)
                        self.p.cpx_pixel_set(neopixel, r, g, b)
                        self.p.cpx_pixels_show()
                        time.sleep(.2)
                    else:
                        self.p.cpx_pixels_clear()
                        self.p.cpx_pixels_show()
                        time.sleep(.001)

            except KeyboardInterrupt:
                # If you press control-C, cleanly exit
                self.p.cpx_pixels_clear()
                self.p.cpx_pixels_show()
                self.p.cpx_close_and_exit()

    def listen(self, data):
        """
        Turn off the light show and exit
        :param data: data[0] = 2 indicating this is analog data
                     data[1] = pin attached to mic- pin 4
                     data[3] = readings from microphone
        """
        if data[2] > 600:
            # self.p.cpx_pixels_clear()
            # self.p.cpx_pixels_show()
            self.go = not self.go
Exemplo n.º 3
0
class LightMeter:
    """
    Using the light sensor, select and
    illuminate pixels based on the current light sensor reading.
    As the light sensor values increase, the pixels will be lit
    in a clockwise fashion.
    """
    def __init__(self):
        # a dictionary of pixels as the key and
        # associated rgb color values
        self.pix_d = {
            0: [153, 76, 0],
            1: [153, 0, 0],
            2: [153, 153, 0],
            3: [204, 204, 0],
            4: [0, 153, 0],
            5: [0, 153, 153],
            6: [0, 0, 233],
            7: [153, 0, 153],
            8: [255, 0, 255],
            9: [255, 255, 255],
        }

        # save the previous pixel number that was illuminated
        self.last_pixel_used = 0

        # instantiate pymatacpx
        self.p = PyMataCpx()

        # clear the pixels before monitoring the light
        # sensor values
        self.p.cpx_pixels_clear()
        # set pixel 0 to be the initial pixel and set its rgb
        # from the dictionary
        self.p.cpx_pixel_set(0, *self.pix_d[0])

        self.p.cpx_pixels_show()

        # enable the light sensor and provide a callback.
        # Note: the callback is a member of this class.
        self.p.cpx_light_sensor_start(self.light_sensor_callback)

        print()
        print(
            'Move a light source near the light sensor, and depending upon the'
        )
        print(
            'intensity of the light, an associated pixel will be illuminated.')
        print()

        while True:
            # just kill time waiting for a light data to arrive
            try:
                time.sleep(.1)
            except KeyboardInterrupt:
                # If you press control-C, cleanly exit
                self.p.cpx_close_and_exit()

    # This is the callback to process light sensor data
    def light_sensor_callback(self, data):
        """
        Light sensor data processor
        :param data: data[2] contains the current light sensor reading
        :return:
        """
        # get the currently reported level
        level = data[2]

        # the level is in the range of 0-1000.
        # adjust the level to map into a valid pixel number
        if level in range(0, 99):
            pixel = 0
        elif level in range(100, 199):
            pixel = 1
        elif level in range(200, 299):
            pixel = 2
        elif level in range(300, 399):
            pixel = 3
        elif level in range(400, 499):
            pixel = 4
        elif level in range(500, 599):
            pixel = 5
        elif level in range(600, 699):
            pixel = 6
        elif level in range(700, 799):
            pixel = 7
        elif level in range(800, 899):
            pixel = 8
        else:
            pixel = 9

        # get the rgb value for the pixel
        rgb = self.pix_d[pixel]

        # if this is not the same pixel as the last one enabled
        # then manipulate the pixels.

        # turn off the current pixel and turn on the new one.
        if pixel != self.last_pixel_used:
            # extinguish the previous pixel
            self.p.cpx_pixel_set(self.last_pixel_used, 0, 0, 0)

            # set the new pixel
            self.p.cpx_pixel_set(pixel, *rgb)

            # control the pixels
            self.p.cpx_pixels_show()
            self.last_pixel_used = pixel
Exemplo n.º 4
0
class Thermometer:
    """
    Touch the temperature sensor on the playground express.
    As the temperature increases, pixels will illuminate to
    indicate the temperature.
    """

    def __init__(self):
        # a dictionary of pixels as the key and
        # associated rgb color values
        self.pix_d = {
            0: [153, 76, 0],
            1: [153, 0, 0],
            2: [153, 153, 0],
            3: [204, 204, 0],
            4: [0, 153, 0],
            5: [0, 153, 153],
            6: [0, 0, 233],
            7: [153, 0, 153],
            8: [255, 0, 255],
            9: [255, 255, 255],
        }

        # save the previous pixel number that was illuminated
        self.last_pixel_used = 0

        # save the first temperature read as the ambient temperature
        # and use that as the basis of comparison.
        self.ambient = 0

        # instantiate pymatacpx
        self.p = PyMataCpx()

        # clear the pixels before monitoring the light
        # sensor values
        self.p.cpx_pixels_clear()
        # set pixel 0 to be the initial pixel and set its rgb
        # from the dictionary
        self.p.cpx_pixel_set(0, *self.pix_d[0])

        self.p.cpx_pixels_show()

        # enable the temperature sensor and provide a callback.
        self.p.cpx_temperature_start(self.temp_callback)

        print()
        print('Touch the temperature sensor. As the temperature changes')
        print('Different neopixels will light up.')
        print()
        print('The current temperature and pixel selected will be shown on the console.')
        print()

        while True:
            # just kill time waiting for a light data to arrive
            try:
                time.sleep(.1)
            except KeyboardInterrupt:
                # If you press control-C, cleanly exit
                self.p.cpx_close_and_exit()

    # This is the callback to process light sensor data
    def temp_callback(self, data):
        """
        Light sensor data processor
        :param data: data[0] = 2 analog mode
                     data[1] = pin 0
                     data[2] = temp in degrees C
        """
        # the current temperature
        the_current_temperature = data[2]

        # save the temperature the first time
        # through as ambient
        if not self.ambient:
            self.ambient = the_current_temperature

        # select the pixel based on the current temperature
        if self.ambient < the_current_temperature < (self.ambient + .6):
            pixel = 0
        elif (self.ambient + 0.6) < the_current_temperature < (self.ambient + 1.2):
            pixel = 1
        elif (self.ambient < the_current_temperature + 1.2) < the_current_temperature < (self.ambient + 1.8):
            pixel = 2
        elif (self.ambient < the_current_temperature + 1.8) < the_current_temperature < (self.ambient + 2.4):
            pixel = 3
        elif (self.ambient < the_current_temperature + 2.4) < the_current_temperature < (self.ambient + 3.0):
            pixel = 4
        elif (self.ambient < the_current_temperature + 3.0) < the_current_temperature < (self.ambient + 3.6):
            pixel = 5
        elif (self.ambient < the_current_temperature + 3.6) < the_current_temperature < (self.ambient + 4.2):
            pixel = 6
        elif (self.ambient < the_current_temperature + 4.2) < the_current_temperature < (self.ambient + 4.8):
            pixel = 7
        elif (self.ambient < the_current_temperature + 4.8) < the_current_temperature < (self.ambient + 5.4):
            pixel = 8
        else:
            pixel = 9

        # get the rgb value for the pixel
        rgb = self.pix_d[pixel]

        # if this is not the same pixel as the last one enabled
        # then manipulate the pixels.

        # turn off the current pixel and turn on the new one.
        if pixel != self.last_pixel_used:
            # extinguish the previous pixel
            self.p.cpx_pixel_set(self.last_pixel_used, 0, 0, 0)

            # set the new pixel
            self.p.cpx_pixel_set(pixel, *rgb)

            # control the pixels
            self.p.cpx_pixels_show()
            self.last_pixel_used = pixel

        print('ambient: {} current: {} pixel{}'.format(round(self.ambient, 3),
                                                       round(the_current_temperature, 3),
                                                       pixel))
Exemplo n.º 5
0
class CpxGateway(GatewayBase, threading.Thread):
    """
    This class is the interface class for the Circuit Playground
    Express supporting Scratch 3.
    """
    def __init__(self,
                 *subscriber_list,
                 back_plane_ip_address=None,
                 subscriber_port='43125',
                 publisher_port='43124',
                 process_name='CpxGateway',
                 publisher_topic=None,
                 log=False):
        """
        :param subscriber_list: a tuple or list of subscription topics.
        :param back_plane_ip_address:
        :param subscriber_port:
        :param publisher_port:
        :param process_name:
        """

        # initialize parent
        super(CpxGateway,
              self).__init__(subscriber_list=subscriber_list,
                             back_plane_ip_address=back_plane_ip_address,
                             subscriber_port=subscriber_port,
                             publisher_port=publisher_port,
                             process_name=process_name)
        self.log = log
        if self.log:
            fn = str(pathlib.Path.home()) + "/cpxgw.log"
            self.logger = logging.getLogger(__name__)
            logging.basicConfig(filename=fn, filemode='w', level=logging.DEBUG)
            sys.excepthook = self.my_handler

        self.publisher_topic = publisher_topic
        self.cpx = PyMataCpx()
        atexit.register(self.shutdown)

        # hold the time of the last analog data to be received.
        # use to determine if connectivity is gone.
        self.last_analog_data_time = None

        # start up all the sensors
        self.cpx.cpx_accel_start(self.tilt_callback)
        self.cpx.cpx_button_a_start(self.switch_callback)
        self.cpx.cpx_button_b_start(self.switch_callback)
        self.cpx.cpx_slide_switch_start(self.switch_callback)

        self.cpx.cpx_light_sensor_start(self.analog_callback)
        self.cpx.cpx_microphone_start(self.analog_callback)
        self.cpx.cpx_temperature_start(self.analog_callback)
        for touch_pad in range(1, 8):
            self.cpx.cpx_cap_touch_start(touch_pad, self.touchpad_callback)

        threading.Thread.__init__(self)
        self.daemon = True

        # start the watchdog thread
        self.start()
        # start the banyan receive loop
        try:
            self.receive_loop()
        except:
            pass
        # except KeyboardInterrupt:
        # except KeyboardInterrupt:
        # self.cpx.cpx_close_and_exit()
        # sys.exit(0)
        #     os._exit(1)

    def init_pins_dictionary(self):
        pass

    def play_tone(self, topic, payload):
        """
        This method plays a tone on a piezo device connected to the selected
        pin at the frequency and duration requested.
        Frequency is in hz and duration in milliseconds.

        Call set_mode_tone before using this method.
        :param topic: message topic
        :param payload: {"command": "play_tone", "pin": “PIN”, "tag": "TAG",
                         “freq”: ”FREQUENCY”, duration: “DURATION”}
        """
        self.cpx.cpx_tone(payload['freq'], payload['duration'])

    def additional_banyan_messages(self, topic, payload):
        if payload['command'] == 'pixel':
            self.set_pixel(payload)

    def set_pixel(self, payload):
        self.cpx.cpx_pixel_set(payload['pixel'], payload['red'],
                               payload['green'], payload['blue'])
        self.cpx.cpx_pixels_show()

    def digital_write(self, topic, payload):
        """
        This method performs a digital write to the board LED
        :param topic: message topic
        :param payload: {"command": "digital_write", "pin": “PIN”, "value": “VALUE”}
        """
        if payload['value']:
            self.cpx.cpx_board_light_on()
        else:
            self.cpx.cpx_board_light_off()

    # The CPX sensor callbacks

    def tilt_callback(self, data):
        """
        Report the tilt of the express board

        Take the raw xyz data and transform it to
        positional strings.
        :param data: data [0] = data mode 32 is analog.
                     data[1] = the pin number - this is a pseudo pin number
                     data[2] = x value
                     data[3] = y value
                     data[4] = z value
        """
        x = data[2]
        y = data[3]
        z = data[4]

        # Convert raw Accelerometer values to degrees
        x_angle = int((math.atan2(y, z) + math.pi) * (180 / math.pi))
        y_angle = int((math.atan2(z, x) + math.pi) * (180 / math.pi))

        h = v = -1

        if 175 < x_angle < 185 and 265 < y_angle < 275:
            h = v = 0  # 'flat'

        elif h or v:
            if 180 <= x_angle <= 270:
                v = 1  # up

            elif 90 <= x_angle <= 180:
                v = 2  # down

            if 180 <= y_angle <= 270:
                h = 3  # left

            elif 270 <= y_angle <= 360:
                h = 4  # right

        payload = {'report': 'tilted', 'value': [v, h]}
        self.publish_payload(payload, 'from_cpx_gateway')

    def switch_callback(self, data):
        """
        This handles switches a, b, and slide
        :param data: data[1] - a=4 b=5, slice=7,
        """
        if data[1] == 4:
            switch = 'a'
        elif data[1] == 5:
            switch = 'b'
        else:
            # 0 = right, 1 = left
            switch = 'slide'

        payload = {'report': switch, 'value': data[2]}
        self.publish_payload(payload, 'from_cpx_gateway')

    def analog_callback(self, data):
        """
        This handles the light, temperature and sound sensors.

        It also sets up a "watchdog timer" and if there is no activity
        for > 1 second will exit.


        :param data: data[1] - 8 = light, temp = 9, 10 = sound,
        """

        self.last_analog_data_time = time.time()

        if data[1] == 8:
            sensor = 'light'
        elif data[1] == 9:
            sensor = 'temp'
        else:
            sensor = 'sound'
        payload = {'report': sensor, 'value': round(data[2], 2)}
        self.publish_payload(payload, 'from_cpx_gateway')

    def touchpad_callback(self, data):
        """
        Build and send a banyan message for the pad and value
        :param data: data[1] = touchpad and data[2] = boolean value
        """
        payload = {'report': 'touch' + str(data[1]), 'value': int(data[2])}
        self.publish_payload(payload, 'from_cpx_gateway')

    def shutdown(self):
        try:
            self.cpx.cpx_close_and_exit()
            sys.exit(0)
        except serial.serialutil.SerialException:
            pass

    def my_handler(self, xtype, value, tb):
        """
        for logging uncaught exceptions
        :param xtype:
        :param value:
        :param tb:
        :return:
        """
        self.logger.exception("Uncaught exception: {0}".format(str(value)))

    def run(self):
        if not self.last_analog_data_time:
            self.last_analog_data_time = time.time()
        while True:
            if time.time() - self.last_analog_data_time > 1.0:
                print('Watchdog timed out - exiting.')
                os._exit(1)

            time.sleep(1)
Exemplo n.º 6
0
# create a cpx instance
p = PyMataCpx()

# enable all switches and attach all to the same callback
p.cpx_button_a_start(buttons_callback)
p.cpx_button_b_start(buttons_callback)
p.cpx_slide_switch_start(buttons_callback)

# Set pixel 6 initially on and 3 off.
# If the switch is set to the left at start up
# it will be detected and pixel 3 will be turned
# on and pixel 6 turned off.
p.cpx_pixel_set(6, 0, 0, 255)
p.cpx_pixel_set(3, 0, 0, 0)
p.cpx_pixels_show()

print()
print('Press Button A, Button B, Button A and B, or move the slide switch.')
print(
    'Each time you press a button or move the slide switch, the board LED will flash'
)
print('and a neopixel will light indicating that button or slide switch')
print('activation was processed and a message is printed to the console.')
print()

while True:
    # just kill time waiting for a switch change
    try:
        time.sleep(.1)
    except KeyboardInterrupt: