Beispiel #1
0
#
# Copyright (c) 2006-2019, RT-Thread Development Team
#
# SPDX-License-Identifier: MIT License
#
# Change Logs:
# Date           Author       Notes
# 2019-06-13     SummerGift   first version
#

from machine import UART

uart = UART(1, 9600)  # init with given baudrate
uart.init(9600, bits=8, parity=None, stop=1)  # init with given parameters
uart.read(10)  # read 10 characters, returns a bytes object
uart.read()  # read all available characters
uart.readline()  # read a line
uart.readinto(buf)  # read and store into the given buffer
uart.write('abc')  # write the 3 characters
Beispiel #2
0
# do not execute this test on the GPy and FiPy
if os.uname().sysname == 'GPy' or os.uname().sysname == 'FiPy':
    print("SKIP")
    import sys
    sys.exit()

uart = UART(2, 115200)
print(uart)
uart.init(57600, 8, None, 1, pins=('P11', 'P12'))
uart.init(baudrate=9600, stop=2, parity=UART.EVEN, pins=('P11', 'P12'))
uart.init(baudrate=115200, parity=UART.ODD, stop=1, pins=('P11', 'P12'))
uart.read()
print (uart.read())
print (uart.readline())
buff = bytearray(1)
print (uart.readinto(buff, 1))
print (uart.read())
print (uart.any())
print (uart.write('a'))
uart.deinit()

uart = UART(2, 1000000, pins=('P12', 'P11'))
print(uart)
uart.read()
print(uart.write(b'123456') == 6)
print(uart.read() == b'123456')
uart.deinit()
uart = UART(2, 1000000, pins=('P11', 'P12'))
print(uart)
uart.read()
print(uart.write(b'123456') == 6)
Beispiel #3
0
class EbyteModule:
    def __init__(self, uart=1, rx = 5, tx = 4, m0=15, m1=14, aux=22):

        self.__br = ["1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"]
        self.__pr = ["8N1", "8O1", "8E1", "8N12"]
        self.__ar = ["2.4k", "2.4k", "2.4k", "4.8k", "9.6k", "19.2k", "38.4k", "62.5k"]
        self.__sp = ["200 bytes", "128 bytes", "64 bytes", "32 bytes"]
        self.__en = ["disabled", "enabled"]
        self.__tp = ["30dBm", "27dBm", "24dBm", "21dBm"]
        self.__tm = ["TTM", "FTM"]
        self.__wor = ["500ms", "1000ms", "1500ms", "2000ms", "2500ms", "3000ms", "3500ms", "4000ms"]

        self._moduleInfo = None
        self._moduleConfiguration = None
        self._writeResponse = None
        self._m0 = Pin(m0, Pin.OUT)  # Weak Pull UP , Pin.PULL_UP
        self._m1 = Pin(m1, Pin.OUT)  # Weak Pull UP , Pin.PULL_UP
        self._aux = Pin(aux, Pin.IN)
        self._tx = Pin(tx, Pin.OUT)
        self._rx = Pin(rx, Pin.IN)
        self._uart = UART(uart, 9600, bits=8, parity=None, stop=1, tx=self._tx, rx=self._rx)
        self.line = ""
        self.init()

    def init(self):
        self._m0.value(0)
        self._m1.value(0)
        sleep(1)
        self.drainUartBuffer()
        self.waitForAuxLow(1000)

    def setMode(self, mode):
        sleep(RECOVER_DELAY)
        if mode == MODE_NORMAL:
            print("Set NORMAL mode")
            self._m0.value(0)
            self._m1.value(0)
        elif mode == MODE_WAKEUP:
            print("Set WAKEUP mode")
            self._m0.value(1)
            self._m1.value(0)
        elif mode == MODE_POWERDOWN:
            print("Set POWER DOWN mode")
            self._m0.value(0)
            self._m1.value(1)
        elif mode == MODE_PROGRAM:
            print("Set PROGRAM mode")
            self._m0.value(1)
            self._m1.value(1)

        sleep(RECOVER_DELAY)

        self.drainUartBuffer()
        self.waitForAuxLow(1000)

    def configuration(self):
        return {
            'addr': 0x0000,
            'br': '9600',
            'pr': '8N1',
            'ar': '2.4k',
            'sp': '200 bytes',
            'rsn': 'disabled',
            'tp': '21dBm',
            'ch': 23,
            'rb': 'disabled',
            'tm': 'TTM',
            'lbt': 'disabled',
            'wor': '500ms',
            'ck': 0x0000
        }

    def drainUartBuffer(self):
        """Read until no chars in the serial buffer"""
        print("Draining UART buffer")

        if not self._uart.any():
            return

        while self._uart.any():
            read = self._uart.read(1)
            print(read, end="")

        print(" - Drained")

    def waitForAuxLow(self, timeout):
        """Wait until AUX goes low"""
        print("Waiting for AUX low")
        countdown = timeout / 100
        while self._aux.value == 1:
            print("Timeout Countdown: {}".format(countdown))
            countdown -= 1
            if countdown < 0:
                print("Timeout")
                return
            sleep(0.1)
        print("Module Ready")

    def readConfiguration(self):
        self.setMode(MODE_PROGRAM)
        self._uart.write(bytes([0xC1, 0x00, 0x08]))
        self._moduleInfo = bytearray(3 + 8)
        print("Reading module info")
        bytesRead = self._uart.readinto(self._moduleInfo)
        reg = 0
        self._moduleInfo = self._moduleInfo[3:]
        cfg = self._moduleInfo
        for b in cfg:
            print("REG {:02x}H = {:02x} [{:08b}]".format(reg, b, b))
            reg += 1
        print("# REG 0x01 and 0x02")
        print(" Address     : 0x{:04x}".format(256 * cfg[0] + cfg[1]))
        print(" Baudrate    : {}".format(self.__br[(cfg[2] & 0b11100000) >> 5]))
        print(" Parity      : {}".format(self.__pr[(cfg[2] & 0b00011000) >> 3]))
        print(" Air Datarate: {}".format(self.__ar[cfg[2] & 0b111]))
        print("# REG 0x03")
        print(" Sub Packet Setting : {}".format(self.__sp[(cfg[3] & 0b11000000) >> 6]))
        print(" RSSI Ambient Noise : {}".format(self.__en[(cfg[3] & 0b00100000) >> 5]))
        print(" Transmitting Power : {}".format(self.__tp[(cfg[3] & 0b00000011)]))
        print("# REG 0x04")
        print(" Channels : 850.125 + {} * 1M".format(cfg[4]))
        print("# REG 0x05")
        print(" Enable RSSI Byte    : {}".format(self.__en[(cfg[5] & 0b10000000) >> 7]))
        print(" Transmission Method : {}".format(self.__tm[(cfg[5] & 0b01000000) >> 6]))
        print(" LBT       : {}".format(self.__en[(cfg[5] & 0b00010000) >> 4]))
        print(" WOR Cycle : {}".format(self.__wor[(cfg[5] & 0b00000111)]))
        print("# REG 0x06 and 0x07")
        print(" Key : 0x{:04x}".format(256 * cfg[6] + cfg[7]))
        self.setMode(MODE_NORMAL)
        self.waitForAuxLow(1000)

    def writeConfiguration(self):
        cfg = self.configuration()
        self.setMode(MODE_PROGRAM)

        r0 = (cfg['addr'] & 0b1111111100000000) >> 8
        r1 = cfg['addr'] & 0b0000000011111111
        br = self.__br.index(cfg['br'])
        pr = self.__pr.index(cfg['pr'])
        ar = self.__ar.index(cfg['ar'])
        r2 = br << 5 | pr << 3 | ar
        sp = self.__sp.index(cfg['sp'])
        rsn = self.__en.index(cfg['rsn'])
        tp = self.__tp.index(cfg['tp'])
        r3 = sp << 6 | rsn << 4 | tp
        r4 = cfg['ch']
        rb = self.__en.index(cfg['rb'])
        tm = self.__tm.index(cfg['tm'])
        lbt = self.__en.index(cfg['lbt'])
        wor = self.__wor.index(cfg['wor'])
        r5 = rb << 7 | tm << 6 | lbt << 4 | wor
        r6 = (cfg['ck'] & 0b1111111100000000) >> 8
        r7 = cfg['ck'] & 0b0000000011111111
        self._uart.write(bytes([0xc0, 0x00, 0x08, r0, r1, r2, r3, r4, r5, r6, r7]))
        self._writeResponse = bytearray(8)
        bytesRead = self._uart.readinto(self._writeResponse)
        #print(binascii.hexlify(self._writeResponse))
        self.setMode(MODE_NORMAL)
        self.waitForAuxLow(1000)

    def readLine(self):
        if self._uart.any():
            return self._uart.readline()
        else:
            return None

    def sendLine(self, line):
        print("Sending [{}]".format(line))
        self._uart.write(line + "\n")

    def printAux(self):
        print(self._aux.value())
