Example #1
0
 def __init__(self, port):
     self.arduino = ArduinoBoard(port, timeout=5.0, enable_dtr=False)
     self.commands = [["kAcknowledge", "i"],
                      ["kError", "i*"],
                      ["kUnknown", ""],
                      ["kPing", "?"],
                      ["kPingResult", "i"],
                      ["kPong", ""],
                      ["kPauseCalculations", "?"],
                      ["kResumeCalculations", "?"],
                      ["kUploadRedPattern", "?b*"],
                      ["kUploadGreenPattern", "?b*"],
                      ["kUploadBluePattern", "?b*"],
                      ["kSavePattern", "?b"],
                      ["kLoadPattern", "?b"],
                      ["kGetBrightness", "?"],
                      ["kGetBrightnessResult", "b"],
                      ["kSetBrightness", "?b"],
                      ["kSetPixel", "?bbbb"],
                      ["kFillSolid", "?bbb"],
                      ["kClearEeprom", "?"],
                      ["kIsEepromReady", "?"],
                      ["kIsEepromReadyResult", "?"],
                      ["kResetEeprom", "?"],
                      ["kReturnEeprom", "?"],
                      ["kReturnEepromResult", "b*"],
                      ["kJumpToDfu", "?"]]
     self.messenger = CmdMessenger(self.arduino, self.commands)
Example #2
0
class NgalacArduinoController():
    '''  NGALAC uses an arduino to control button presses and turn on
        various lights.

        Use pseudo terminal to test, ie:
        https://stackoverflow.com/questions/52187/virtual-serial-port-for-linux
        miniterm.py to spy
    '''
    def __init__(self, serial_port="/dev/pts/2", baud_rate=9600):

        self.arduino = ArduinoBoard(serial_port, baud_rate)
        self.commands = dict(COMMANDS)
        self.c = CmdMessenger(self.arduino, COMMANDS)
        self.cmd_seq_num = 0

    def _send_cmd(self, cmd, *args):
        if cmd in self.commands:
            self.c.send(cmd, *args)
        else:
            pass  # heh, logging pls thx
        self.cmd_seq_num += 1

    def _recv_cmd(self, cmd):
        try:
            msg = self.c.receive()
        except EOFError:
            # bad command format
            pass

        if msg:
            return _parse_msg(msg)
        else:
            pass

    def _parse_msg(self, msg):
        # self.last_cmd, value, self.exec_time = msg
        value = msg
        return value

    def ping(self):
        return self._send_cmd('ping')

    def is_player(self):
        return self._send_cmd('player')

    def lights(self, on=True):
        return self._send_cmd('lights', True)

    def get_state(self):
        return self._send_cmd('get_state')

    def release_latches(self):
        return self._send_cmd('release_latches')

    def open(self):
        self.arduino.open()

    def close(self):
        self.arduino.close()
Example #3
0
class ArduinoController():
    '''  NGALAC uses an arduino to control button presses and turn on
        various lights.

        Use pseudo terminal to test, ie:
        https://stackoverflow.com/questions/52187/virtual-serial-port-for-linux
        miniterm.py to spy

        soscat -d -d pty,raw,echo=0 pty,raw,echo=0
        opens a tty connection with 2 ends.  Device on 1, io on other
    '''

    __firmware_version__ = (0, 1, 6)

    def __init__(self, serial_port="/dev/pts/2", baud_rate=9600):

        self.arduino = ArduinoBoard(serial_port, baud_rate)
        self.commands = dict(COMMANDS)
        self.c = CmdMessenger(self.arduino, COMMANDS)
        self.cmd_seq_num = 0

    def _send_cmd(self, cmd, *args):
        if cmd in self.commands:
            self.c.send(cmd, *args)
        else:
            pass  # heh, logging pls thx
        self.cmd_seq_num += 1

    def _parse_msg(self, msg):
        cmd, value, self.exec_time = msg
        return (cmd, value)

    def _recv_cmd(self):
        msg = None
        try:
            msg = self.c.receive()
        except EOFError:
            # bad command format
            pass

        if msg:
            return self._parse_msg(msg)
        else:
            pass

    def get_firmware(self):
        self._send_cmd('req_firmware')
        cmd, board_firmware = self._recv_cmd()
        if cmd == 'send_firmware':
            return board_firmware
        else:
            # bad command handling
            pass

        return board_firmware

    def check_firmware(self):

        board_firmware = self.get_firmware()
        return all(self.__firmware_version__[i] == board_firmware[i]
                   for i in range(0, 3))

    def flush(self):
        while self._recv_cmd() is not None:
            pass

    def read(self):
        return self._recv_cmd()

    def ping(self):
        return self._send_cmd('ping')

    def is_player(self):
        return self._send_cmd('player')

    def on_air(self):
        return self._send_cmd("on_air")

    def off_air(self):
        return self._send_cmd("off_air")

    def lights(self, on=1):
        return self._send_cmd('lights', on)

    def get_state(self):
        return self._send_cmd('get_state')

    def release_latches(self):
        return self._send_cmd('release_latches')

    def open(self):
        self.arduino.open()

    def close(self):
        self.arduino.close()
