# # 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
# 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)
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())
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')
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()
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()
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
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
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