Beispiel #4
0
uart0 = UART(0, 1000000, pins=uart_pins[0][0])
print(uart0)
uart1 = UART(1, 1000000, pins=uart_pins[1][0])
print(uart1)

print(uart0.write(b'123456') == 6)
print(uart1.read() == b'123456')

print(uart1.write(b'123') == 3)
print(uart0.read(1) == b'1')
print(uart0.read(2) == b'23')
print(uart0.read() == None)

uart0.write(b'123')
buf = bytearray(3)
print(uart1.readinto(buf, 1) == 1) 
print(buf)
print(uart1.readinto(buf) == 2)
print(buf)

# try initializing without the id
uart0 = UART(baudrate=1000000, pins=uart_pins[0][0])
uart0.write(b'1234567890')
time.sleep_ms(2) # because of the fifo interrupt levels
print(uart1.any() == 10)
print(uart1.readline() == b'1234567890')
print(uart1.any() == 0)

uart0.write(b'1234567890')
print(uart1.readall() == b'1234567890')
Beispiel #5
0
class RPLidar(object):

    def __init__(self, id = 2, baudrate=115200, timeout=5000, motoctl = 'X6'):
        self.uart = None
        self.motoctl = Pin(motoctl)
        self.motoctl_timer = Timer(2, freq = 20000)
        self.motoPWM_channel = self.motoctl_timer.channel(1, Timer.PWM, pin=self.motoctl)
        self.motoPWM_channel.pulse_width_percent(50)
        self.connect(id, baudrate, timeout)

        self._rxbuffer = bytearray(32)
        self._headings = array('H', [0 for i in range(READINGS_LENGTH)])#heading = heading[i]/64.0
        self._distances = array('H', [0 for i in range(READINGS_LENGTH)])#distance = distance[i]/4.0 #in mm
        self._readings_index = 0
        self._descriptor_queue = collections.deque((), 32) #File fifo
        self._next_data_type = None

        self._status = None
        self._error = None
        self._scanerrors = 0

    def connect(self, id, _baudrate, _timeout):
        self.uart = UART(id)
        self.uart.init(baudrate = _baudrate, bits=8, parity=None, stop=1, timeout = _timeout, read_buf_len=RXBUFFER_LENGTH)
        self.set_motor_pwm()

    def disconnect(self):
        self.uart.deinit()
        self.set_motor_pwm(0)
        

    def _send_request(self, command):
        if command == COMMAND_SCAN:
            self._descriptor_queue.append((SCAN_RESPONSE_LENGTH, False, SCAN_DATATYPE))
        elif command == COMMAND_GET_HEALTH:
            self._descriptor_queue.append((GET_HEALTH_RESPONSE_LENGTH, False, GET_HEALTH_DATATYPE))

        req = START_FLAG_1 + command
        self.uart.write(req)
        print('Command sent: %s' % req)

    def _read_response_descriptor(self):
        descriptor = self.uart.read(RESPONSE_DECRIPTOR_LENGTH)
        print('Recieved descriptor: ', descriptor)

        if(descriptor == None):
            print("Timeout")
            raise CommunicationError
        elif(len(descriptor) != RESPONSE_DECRIPTOR_LENGTH):
            print("Descriptor length mismatch")
            raise CommunicationError
        elif(not descriptor.startswith(START_FLAG_1 + START_FLAG_2)):
            print("Wrong descriptor starting bytes")
            raise CommunicationError

        data_response_lenght = int.from_bytes(descriptor[2:5], 'little') & ~(0b11<<28) #Remove 2btis from last byte that are reserved for send_mode

        send_mode = int.from_bytes(descriptor[5:6], 'little') & 0b11000000 #Extract the 2 bits from the byte
        is_single = send_mode == 0x0

        data_type = descriptor[6]

        print("Data response length : ", data_response_lenght)
        print("is single : ", is_single)
        print("data type : ", data_type)

        return data_response_lenght, is_single, data_type
    
    def _read_response(self, length):
        #print("Trying to read response: ",length," bytes")
        bytes_read = self.uart.readinto(self._rxbuffer, length)
        #print('Recieved data: ', self._rxbuffer)
        if bytes_read == None :
            print("Timout")
            raise CommunicationError
        if bytes_read != length:
            print('Wrong body size')
            raise CommunicationError

    def _serial_handler(self):

        if(bool(self._descriptor_queue)): #if descriptor queue is not empty, expecting a response descriptor
            data_response_lenght, is_single, data_type = self._descriptor_queue.popleft()
            if self._read_response_descriptor() !=  (data_response_lenght, is_single, data_type):
                print("Unexpected response descirptor")
                raise CommunicationError
            self._next_data_type = data_type
            return
        
        elif self._next_data_type == SCAN_DATATYPE: 
            self._read_response(SCAN_RESPONSE_LENGTH)

            S = self._rxbuffer[0] & 0b00000001
            not_S = (self._rxbuffer[0] & 0b00000010) >> 1
            C = self._rxbuffer[1] & 0b00000001
            if S == not_S:
                #print("Problem S = not_S")
                self._scanerrors += 1
                return
            #quality = data[0] >> 
            if C != 1:
                #print("Problem C != 1")
                self._scanerrors += 1
                return
            
            if(self._scanerrors > 10):#11 consecutive scan error, reseting lidar
                print("Many consecutive scan errors, reseting lidar")
                self.reset()
                self._scanerrors = 0
                self.start_scanning()
                return

            self._scanerrors = 0 #managed to read without error
            distance_q2 = (self._rxbuffer[3]) + (self._rxbuffer[4] << 8)
            if distance_q2 != 0:
                heading = ((self._rxbuffer[1] >> 1) + (self._rxbuffer[2] << 7))
                self._headings[self._readings_index] = heading
                self._distances[self._readings_index] = distance_q2
                self._readings_index += 1
                if(self._readings_index >= READINGS_LENGTH):
                    self._readings_index = 0
                
                
        elif self._next_data_type == 6:
            self._read_response(3)
            print(self._rxbuffer[0:1])
            self._status = int.from_bytes(self._rxbuffer[0:1], "little")
            self._error = int.from_bytes(self._rxbuffer[1:2], "little")
            
        


    def set_motor_pwm(self, pulse_width_percent=50):
        self.motoPWM_channel.pulse_width_percent(pulse_width_percent)

    def get_health(self):
        self._status = None
        self._error = None
        self._send_request(COMMAND_GET_HEALTH)

        while self._status == None or self._error == None:
            time.sleep(0.02)
        
        print("Status : ", self._status)
        print("Error : ", self._error)
        return self._status, self._error
            
    def stop(self):
        '''RPLIDAR will exit the current scanning state. 
            The laser diode and the measurement system will be disabled and the Idle state will be entered. 
            This request will be ignored when RPLIDAR is in the Idle or Protection Stop state.
            Since RPLIDAR won’t send response packet for this request, host systems should
            wait for at least 1 millisecond (ms) before sending another request'''
        print("Stopping scan")
        self.should_scan = False
        self._send_request(COMMAND_STOP)
        time.sleep(.002)
        if self.uart.any() > 0:
            print("Clearing buffer")
            self.uart.read() #clear uart buffer

    def reset(self):
        '''A reset operation will make RPLIDAR revert to a similar state as it has just been
            powered up. This request is useful when RPLIDAR has entered the Protection Stop
            state. After a core reset, RPLIDAR will return to the idle state which will accept the
            start scan request again.
            Since RPLIDAR won’t send response packet for this request, host systems should
            wait for at least 2 milliseconds (ms) before sending another request. '''
        print("Resseting RPLidar")
        self._send_request(COMMAND_RESET)
        time.sleep(1)
        if self.uart.any() > 0:
            print("Clearing buffer")
            self.uart.read(self.uart.any()) #clear uart buffer
        while bool(self._descriptor_queue):
            self._descriptor_queue.popleft()

    def start_scanning(self):
        self._send_request(COMMAND_SCAN)

    #Slow no preallocation
    def get_reading(self):
        reading = []
        for i in range(len(self._headings)):
            reading.append([self._headings[i]/64.0, self._distances[i]/4.0])
        return reading

    def get_headings_mv(self):
        return memoryview(self._headings)

    def get_distances_mv(self):
        return memoryview(self._distances)

    def update(self):
        inBuff = self.uart.any()
        if(inBuff > 0):            
            while  (bool(self._descriptor_queue) and inBuff >= RESPONSE_DECRIPTOR_LENGTH) or \
                (self._next_data_type == SCAN_DATATYPE and inBuff >= SCAN_RESPONSE_LENGTH) or \
                (self._next_data_type == GET_HEALTH_DATATYPE and inBuff >= GET_HEALTH_RESPONSE_LENGTH):
                    self._serial_handler()
                    inBuff = self.uart.any()