Example #4
0
    def __init__(self, serial_port="/dev/pts/2", baud_rate=9600):

        self.arduino = ArduinoBoard(serial_port, baud_rate)
        self.commands = dict(COMMANDS)
        self.c = CmdMessenger(self.arduino, COMMANDS)
        self.cmd_seq_num = 0
Example #5
0
class LedStripMessenger(object):
    def __init__(self, port):
        self.arduino = ArduinoBoard(port, timeout=5.0, enable_dtr=False)
        self.commands = [["kAcknowledge", "i"],
                         ["kError", "i*"],
                         ["kUnknown", ""],
                         ["kPing", "?"],
                         ["kPingResult", "i"],
                         ["kPong", ""],
                         ["kPauseCalculations", "?"],
                         ["kResumeCalculations", "?"],
                         ["kUploadRedPattern", "?b*"],
                         ["kUploadGreenPattern", "?b*"],
                         ["kUploadBluePattern", "?b*"],
                         ["kSavePattern", "?b"],
                         ["kLoadPattern", "?b"],
                         ["kGetBrightness", "?"],
                         ["kGetBrightnessResult", "b"],
                         ["kSetBrightness", "?b"],
                         ["kSetPixel", "?bbbb"],
                         ["kFillSolid", "?bbb"],
                         ["kClearEeprom", "?"],
                         ["kIsEepromReady", "?"],
                         ["kIsEepromReadyResult", "?"],
                         ["kResetEeprom", "?"],
                         ["kReturnEeprom", "?"],
                         ["kReturnEepromResult", "b*"],
                         ["kJumpToDfu", "?"]]
        self.messenger = CmdMessenger(self.arduino, self.commands)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.close()

    def send(self, request_ack, has_response, command, *args, arg_formats=None):
        logger.info("Sending {0:s}".format(command))
        with DelayedKeyboardInterrupt():
            self.messenger.send(command, *(request_ack, *args), arg_formats=arg_formats)
            if request_ack:
                acknowledgement = self.messenger.receive()
            if has_response:
                response = self.messenger.receive()
        
        if request_ack:
            try:
                assert (acknowledgement[0] == "kAcknowledge" and self.commands[acknowledgement[1][0]][0] == command)
                logger.info("Received kAcknowledge for {}".format(command))
            except (AssertionError, TypeError):
                logger.error("Acknowledgement error")
                logger.error("Actual response was {}.".format(repr(acknowledgement)))
                if acknowledgement is not None:
                    logger.error("Acknowledged Command was {}.".format(self.commands[acknowledgement[1][0]][0]))
                logger.error("Command was {}.".format(command))

        if has_response:
            try:
                assert (response[0][:-6] == command and response[0][-6:] == "Result")
            except (AssertionError, TypeError):
                logger.error("Response error")
                logger.error("Actual response command was {}".format(repr(response)))
                logger.error("Command was {0:s}.".format(command))

        if has_response and response is not None:
            return response[1]

    def close(self):
        self.arduino.close()

    def ping(self, attempts = 5):
        for i in range(attempts):
            response = self.send(False, True, "kPing")
            if response is not None and self.commands[response[0]][0] == "kPong":
                logger.info("Received kPong")
                break
            else:
                logger.error("Ping response was not pong")
                logger.error("Actual response command was {}".format(repr(response)))
                if i < attempts:
                    logger.error("Trying again... {} tries remaining".format(attempts - i - 1))

    def uploadPattern(self, r_pattern, g_pattern, b_pattern):
        PythonOpcode = Enum("PythonOpcode",
            '''
            UNARY_POSITIVE
            UNARY_NEGATIVE
            UNARY_NOT
            UNARY_INVERT
            BINARY_POWER
            BINARY_MULTIPLY
            BINARY_MODULO
            BINARY_ADD
            BINARY_SUBTRACT
            BINARY_SUBSCR
            BINARY_FLOOR_DIVIDE
            BINARY_TRUE_DIVIDE
            BINARY_LSHIFT
            BINARY_RSHIFT
            BINARY_AND
            BINARY_XOR
            BINARY_OR
            RETURN_VALUE
            LOAD_CONST
            LOAD_NAME
            CALL_FUNCTION
        ''')

        def compilePattern(pattern):
            bytecode = compile(pattern, "<string>", "eval")
            rv = []

            for i in dis.Bytecode(bytecode):
                argval = i.argval

                if type(argval) is str:
                    if argval == "time":
                        argval = 0
                    elif argval == "index":
                        argval = 1
                    elif argval == "sin":
                        argval = 2
                    elif argval == "cos":
                        argval = 3
                elif argval is None:
                    argval = 0
                else:
                    argval = int(argval)    

                rv.append(PythonOpcode[i.opname].value - 1)
                rv.append(argval)

            if len(rv) > 16:
                logger.error("Instruction set is greater than allowed, 16.")
                logger.error("Actual length is {}.".format(len(rv)))
                rv = []

            return rv

        self.pauseCalculations()
        self.send(True, False, "kUploadRedPattern", *compilePattern(r_pattern))
        self.send(True, False, "kUploadGreenPattern", *compilePattern(g_pattern))
        self.send(True, False, "kUploadBluePattern", *compilePattern(b_pattern))
        self.resumeCalculations()
        logger.info("Pattern uploaded")

    def savePattern(self, index):
        self.send(True, False, "kSavePattern", index)

    def loadPattern(self, index):
        self.send(True, False, "kLoadPattern", index)

    def pauseCalculations(self):
        self.send(True, False, "kPauseCalculations")

    def resumeCalculations(self):
        self.send(True, False, "kResumeCalculations")

    def getBrightness(self):
        return self.send(True, True, "kGetBrightness")[0]

    def setBrightness(self, brightness):
        self.send(True, False, "kSetBrightness", brightness)

    def setPixel(self, index, r, g, b):
        self.send(False, False, "kSetPixel", index, r, g, b)

    def fillSolid(self, r, g, b):
        self.send(False, False, "kFillSolid", r, g, b)

    def setDeltaHue(self, deltaHue):
        self.send(True, False, "kSetDeltaHue", deltaHue)

    def clearEeprom(self):
        self.send(True, False, "kClearEeprom")

    def isEepromReady(self):
        ready = self.send(True, True, "kIsEepromReady")[0]

        if ready:
            logger.info("Eeprom is ready")
        else:
            logger.error("Eeprom is not ready")

        return ready

    def resetEeprom(self):
        self.send(True, False, "kResetEeprom")

    def returnEeprom(self):
        eeprom = self.send(True, True, "kReturnEeprom")

        for i, byte in enumerate(eeprom):
            s = ""
            if i < 2 * 16 * 3 * 8:
                if i % (2 * 16) == 0:
                    s += "Pattern[{}]".format(int(i / (2 * 16 * 3)))
                    if i / (2 * 16) % 3 == 0:
                        s += '["r"]'
                    elif i / (2 * 16) % 3 == 1:
                        s += '["g"]'
                    elif i / (2 * 16) % 3 == 2:
                        s += '["b"]'

            elif i == 768:
                s += "ready"
            elif i == 769:
                s += "currentPattern"
            elif i == 770:
                s += "currentBrightness"

            logger.info("{0:4d}: {1:3d}{2:s}".format(i, byte, " //" + s if s != "" else ""))

        return eeprom

    def jumpToDfu(self):
        self.send(False, False, "kJumpToDfu")