def read_serial(ser: serial.Serial, q_out: queue.Queue, q_in: queue.Queue, stop_event: threading.Event): while (ser.isOpen()): if stop_event.is_set(): return if not q_in.empty(): ser.write(q_in.get() + b'\n') q_out.put(bytestostr(ser.readline()))
def main(): print "Opening serial port" s = Serial(serial_port, serial_bauds); print "Reading first line from port" line = s.readline() print "Initializing communication" counter = 1 # debug stuff # tic = time.time() log = open("/home/pi/vibration/log.csv", "a") while counter <= 1000: counter += 1 line = s.readline() m = re.match(serial_pattern, line) try: log.write("\n" + str(ts) + "," + str(counter) + "," + str(m.group(1))) except: log.write("\n" + str(ts) + "," + str(counter) + "," + str("NaN")) # debug stuff # toc = time.time() # print(tic) # print(toc) log.close()
class Rubinstein(object): def __init__(self, port='/dev/ttyUSB0', baudrate=250000, timeout=0.25): self.serial = Serial(port=port, baudrate=baudrate, timeout=timeout) # FIXME don't know why initialization stops with this line while self.serial.readline() != 'echo:SD init fail\n': sleep(0.2) self.busy = False def command(self, cmd, timeout=float('inf')): # FIXME needs mutex! if self.busy or self.serial.read(): raise RuntimeError("busy") self.busy = True self.serial.write("{}\n".format(cmd)) response = '' start = time() while time() - start < timeout: sleep(0.2) line = self.serial.readline() if line == 'ok\n': # FIXME missing try/finally for busy=False self.busy = False return response if len(line) > 0: print line, response += line else: raise RuntimeError( "timeout when waiting for command {}".format(cmd))
class PlotUpdater(threading.Thread): """This class sets the fraction of the progressbar""" #Thread event, stops the thread if it is set. stopthread = threading.Event() def __init__(self, gui): threading.Thread.__init__(self) #Call constructor of parent self.gui = gui self.frac = 0 self.ser = Serial("/dev/ttyACM0",115200) #self.ser.timeout = 1 self.i = 0 def run(self): """Run method, this is the code that runs while thread is alive.""" #self.ser.readline() #self.ser.readline() #While the stopthread event isn't setted, the thread keeps going on while not self.stopthread.isSet() : # Acquiring the gtk global mutex #gtk.threads_enter() #Setting the fraction self.frac += 0.01 self.i += 1 #self.gui.line.set_data((t, np.sin(3*np.pi*(t+self.frac)))) rslt = '' self.ser.write("d\n") s = self.ser.readline().strip() while s != '' : rslt += s+'\n' s = self.ser.readline().strip() #print repr(s) try: n = np.loadtxt(StringIO(rslt)) angles = n[:,1] intensities = n[:,2] #(self.gui.s0p, self.gui.s1, self.gui.s2, self.gui.s3, self.gui.dop)=get_stokes(angles,intensities) self.gui.line.set_data((angles, intensities)) except ValueError: print "Value Error" # Releasing the gtk global mutex #gtk.threads_leave() #Delaying 100ms until the next iteration self.ser.close() def stop(self): """Stop method, sets the event to terminate the thread's main loop""" self.stopthread.set()
class DenonMixer(BaseMixer): """ Mixer for controlling Denon amplifiers and receivers using the RS-232 protocol. The external mixer is the authoritative source for the current volume. This allows the user to use his remote control the volume without Mopidy cancelling the volume setting. **Dependencies** - pyserial (python-serial on Debian/Ubuntu) **Settings** - :attr:`mopidy.settings.MIXER_EXT_PORT` -- Example: ``/dev/ttyUSB0`` """ def __init__(self, *args, **kwargs): """ Connects using the serial specifications from Denon's RS-232 Protocol specification: 9600bps 8N1. """ super(DenonMixer, self).__init__(*args, **kwargs) device = kwargs.get('device', None) if device: self._device = device else: from serial import Serial self._device = Serial(port=settings.MIXER_EXT_PORT, timeout=0.2) self._levels = ['99'] + ["%(#)02d" % {'#': v} for v in range(0, 99)] self._volume = 0 self._lock = Lock() def _get_volume(self): self._lock.acquire() self.ensure_open_device() self._device.write('MV?\r') vol = str(self._device.readline()[2:4]) self._lock.release() logger.debug(u'_get_volume() = %s' % vol) return self._levels.index(vol) def _set_volume(self, volume): # Clamp according to Denon-spec if volume > 99: volume = 99 self._lock.acquire() self.ensure_open_device() self._device.write('MV%s\r'% self._levels[volume]) vol = self._device.readline()[2:4] self._lock.release() self._volume = self._levels.index(vol) def ensure_open_device(self): if not self._device.isOpen(): logger.debug(u'(re)connecting to Denon device') self._device.open()
class TempReceiver: def __init__(self, port, db_name): self.connection = sqlite3.connect(DB_NAME) self.cursor = self.connection.cursor() self.port = Serial(port) def listen(self): current_data = {} self.port.readline() # to empty buffer while True: ser_data = self.port.readline() res = self.process_data(ser_data) if res is None: continue addr, raw, cal = res if current_data.get(addr, None): self.save_data(current_data) current_data = {addr: (raw, cal)} else: current_data[addr] = raw, cal def process_data(self, data): data = data.strip().split(delimiter) if len(data) != 2: return None chip_id = data[0] raw_temp = data[1] cal_temp = self.calibrate(raw_temp) return chip_id, raw_temp, cal_temp def calibrate(self, temp): return temp def save_data(self, data): """write one row of data to database""" timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') for addr, temp in data.iteritems(): self.cursor.execute( 'select * from "sqlite_master" ' 'where type="table" ' 'and name="{}"'.format(addr) ) if not self.cursor.fetchall(): logging.info('new sensor detected: {}'. format(addr)) self.cursor.execute( 'create table if not exists "{}"' '(timestamp, raw_temp, cal_temp)'. format(addr) ) self.cursor.execute( 'insert into "{}" (timestamp, raw_temp, cal_temp) ' 'values ("{}", "{}", "{}")'. format(addr, timestamp, temp[0], temp[1]) ) self.connection.commit()
class CommVacuum: message_time = .01 # initialize the serial comm def __init__(self): # on linux use port="/dev/ttyUSB2" # attempt to connect foundPort = False ports = list(serial.tools.list_ports.comports()) portArray = [] for p in ports: if "Arduino Mega" in p[1]: # print "Port =", p[0] port = p[0] # print port portArray.append(port) foundPort = True if foundPort == False: print "No Port Found (Arduino Mega)" for i in range(len(portArray)): port = portArray[i] while True: try: self.com = Serial(port, 9600) break except SerialException: print 'Error: No device is on port' + port print 'Type an alternative ttyUSB number or a full port name' port = input('Port = ') if port.isdigit(): port = '/dev/ttyUSB' + port print('connected to an arduino... checking ID (vacuum)...') time.sleep(0.5) # Reset Arduino self.com.setDTR(False) # Drop DTR time.sleep(0.022) # Read somewhere that 22ms is what the UI does. self.com.setDTR(True) # UP the DTR back arduinoID = self.com.readline() while not (("c" in arduinoID) or ("b" in arduinoID) or ("a" in arduinoID)): arduinoID = self.com.readline() time.sleep(0.01) # print "ID:", arduinoID if "c" in arduinoID: print "ID Checked (vacuum controller)" break else: print "Wrong ID:", arduinoID # send commands to the arduino for the vacuum, should be 0 or 1 (on or off) def change_vacuum_state(self, comm): self.com.write(str(comm)) time.sleep(self.message_time)
class SerialDevice(object): def __init__(self, dev="/dev/ttyACM0", baud=115200, debug=False): self._s = Serial(dev, baud) self._dev = dev self._baud = baud self._debug = debug sleep(1) self.flush() sleep(1) def write(self, data): if self._debug: print ":", data self._s.write(data) def readline(self): line = self._s.readline() if self._debug: print ">", line.rstrip() return line def read_response(self): r = Response(self.readline()) return r def command(self, cmd): self.write(cmd + ";") return self.read_response() def print_conf(self): r = self.command("C") if r.ok: for i in xrange(int(r.data[0])): print self._s.readline().rstrip() def open(self, dev=None, baud=None): if dev is None and baud is None: self._s.open() else: if dev is None: dev = self._dev if baud is None: baud = self._baud self._s = Serial(dev, baud) def flush(self): while self._s.inWaiting(): self._s.read() def close(self): self._s.close()
class DenonMixer(ThreadingActor, BaseMixer): """ Mixer for controlling Denon amplifiers and receivers using the RS-232 protocol. The external mixer is the authoritative source for the current volume. This allows the user to use his remote control the volume without Mopidy cancelling the volume setting. **Dependencies** - pyserial (python-serial on Debian/Ubuntu) **Settings** - :attr:`mopidy.settings.MIXER_EXT_PORT` -- Example: ``/dev/ttyUSB0`` """ def __init__(self, device=None): super(DenonMixer, self).__init__() self._device = device self._levels = ['99'] + ["%(#)02d" % {'#': v} for v in range(0, 99)] self._volume = 0 def on_start(self): if self._device is None: from serial import Serial self._device = Serial(port=settings.MIXER_EXT_PORT, timeout=0.2) def get_volume(self): self._ensure_open_device() self._device.write('MV?\r') vol = str(self._device.readline()[2:4]) logger.debug(u'_get_volume() = %s' % vol) return self._levels.index(vol) def set_volume(self, volume): # Clamp according to Denon-spec if volume > 99: volume = 99 self._ensure_open_device() self._device.write('MV%s\r'% self._levels[volume]) vol = self._device.readline()[2:4] self._volume = self._levels.index(vol) def _ensure_open_device(self): if not self._device.isOpen(): logger.debug(u'(re)connecting to Denon device') self._device.open()
class MachineCom(): def __init__(self, port = 'AUTO', baudrate = 250000): self.serial = None if port == 'AUTO': programmer = stk500v2.Stk500v2() for port in serialList(): try: programmer.connect(port) programmer.close() self.serial = Serial(port, baudrate, timeout=5) break except ispBase.IspError: pass programmer.close() else: self.serial = Serial(port, baudrate, timeout=5) def readline(self): if self.serial == None: return '' ret = self.serial.readline() print "Recv: " + ret.rstrip() return ret def close(self): if self.serial != None: self.serial.close() self.serial = None def sendCommand(self, cmd): if self.serial == None: return self.serial.write(cmd + '\n')
class tarjetaTOC(): ''' Clase de comunicacion con la tarjeta mediante puerto serial. ''' def __init__(self, controlador): ''' Constructor de la clase ''' self.puerto = "/dev/ttyS0" self.BAUDS = "9600" self.TIMEOUT = 1 self.serial = Serial(port=self.puerto, baudrate=self.BAUDS, bytesize=8, stopbits=1, timeout=self.TIMEOUT, dsrdtr=False, rtscts=True) self.cerrar_puerto() def abrir_puerto(self): try: self.serial.open() #time.sleep(2) except: print "Error de apertura de puerto" def cerrar_puerto(self): self.serial.close() def desconectar(self): self.cerrar_puerto() def escribir_datos(self, datos): # Escribe datos en el puerto self.serial.flushOutput() self.serial.write(datos) print "Escribio" def crear_datos_simulador(self): pass def leer_datos(self): recv = self.serial.readline() if len(recv) >= 5: self.serial.flushInput() return recv else: return (recv) def enviar_comando(self, comando): # Envia un comando y espera a que se reciba respuesta self.abrir_puerto() self.escribir_datos(comando) recv = self.leer_datos() self.cerrar_puerto() return recv
class Joystick(): def __init__(self, port, baud=57600): self.port = port self.baud = baud self.ser = None def open(self): try: self.ser = Serial(self.port, self.baud) except: print(" Open serial port %s failled with baudrate %d"%(self.port, self.baud)) def __enter__(self): self.open() return self def __exit__(self, type, value, traceback): self.ser.close() return True def __iter__(self): print("iter") return self def __next__(self): s = self.ser.readline() return s
class DataSource_Serial: def __init__(self): self.con = Serial(TTY_DEVICE, 2400) self.logfile = StringIO.StringIO() def read(self,length): data = self.con.read(length) self.logfile.write(data) return data def readline(self): global LOGFILE data = self.con.readline() if data=="START\n": self.logfile = self.create_logfile() self.logfile.write(data) return data def create_logfile(self): f = None i = 0 while not f: fname = 'logs/ttydump-%d.dat' % i if exists(fname): i+=1 else: f = file(fname, 'w') return f
def main(): global frequency if len(sys.argv) != 2: print "usage: python %s <serial>" % __file__ sys.exit(2) serial = Serial(sys.argv[1], timeout=5) audio = pyaudio.PyAudio() stream = audio.open(format=pyaudio.paInt8, channels=1, rate=44100, output=True, stream_callback=callback) while True: serial.write("S") distance = int(serial.readline().strip()) if distance > 50: frequency = 0 else: frequency = 50 + (distance * 10) sys.stdout.write("Frequency is %s \r" % str(distance)) sys.stdout.flush() stream.stop_stream() stream.close() audio.terminate()
class serio: def __init__(self, line, baud, tracefile=None): self.__s = Serial(line, baud, timeout=None) if tracefile: self.__trace = open(tracefile, 'w') self.flush_buffers() def trace(self, line): self.__trace.write(line + '\n') self.__trace.flush() def tx(self, cmd): #cmd = cmd + '\r\n' self.trace(">>> %r"%cmd) self.__s.write(cmd) def peekbuffer(self, tmo=0): self.__s.setTimeout(tmo) ret = self.rx() self.__s.setTimeout(None) return ret def rx(self): ret = self.__s.readline() if ret[-1:] == '\n': ret = ret[:-1] if ret[-1:] == '\r': ret = ret[:-1] self.trace("<<< %r"%ret) return ret def flush_buffers(self): self.__s.flushInput() self.__s.flushOutput() self.trace("--- flushed buffers")
def run(port, max_height=223, max_width=123): ser = Serial(port, 9600) prev = time() while True: line = ser.readline().rstrip('\n\r') data = line.split(',') if len(data) != 3: continue for i in range(3): try: data[i] = calibration * float(data[i]) except ValueError: continue now = time() rate = 1 / (now - prev) ut = data[0] ul = data[1] ur = data[2] width = 0 height = max_height - ut if not (ul > 120 and ur > 120): width = max_width - ul - ur #print '{:5.2f} {:5.2f} {:5.2f} {:5.2f} {:4.2f}'.format(height, ul, ur, width, rate) prev = now
def uart1(portName, q): while not exitFlag: queueLock.acquire() if not workQueue.empty(): data = q.get() ser = Serial( data, baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None) while True: line = ser.readline(ser.inWaiting()).decode('utf-8')[:-2] if line: t = line.split(",") line2 = float(t[5]) if line2 > 0: print(portName, line2) if line == '520': subprocess.call(["xte", "key Up"]) elif line == '620': subprocess.call(["xte", "key Down"]) elif line == '110': break ser.close()
def handle(self, *args, **options): if len(args) < 2: print "No enough arguments" return n = 0 MAX = 5 while(n < MAX): try: ser = Serial(args[0], args[1], timeout=5) ser.write('t') temp = float(ser.readline()[:-1]) / 10 ser.write('c') state = ser.read() TempHistory.objects.create(datetime=datetime.utcnow(), temp=temp, state=state) settings = TempSettings.load() ser.write('sl{:d} '.format(int(settings.low_boundary * 10))) ser.write('sh{:d} '.format(int(settings.high_boundary * 10))) except TimeoutException: ser.close() n += 1 else: break if n == MAX: sys.stderr.write('Error syncing with thermostat')
class GPS: def __init__(self, port_name, baud_rate, logger): self.logger = logger self.logger.write("Starting GPS Communications") self.serial = Serial(port_name, baud_rate) self.lat = 0 self.long = 0 def get_GPS(self): while (self.lat == 0.0): self.logger.write("Waiting for GPS") time.sleep(1) return (self.lat, self.long) def read_data(self): if self.serial.inWaiting() > 0: data = self.serial.readline().rstrip() if data[0:6] == "$GPRMC": fields = data.split(',') if fields[2] == 'A': self.lat = int(fields[3][0:2]) + (float(fields[3][2:]) / 60.0) #ASSUMES TWO DIGIT LATITUDE self.long = int(fields[5][0:3]) + (float(fields[5][3:]) / 60.0) #ASSUMES THREE DIGIT LONGITUDE else: self.lat = 0.0 self.long = 0.0 def close(self): self.serial.close()
def send(message): ser = Serial("COM3", baudrate=57600) ser.flush() ser.write(message.encode()) sleep(0.1) if ser.inWaiting(): print(ser.readline().decode().rstrip('\r\n').split(",")[0])
class SerialServer(Thread): def __init__(self, port="/dev/ttyACM0", baudrate=9600, timetoread=2): Thread.__init__(self) self.server = Serial(port=port, baudrate=baudrate) self.dataInQueeud = False self.running = True self.timetoread = timetoread #periodicite de lecture du port self.datas = "" #les donnees lus self.dataToSend = "" #les donneees à envoyer def run(self): """lecture continue du port série. Lorsqu'il y'a quelque chose à lire, il lie puis envoie les donnees""" while self.running == True: while self.server.inWaiting() > 0: self.datas += self.server.readline() sleep(self.timetoread) #pause #envoie s'il y'a quelques a envoyer if self.dataToSend != "": self.server.write(self.dataToSend) self.server.flush() def recvdatas(self): res = self.datas self.datas = "" return res def senddatas(self, data = ""): self.dataToSend = data def toStop(self): self.server.close() self.running = False
class Connexion: """ Manage the USB connexion. """ def __init__(self, tty = "/dev/ttyACM0"): """ Open a serial connexion on specified tty, with a 1152000 baudrate. """ try: self.serial = Serial(tty, baudrate = 115200) except SerialException: print("Can't open", tty) exit(1) def read(self): """ Read a line. """ try: return self.serial.readline().decode("ascii", "ignore") except OSError: sleep(1) return self.read() def write(self, msg): """ Send a string. """ self.serial.write(normalize("NFD", msg).encode("ascii", "ignore"))
def listenPort(): ser = Serial(port=config.serialPort, baudrate=config.serialBaudrate, timeout=1) print("connected to: " + ser.portstr) while True: line = ser.readline() if line: parse(line) ser.close()
class TinkwiseGateway(object): def __init__(self): self._logger = logging.getLogger() self._logger.setLevel(logging.INFO) self._logger.addHandler(logging.handlers.SysLogHandler(address='/dev/log')) parser = argparse.ArgumentParser(description='tinkwise gateway') parser.add_argument('-c','--config_file', type=str, dest='config_file', default='/etc/tinkwise.conf') args = parser.parse_args() config = ConfigParser() config.read(args.config_file) connection_type = config.get('connection', 'type') connection_file = config.get('connection', 'file') self._rrd_dir = config.get('rrd', 'path') self._rrd = RrdHelper(self._rrd_dir) if connection_type == 'file': self._input_file = file(connection_file) elif connection_type == 'serial': try: self._input_file = Serial(port=connection_file, baudrate=115200) except Exception as e: self._logger.critical('failed to open serial port ' + connection_file + ':' + e.message) raise def run(self): while True: line = self._input_file.readline() if line == '': sleep(1) continue self._logger.info('processing ' + line) try: sample = json.loads(line) except Exception, e: self._logger.error('could not parse JSON string ' + line) self._logger.error(e.message) continue if not 'node' in sample: self._logger.error('no node found in JSON string' + line) continue node_index = int(sample['node']) self._logger.info('node ' + str(node_index)) del sample['node'] data_sources_spaces = map(lambda o: o.encode('ascii', 'ignore'), sample.keys()) data_sources = map(lambda s: s.replace(' ', '_'), data_sources_spaces) data_values = map(str, sample.values()) self._rrd.create_if_not_existing(node_index, data_sources) try: self._rrd.update(node_index, data_sources, data_values) except RrdHelper.DataSourceNotFoundException: self._logger.warning('data source reveived is missing in config file')
class MachineCom: def __init__(self, port=None, baudrate=None): if port == None: port = profile.getPreference("serial_port") if baudrate == None: baudrate = int(profile.getPreference("serial_baud")) self.serial = None if port == "AUTO": programmer = stk500v2.Stk500v2() for port in serialList(): try: print "Connecting to: %s %i" % (port, baudrate) programmer.connect(port) programmer.close() time.sleep(1) self.serial = Serial(port, baudrate, timeout=2) break except ispBase.IspError as (e): print "Error while connecting to %s %i" % (port, baudrate) print e pass except: print "Unexpected error while connecting to serial port:" + port, sys.exc_info()[0] programmer.close() elif port == "VIRTUAL": self.serial = VirtualPrinter() else: try: self.serial = Serial(port, baudrate, timeout=2) except: print "Unexpected error while connecting to serial port:" + port, sys.exc_info()[0] print self.serial def readline(self): if self.serial == None: return None ret = self.serial.readline() # if ret != '': # print "Recv: " + ret.rstrip() return ret def close(self): if self.serial != None: self.serial.close() self.serial = None def __del__(self): self.close() def isOpen(self): return self.serial != None def sendCommand(self, cmd): if self.serial == None: return # print 'Send: ' + cmd self.serial.write(cmd + "\n")
def read_message(serial_port: serial.Serial) -> str: """Read in, decode, and return a sentence from the serial port.""" while True: try: line = serial_port.readline().decode("ascii").replace('\r', '').replace('\n', '') except UnicodeError: line = "" if len(line) > 0 and line[0] == "$": return line
def read(self): try: ser = Serial('/dev/ttyUSB0', 9600) except: print "Failed to connect on /dev/ttyUSB0" if ser.isOpen(): while True: response = ser.readline() print(response)
class DataReader(threading.Thread): #Thread event, stops the thread if it is set. stopthread = threading.Event() def __init__(self): threading.Thread.__init__(self) #Call constructor of parent self.ser = Serial(port,9600) #Initialize serial port self.data_buff_size = 200 #Buffer size self.data = zeros(self.data_buff_size) #Data buffer self.start() def run(self): #Run method, this is the code that runs while thread is alive. num_bytes = 400 #Number of bytes to read at once val = 0 #Read value while not self.stopthread.isSet() : while self.ser.inWaiting()>0: line = self.ser.readline() #print(line.split(b',')) valid=line.split(b',') if len(valid)!=8: continue values = [int(x) for x in valid] print(values) lock.acquire() self.data=roll(self.data,-1) self.data[-1]=values[0] lock.release() """ rslt = self.ser.read(num_bytes) #Read serial data byte_array = unpack('%dB'%num_bytes,rslt) #Convert serial data to array of numbers first = False #Flag to indicate weather we have the first byte of the number for byte in byte_array: if 224 <= byte <= 255: #If first byte of number val = (byte & 0b11111) << 5 first = True elif 96 <= byte <= 127: #If second byte of number val |= (byte & 0b11111) if first: lock.acquire() self.data = roll(self.data,-1) self.data[-1] = val lock.release() """ self.ser.close() def stop(self): self.stopthread.set()
class GPSreader(): __KNOT = 1.852 __r = 6371000 _GPRMC_pattern = { 'HOUR':1, 'STATUS':2, 'LAT':3, 'LAT_NS':4, 'LON':5, 'LON_EW':6, 'SPEED':7, 'COURSE':8, 'DATE':9, 'VAR':10, 'VAR_E_W':11, 'CHKS':12, 'LENGTH':13} def __init__(self, port = None): if port: self.gps = Serial(port) self.coords = self._coords_gen() else: self.get_coords = None self._speed_gps = 0 self._speed_calc = 0 self._latitude = 0 self._longitude = 0 self._latitude_prev = 0 self._longitude_prev = 0 self._time_now = 0 self._time_prev = 0 self._timestamp = "-" self._gps_raw = {} @property def speed_gps(self): return round(self._speed_gps, 3) @property def speed_calc(self): return round(self._speed_calc, 3) @property def latitude(self): return round(self._latitude, 7) @property def longitude(self): return round(self._longitude, 7) @property def timestamp(self): return self._timestamp def _split_gps_str(self, gps_str): self._gps_raw = {key:"" for key in self._GPRMC_pattern} gps_split = gps_str.split(',') if len(gps_split) == self._GPRMC_pattern['LENGTH']: self._gps_raw = {key:(gps_split[self._GPRMC_pattern[key]] if key != 'LENGTH' else 0) for key in self._GPRMC_pattern} self._gps_raw.pop('LENGTH') return self._gps_raw def _gps2coords(self, coord_text, nswe): try: major, minor = coord_text.split('.') degrees = int(major) // 100 minutes = (int(major) % 100 + float('0.' + minor)) / 60 coordinate = round(degrees + minutes, 7) if nswe.upper() == 'W': return coordinate * -1 else: return coordinate except: return -1 def _gps2time(self, hour_time, day_time): try: major, minor = hour_time.split('.') hours = int(major) // 10000 minutes = (int(major) % 10000) // 100 sec = int(major) % 100 ssec = int(minor) day = int(day_time) // 10000 month = (int(day_time) % 10000) // 100 year = (int(day_time) % 100) + 2000 time_obj = datetime.datetime(year, month, day, hours, minutes, sec, ssec) return str(time_obj) except: return -1 def _gps2speed(self, speed): try: speed_gps = float(speed) * self.__KNOT return speed_gps except: return -1 def _calc_speed(self): lat1 = (self._latitude_prev * pi) / 180 lon1 = (self._longitude_prev * pi) / 180 lat2 = (self._latitude * pi) / 180 lon2 = (self._longitude * pi) / 180 rho1 = self.__r * cos(lat1) z1 = self.__r * sin(lat1) x1 = rho1 * cos(lon1) y1 = rho1 * sin(lon1) rho2 = self.__r * cos(lat2) z2 = self.__r * sin(lat2) x2 = rho2 * cos(lon2) y2 = rho2 * sin(lon2) dot = x1 * x2 + y1 * y2 + z1 * z2 cos_theta = dot / (self.__r ** 2) theta = acos(round(cos_theta, 6)) distance = self.__r * theta speed_calc = (distance / (self._time_now - self._time_prev)) * 3.6 return speed_calc def get_coords(self, gps_str): coords_dict = {'LAT':0, 'LON':0, 'SPEED_GPS':0, 'SPEED_CALC':0, 'TIME':""} self._split_gps_str(gps_str) if self._gps_raw['STATUS'] == 'A': self._latitude = self._gps2coords(self._gps_raw['LAT'], self._gps_raw['LAT_NS']) self._longitude = self._gps2coords(self._gps_raw['LON'], self._gps_raw['LON_EW']) self._speed_gps = self._gps2speed(self._gps_raw['SPEED']) self._timestamp = self._gps2time(self._gps_raw['HOUR'], self._gps_raw['DATE']) self._speed_calc = self._calc_speed() self._latitude_prev, self._longitude_prev = self._latitude, self._longitude coords_dict = { 'LAT':self.latitude, 'LON':self.longitude, 'SPEED_GPS':self.speed_gps, 'SPEED_CALC':self.speed_calc, 'TIME':self.timestamp} return coords_dict def _coords_gen(self): self.gps.flush() while True: self._time_now = time.time() gps_line = self.gps.readline() if "GPRMC" in gps_line: yield self.get_coords(gps_line) self._time_prev = self._time_now
class Module: """ Allows communication to Lakeshore Module. Contains list of inputs which can be read from. """ def __init__(self, port='/dev/tty.SLAB_USBtoUART', baud=115200, timeout=10): """ Establish Serial communication and initialize channels. """ # Running with a simulator # Make sure to write over tcp instead of serial. if port[:6] == 'tcp://': self.simulator = True address, socket_port = port[6:].split(':') socket_port = int(socket_port) for p in range(socket_port, socket_port + 10): try: print(f"Trying to connect to {address} on port {p}") self.com = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.com.connect((address, p)) print(f"Found connection on port {p}") break except ConnectionRefusedError as e: if e.errno == 61: continue else: raise e else: self.com = Serial(port=port, baudrate=baud, timeout=timeout) self.simulator = False # First comms usually fails if this is your first time communicating # after plugging in the LS240. Try three times, then give up. for i in range(3): try: print('attempt %s' % i) idn = self.msg("*IDN?") break except TimeoutError: print("Comms failed on attempt %s" % i) self.manufacturer, self.model, self.inst_sn, self.firmware_version = idn.split( ',') num_channels = int(self.model[-2]) self.name = self.msg("MODNAME?") self.channels: List[Channel] = [] for i in range(num_channels): c = Channel(self, i + 1) self.channels.append(c) def close(self): if self.simulator: self.com.close() def __exit__(self): self.close() def msg(self, msg): """ Send command or query to module. Return response (within timeout) if message is a query. """ if self.simulator: message_string = "{};".format(msg) self.com.send(message_string.encode()) resp = '' if '?' in msg: resp = self.com.recv(BUFF_SIZE).decode() return resp else: # Writes message message_string = "{}\r\n;".format(msg).encode() # write(message_string) self.com.write(message_string) # Reads response if queried resp = '' if "?" in msg: resp = self.com.readline() resp = str(resp[:-2], 'utf-8') # Strips terminating chars if not resp: raise TimeoutError("Device timed out") # Must wait 10 ms before sending another command time.sleep(.01) return resp def set_name(self, name): self.name = name self.msg("MODNAME {}".format(name)) def __str__(self): return "{} ({})".format(self.name, self.inst_sn)
from serial import Serial ser = Serial('/dev/ttyUSB0',115200) while True: read_serial = ser.readline() read_serial = read_serial.decode("utf-8") # print (read_serial) read_serial = read_serial.split(",") if len(read_serial) > 1 : read_serial[-1] = read_serial[-1].replace("\r\n","") print (read_serial) if read_serial == ['3686744587', '219', '191', '66', '11'] : print("True") ser.write("DerpHashTurnOn".encode()) else: print("False") ser.write("off".encode())
class printcore(): def __init__(self, port=None, baud=None): """Initializes a printcore instance. Pass the port and baud rate to connect immediately """ self.baud = None self.port = None self.printer = None #Serial instance connected to the printer, None when disconnected self.clear = 0 #clear to send, enabled after responses self.online = False #The printer has responded to the initial command and is active self.printing = False #is a print currently running, true if printing, false if paused self.mainqueue = [] self.priqueue = [] self.queueindex = 0 self.lineno = 0 self.resendfrom = -1 self.paused = False self.sentlines = {} self.log = [] self.sent = [] self.tempcb = None #impl (wholeline) self.recvcb = None #impl (wholeline) self.sendcb = None #impl (wholeline) self.errorcb = None #impl (wholeline) self.startcb = None #impl () self.endcb = None #impl () self.onlinecb = None #impl () self.loud = False #emit sent and received lines to terminal if port is not None and baud is not None: #print port, baud self.connect(port, baud) #print "connected\n" def disconnect(self): """Disconnects from printer and pauses the print """ if (self.printer): self.printer.close() self.printer = None self.online = False self.printing = False def connect(self, port=None, baud=None): """Set port and baudrate if given, then connect to printer """ if (self.printer): self.disconnect() if port is not None: self.port = port if baud is not None: self.baud = baud if self.port is not None and self.baud is not None: self.printer = Serial(self.port, self.baud, timeout=5) Thread(target=self._listen).start() def reset(self): """Reset the printer """ if (self.printer): self.printer.setDTR(1) self.printer.setDTR(0) def _listen(self): """This function acts on messages from the firmware """ self.clear = True time.sleep(1.0) self.send_now("M105") while (True): if (not self.printer or not self.printer.isOpen): break try: line = self.printer.readline() except SelectError, e: if 'Bad file descriptor' in e.args[1]: print "Can't read from printer (disconnected?)." break else: raise if (len(line) > 1): self.log += [line] if self.recvcb is not None: try: self.recvcb(line) except: pass if self.loud: print "RECV: ", line.rstrip() if (line.startswith('DEBUG_')): continue if (line.startswith('start') or line.startswith('ok')): self.clear = True if (line.startswith('start') or line.startswith('ok') or "T:" in line): if (not self.online or line.startswith('start') ) and self.onlinecb is not None: try: self.onlinecb() except: pass self.online = True if (line.startswith('ok')): #self.resendfrom=-1 #put temp handling here if "T:" in line and self.tempcb is not None: try: self.tempcb(line) except: pass #callback for temp, status, whatever elif (line.startswith('Error')): if self.errorcb is not None: try: self.errorcb(line) except: pass #callback for errors pass if "resend" in line.lower() or "rs" in line: try: toresend = int( line.replace("N:", " ").replace("N", " ").replace( ":", " ").split()[-1]) except: if "rs" in line: toresend = int(line.split()[1]) self.resendfrom = toresend self.clear = True self.clear = True
import os # Pour executer une commande bash import datetime # Pour avoir l'heure from serial import Serial serial_port = Serial(port='/dev/tty.wchusbserial1410', baudrate=9600) while True: direction_lue = serial_port.readline() direction_lue = int( direction_lue ) # on le cast en int car readline prend les caracteres charriots now = datetime.datetime.now() os.system( "curl -i -X POST -H \"Content-Type:application/json\" -d '{ \"direction\" : \"" + str(direction_lue) + "\", \"date\" : \"" + str(now.strftime("%Y-%m-%d %H:%M:%S")) + "\" }' https://api.mlab.com/api/1/databases/project-arduino-rs/collections/direction?apiKey=LOfDlu3AOFaGioAYucPxA_WUUBMiAxd9" ) pass
args = parser.parse_args() print("** Using TTY %s." % (args.tty, )) if args.do_reset: print("** Opening serial port %s..." % (args.tty, )) serial = Serial(args.tty) print("** Reinitializing Arduino...") serial.setDTR(1) time.sleep(0.5) serial.setDTR(0) serial.close() print("** (re)Opening %s at %d bauds..." % (args.tty, args.bauds)) serial = Serial(args.tty, args.bauds) try: while True: line = serial.readline().decode('utf-8').rstrip("\n") print(line) except KeyboardInterrupt: pass except OSError as err: if err.errno != 11: raise print("** Disconnected (resource unavailable)") finally: print("** Closing serial port...") serial.close()
except SerialException: print "Fatal Serial Error. Closing program" quit() f = open("/home/pi/AeroHacks/data.txt", "w") # Reading data stream and converting to JSON # 2-minute data read => 120s # sampling freq = .5Hz => 60 samples for i in tuple(range(60)): # convert to tuple for speed try: obj = {} # dict for JSON conversion ser.write("r".encode('utf-8')) # request data cmd ser.flush() sleep(.08) # wait for data to buffer gas_volt = ser.readline() print gas_volt lArr = gas_volt.split(':') print lArr obj[lArr[0]] = float(lArr[1]) pressure = ser.readline() print pressure lArr = pressure.split(':') print lArr obj[lArr[0]] = float(lArr[1]) humidity = ser.readline() print humidity lArr = humidity.split(':') print lArr obj[lArr[0]] = float(lArr[1]) temp = ser.readline()
# not used for arduino ser = Serial() ser.port = 'COM7' ser.baudrate = 19200 ser.open() print(ser.is_open) #ser.write(b"*IDN?\n") #ser.write("*IDN?\n".encode()) # end of line (EOL) character is \n #print(ser.read(39)) # number of bytes, if larger than output will run loop ### Communicating read and write no matter how long ### ser.write(b":READ:POWer:WAVelength?\n") ser_bytes = ser.readline() decoded_bytes = ser_bytes[0:len(ser_bytes) - 1].decode() print(decoded_bytes) ser.write(b"*IDN?\n") ser_bytes2 = ser.readline() decoded_bytes2 = ser_bytes2[0:len(ser_bytes2) - 1].decode() print(decoded_bytes2) ### Loop ### while True: try: ser.write(b":READ:POWer:WAVelength?\n") ser_bytes = ser.readline() decoded_bytes = ser_bytes[0:len(ser_bytes) - 1].decode() print(decoded_bytes)
sleep(1) print("in Main Loop") print("Listing to serial...") # A hope-for-the-best sort of delay sleep(HOPE_SERIAL_IS_OK_DELAY) while (True): if not DUMMY_MODE: try: if (ser == None): ser = Serial(SERIAL_CONN, baudrate=SERIAL_BAUD, timeout=None) print("Reconnecting") line = ser.readline() # read a '\n' terminated line decodedLine = line.decode('utf-8').rstrip() parse_message(decodedLine) except Exception as e: ts = time.asctime(time.localtime(time.time())) print(str(ts), 'In main switchbox loop: ', e) if (not (ser == None)): ser.close() ser = None print("Disconnecting...") print("More than likely, no Connection or serial line borked") sleep(0.7) client.loop_stop() # Stop loop client.disconnect() # disconnect
class SeaGet(): def __init__(self, baud, cont, filename, device, new_baud, debug=0, timeout=0.004, benchmark=0): self.debug = debug self.timeout = timeout self.benchmark = benchmark self.device = device self.ser = Serial(port=self.device, baudrate=baud, bytesize=8, parity='N', stopbits=1, timeout=self.timeout) #start diagnostic mode if self.debug > 0: print('Start diagnostic mode') _, mode = self.send("\x1A") if mode not in ['1', 'T']: sys.exit("Something has gone wrong. Modus is %s (expected 1 or T)" % mode) #if you want a different baud rate you get it! if new_baud: if self.debug > 0: print('Set new baud rate') self.set_baud(new_baud) baud = new_baud #set the right mode to access memory and buffer if self.debug > 0: print('Set mode /1') incoming, mode = self.send("/1") if mode != "1": exit_msgs = ["Couldn't set modus to 1. Failed with %s" % incoming, ] if re.match('Input Command Error', incoming) and baud != 38400: exit_msgs.append('You probably set a higher baud rate, on a hd that has a bug.') exit_msgs.append('Turn the hd off and on again and try the default baud rate 38400.') sys.exit('\n'.join(exit_msgs)) def send(self, command): #if this doesn't work for you try setting a greater timeout (to be on the safe side try 1) #zc is the zerocounter and used to prevent it from going forever incom = [""] line = True zc = 0 self.ser.write(command + "\n") while 1: try: line = self.ser.readline() if line == "": zc += 1 else: zc = 0 if zc == 500: break incom.append(line) except: sys.exit('Failed to read line. Maybe the timeout is too low.') incom = "".join(incom) #You can (and have to) set different modi for the hd. #a different modus means you get a different set of commands #checking the modi after every command can be used for debugging and/or to verify that a command got executed correctly try: modus = re.findall('F3 (.)>', incom) modus = modus[len(modus)-1] except: exit_msgs = ["Failed to execute regex.", "This usually means that you didn't get the whole message or nothing at all.", "Check your baud rate and timeout/zc.", incom, ] sys.exit(exit_msgs) return incom, modus def get_modus(self): return self.send("")[1] def set_baud(self, newbaud): modus = self.get_modus() print('Setting baud to %s' % newbaud) if modus != "T": print('Changing mode to T') self.send("/T") self.send("B"+str(newbaud)) self.ser = Serial(port=self.device, baudrate=newbaud, bytesize=8, parity='N', stopbits=1, timeout=self.timeout) newmodus = self.send("/"+modus)[1] return modus == newmodus def parse(self, buff): hex = "" fooR = re.compile('[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]\s+(.+)\r') parsed = fooR.findall(buff) # for line in parsed: # hex=hex+re.sub(' ','',line) hex = re.sub(' ', '', ''.join(parsed)) bin = hex.decode("hex") return hex, bin def read_buffer(self, hexa): #hexa xxxx #hexa is the address you want to read in hex res, modus = self.send('B'+str(hexa)) return self.parse(res) def read_memory(self, hexa, hexb): #hexa xx #hexb yyyy #it always gives you 256bytes resp, modus = self.send('D'+str(hexa)+','+str(hexb)) parsed = self.parse(resp) if len(parsed[1]) != 512: #should never happen,but could if timeout is too low return False, False return parsed def dump_memory(self, filename, cont): if cont: memf = open(filename, 'r+') fsize = len(memf.read()) if fsize % 512 != 0: sys.exit('%s seems to be corrupted (wrong file size)' % filename) sj = math.trunc(fsize/512/64) si = fsize/512-64*sj if self.debug > 0: print('Starting from %s %s' % (sj, si)) else: memf = open(filename, 'w') fsize = 0 sj, si = 0, 0 k = fsize/512 total = (64*128*512)/1000.0 stime = time.time() # start time print('Starting memory dump') for j in range(sj, 64): for i in range(si, 128): k += 1 zz = time.time() memf.write(self.read_memory(hex(j)[2:], hex(i*0x200)[2:])[1]) size = (k*512)/1000.0 if self.benchmark == 1: speed = round(512/(time.time()-zz), 2) percentage = round(100.0/total*size, 2) minleft = round((time.time()-stime)/k*(247*128-k)/60, 2) progress_bar(time.time()-stime, size*1000, total*1000) memf.close() def dump_buffer(self,filename,cont): #not tested yet #so it's "experimental" I guess... #and I wouldn't use continue yet #and the file dump get's much too big because they loop the buffer over and over and I'm not quite sure if the buffer has always the same size if cont: bufff = open(filename, 'r+') fsize = len(bufff.read()) if fsize % 512 != 0: sys.exit('%s seems to be corrupted (wrong file size)' % filename) sp = math.trunc(fsize/512) if self.debug > 0: print('Starting from %s' % (sp)) else: bufff = open(filename, 'w') fsize = 0 sp = 0 k = fsize/512 total = (65535*512)/1000.0 stime = time.time() # start time print ('Start buffer dump') for i in range(sp,65535): k += 1 zz = time.time() bufff.write(self.read_buffer(hex(i)[2:])[1]) size = (k*512)/1000.0 if self.benchmark == 1: speed = round(512/(time.time()-zz), 2) percentage = round(100.0/total*size, 2) minleft = round((time.time()-stime)/k*(247*128-k)/60, 2) progress_bar(time.time()-stime, size*1000, total*1000)
class Device(object): def __init__(self, **kwargs): self.steps_per_unit = STEPS_PER_INCH self.pen_up_position = PEN_UP_POSITION self.pen_up_speed = PEN_UP_SPEED self.pen_up_delay = PEN_UP_DELAY self.pen_down_position = PEN_DOWN_POSITION self.pen_down_speed = PEN_DOWN_SPEED self.pen_down_delay = PEN_DOWN_DELAY self.acceleration = ACCELERATION self.max_velocity = MAX_VELOCITY self.corner_factor = CORNER_FACTOR for k, v in kwargs.items(): setattr(self, k, v) self.error = (0, 0) # accumulated step error port = find_port() if port is None: raise Exception('cannot find axidraw device') self.serial = Serial(port, timeout=1) self.configure() def configure(self): servo_min = 7500 servo_max = 28000 pen_up_position = self.pen_up_position / 100 pen_up_position = int(servo_min + (servo_max - servo_min) * pen_up_position) pen_down_position = self.pen_down_position / 100 pen_down_position = int(servo_min + (servo_max - servo_min) * pen_down_position) self.command('SC', 4, pen_up_position) self.command('SC', 5, pen_down_position) self.command('SC', 11, int(self.pen_up_speed * 5)) self.command('SC', 12, int(self.pen_down_speed * 5)) def close(self): self.serial.close() def make_planner(self): return Planner(self.acceleration, self.max_velocity, self.corner_factor) def readline(self): return self.serial.readline().strip() def command(self, *args): line = ','.join(map(str, args)) self.serial.write(line + '\r') return self.readline() # higher level functions def move(self, dx, dy): self.run_path([(0, 0), (dx, dy)]) def goto(self, x, y): px, py = self.read_position() self.run_path([(px, py), (x, y)]) def home(self): self.goto(0, 0) # misc commands def version(self): return self.command('V') # motor functions def enable_motors(self): m = MICROSTEPPING_MODE return self.command('EM', m, m) def disable_motors(self): return self.command('EM', 0, 0) def motor_status(self): return self.command('QM') def zero_position(self): return self.command('CS') def read_position(self): response = self.command('QS') self.readline() a, b = map(int, response.split(',')) a /= self.steps_per_unit b /= self.steps_per_unit y = (a - b) / 2 x = y + b return x, y def stepper_move(self, duration, a, b): return self.command('XM', duration, a, b) def wait(self): while '1' in self.motor_status(): time.sleep(0.01) def run_plan(self, plan): step_ms = TIMESLICE_MS step_s = step_ms / 1000 t = 0 while t < plan.t: i1 = plan.instant(t) i2 = plan.instant(t + step_s) d = i2.p.sub(i1.p) ex, ey = self.error ex, sx = modf(d.x * self.steps_per_unit + ex) ey, sy = modf(d.y * self.steps_per_unit + ey) self.error = ex, ey self.stepper_move(step_ms, int(sx), int(sy)) t += step_s self.wait() def run_path(self, path): planner = self.make_planner() plan = planner.plan(path) self.run_plan(plan) def run_drawing(self, drawing, progress=True): self.pen_up() position = (0, 0) bar = Bar(enabled=progress) for path in bar(drawing.paths): self.run_path([position, path[0]]) self.pen_down() self.run_path(path) self.pen_up() position = path[-1] self.run_path([position, (0, 0)]) def plan_drawing(self, drawing): result = [] planner = self.make_planner() for path in drawing.all_paths: result.append(planner.plan(path)) return result # pen functions def pen_up(self): delta = abs(self.pen_up_position - self.pen_down_position) duration = int(1000 * delta / self.pen_up_speed) delay = max(0, duration + self.pen_up_delay) return self.command('SP', 1, delay) def pen_down(self): delta = abs(self.pen_up_position - self.pen_down_position) duration = int(1000 * delta / self.pen_down_speed) delay = max(0, duration + self.pen_down_delay) return self.command('SP', 0, delay)
class GPS_Interface(Thread): _NMEA_VALID_COMMANDS = ["GPGLL", "GPRMC", "GPTRF", "GPVBW", "GPVTG"] KNOTS_TO_KM = 1.852 RADIUS_OF_EARTH = 6371e3 def __init__(self, loc: str = '/dev/ttyACM0', baud: int = 4800): self.__gps_serial = Serial() self.__gps_serial.port = loc self.__gps_serial.baudrate = baud super(GPS_Interface, self).__init__() self._latitude = 0 self._longitude = 0 self._altitude = 0 self._ground_speed = 0 self._latitude_rel = 0 self._longitude_rel = 0 self._gps_time = 0 self._prev_gps_time = 0 self.__running = False self.error_flag = False self._new_data_flag = False self._current_time = 0 self._prev_time = 0 self._sample_rate = 0 atexit.register(self.exit_func) # Control Functions def stop_thread(self): self.__running = False def exit_func(self): self.__gps_serial.close() def __do_new_data_flag(self): self._current_time = perf_counter() if self._gps_time == self._prev_gps_time: self._new_data_flag = False return if self.position == [0.0, 0.0] or self.position == [ float("NaN"), float("NaN") ]: # not initialized or started self._new_data_flag = False return self._sample_rate = self._current_time - self._prev_time self._prev_time = self._current_time self._prev_gps_time = self._gps_time self._new_data_flag = True # parse functions def __parse_time(self, _time: str): time_string = list(_time) if time_string.__len__() >= 9: hour = str(time_string[0] + time_string[1]) minute = str(time_string[2] + time_string[3]) second = str(time_string[4] + time_string[5]) self._gps_time = datetime(year=datetime.now().year, month=datetime.now().month, day=datetime.now().day, hour=int(hour), minute=int(minute), second=int(second)) def __parse_GGA(self, data: list): self.__parse_time(data[0]) self._latitude = self.convert_min_to_decimal(data[1], data[2]) if ( data[1] != "" or data[2] != "") else float("NaN") self._longitude = self.convert_min_to_decimal(data[3], data[4]) if ( data[3] != "" or data[4] != "") else float("NaN") self._altitude = float(data[8]) if (data[8] != "") else float("NaN") self.__do_new_data_flag() def __parse_GGL(self, data: list): self.__parse_time(data[4]) self._latitude = self.convert_min_to_decimal(data[0], data[1]) self._longitude = self.convert_min_to_decimal(data[2], data[3]) self.__do_new_data_flag() def __parse_RMA(self, data: list): if data[0] == 'A': self._latitude = self.convert_min_to_decimal(data[1], data[2]) if ( data[1] != "" or data[2] != "") else float("NaN") self._longitude = self.convert_min_to_decimal( data[3], data[4]) if (data[3] != "" or data[4] != "") else float("NaN") self._ground_speed = float( data[7]) * GPS_Interface.KNOTS_TO_KM if ( data[7] != "") else float("NaN") self.__do_new_data_flag() def __parse_RMC(self, data: list): self.__parse_time(data[0]) self._latitude = self.convert_min_to_decimal(data[2], data[3]) if ( data[2] != "" or data[3] != "") else float("NaN") self._longitude = self.convert_min_to_decimal(data[4], data[5]) if ( data[4] != "" or data[5] != "") else float("NaN") self._ground_speed = float(data[6]) * GPS_Interface.KNOTS_TO_KM if ( data[6] != "") else float("NaN") self.__do_new_data_flag() def __parse_TRF(self, data: list): self.__parse_time(data[0]) self._latitude = self.convert_min_to_decimal(data[2], data[3]) if ( data[2] != "" or data[3] != "") else float("NaN") self._longitude = self.convert_min_to_decimal(data[4], data[5]) if ( data[4] != "" or data[5] != "") else float("NaN") self.__do_new_data_flag() # run funtions def start(self) -> None: super(GPS_Interface, self).start() self.__running = True self._new_data_flag = False def run(self) -> None: self.__gps_serial.open() for i in range(0, 7): # first handful of lines are bs self.__gps_serial.readline() while self.__running: data = str(self.__gps_serial.readline()).replace("'", "").replace( "b", "").split(",") command = data.pop(0) if data[0] != "": if command == "$GPGGA": self.__parse_GGA(data) elif command == "$GPGLL": self.__parse_GGL(data) elif command == "$GPRMC": self.__parse_RMC(data) elif command == "$GPTRF": self.__parse_TRF(data) else: self.error_flag = True self.__gps_serial.close() # get functions @property def running(self): return self.__running @property def position(self) -> list: self._new_data_flag = False return [self._latitude, self._longitude] @property def latitude(self) -> float: return self._latitude @property def longitude(self) -> float: return self._longitude @property def new_data_flag(self): return self._new_data_flag @property def ground_speed(self) -> float: return self._ground_speed @property def sample_rate(self) -> float: return self._sample_rate @property def gps_time(self): return self._gps_time # math functions @staticmethod def haversin(start: list, goal: list) -> float: lat1, lon1, lat2, lon2 = map(radians, [start[0], start[1], goal[0], goal[1]]) delta_lat = lat1 - lat2 delta_lon = lon1 - lon2 a = sin( delta_lat / 2)**2 + cos(lat1) * cos(lat2) * sin(delta_lon / 2)**2 c = 2 * asin(sqrt(a)) return c * GPS_Interface.RADIUS_OF_EARTH @staticmethod def bearing_to(start: list, goal: list) -> float: lat, lon = map(radians, [goal[0] - start[0], goal[1] - start[1]]) return atan(lon / lat) # conversion functions @staticmethod def convert_min_to_decimal(position: str, direction: chr) -> float: try: temp = position.split(".") before = list(temp[0]) if before[0] == '0': before.remove('0') degrees = float(before[0] + before[1]) minutes = float(before[2] + before[3] + ',' + temp[1]) except: degrees = 0 minutes = 0 return float("NaN") return (1 if (direction == 'N' or direction == 'E') else -1) * (degrees + (minutes / 60))
class PozyxSerial(PozyxLib): """ PozyxSerial =========== This class provides the Pozyx Serial interface, and opens and locks the serial port to use with Pozyx. All functionality from PozyxLib and PozyxCore is included. Args: port: string name of the serial port. On UNIX this will be '/dev/ttyACMX', on Windows this will be 'COMX', with X a random number. Kwargs: baudrate: the baudrate of the serial port. Default value is 115200. timeout: timeout for the serial port communication in seconds. Default is 0.1s or 100ms. print_output: boolean for printing the serial exchanges, mainly for debugging purposes debug_trace: boolean for printing the trace on bad serial init (DEPRECATED) show_trace: boolean for printing the trace on bad serial init (DEPRECATED) suppress_warnings: boolean for suppressing warnings in the Pozyx use, usage not recommended Example usage: >>> pozyx = PozyxSerial('COMX') # Windows >>> pozyx = PozyxSerial('/dev/ttyACMX', print_output=True) # Linux and OSX. Also puts debug output on. Finding the serial port ======================= Finding the serial port can be easily done with the following code: >>> import serial.tools.list_ports >>> print serial.tools.list_ports.comports()[0] Putting one and two together, automating the correct port selection with one Pozyx attached: >>> import serial.tools.list_ports >>> pozyx = PozyxSerial(serial.tools.list_ports.comports()[0]) """ # \addtogroup core # @{ def __init__(self, port, baudrate=115200, timeout=0.1, write_timeout=0.1, print_output=False, debug_trace=False, show_trace=False, suppress_warnings=False): """Initializes the PozyxSerial object. See above for details.""" self.print_output = print_output if debug_trace is True or show_trace is True: if not suppress_warnings: warn( "debug_trace or show_trace are on their way out, exceptions of the type PozyxException are now raised.", DeprecationWarning) self.suppress_warnings = suppress_warnings self.connectToPozyx(port, baudrate, timeout, write_timeout) sleep(0.25) self.validatePozyx() def connectToPozyx(self, port, baudrate, timeout, write_timeout): """Attempts to connect to the Pozyx via a serial connection""" self.port = port self.baudrate = baudrate self.timeout = timeout self.write_timeout = write_timeout try: if is_correct_pyserial_version(): if not is_pozyx(port) and not self.suppress_warnings: warn( "The passed device is not a recognized Pozyx device, is %s" % get_port_object(port).description, stacklevel=2) self.ser = Serial(port=port, baudrate=baudrate, timeout=timeout, write_timeout=write_timeout) else: if not self.suppress_warnings: warn( "PySerial version %s not supported, please upgrade to 3.0 or (prefferably) higher" % PYSERIAL_VERSION, stacklevel=0) self.ser = Serial(port=port, baudrate=baudrate, timeout=timeout, writeTimeout=write_timeout) except SerialException as exc: raise PozyxConnectionError( "Wrong or busy serial port, SerialException: {}".format( str(exc))) except Exception as exc: raise PozyxConnectionError( "Couldn't connect to Pozyx, {}: {}".format( exc.__class__.__name__, str(exc))) def validatePozyx(self): """Validates whether the connected device is indeed a Pozyx device""" whoami = SingleRegister() if self.getWhoAmI(whoami) != POZYX_SUCCESS: raise PozyxConnectionError( "Connected to device, but couldn't read serial data. Is it a Pozyx?" ) if whoami.value != 0x43: raise PozyxConnectionError( "POZYX_WHO_AM_I returned 0x%0.2x, something is wrong with Pozyx." % whoami.value) # @} def regWrite(self, address, data): """ Writes data to the Pozyx registers, starting at a register address, if registers are writable. Args: address: Register address to start writing at. data: Data to write to the Pozyx registers. Has to be ByteStructure-derived object. Returns: POZYX_SUCCESS, POZYX_FAILURE """ data.load_hex_string() index = 0 runs = int(data.byte_size / MAX_SERIAL_SIZE) for i in range(runs): s = 'W,%0.2x,%s\r' % (address + index, data.byte_data[2 * index:2 * (index + MAX_SERIAL_SIZE)]) index += MAX_SERIAL_SIZE try: self.ser.write(s.encode()) except SerialException: return POZYX_FAILURE # delay(POZYX_DELAY_LOCAL_WRITE) s = 'W,%0.2x,%s\r' % (address + index, data.byte_data[2 * index:]) try: self.ser.write(s.encode()) except SerialException: return POZYX_FAILURE return POZYX_SUCCESS def serialExchange(self, s): """ Auxiliary. Performs a serial write to and read from the Pozyx. Args: s: Serial message to send to the Pozyx Returns: Serial message the Pozyx returns, stripped from 'D,' at its start and NL+CR at the end. """ self.ser.write(s.encode()) response = self.ser.readline().decode() if self.print_output: print('The response to %s is %s.' % (s.strip(), response.strip())) if len(response) == 0: raise SerialException if response[0] == 'D': return response[2:-2] raise SerialException def regRead(self, address, data): """ Reads data from the Pozyx registers, starting at a register address, if registers are readable. Args: address: Register address to start writing at. data: Data to write to the Pozyx registers. Has to be ByteStructure-derived object. Returns: POZYX_SUCCESS, POZYX_FAILURE """ runs = int(data.byte_size / MAX_SERIAL_SIZE) r = '' for i in range(runs): s = 'R,%0.2x,%i\r' % (address + i * MAX_SERIAL_SIZE, MAX_SERIAL_SIZE) try: r += self.serialExchange(s) except SerialException: return POZYX_FAILURE s = 'R,%0.2x,%i\r' % (address + runs * MAX_SERIAL_SIZE, data.byte_size - runs * MAX_SERIAL_SIZE) try: r += self.serialExchange(s) except SerialException: return POZYX_FAILURE data.load_bytes(r) return POZYX_SUCCESS def regFunction(self, address, params, data): """ Performs a register function on the Pozyx, if the address is a register function. Args: address: Register function address of function to perform. params: Parameters for the register function. Has to be ByteStructure-derived object. data: Container for the data the register function returns. Has to be ByteStructure-derived object. Returns: POZYX_SUCCESS, POZYX_FAILURE """ params.load_hex_string() s = 'F,%0.2x,%s,%i\r' % (address, params.byte_data, data.byte_size + 1) try: r = self.serialExchange(s) except SerialException: return POZYX_FAILURE if len(data) > 0: data.load_bytes(r[2:]) return int(r[0:2], 16) def waitForFlag(self, interrupt_flag, timeout_s, interrupt=None): """ Waits for a certain interrupt flag to be triggered, indicating that that type of interrupt occured. Args: interrupt_flag: Flag indicating interrupt type. timeout_s: time in seconds that POZYX_INT_STATUS will be checked for the flag before returning POZYX_TIMEOUT. Kwargs: interrupt: Container for the POZYX_INT_STATUS data Returns: POZYX_SUCCESS, POZYX_FAILURE, POZYX_TIMEOUT """ if interrupt is None: interrupt = SingleRegister() return self.waitForFlagSafe(interrupt_flag, timeout_s, interrupt)
wiederversuch = True while wiederversuch: try: device.write(nachricht.encode('ascii')) print('Laptop: \t', nachricht) # print(nachricht[0]) # print(nachricht[1]) # print(nachricht[2]) '''Wenn die GUI Anfrage mit 30 beginnt, Antwort vom Arduino abwarten und an die GUI leiten''' if nachricht[0] == '1': sleep(2) if nachricht[0] == '3' and nachricht[1] == '0': # print('warte auf Antwort') sleep(1 / 200) antwort_raw = device.readline() # antwort = antwort_raw.decode() antwort = str(antwort_raw[:-2].decode()) antwort += ' ' antwort = '{0:{1}<26}'.format(antwort, '0') # antwort += ' ' # for i in range(len(antwort), 29): # antwort += '0' # antwort.ljust(100, '0') print('Antwort: \t', antwort) # device.flushInput() komm.send(antwort.encode('ascii')) if nachricht[0] == '5':
def poll(ser: serial.Serial): while True: i: bytes = ser.readline() print(i.decode())
def main(): port1 = PORT1 port2 = PORT2 if len(argv) > 1: port1 = argv[1] if len(argv) > 2: port2 = argv[2] # Open serial connections ser1 = Serial(port=port1, baudrate=BAUDRATE, timeout=TIMEOUT) if not ser1.is_open: ser1.open() print(ser1) ser2 = Serial(port=port2, baudrate=BAUDRATE, timeout=TIMEOUT) if not ser2.is_open: ser2.open() print(ser2) # Open messageboard # mb = messageboard.MessageBoard("tag") # print(mb) cmd = "location_data" floor = 2 status = "testing" name_to_point = NAME_TO_POINT def signal_handler(*args): print("keyboard interrupt") ser1.close() ser2.close() exit() # set up signal handler to stop while loop signal.signal(signal.SIGINT, signal_handler) clearSer(ser1) clearSer(ser2) # write les and send enter command to stop tag # ser.write(CLEAR) ser1.write(LES) ser1.write(ENTER) ser2.write(LES) ser2.write(ENTER) # clear starting nonsense ser1.readline() ser1.read(5) ser2.readline() ser2.read(5) while (True): now = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) lines = {} line1 = readLine(ser1) if len(line1) < 1: # print("no line - 1") pass else: # print("ACM0") lines[1] = line1 line = line1 line2 = readLine(ser2) if len(line2) < 1: # print("no line - 2") pass else: # print("ACM1") lines[2] = line2 line = line2 if len(lines) != 0: print(lines) angle = 0 if len(lines) == 0: continue elif len(lines) == 1: # print('only 1 line') # get x, y coords dists = line anch_pred, prediction = get_location(dists) x, y = prediction else: # get x, y coords dists1 = line1 anch_pred1, prediction1 = get_location(dists1) x1, y1 = prediction1 dists2 = line2 anch_pred2, prediction2 = get_location(dists2) x2, y2 = prediction2 # get ave position x = (x1 + x2) / 2 y = (y1 + y2) / 2 x_m = PIX_TO_M_X * x y_m = PIX_TO_M_Y * y # Check within bounds # if x > 87 and y > 87: # continue # get angle angle = get_angle(x1, y1, x2, y2) # print((prediction1, prediction2, angle)) msg = { "x_pix_global": x, "y_pix_global": y, "x_meter_global": x_m, "y_meter_global": y_m, "floor": floor, "status": status, "angle": angle } mb.postMsg(cmd, msg) ser.close()
from serial import Serial import time ser = Serial('/dev/ttyACM0', 9600) print('opened ' + ser.name) time.sleep(1) ser.setDTR(value=0) time.sleep(1) ser.write('10000') print(ser.readline().strip()) print(ser.readline().strip())
from threading import Thread from time import sleep from serial import Serial import requests import urllib2 import time # todo Enter url + endpoint to POST temperature data. url = '' ser = Serial('/dev/ttyACM0', 9600) while True: temperatureC = str(ser.readline()).strip() r = requests.post(url + temperatureC) print temperatureC time.sleep(5)
ser = Serial(port='/dev/ttyUSB1', baudrate=115200, timeout=None) def adddata(data): '''a function to add the data to the text file''' date = time.time() h = str(data) + ',' + str(date) + '\n' fh = open('output_minized.txt', 'a') fh.write(h) fh.close while 1: ''' infinit loop''' while (ser.inWaiting() == 0): '''wait for the data from serial''' time.sleep(0.2) # print(".") #read and decode the data''' line = ser.readline().decode('utf-8') line = line.rstrip() count = line.count(",") #parse if theres enough values if (count == 6): print(line) '''add the data to the txt file''' adddata(line) else: print("The count is:", count)
import time #import enaml from serial import Serial s = Serial('/dev/ttyACM0', 9600) # open serial port ACK = 0 while True: #x = input() x = "-75.00/10.00/10.00/10.00/10.00" s.write(bytes(x, 'UTF-8')) print(str(s.readline())[2:-5]) time.sleep(5) #x = "-50.00/-10.00/-10.00/-10.00/-10.00" #s.write(bytes(x, 'UTF-8')) #print(str(s.readline())[2:-5]) #time.sleep(3)
# Input pin for the digital signal will be picked here Digital_PIN = 29 GPIO.setup(Digital_PIN, GPIO.IN, pull_up_down = GPIO.PUD_OFF) ############################################################################################################# # ######## # main program loop # ######## # The program reads the current value of the input pin # and shows it at the terminal try: while True: val = ser.readline() if 'J5' in val: # Output at the terminal if GPIO.input(Digital_PIN) == False: print ("Analog voltage value:", val,"mV, ","extreme value: not reached") else: print ("Analog voltage value:", val, "mV, ", "extreme value: reached") print ("---------------------------------------") sleep(delayTime) except KeyboardInterrupt: GPIO.cleanup()
############## ## Script listens to serial port and writes contents into a file ############## ## requires pySerial to be installed ## pip3 install pyserial from serial import Serial import datetime import time serial_port = '/dev/ttyACM0' #'COM7' # /dev/cu.usbmodem1411' #'/dev/cu.usbmodem1421'; #/dev/ttyACM0'; baud_rate = 9600 #In arduino, Serial.begin(baud_rate) write_to_file_path = "output_" + str(datetime.datetime.now()) + ".txt" #write_to_file_path = "output_" + str( int(time.time()) ) + ".txt"; output_file = open(write_to_file_path, "w+", buffering=1) ser = Serial(serial_port, baud_rate) while True: line = ser.readline() line = line.decode( "utf-8") #ser.readline returns a binary, convert to string now = datetime.datetime.now() print(str(now) + " " + line) output_file.write(line) #str(now)+line);
#!/usr/bin/env python3 from serial import Serial ''' Run this in shell first: $ stty -F /dev/ttyUSB0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts ''' s = Serial('/dev/ttyUSB0', 9600) for i in range(180): s.write(bytes([i])) s.flush() print(s.readline().rstrip()) s.close()
ser1 = Serial('COM7', 9600) ser2 = Serial('COM10', 9600) cred = credentials.Certificate( "spam-85498-firebase-adminsdk-wsavj-a18faa0fe2.json") # 파이어베이스 연결용 비공개 키 firebase_admin.initialize_app(cred) db = firestore.client() # Firestore 객체 생성 Device_id = "12345" # 각 기기별 고유번호, User_info 밑에 저장될 데이터 doc_ref = db.collection('Device_data').document(Device_id) # Firestore에서 Device_data 컬렉션 내부에 Device_id를 이름으로 현재 데이터값 갱신 while ser1.readable() or ser2.readable(): now = datetime.now() if ser1.readable(): res1 = ser1.readline() res1 = str(res1) ref1 = list(res1.split(',')) ref1[0] = ref1[0][-1] ref1[3] = ref1[3][:-6] # print(ref1) if ser2.readable(): now2 = datetime res2 = ser2.readline() res2 = str(res2) ref2 = list(res2.split(',')) ref2[0] = ref2[0][-1] ref2[3] = ref2[3][:-6] # print(ref2)
footSensorPin = 21 #7 for pi1 GPIO.setmode(GPIO.BCM) GPIO.setup(footSensorPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) counter = 0 while True: print("\033[2J\033[1;1H") #clear screen & home counter = counter + 1 print("COUNTER: %d" % (counter)) footActive = not GPIO.input(footSensorPin) if footActive: print("FOOT: ACTIVE\n") else: print("FOOT: NOT ACTIVE\n") send = bytes([255, 1, 128, 128, 128]) print("TX: ") print(send.hex()) print("\n ") serial.write(send) line = serial.readline() print("RX: ") print(line.hex()) print("\n") sleep(0.05)
class PrologixGPIB_Omicron(object): '''>>> import serial >>> ser = serial.Serial('/dev/ttyUSB0') # open serial port''' def __init__(self, port, address=1, debug=False): self.port = port self.ser = Serial(port, timeout=1.0, writeTimeout = 0) self.debug = debug self.write_config_gpib() self.set_address(address) if self.debug: self.read_print_config_gpib() def close(self): return self.ser.close() def set_address(self, address=1): cmd_str = '++addr {:d}\n'.format(address).encode() #if self.debug: print("prologix set_addr", repr(cmd_str)) self.ser.write(cmd_str) def write_config_gpib(self): '''configure prologix usb GPIB for Omicron''' ser = self.ser #no automatic read after write ser.write(b"++auto 0\n") #assert gpib EOI after write ser.write(b"++eoi 1\n") #no CR, LF after write ser.write(b"++eos 3\n") #be controller, send to omicron ser.write(b"++mode 1\n") #no CR, LF with read ser.write(b"++eos 3\n") def read_print_config_gpib(self): ''' get prologix gpib configuration''' self.ser.write(b'++ver\n') print( self.ser.readline().decode()) self.ser.write(b"++auto\n") print( 'auto '+self.ser.readline().decode()) self.ser.write(b"++eoi\n") print( 'eoi '+self.ser.readline().decode()) self.ser.write(b"++eos\n") print( 'eos '+self.ser.readline().decode()) self.ser.write(b"++mode\n") print( 'mode '+self.ser.readline().decode()) self.ser.write(b"++addr\n") print( 'address '+self.ser.readline().decode()) def binary_escape_gpib_string( self, s ): ''' prevent binary data from being interpreted as prologix configuration commands, add lf''' #print('binary_escape_gpib_string', repr(s)) esc = bytes([27]) lf = b'\n' cr = bytes([0xd]) plus = b'+' out = bytearray() for c in s: if bytes([c]) in (esc, lf, cr, plus ): out += esc out.append(c) out += lf return out def write(self, s): #s = s.encode() #print('write', repr(s)) out = self.binary_escape_gpib_string(s) if self.debug: str = "prologix gpib \t" + " ".join(["{:02x}".format(c) for c in s]) print(str) #print("\t", " ".join(["{:08b}".format(c) for c in s])) return self.ser.write(out)
for x in elements: #sys.stdout.write(chr(x)) #sys.stdout.flush() serial.write(chr(x)) except Exception: pass # try to read value from Arduino safe = True while safe: try: value = serial.readline().strip() value = int(value) safe = True except Exception: safe = False # value available and different from old one? if safe and value != oldvalue: # limit to 0..127 value = max( min( int(value), 127 ), 0 ) # update cached value oldvalue = value
class USBPrinterOutputDevice(PrinterOutputDevice): def __init__(self, serial_port: str, baud_rate: Optional[int] = None) -> None: super().__init__(serial_port, connection_type=ConnectionType.UsbConnection) self.setName(catalog.i18nc("@item:inmenu", "USB printing")) self.setShortDescription( catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print via USB")) self.setDescription(catalog.i18nc("@info:tooltip", "Print via USB")) self.setIconName("print") self._serial = None # type: Optional[Serial] self._serial_port = serial_port self._address = serial_port self._timeout = 3 # List of gcode lines to be printed self._gcode = [] # type: List[str] self._gcode_position = 0 self._use_auto_detect = True self._baud_rate = baud_rate self._all_baud_rates = [ 115200, 250000, 500000, 230400, 57600, 38400, 19200, 9600 ] # Instead of using a timer, we really need the update to be as a thread, as reading from serial can block. self._update_thread = Thread(target=self._update, daemon=True) self._last_temperature_request = None # type: Optional[int] self._firmware_idle_count = 0 self._is_printing = False # A print is being sent. ## Set when print is started in order to check running time. self._print_start_time = None # type: Optional[float] self._print_estimated_time = None # type: Optional[int] self._accepts_commands = True self._paused = False self._printer_busy = False # When printer is preheating and waiting (M190/M109), or when waiting for action on the printer self.setConnectionText( catalog.i18nc("@info:status", "Connected via USB")) # Queue for commands that need to be sent. self._command_queue = Queue() # type: Queue # Event to indicate that an "ok" was received from the printer after sending a command. self._command_received = Event() self._command_received.set() self._firmware_name_requested = False self._firmware_updater = AvrFirmwareUpdater(self) self._monitor_view_qml_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "MonitorItem.qml") CuraApplication.getInstance().getOnExitCallbackManager().addCallback( self._checkActivePrintingUponAppExit) # This is a callback function that checks if there is any printing in progress via USB when the application tries # to exit. If so, it will show a confirmation before def _checkActivePrintingUponAppExit(self) -> None: application = CuraApplication.getInstance() if not self._is_printing: # This USB printer is not printing, so we have nothing to do. Call the next callback if exists. application.triggerNextExitCheck() return application.setConfirmExitDialogCallback( self._onConfirmExitDialogResult) application.showConfirmExitDialog.emit( catalog.i18nc( "@label", "A USB print is in progress, closing Cura will stop this print. Are you sure?" )) def _onConfirmExitDialogResult(self, result: bool) -> None: if result: application = CuraApplication.getInstance() application.triggerNextExitCheck() ## Reset USB device settings # def resetDeviceSettings(self) -> None: self._firmware_name = None ## Request the current scene to be sent to a USB-connected printer. # # \param nodes A collection of scene nodes to send. This is ignored. # \param file_name A suggestion for a file name to write. # \param filter_by_machine Whether to filter MIME types by machine. This # is ignored. # \param kwargs Keyword arguments. def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, limit_mimetypes: bool = False, file_handler: Optional["FileHandler"] = None, filter_by_machine: bool = False, **kwargs) -> None: if self._is_printing: message = Message(text=catalog.i18nc( "@message", "A print is still in progress. Cura cannot start another print via USB until the previous print has completed." ), title=catalog.i18nc("@message", "Print in Progress")) message.show() return # Already printing self.writeStarted.emit(self) # cancel any ongoing preheat timer before starting a print controller = cast(GenericOutputController, self._printers[0].getController()) controller.stopPreheatTimers() CuraApplication.getInstance().getController().setActiveStage( "MonitorStage") #Find the g-code to print. gcode_textio = StringIO() gcode_writer = cast( MeshWriter, PluginRegistry.getInstance().getPluginObject("GCodeWriter")) success = gcode_writer.write(gcode_textio, None) if not success: return self._printGCode(gcode_textio.getvalue()) ## Start a print based on a g-code. # \param gcode The g-code to print. def _printGCode(self, gcode: str): self._gcode.clear() self._paused = False self._gcode.extend(gcode.split("\n")) # Reset line number. If this is not done, first line is sometimes ignored self._gcode.insert(0, "M110") self._gcode_position = 0 self._print_start_time = time() self._print_estimated_time = int(CuraApplication.getInstance( ).getPrintInformation().currentPrintTime.getDisplayString( DurationFormat.Format.Seconds)) for i in range( 0, 4): # Push first 4 entries before accepting other inputs self._sendNextGcodeLine() self._is_printing = True self.writeFinished.emit(self) def _autoDetectFinished(self, job: AutoDetectBaudJob): result = job.getResult() if result is not None: self.setBaudRate(result) self.connect() # Try to connect (actually create serial, etc) def setBaudRate(self, baud_rate: int): if baud_rate not in self._all_baud_rates: Logger.log( "w", "Not updating baudrate to {baud_rate} as it's an unknown baudrate" .format(baud_rate=baud_rate)) return self._baud_rate = baud_rate def connect(self): self._firmware_name = None # after each connection ensure that the firmware name is removed if self._baud_rate is None: if self._use_auto_detect: auto_detect_job = AutoDetectBaudJob(self._serial_port) auto_detect_job.start() auto_detect_job.finished.connect(self._autoDetectFinished) return if self._serial is None: try: self._serial = Serial(str(self._serial_port), self._baud_rate, timeout=self._timeout, writeTimeout=self._timeout) except SerialException: Logger.log( "w", "An exception occurred while trying to create serial connection" ) return CuraApplication.getInstance().globalContainerStackChanged.connect( self._onGlobalContainerStackChanged) self._onGlobalContainerStackChanged() self.setConnectionState(ConnectionState.Connected) self._update_thread.start() def _onGlobalContainerStackChanged(self): container_stack = CuraApplication.getInstance( ).getGlobalContainerStack() num_extruders = container_stack.getProperty("machine_extruder_count", "value") # Ensure that a printer is created. controller = GenericOutputController(self) controller.setCanUpdateFirmware(True) self._printers = [ PrinterOutputModel(output_controller=controller, number_of_extruders=num_extruders) ] self._printers[0].updateName(container_stack.getName()) def close(self): super().close() if self._serial is not None: self._serial.close() # Re-create the thread so it can be started again later. self._update_thread = Thread(target=self._update, daemon=True) self._serial = None ## Send a command to printer. def sendCommand(self, command: Union[str, bytes]): if not self._command_received.is_set(): self._command_queue.put(command) else: self._sendCommand(command) def _sendCommand(self, command: Union[str, bytes]): if self._serial is None or self._connection_state != ConnectionState.Connected: return new_command = cast(bytes, command) if type(command) is bytes else cast( str, command).encode() # type: bytes if not new_command.endswith(b"\n"): new_command += b"\n" try: self._command_received.clear() self._serial.write(new_command) except SerialTimeoutException: Logger.log("w", "Timeout when sending command to printer via USB.") self._command_received.set() except SerialException: Logger.logException( "w", "An unexpected exception occurred while writing to the serial." ) self.setConnectionState(ConnectionState.Error) def _update(self): while self._connection_state == ConnectionState.Connected and self._serial is not None: try: line = self._serial.readline() except: continue if not self._firmware_name_requested: self._firmware_name_requested = True self.sendCommand("M115") if b"FIRMWARE_NAME:" in line: self._setFirmwareName(line) if self._last_temperature_request is None or time( ) > self._last_temperature_request + self._timeout: # Timeout, or no request has been sent at all. if not self._printer_busy: # Don't flood the printer with temperature requests while it is busy self.sendCommand("M105") self._last_temperature_request = time() if re.search( b"[B|T\d*]: ?\d+\.?\d*", line ): # Temperature message. 'T:' for extruder and 'B:' for bed extruder_temperature_matches = re.findall( b"T(\d*): ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line) # Update all temperature values matched_extruder_nrs = [] for match in extruder_temperature_matches: extruder_nr = 0 if match[0] != b"": extruder_nr = int(match[0]) if extruder_nr in matched_extruder_nrs: continue matched_extruder_nrs.append(extruder_nr) if extruder_nr >= len(self._printers[0].extruders): Logger.log( "w", "Printer reports more temperatures than the number of configured extruders" ) continue extruder = self._printers[0].extruders[extruder_nr] if match[1]: extruder.updateHotendTemperature(float(match[1])) if match[2]: extruder.updateTargetHotendTemperature(float(match[2])) bed_temperature_matches = re.findall( b"B: ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line) if bed_temperature_matches: match = bed_temperature_matches[0] if match[0]: self._printers[0].updateBedTemperature(float(match[0])) if match[1]: self._printers[0].updateTargetBedTemperature( float(match[1])) if line == b"": # An empty line means that the firmware is idle # Multiple empty lines probably means that the firmware and Cura are waiting # for eachother due to a missed "ok", so we keep track of empty lines self._firmware_idle_count += 1 else: self._firmware_idle_count = 0 if line.startswith(b"ok") or self._firmware_idle_count > 1: self._printer_busy = False self._command_received.set() if not self._command_queue.empty(): self._sendCommand(self._command_queue.get()) elif self._is_printing: if self._paused: pass # Nothing to do! else: self._sendNextGcodeLine() if line.startswith(b"echo:busy:"): self._printer_busy = True if self._is_printing: if line.startswith(b'!!'): Logger.log( 'e', "Printer signals fatal error. Cancelling print. {}". format(line)) self.cancelPrint() elif line.lower().startswith(b"resend") or line.startswith( b"rs"): # A resend can be requested either by Resend, resend or rs. try: self._gcode_position = int( line.replace(b"N:", b" ").replace(b"N", b" ").replace( b":", b" ").split()[-1]) except: if line.startswith(b"rs"): # In some cases of the RS command it needs to be handled differently. self._gcode_position = int(line.split()[1]) def _setFirmwareName(self, name): new_name = re.findall(r"FIRMWARE_NAME:(.*);", str(name)) if new_name: self._firmware_name = new_name[0] Logger.log("i", "USB output device Firmware name: %s", self._firmware_name) else: self._firmware_name = "Unknown" Logger.log("i", "Unknown USB output device Firmware name: %s", str(name)) def getFirmwareName(self): return self._firmware_name def pausePrint(self): self._paused = True def resumePrint(self): self._paused = False self._sendNextGcodeLine( ) #Send one line of g-code next so that we'll trigger an "ok" response loop even if we're not polling temperatures. def cancelPrint(self): self._gcode_position = 0 self._gcode.clear() self._printers[0].updateActivePrintJob(None) self._is_printing = False self._paused = False # Turn off temperatures, fan and steppers self._sendCommand("M140 S0") self._sendCommand("M104 S0") self._sendCommand("M107") # Home XY to prevent nozzle resting on aborted print # Don't home bed because it may crash the printhead into the print on printers that home on the bottom self.printers[0].homeHead() self._sendCommand("M84") def _sendNextGcodeLine(self): if self._gcode_position >= len(self._gcode): self._printers[0].updateActivePrintJob(None) self._is_printing = False return line = self._gcode[self._gcode_position] if ";" in line: line = line[:line.find(";")] line = line.strip() # Don't send empty lines. But we do have to send something, so send M105 instead. # Don't send the M0 or M1 to the machine, as M0 and M1 are handled as an LCD menu pause. if line == "" or line == "M0" or line == "M1": line = "M105" checksum = functools.reduce( lambda x, y: x ^ y, map(ord, "N%d%s" % (self._gcode_position, line))) self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum)) print_job = self._printers[0].activePrintJob try: progress = self._gcode_position / len(self._gcode) except ZeroDivisionError: # There is nothing to send! if print_job is not None: print_job.updateState("error") return elapsed_time = int(time() - self._print_start_time) if print_job is None: controller = GenericOutputController(self) controller.setCanUpdateFirmware(True) print_job = PrintJobOutputModel(output_controller=controller, name=CuraApplication.getInstance(). getPrintInformation().jobName) print_job.updateState("printing") self._printers[0].updateActivePrintJob(print_job) print_job.updateTimeElapsed(elapsed_time) estimated_time = self._print_estimated_time if progress > .1: estimated_time = self._print_estimated_time * ( 1 - progress) + elapsed_time print_job.updateTimeTotal(estimated_time) self._gcode_position += 1
class printcore(): def __init__(self, port=None, baud=None, dtr=None): """Initializes a printcore instance. Pass the port and baud rate to connect immediately""" self.baud = None self.dtr = None self.port = None self.analyzer = gcoder.GCode() # Serial instance connected to the printer, should be None when # disconnected self.printer = None # clear to send, enabled after responses # FIXME: should probably be changed to a sliding window approach self.clear = 0 # The printer has responded to the initial command and is active self.online = False # is a print currently running, true if printing, false if paused self.printing = False self.mainqueue = None self.priqueue = Queue(0) self.queueindex = 0 self.lineno = 0 self.resendfrom = -1 self.paused = False self.sentlines = {} self.log = deque(maxlen=10000) self.sent = [] self.writefailures = 0 self.tempcb = None # impl (wholeline) self.recvcb = None # impl (wholeline) self.sendcb = None # impl (wholeline) self.preprintsendcb = None # impl (wholeline) self.printsendcb = None # impl (wholeline) self.layerchangecb = None # impl (wholeline) self.errorcb = None # impl (wholeline) self.startcb = None # impl () self.endcb = None # impl () self.onlinecb = None # impl () self.loud = False # emit sent and received lines to terminal self.tcp_streaming_mode = False self.greetings = ['start', 'Grbl '] self.wait = 0 # default wait period for send(), send_now() self.read_thread = None self.stop_read_thread = False self.send_thread = None self.stop_send_thread = False self.print_thread = None self.readline_buf = [] self.selector = None self.event_handler = PRINTCORE_HANDLER # Not all platforms need to do this parity workaround, and some drivers # don't support it. Limit it to platforms that actually require it # here to avoid doing redundant work elsewhere and potentially breaking # things. self.needs_parity_workaround = platform.system( ) == "linux" and os.path.exists("/etc/debian") for handler in self.event_handler: try: handler.on_init() except: logging.error(traceback.format_exc()) if port is not None and baud is not None: self.connect(port, baud) self.xy_feedrate = None self.z_feedrate = None def addEventHandler(self, handler): ''' Adds an event handler. @param handler: The handler to be added. ''' self.event_handler.append(handler) def logError(self, error): for handler in self.event_handler: try: handler.on_error(error) except: logging.error(traceback.format_exc()) if self.errorcb: try: self.errorcb(error) except: logging.error(traceback.format_exc()) else: logging.error(error) @locked def disconnect(self): """Disconnects from printer and pauses the print """ if self.printer: if self.read_thread: self.stop_read_thread = True if threading.current_thread() != self.read_thread: self.read_thread.join() self.read_thread = None if self.print_thread: self.printing = False self.print_thread.join() self._stop_sender() try: if self.selector is not None: self.selector.unregister(self.printer_tcp) self.selector.close() self.selector = None if self.printer_tcp is not None: self.printer_tcp.close() self.printer_tcp = None self.printer.close() except socket.error: logger.error(traceback.format_exc()) pass except OSError: logger.error(traceback.format_exc()) pass for handler in self.event_handler: try: handler.on_disconnect() except: logging.error(traceback.format_exc()) self.printer = None self.online = False self.printing = False @locked def connect(self, port=None, baud=None, dtr=None): """Set port and baudrate if given, then connect to printer """ if self.printer: self.disconnect() if port is not None: self.port = port if baud is not None: self.baud = baud if dtr is not None: self.dtr = dtr if self.port is not None and self.baud is not None: # Connect to socket if "port" is an IP, device if not host_regexp = re.compile( "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$" ) is_serial = True if ":" in self.port: bits = self.port.split(":") if len(bits) == 2: hostname = bits[0] try: port_number = int(bits[1]) if host_regexp.match( hostname) and 1 <= port_number <= 65535: is_serial = False except: pass self.writefailures = 0 if not is_serial: self.printer_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.printer_tcp.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.timeout = 0.25 self.printer_tcp.settimeout(1.0) try: self.printer_tcp.connect((hostname, port_number)) #a single read timeout raises OSError for all later reads #probably since python 3.5 #use non blocking instead self.printer_tcp.settimeout(0) self.printer = self.printer_tcp.makefile('rwb', buffering=0) self.selector = selectors.DefaultSelector() self.selector.register(self.printer_tcp, selectors.EVENT_READ) except socket.error as e: if (e.strerror is None): e.strerror = "" self.logError( _("Could not connect to %s:%s:") % (hostname, port_number) + "\n" + _("Socket error %s:") % e.errno + "\n" + e.strerror) self.printer = None self.printer_tcp = None return else: disable_hup(self.port) self.printer_tcp = None try: if self.needs_parity_workaround: self.printer = Serial(port=self.port, baudrate=self.baud, timeout=0.25, parity=PARITY_ODD) self.printer.close() self.printer.parity = PARITY_NONE else: self.printer = Serial(baudrate=self.baud, timeout=0.25, parity=PARITY_NONE) self.printer.port = self.port try: #this appears not to work on many platforms, so we're going to call it but not care if it fails self.printer.dtr = dtr except: #self.logError(_("Could not set DTR on this platform")) #not sure whether to output an error message pass self.printer.open() except SerialException as e: self.logError( _("Could not connect to %s at baudrate %s:") % (self.port, self.baud) + "\n" + _("Serial error: %s") % e) self.printer = None return except IOError as e: self.logError( _("Could not connect to %s at baudrate %s:") % (self.port, self.baud) + "\n" + _("IO error: %s") % e) self.printer = None return for handler in self.event_handler: try: handler.on_connect() except: logging.error(traceback.format_exc()) self.stop_read_thread = False self.read_thread = threading.Thread(target=self._listen, name='read thread') self.read_thread.start() self._start_sender() def reset(self): """Reset the printer """ if self.printer and not self.printer_tcp: self.printer.dtr = 1 time.sleep(0.2) self.printer.dtr = 0 def _readline_buf(self): "Try to readline from buffer" if len(self.readline_buf): chunk = self.readline_buf[-1] eol = chunk.find(b'\n') if eol >= 0: line = b''.join(self.readline_buf[:-1]) + chunk[:(eol + 1)] self.readline_buf = [] if eol + 1 < len(chunk): self.readline_buf.append(chunk[(eol + 1):]) return line return PR_AGAIN def _readline_nb(self): "Non blocking readline. Socket based files do not support non blocking or timeouting readline" if self.printer_tcp: line = self._readline_buf() if line: return line chunk_size = 256 while True: chunk = self.printer.read(chunk_size) if chunk is SYS_AGAIN and self.selector.select(self.timeout): chunk = self.printer.read(chunk_size) #print('_readline_nb chunk', chunk, type(chunk)) if chunk: self.readline_buf.append(chunk) line = self._readline_buf() if line: return line elif chunk is SYS_AGAIN: return PR_AGAIN else: #chunk == b'' means EOF line = b''.join(self.readline_buf) self.readline_buf = [] self.stop_read_thread = True return line if line else PR_EOF else: # serial port return self.printer.readline() def _readline(self): try: line_bytes = self._readline_nb() if line_bytes is PR_EOF: self.logError( _("Can't read from printer (disconnected?). line_bytes is None" )) return PR_EOF line = line_bytes.decode('utf-8') if len(line) > 1: self.log.append(line) for handler in self.event_handler: try: handler.on_recv(line) except: logging.error(traceback.format_exc()) if self.recvcb: try: self.recvcb(line) except: self.logError(traceback.format_exc()) if self.loud: logging.info("RECV: %s" % line.rstrip()) return line except UnicodeDecodeError: self.logError( _("Got rubbish reply from %s at baudrate %s:") % (self.port, self.baud) + "\n" + _("Maybe a bad baudrate?")) return None except SelectError as e: if 'Bad file descriptor' in e.args[1]: self.logError( _("Can't read from printer (disconnected?) (SelectError {0}): {1}" ).format(e.errno, decode_utf8(e.strerror))) return None else: self.logError( _("SelectError ({0}): {1}").format(e.errno, decode_utf8( e.strerror))) raise except SerialException as e: self.logError( _("Can't read from printer (disconnected?) (SerialException): {0}" ).format(decode_utf8(str(e)))) return None except socket.error as e: self.logError( _("Can't read from printer (disconnected?) (Socket error {0}): {1}" ).format(e.errno, decode_utf8(e.strerror))) return None except OSError as e: if e.errno == errno.EAGAIN: # Not a real error, no data was available return "" self.logError( _("Can't read from printer (disconnected?) (OS Error {0}): {1}" ).format(e.errno, e.strerror)) return None def _listen_can_continue(self): if self.printer_tcp: return not self.stop_read_thread and self.printer return (not self.stop_read_thread and self.printer and self.printer.is_open) def _listen_until_online(self): while not self.online and self._listen_can_continue(): self._send("M105") if self.writefailures >= 4: logging.error( _("Aborting connection attempt after 4 failed writes.")) return empty_lines = 0 while self._listen_can_continue(): line = self._readline() if line is None: break # connection problem # workaround cases where M105 was sent before printer Serial # was online an empty line means read timeout was reached, # meaning no data was received thus we count those empty lines, # and once we have seen 15 in a row, we just break and send a # new M105 # 15 was chosen based on the fact that it gives enough time for # Gen7 bootloader to time out, and that the non received M105 # issues should be quite rare so we can wait for a long time # before resending if not line: empty_lines += 1 if empty_lines == 15: break else: empty_lines = 0 if line.startswith(tuple(self.greetings)) \ or line.startswith('ok') or "T:" in line: self.online = True for handler in self.event_handler: try: handler.on_online() except: logging.error(traceback.format_exc()) if self.onlinecb: try: self.onlinecb() except: self.logError(traceback.format_exc()) return def _listen(self): """This function acts on messages from the firmware """ self.clear = True if not self.printing: self._listen_until_online() while self._listen_can_continue(): line = self._readline() if line is None: logging.debug('_readline() is None, exiting _listen()') break if line.startswith('DEBUG_'): continue if line.startswith(tuple(self.greetings)) or line.startswith('ok'): self.clear = True if line.startswith('ok') and "T:" in line: for handler in self.event_handler: try: handler.on_temp(line) except: logging.error(traceback.format_exc()) if self.tempcb: # callback for temp, status, whatever try: self.tempcb(line) except: self.logError(traceback.format_exc()) elif line.startswith('Error'): self.logError(line) # Teststrings for resend parsing # Firmware exp. result # line="rs N2 Expected checksum 67" # Teacup 2 if line.lower().startswith("resend") or line.startswith("rs"): for haystack in ["N:", "N", ":"]: line = line.replace(haystack, " ") linewords = line.split() while len(linewords) != 0: try: toresend = int(linewords.pop(0)) self.resendfrom = toresend break except: pass self.clear = True self.clear = True logging.debug('Exiting read thread') def _start_sender(self): self.stop_send_thread = False self.send_thread = threading.Thread(target=self._sender, name='send thread') self.send_thread.start() def _stop_sender(self): if self.send_thread: self.stop_send_thread = True self.send_thread.join() self.send_thread = None def _sender(self): while not self.stop_send_thread: try: command = self.priqueue.get(True, 0.1) except QueueEmpty: continue while self.printer and self.printing and not self.clear: time.sleep(0.001) self._send(command) while self.printer and self.printing and not self.clear: time.sleep(0.001) def _checksum(self, command): return reduce(lambda x, y: x ^ y, map(ord, command)) def startprint(self, gcode, startindex=0): """Start a print, gcode is an array of gcode commands. returns True on success, False if already printing. The print queue will be replaced with the contents of the data array, the next line will be set to 0 and the firmware notified. Printing will then start in a parallel thread. """ if self.printing or not self.online or not self.printer: return False self.queueindex = startindex self.mainqueue = gcode self.printing = True self.lineno = 0 self.resendfrom = -1 if not gcode or not gcode.lines: return True self.clear = False self._send( "M110", -1, True ) # this to makesure connection if connection fail will be trap on wait and self.clear should set to false first resuming = (startindex != 0) self.print_thread = threading.Thread(target=self._print, name='print thread', kwargs={"resuming": resuming}) self.print_thread.start() return True def cancelprint(self): self.pause() self.paused = False self.mainqueue = None self.clear = True # run a simple script if it exists, no multithreading def runSmallScript(self, filename): if filename is None: return f = None try: with open(filename) as f: for i in f: l = i.replace("\n", "") l = l[:l.find(";")] # remove comments self.send_now(l) except: pass def pause(self): """Pauses the print, saving the current position. """ if not self.printing: return False self.paused = True self.printing = False # ';@pause' in the gcode file calls pause from the print thread if not threading.current_thread() is self.print_thread: try: self.print_thread.join() except: self.logError(traceback.format_exc()) self.print_thread = None # saves the status self.pauseX = self.analyzer.abs_x self.pauseY = self.analyzer.abs_y self.pauseZ = self.analyzer.abs_z self.pauseE = self.analyzer.abs_e self.pauseF = self.analyzer.current_f self.pauseRelative = self.analyzer.relative self.pauseRelativeE = self.analyzer.relative_e def resume(self): """Resumes a paused print.""" if not self.paused: return False # restores the status self.send_now("G90") # go to absolute coordinates xyFeed = '' if self.xy_feedrate is None else ' F' + str( self.xy_feedrate) zFeed = '' if self.z_feedrate is None else ' F' + str(self.z_feedrate) self.send_now("G1 X%s Y%s%s" % (self.pauseX, self.pauseY, xyFeed)) self.send_now("G1 Z" + str(self.pauseZ) + zFeed) self.send_now("G92 E" + str(self.pauseE)) # go back to relative if needed if self.pauseRelative: self.send_now("G91") if self.pauseRelativeE: self.send_now('M83') # reset old feed rate self.send_now("G1 F" + str(self.pauseF)) self.paused = False self.printing = True self.print_thread = threading.Thread(target=self._print, name='print thread', kwargs={"resuming": True}) self.print_thread.start() def send(self, command, wait=0): """Adds a command to the checksummed main command queue if printing, or sends the command immediately if not printing""" if self.online: if self.printing: self.mainqueue.append(command) else: self.priqueue.put_nowait(command) else: self.logError(_("Not connected to printer.")) def send_now(self, command, wait=0): """Sends a command to the printer ahead of the command queue, without a checksum""" if self.online: self.priqueue.put_nowait(command) else: self.logError(_("Not connected to printer.")) def _print(self, resuming=False): self._stop_sender() try: for handler in self.event_handler: try: handler.on_start(resuming) except: logging.error(traceback.format_exc()) if self.startcb: # callback for printing started try: self.startcb(resuming) except: self.logError( _("Print start callback failed with:") + "\n" + traceback.format_exc()) while self.printing and self.printer and self.online: self._sendnext() self.sentlines = {} self.log.clear() self.sent = [] for handler in self.event_handler: try: handler.on_end() except: logging.error(traceback.format_exc()) if self.endcb: # callback for printing done try: self.endcb() except: self.logError( _("Print end callback failed with:") + "\n" + traceback.format_exc()) except: self.logError( _("Print thread died due to the following error:") + "\n" + traceback.format_exc()) finally: self.print_thread = None self._start_sender() def process_host_command(self, command): """only ;@pause command is implemented as a host command in printcore, but hosts are free to reimplement this method""" command = command.lstrip() if command.startswith(";@pause"): self.pause() def _sendnext(self): if not self.printer: return while self.printer and self.printing and not self.clear: time.sleep(0.001) # Only wait for oks when using serial connections or when not using tcp # in streaming mode if not self.printer_tcp or not self.tcp_streaming_mode: self.clear = False if not (self.printing and self.printer and self.online): self.clear = True return if self.resendfrom < self.lineno and self.resendfrom > -1: self._send(self.sentlines[self.resendfrom], self.resendfrom, False) self.resendfrom += 1 return self.resendfrom = -1 if not self.priqueue.empty(): self._send(self.priqueue.get_nowait()) self.priqueue.task_done() return if self.printing and self.mainqueue.has_index(self.queueindex): (layer, line) = self.mainqueue.idxs(self.queueindex) gline = self.mainqueue.all_layers[layer][line] if self.queueindex > 0: (prev_layer, prev_line) = self.mainqueue.idxs(self.queueindex - 1) if prev_layer != layer: for handler in self.event_handler: try: handler.on_layerchange(layer) except: logging.error(traceback.format_exc()) if self.layerchangecb and self.queueindex > 0: (prev_layer, prev_line) = self.mainqueue.idxs(self.queueindex - 1) if prev_layer != layer: try: self.layerchangecb(layer) except: self.logError(traceback.format_exc()) for handler in self.event_handler: try: handler.on_preprintsend(gline, self.queueindex, self.mainqueue) except: logging.error(traceback.format_exc()) if self.preprintsendcb: if self.mainqueue.has_index(self.queueindex + 1): (next_layer, next_line) = self.mainqueue.idxs(self.queueindex + 1) next_gline = self.mainqueue.all_layers[next_layer][ next_line] else: next_gline = None gline = self.preprintsendcb(gline, next_gline) if gline is None: self.queueindex += 1 self.clear = True return tline = gline.raw if tline.lstrip().startswith(";@"): # check for host command self.process_host_command(tline) self.queueindex += 1 self.clear = True return # Strip comments tline = gcoder.gcode_strip_comment_exp.sub("", tline).strip() if tline: self._send(tline, self.lineno, True) self.lineno += 1 for handler in self.event_handler: try: handler.on_printsend(gline) except: logging.error(traceback.format_exc()) if self.printsendcb: try: self.printsendcb(gline) except: self.logError(traceback.format_exc()) else: self.clear = True self.queueindex += 1 else: self.printing = False self.clear = True if not self.paused: self.queueindex = 0 self.lineno = 0 self._send("M110", -1, True) def _send(self, command, lineno=0, calcchecksum=False): # Only add checksums if over serial (tcp does the flow control itself) if calcchecksum and not self.printer_tcp: prefix = "N" + str(lineno) + " " + command command = prefix + "*" + str(self._checksum(prefix)) if "M110" not in command: self.sentlines[lineno] = command if self.printer: self.sent.append(command) # run the command through the analyzer gline = None try: gline = self.analyzer.append(command, store=False) except: logging.warning( _("Could not analyze command %s:") % command + "\n" + traceback.format_exc()) if self.loud: logging.info("SENT: %s" % command) for handler in self.event_handler: try: handler.on_send(command, gline) except: logging.error(traceback.format_exc()) if self.sendcb: try: self.sendcb(command, gline) except: self.logError(traceback.format_exc()) try: self.printer.write((command + "\n").encode('ascii')) if self.printer_tcp: try: self.printer.flush() except socket.timeout: pass self.writefailures = 0 except socket.error as e: if e.errno is None: self.logError( _("Can't write to printer (disconnected ?):") + "\n" + traceback.format_exc()) else: self.logError( _("Can't write to printer (disconnected?) (Socket error {0}): {1}" ).format(e.errno, decode_utf8(e.strerror))) self.writefailures += 1 except SerialException as e: self.logError( _("Can't write to printer (disconnected?) (SerialException): {0}" ).format(decode_utf8(str(e)))) self.writefailures += 1 except RuntimeError as e: self.logError( _("Socket connection broken, disconnected. ({0}): {1}"). format(e.errno, decode_utf8(e.strerror))) self.writefailures += 1
class DataReader: def __init__(self, device_path): self.device_path = device_path self._connection = None self._connected = False @property def connected(self): return self._connected def _connect(self): log.debug('_connect()') log.info(f'Try to connect to device {self.device_path}') try: self._connection = Serial(self.device_path) except SerialException: log.warning(f'[FAIL] Cannot connect to device {self.device_path}') self._connected = False else: log.info(f'[OK] Connected to {self.device_path}') self._connected = True def _connect_with_retry(self, attempts=CONNECT_WITH_RETRY_ATTEMPTS, sleep_time=CONNECT_WITH_RETRY_SLEEP_TIME): log.debug( f'_connect_with_retry(attempts={attempts}, sleep_time={sleep_time})' ) for attempt in range(1, attempts + 1): log.info(f'Attempt {attempt}') self._connect() if self._connected is True: break else: if attempt != attempts: log.info(f'Sleep {sleep_time} seconds before next attempt') time.sleep(sleep_time) def connect(self, with_retry=True, **kwargs): log.debug(f'connect(with_retry={with_retry}, kwargs={kwargs})') if with_retry is True: self._connect_with_retry(**kwargs) else: self._connect() def _get_value(self): log.debug('_get_value()') try: value = int(self._connection.readline()) except SerialException: raise DataReaderException('Error in serial connection') except KeyboardInterrupt: raise DataReaderException('Serial data read interrupted') else: return value def _get_value_with_reconnect(self, **kwargs): log.debug('_get_value_with_reconnect()') try: value = self._get_value() except DataReaderException: self._connect_with_retry(**kwargs) if self._connected is False: raise DataReaderException( 'Cannot read the value from serial port') else: return self._get_value_with_reconnect(**kwargs) else: return value def get_value(self, with_reconnect=True, **kwargs): log.debug(f'get_value(with_reconnect={with_reconnect})') if with_reconnect is True: return self._get_value_with_reconnect(**kwargs) else: return self._get_value()
def main(): args = parse_arguments() images = scan_for_images(args.folder) if len(images) == 0: print('Error: found no jpeg images in "%s".' % args.folder) sys.exit(1) print('Found %d images.' % len(images)) serial = Serial(args.port) serial.baudrate = args.baudrate print('Opened serial port %s.' % serial.name) print('Interval between pictures is %d seconds.' % args.interval) width = 0 height = 0 # display random pictures while True: time.sleep(args.interval) if width == 0: # connect to the Arduino and obtain screen size serial.write('C') width = int(serial.readline()) height = int(serial.readline()) print('Display is %dx%d.' % (width, height)) image = random.choice(images) print('Uploading "%s"...' % image) upload_image(image, serial, (width, height))
def interact(self): if not self.mock: try: serial = Serial(SERIAL_DEVICE, SERIAL_RATE) except SerialException: print("Error opening serial. To use without arduino: ./server.py --mock") os._exit(1) while True: try: while True: cmd = self.sendq.get(block=False) if self.mock: print("SERIAL WRITE:", cmd) else: serial.write(cmd.encode('ascii')) serial.write(b'\n') except Empty: pass if self.mock: time.sleep(1) line = b'temp 18\n' else: line = serial.readline() key, value = line.decode('ascii').strip().split(' ') value = self.from_arduino(key, int(value)) self.log_value(key, value) self.state[key] = value self.handle() self.recvq.put((key, value))