Beispiel #6
0
sensor = sds011_sensor(display)

def test_sensor():
    """ Can be called to pump some test sequences into the sensor
    """


    test_sequences = [ ['0xaa', '0xc0', '0xf', '0x0', '0x22', '0x0', '0xe1', '0xdb', '0xed', '0xab'],
        ['0xaa', '0xc0', '0x13', '0x0', '0x3e', '0x0', '0xe1', '0xdb', '0xb', '0xab'], # bad checksum
        ['0xaa', '0xc0', '0x13', '0x0', '0x3e', '0x0', '0xe1', '0xdb', '0xa', '0xab'],
        ['0xaa', '0xc0', '0x13', '0x0', '0x3e', '0x0', '0xe1', '0xdb', '0xd', '0xab'] ]

    for test_sequence in test_sequences:
        for ch in test_sequence:
            sensor.pump_byte(int(ch))

# test_sensor()

buffer = bytearray([0])

while (not Buttons.is_pressed(Buttons.BTN_A)) and (not Buttons.is_pressed(Buttons.BTN_B)) and (not Buttons.is_pressed(Buttons.BTN_Menu)):
    while sensor_port.any() > 0:
        sensor_port.readinto(buffer,1)
        sensor.pump_byte(buffer[0])
    sleep.wfi()

ugfx.clear()

app.restart_to_default()

Beispiel #7
0
    uart = UART(1, 38400, rx=3, tx=1)

    # Create and send Scratch data packet
    def convert(a, b):
        sensor = bytearray(2)
        upper = (b & 0x380) >> 7
        sensor[1] = b & 0x7f
        sensor[0] = (1 << 7) | a << 3 | upper
        uart.write(sensor)

    request = bytearray(1)

    while True:

        if uart.readinto(request) == 1 and request[0] == 0x01:       #当接收到scratch发来的0x01字节
            rgb.fill((0,20,0))
            rgb.write()
            convert(15, 0x04)
            sleep_us(10)
            extValue=int(ext.read_analog()/4)                              # Get ext
            convert(0,extValue)
            reading = accelerometer.get_y()*1000                    # Get accelerometer's y
            if reading >= 0:
                reading = int(reading / 2) + 512
                convert(1, reading)
            else:
                reading = 512 - abs(int(reading / 2))
                convert(1, reading)

            reading = accelerometer.get_x()*1000                    # Get accelerometer's x
Beispiel #8
0
rdr = mfrc522.MFRC522(14, 13, 12, 5, 21)

#---ST735---
spi = SPI(2, baudrate=20000000, polarity=0, phase=0, sck=Pin(27), mosi=Pin(32), miso=Pin(12))
tft=TFT(spi,33,17,18)
tft.initg()
tft.rgb(False)
tft.fill(TFT.BLACK)


#--------bouvcle principale------------
while True:

    #---lecture ID (125kHz)---#
    if uart1.any():
        uart1.readinto(buf)                          # UART.read([nbytes]) ou sinon UART.readinto(buf[, nbytes])
	ID = bytes(buf)
    
    #---lecture ID (13MHz)---#
    (stat, tag_type) = rdr.request(rdr.REQIDL)
	if stat == rdr.OK:
		(stat, raw_uid) = rdr.anticoll()
		if stat == rdr.OK:
            ID = raw_uid[0] + raw_uid[1] + raw_uid[2] + raw_uid[3]
					#print("New card detected")
					#print("  - tag type: 0x%02x" % tag_type)
					#print("  - uid	 : 0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
					#print("")
					#if rdr.select_tag(raw_uid) == rdr.OK:
					#	key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
					#	if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
class LTEModule(object):
    """Controls Quectel EC21 LTE Module."""
    CR = const(0x0d)
    LF = const(0x0a)

    SOCKET_TCP = const(0)
    SOCKET_UDP = const(1)

    MAX_CONNECT_ID = const(12)
    MAX_SOCKET_DATA_SIZE = const(1460)

    def __init__(self):
        self.__pin_reset_module = Pin('RESET_MODULE')
        self.__pin_dtr_module = Pin('DTR_MODULE')
        self.__pin_pwrkey_module = Pin('PWRKEY_MODULE')
        self.__pin_module_power = Pin('M_POWR')
        self.__pin_module_status = Pin('STATUS')
        self.__pin_disable_module = Pin('W_DISABLE')
        self.__pin_wakeup_module = Pin('WAKEUP_IN')

        self.__uart = UART('LTE')
        self.__urcs = None
        self.__connections = []

        from uasyncio import sleep_ms, CancelledError
        self.sleep_ms = sleep_ms
        self.CancelledError = CancelledError

    def initialize(self):
        """
        Initialize I/O ports and peripherals to communicate
        with the module.
        """
        self.__pin_reset_module.init(Pin.OUT)
        self.__pin_dtr_module.init(Pin.OUT)
        self.__pin_pwrkey_module.init(Pin.OUT)
        self.__pin_module_power.init(Pin.OUT)
        self.__pin_module_status.init(Pin.IN)
        self.__pin_disable_module.init(Pin.OUT)
        self.__pin_wakeup_module.init(Pin.OUT)

        self.__pin_dtr_module.off()
        self.__pin_pwrkey_module.off()
        self.__pin_module_power.off()
        self.__pin_reset_module.on()
        self.__pin_disable_module.on()
        self.__pin_wakeup_module.off()

        self.__uart.init(baudrate=115200, timeout=5000, timeout_char=1000)

    def set_supply_power(self, to_supply):
        """Enable/Disable power supply to the module."""
        self.__pin_module_power.value(1 if to_supply else 0)

    async def reset(self):
        """Reset the module."""
        self.__pin_reset_module.off()
        await self.sleep_ms(200)
        while self.__uart.any():
            self.__uart.read(self.__uart.any())
        self.__pin_reset_module.on()
        await self.sleep_ms(300)

        for trial in range(15):
            if await self.wait_response(b'RDY') is not None:
                return True
        return False

    async def wait_busy(self, max_trials=50):
        """Wait while the module is busy."""
        for trial in range(max_trials):
            if not self.is_busy():
                return True
            await self.sleep_ms(100)
        return False

    async def turn_on(self):
        """Turn on the module."""
        await self.sleep_ms(100)
        self.__pin_pwrkey_module.on()
        await self.sleep_ms(200)
        self.__pin_pwrkey_module.off()

        if not await self.wait_busy():
            return False

        for trial in range(15):
            if await self.wait_response(b'RDY') is not None:
                return True
        return False

    async def turn_on_or_reset(self):
        """
        Turn on or reset the module and wait until the LTE
        commucation gets available.
        """
        self.__urcs = []

        if self.is_busy():
            if not await self.turn_on():
                return False
        else:
            if not await self.reset():
                return False

        # Check if the module can accept commands.
        if not await self.write_command_wait(b'AT', b'OK'):
            return False
        # Disable command echo
        if not await self.write_command_wait(b'ATE0', b'OK'):
            return False
        # Use UART1 port to receive URC
        if not await self.write_command_wait(b'AT+QURCCFG="urcport","uart1"',
                                             b'OK'):
            return False

        buffer = bytearray(1024)
        result, responses = await self.execute_command(
            b'AT+QSCLK=1', buffer, expected_response_list=[b'OK', b'ERROR'])
        if not result:
            return False

        while True:
            result, responses = await self.execute_command(b'AT+CPIN?',
                                                           buffer,
                                                           timeout=1000)
            if len(responses) == 0: return False
            if result:
                return True

    async def get_IMEI(self):
        """Gets International Mobile Equipment Identity (IMEI)"""
        response = await self.execute_command_single_response(b'AT+GSN')
        return str(response, 'utf-8') if response is not None else None

    async def get_IMSI(self):
        """Gets International Mobile Subscriber Identity (IMSI)"""
        response = await self.execute_command_single_response(b'AT+CIMI')
        return str(response, 'utf-8') if response is not None else None

    async def get_phone_number(self):
        "Gets phone number (subscriber number)"
        response = await self.execute_command_single_response(
            b'AT+CNUM', b'+CNUM:')
        return str(response[6:], 'utf-8') if response is not None else None

    async def get_RSSI(self):
        "Gets received signal strength indication (RSSI)"
        response = await self.execute_command_single_response(
            b'AT+CSQ', b'+CSQ:')
        if response is None:
            return None
        try:
            s = str(response[5:], 'utf-8')
            rssi, ber = s.split(',', 2)
            return (int(rssi), int(ber))
        except ValueError:
            return None

    async def activate(self,
                       access_point: str,
                       user: str,
                       password: str,
                       timeout: int = None):
        #print("Activating network...")
        while True:
            # Read network registration status.
            response = await self.execute_command_single_response(
                b'AT+CGREG?', b'+CGREG:', timeout)
            if response is None:
                raise LTEModuleError('Failed to get registration status.')
            s = str(response, 'utf-8')
            #print('AT+CGREG?:{}'.format(s))
            n, stat = s.split(',')[:2]
            if stat == '0' or stat == '4':  # Not registered and not searching (0), or unknown (4).
                #raise LTEModuleError('Invalid registration status.')
                pass
            elif stat == '1' or stat == '5':  # Registered.
                break

        while True:
            # Read EPS network registration status
            response = await self.execute_command_single_response(
                b'AT+CEREG?', b'+CEREG:', timeout)
            if response is None:
                raise LTEModuleError('Failed to get registration status.')
            s = str(response, 'utf-8')
            #print('AT+CEREG?:{}'.format(s))
            n, stat = s.split(',')[:2]
            if stat == '0' or stat == '4':  # Not registered and not searching (0), or unknown (4).
                raise LTEModuleError('Invalid registration status.')
            elif stat == '1' or stat == '5':  # Registered.
                break
        # Configure TCP/IP contect parameters
        # contextID,context_type,APN,username,password,authentication
        # context_type  : IPv4 = 1, IPv4/v6 = 2
        # authentication: None = 0, PAP = 1, CHAP = 2, PAP or CHAP = 3
        command = bytes(
            'AT+QICSGP=1,1,"{0}","{1}","{2}",1'.format(access_point, user,
                                                       password), 'utf-8')
        if not await self.write_command_wait(command, b'OK', timeout):
            return False
        # Activate a PDP context
        if not await self.write_command_wait(b'AT+QIACT=1', b'OK', timeout):
            return False
        if not await self.write_command_wait(b'AT+QIACT?', b'OK', timeout):
            return False

        return True

    async def get_ip_address(self,
                             host: str,
                             timeout: int = 60 * 1000) -> List[str]:
        """
        Get IP address from hostname using DNS.

        :param str host:        An address of the remote host.  
        :return:                A list of IP addresses corresponding to the hostname.
        :raises LTEModuleError: If the communication module failed to open a new socket.
        """
        assert (host is not None)

        await self.__process_remaining_urcs(timeout=timeout)

        buffer = bytearray(1024)

        try:
            # Query host address.
            command = bytes('AT+QIDNSGIP=1,"{0}"'.format(host), 'utf-8')
            if not await self.write_command_wait(
                    command, b'OK', timeout=timeout):
                raise LTEModuleError('Failed to get IP.')

            response = await self.wait_response(b'+QIURC: "dnsgip"',
                                                timeout=timeout)  # type:bytes
            if response is None:
                return None
            fields = str(response, 'utf-8').split(',')

            if len(fields) < 4 or int(fields[1]) != 0:
                return None
            count = int(fields[2])
            ipaddrs = []
            for i in range(count):
                mv = await self.wait_response_into(b'+QIURC: "dnsgip",',
                                                   response_buffer=buffer,
                                                   timeout=1000)
                if mv is not None:
                    ipaddrs.append(str(mv[18:-1],
                                       'utf-8'))  # strip double-quote
            return ipaddrs
        except ValueError:
            return None

        except self.CancelledError:
            pass

    async def get_time(self):
        """
        Returns an 6-touple with the current date and time.
        The 6-touple has following format:
          (year, month, day, hours, minutes, seconds)
        """
        import ure as re
        response = await self.execute_command_single_response(
            b'AT+CCLK?', b'+CCLK:')
        response = response.decode('utf-8')
        #print('res:', response)
        re_res = re.match(
            r'\+CCLK: "(\d\d)/(\d\d)/(\d\d),(\d\d):(\d\d):(\d\d)\+(\d\d)"',
            response)
        if re_res is None:
            raise LTEModuleError('Failed to get time.')
        return (
            int(re_res.group(1)) + 2000,  # year
            int(re_res.group(2)),  # month
            int(re_res.group(3)),  # day
            int(re_res.group(4)),  # hours
            int(re_res.group(5)),  # minutes
            int(re_res.group(6)))  # seconds

    async def socket_open(self, host, port, socket_type, timeout=30 * 1000):
        """
        Open a new socket to communicate with a host.

        :param str host:        An address of the remote host.  
        :param int port:        Port number of the remote host.
        :param int socket_type: Socket type. SOCKET_TCP or SOCKET_UDP
        :return:                Connection ID of opened socket if success. Otherwise raise LTEModuleError.
        :raises LTEModuleError: If the communication module failed to open a new socket.
        """
        assert (host is not None)
        assert (port is not None and 0 <= port and port <= 65535)
        if socket_type == LTEModule.SOCKET_TCP:
            socket_type_name = 'TCP'
        elif socket_type == LTEModule.SOCKET_UDP:
            socket_type_name = 'UDP'
        else:
            socket_type_name = None
        assert (socket_type_name is not None)

        await self.__process_remaining_urcs(timeout=timeout)

        buffer = bytearray(1024)

        success, responses = await self.execute_command(b'AT+QISTATE?',
                                                        buffer,
                                                        timeout=timeout)
        if not success:
            raise LTEModuleError('Failed to get socket status')
        connect_id_in_use = set()
        for response in responses:
            if len(response) < 10 or response[:10] != b'+QISTATE: ': continue
            s = str(bytes(response[10:]), 'utf-8')
            params = s.split(',', 1)
            connect_id = int(params[0])
            connect_id_in_use.add(connect_id)

        new_connect_id = None
        for connect_id in range(LTEModule.MAX_CONNECT_ID):
            if connect_id not in connect_id_in_use and connect_id not in self.__connections:
                new_connect_id = connect_id
                break
        if new_connect_id is None:
            raise LTEModuleError('No connection resources available.')

        # Open socket.
        command = bytes(
            'AT+QIOPEN=1,{0},"{1}","{2}",{3},0,0'.format(
                connect_id, socket_type_name, host, port), 'utf-8')
        if not await self.write_command_wait(command, b'OK', timeout=timeout):
            raise LTEModuleError('Failed to open socket. OK')
        response = await self.wait_response(bytes(
            '+QIOPEN: {0},'.format(connect_id), 'utf-8'),
                                            timeout=timeout)
        if response is None:
            raise LTEModuleError('Failed to open socket. QIOPEN')
        error = str(response, 'utf-8').split(',')[1]
        if error != '0':
            raise LTEModuleError(
                'Failed to open socket. error={0}'.format(error))

        self.__connections.append(connect_id)
        return connect_id

    async def socket_send(self,
                          connect_id,
                          data,
                          offset=0,
                          length=None,
                          timeout=None):
        """Send a packet to destination."""
        assert (0 <= connect_id and connect_id <= LTEModule.MAX_CONNECT_ID)
        await self.__process_remaining_urcs(timeout=timeout)
        if connect_id not in self.__connections:
            return False

        length = len(data) if length is None else length
        if length == 0:
            return True
        assert (length <= LTEModule.MAX_SOCKET_DATA_SIZE)

        command = bytes('AT+QISEND={0},{1}'.format(connect_id, length),
                        'utf-8')
        self.write_command(command)
        if not await self.wait_prompt(b'> ', timeout=timeout):
            return False
        mv = memoryview(data)
        self.__uart.write(mv[offset:offset + length])
        return await self.wait_response(b'SEND OK',
                                        timeout=timeout) is not None

    async def socket_receive(self,
                             connect_id,
                             buffer,
                             offset=0,
                             length=None,
                             timeout=None):
        assert (0 <= connect_id and connect_id <= LTEModule.MAX_CONNECT_ID)
        await self.__process_remaining_urcs(timeout=timeout)
        if connect_id not in self.__connections:
            return False

        length = len(buffer) if length is None else length
        if length == 0:
            return 0
        assert (length <= LTEModule.MAX_SOCKET_DATA_SIZE)

        command = bytes('AT+QIRD={0},{1}'.format(connect_id, length), 'utf-8')
        self.write_command(command)
        response = await self.wait_response(b'+QIRD: ', timeout=timeout)
        if response is None:
            return None
        actual_length = int(str(response[7:], 'utf-8'))
        if actual_length == 0:
            return 0 if await self.wait_response(
                b'OK', timeout=timeout) is not None else None
        mv = memoryview(buffer)
        bytes_read = self.__uart.readinto(mv[offset:offset + length],
                                          actual_length)
        return actual_length if bytes_read == actual_length and await self.wait_response(
            b'OK', timeout=timeout) is not None else None

    async def socket_close(self, connect_id, timeout=None):
        assert (0 <= connect_id and connect_id <= LTEModule.MAX_CONNECT_ID)
        if connect_id not in self.__connections:
            return False
        command = bytes('AT+QICLOSE={0}'.format(connect_id), 'utf-8')
        await self.write_command_wait(command,
                                      expected_response=b'OK',
                                      timeout=timeout)
        self.__connections.remove(connect_id)
        return True

    def socket_is_connected(self, connect_id):
        return connect_id in self.__connections and (
            "closed", connect_id) not in self.__urcs

    def is_busy(self):
        return bool(self.__pin_module_status.value())

    def write(self, s):
        self.__uart.write(s)

    def read(self, length: int) -> bytes:
        return self.__uart.read(length)

    def write_command(self, command: bytes) -> None:
        self.__uart.write(command)
        self.__uart.write('\r')

    async def write_command_wait(self,
                                 command,
                                 expected_response,
                                 timeout=None):
        self.write_command(command)
        return await self.wait_response(expected_response,
                                        timeout=timeout) is not None

    async def read_response_into(self, buffer, offset=0, timeout=None):
        while True:
            length = await self.__read_response_into(buffer=buffer,
                                                     offset=offset,
                                                     timeout=timeout)
            mv = memoryview(buffer)
            if (length is not None and length >= 8 and mv[0:8] == b"+QIURC: "):
                if length > 17 and mv[8:16] == b'"closed"':
                    connect_id = int(str(mv[17:length], 'utf-8'))
                    self.__urcs.append(("closed", connect_id))
                    continue

            return length

    async def __read_response_into(self, buffer, offset=0, timeout=None):
        buffer_length = len(buffer)
        response_length = 0
        state = 0
        start_time_ms = ticks_ms()
        while True:
            c = self.__uart.readchar()
            if c < 0:
                if (timeout is not None
                        and ticks_diff(ticks_ms(), start_time_ms) >= timeout):
                    return None
                try:
                    await self.sleep_ms(1)
                except self.CancelledError:
                    return None
                continue

            if state == 0 and c == LTEModule.CR:
                state = 1
            elif state == 1 and c == LTEModule.LF:
                state = 2
            elif state == 1 and c == LTEModule.CR:
                state = 1
            elif state == 1 and c != LTEModule.LF:
                response_length = 0
                state = 0
            elif state == 2 and c == LTEModule.CR:
                if response_length == 0:
                    state = 1  # Maybe there is another corresponding CR-LF followed by actual response data. So we have to return to state 1.
                else:
                    state = 4
            elif state == 2 and c != LTEModule.CR:
                buffer[offset + response_length] = c
                response_length += 1
                if offset + response_length == buffer_length:
                    state = 3
            elif state == 3 and c == LTEModule.CR:
                state = 4
            elif state == 4 and c == LTEModule.LF:
                return response_length

    async def __process_remaining_urcs(self, timeout=None):
        for urc_type, urc_params in self.__urcs:
            if urc_type == 'closed':
                await self.socket_close(urc_params, timeout=timeout)
        self.__urcs.clear()

    async def wait_response(self,
                            expected_response,
                            max_response_size=1024,
                            timeout=None):
        response = bytearray(max_response_size)
        expected_length = len(expected_response)
        while True:
            length = await self.read_response_into(response, timeout=timeout)
            if length is None: return None
            if length >= expected_length and response[:
                                                      expected_length] == expected_response:
                return response[:length]

    async def wait_response_into(self,
                                 expected_response,
                                 response_buffer,
                                 timeout=None):
        expected_length = len(expected_response)
        mv = memoryview(response_buffer)
        while True:
            length = await self.read_response_into(response_buffer,
                                                   timeout=timeout)
            if length is None: return None
            if length >= expected_length and mv[:
                                                expected_length] == expected_response:
                return mv[:length]

    async def wait_prompt(self, expected_prompt, timeout=None):
        prompt_length = len(expected_prompt)
        index = 0
        start_time_ms = ticks_ms()

        while True:
            c = self.__uart.readchar()
            if c < 0:
                if ticks_diff(ticks_ms(), start_time_ms) > timeout:
                    return False
                await self.sleep_ms(1)
                continue
            if expected_prompt[index] == c:
                index += 1
                if index == prompt_length:
                    return True
            else:
                index = 0

    async def execute_command(self,
                              command,
                              response_buffer,
                              index=0,
                              expected_response_predicate=None,
                              expected_response_list=[b'OK'],
                              timeout=None):
        assert expected_response_predicate is not None or expected_response_list is not None
        if expected_response_predicate is None:
            expected_response_predicate = lambda mv: mv in expected_response_list
        self.write_command(command)
        buffer_length = len(response_buffer)
        responses = []
        mv = memoryview(response_buffer)
        while True:
            length = await self.read_response_into(response_buffer,
                                                   index,
                                                   timeout=timeout)
            if length is None:
                return (False, responses)
            response = mv[index:index + length]
            responses.append(response)
            if expected_response_predicate(response):
                return (True, responses)
            index += length

    async def execute_command_single_response(self,
                                              command,
                                              starts_with=None,
                                              timeout=None):
        buffer = bytearray(1024)
        result, responses = await self.execute_command(command,
                                                       buffer,
                                                       timeout=timeout)
        if not result: return None
        starts_with_length = len(starts_with) if starts_with is not None else 0

        for response in responses:
            if starts_with_length == 0 and len(response) > 0:
                response = bytes(response)
                return response
            if starts_with_length > 0 and len(
                    response
            ) >= starts_with_length and response[:
                                                 starts_with_length] == starts_with:
                response = bytes(response)
                return response
        return None
Beispiel #10
0
class NEO6MGPS(object):
    def __init__(self, baudrate=9600):
        # pin 17 tx, pin 16 rx
        self.uart = UART(2, baudrate)
        # init with given parameters
        self.uart.init(baudrate, bits=8, parity=None, stop=1)

    def update(self):
        self.read_raw()
        self.setValues()

    def read_raw(self):
        self.data = self.uart.read()
        self.data = self.data.splitlines()
        self.data.sort()

    def setValues(self):
        for i in range(0, len(self.data)):
            if (self.data[i].find('GPGGA'.encode()) == 1):
                self.gpgga = self.data[i]
            elif (self.data[i].find('GPGLL'.encode()) == 1):
                self.gpgll = self.data[i]
            elif (self.data[i].find('GPGSA'.encode()) == 1):
                self.gpgsa = self.data[i]
            elif (self.data[i].find('GPGSV'.encode()) == 1):
                self.gpgsv = self.data[i]
            elif (self.data[i].find('GPRMC'.encode()) == 1):
                self.gprmc = self.data[i]
            elif (self.data[i].find('GPVTG'.encode()) == 1):
                self.gpvtg = self.data[i]

    def interpret_rmc(self):
        if (len(self.gprmc) < 23):
            return self.update()
        self.rmc = self.gprmc.split(','.encode())
        self.utc = str(self.rmc[1])[2:-1]
        self.receiver = str(self.rmc[2])[2:-1]
        try:
            self.latitude = float(self.rmc[3]) / 100
        except:
            self.latitude = str(self.rmc[3])[2:-1]
        self.latitude_direction = str(self.rmc[4])[2:-1]
        try:
            self.longitude = float(self.rmc[5]) / 100
        except:
            self.longitude = str(self.rmc[5])[2:-1]
        self.longitude_direction = str(self.rmc[6])[2:-1]
        self.speed = str(self.rmc[7])[2:-1]
        self.cmg = str(self.rmc[8])[2:-1]
        self.fixdata = str(self.rmc[9])[2:-1]
        self.magvar = str(self.rmc[10])[2:-1]
        self.magvardir = str(self.rmc[11])[2:-1]
        self.checksum = str(self.rmc[12])[2:-1]

    def write(self, value):
        self.uart.write(value)

    def writeToArray(self, array):
        self.uart.readinto(array)

    def print_raw_values(self):
        self.raw_values = [
            self.gpgga, self.gpgll, self.gpgsa, self.gpgsv, self.gprmc,
            self.gpvtg
        ]
        for i in range(0, len(self.raw_values)):
            try:
                print(self.raw_values[i])
            except:
                pass

    def getformatedUTC(self, timezone):
        utc = float(self.utc)
        self.hours = int(utc / 10000)
        if (self.hours < 7):
            self.hours += 24
        self.hours += timezone
        utc %= 10000
        self.minutes = int(utc / 100)
        utc %= 100
        self.seconds = int(utc)

        return str(
            str(self.hours) + ":" + str(self.minutes) + ":" +
            str(self.seconds))

    def print_values(self):
        self.value_names = [
            "utc", "latitude", "latitude_direction", "longitude",
            "longitude_direction", "fix_quality", "num_sat_track",
            "horizontal_dilution", "altitude", "altitude_unit",
            "height_above_WGS84", "height_above_WGS84_unit", "last_update",
            "station_ID"
        ]
        self.values = [
            self.utc, self.latitude, self.latitude_direction, self.longitude,
            self.longitude_direction, self.fix_quality, self.num_sat_track,
            self.horizontal_dilution, self.altitude, self.altitude_unit,
            self.height_above_WGS84, self.height_above_WGS84_unit,
            self.last_update, self.station_ID
        ]
        for i in range(0, len(self.values)):
            try:
                print(self.value_names[i] + ":    " + str(self.values[i]))
            except:
                pass