PYQT development using serial port communication (2)

All original articles in this blog use the Creative Commons Edition Agreement. Attribution, non-commercial use and consistency are required. The signature must include my screen name (geokai) and the source of the article (choose the first address of the blog or the specific address of the blog post).

Commercial use requires my prior consent (send Email to [email protected]).

3.2 Serial port Operation of Pyserial

  Python has its own dedicated Serial library. It is not clear whether the serial port library of pyqt inherits this library without carefully reading the code of qt.

   Tell me why I suddenly switched to this library, because the upper computer and the lower computer plan to use ModBus as the communication protocol. I thought that PyQt is a complete inheritance of all classes of C++ Qt, but it doesn’t work, it’s not the case. All the classes starting with QModbus are not found in the pyqt documentation. So it seems not easy to do all the host computer functions with PyQt. After searching, I found that Python has a Modbus_tk library, which encapsulates the related functions of Modbus, including rtu, ascii protocol mode, master and slave node mode. And this library directly inherits the Pyserial library. OK In this case, it will be simpler and more efficient to use the pyserial library directly for the operation of the serial port.

  Pyserial official document address https://pythonhosted.org/pyserial/

  3.2.1 List available serial ports

    import serial.tools.list_ports # The corresponding function is under this package. Import serial directly cannot use this toolkit

    com_list = serial.tools.list_ports.comports() # Return a serial.tools.list_ports.ListPortInfo list object, Each element contains multiple attributes of the serial port

    for port in com_list:

      print(port.device) #Return the port number such as COM3

      print port.describe) #Return the device name

      print(port.location) #Return the location of the device on the computer

    

     After obtaining these more important information You can open the port

  3.2.2 Open the serial port

    import serial

    ser = serial.Serial(com_list[0].device, baudrate=19200, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False) #Create a Serial instance object by directly configuring the parameters, and then directly open the port after execution

    

    ser = serial.Serial()

    ser.baudrate=19200

    ser.port=com_list[0].device

   open() #This method can be configured first and then opened

    ser.close()

  

  3.2.3 Abnormal state judgment of serial port

     Before using the QSerialPort() class, there is an error() method to judge the status of the serial port. But PySerial does not seem to have such complete functions. I don’t have enough ability to realize this function. Here is a method that I want to have basic functions.

After the serial port is opened normally, even if the device is unplugged, use ser.is_open to determine that the serial port status is always True. But by obtaining the serial port information, an empty object is obtained. Based on this idea, rewrite the code that opens the serial port and sends data through the serial port.

    

    ser =serial.Serial()
    ser.baudrate=19200
   
    ser.timeout=1

    try:
      ser.open()
     (  ) /div>

    except serial.SerialException:
      print(‘error’)
     pause, sleep(5) #time.sleep(5) Serial device
     if ser.is_open and len(list(lp.grep(ser.port))) !=0: #
      print(‘ able to send ‘)

for i in range (3):

try:

ser.write (b’aaaaaaaaaaaaaaaaaaaa’ )

print ( ‘send ok’)

break

except serial.SerialException:

print ( ‘re-try’)
          ser.close()

ser.open ()

if i == 2:

ser.close ()

print ( ‘port error’)

    else:
      ser.close()
      print(‘port error’)

>    

4. Communication part

   This part mainly realizes the communication between the upper computer software and the lower computer.

  4.1 host computer modbus master

    The modbus implementation of the host computer adopts python’s existing modbus_tk library to realize, paste the basic code

import modbus_tk
import modbus_tk.defines as cst
import serial
from modbus_tk import modbus_rtu
import time

< div> PORT =’COM3′

def main(master):

  try:
    #Connect to the slave
    master.set_timeout(1)
    master.set_verbose(True)
    x = master.execute(1, cst.READ_INPUT, lower 4) The register value of the machine, the address is 4, and the length is 1, using the cst.READ_INPUT_REGISTERS and cst.READ_HOLDING_REGISTERS methods to have the same effect
    if len(x)>0:
         (x[0]) #Here is the value obtained, pay attention to the symbol, in this example the lower computer also uses 16-bit unsigned numbers

    
  except:

    print(‘unknown’ error)

if __name__ == “__main__”:
  master = modbus_rtu.RtuMaster(
    Serial.Serial(port=PORT, baudrate=19200, bytesize=8, parity=’N’, stopbits=1, xonxoff=0))
  while True:
    main (master)
    tme.sleep(1)

  4.2 The lower computer modbus part is based on Arduino

     uses arduino The modbus library, which sets a register with an address of 4.

    

/**
* Modbus slave example 2:
* The purpose of this example is to link the Arduino digital and analog
* pins to an external device.
*
* Recommended Modbus Master: QModbus
* http://qmodbus.sourceforge.net/
*
* Editado al espa?ol por LuxARTS
*/

//Incluye la librería del protocolo Modbus
#include
#include
#define ID 1

/ /Crear instancia
Modbus slave(ID, 0, 0); //ID del nodo. 0 para el master, 1-247 para esclavo
//Puerto serie (0 = TX: 1-RX: 0)
//Protocolo serie. 0 para RS-232 + USB (default), cualquier pin mayor a 1 para RS-485
boolean led;
int8_t state = 0;
unsigned long tempus;< /p>

uint16_t au16data[9]; //La tabla de registros que se desea compartir por la red

/***************** ****************************************
Configuración del programa
* ************************************************** ******/
void setup() {
io_setup(); //configura las entradas y salidas

slave.begin(19200); //Abre la comunicación como esclavo
tempus = millis() + 100; //Guarda el tiempo actual + 100ms
digitalWrite(13 , HIGH ); //Prende el led del pin 13 (el de la placa)
au16data[4] = 0x8000;
}

/********** ***********************************************
Inicio del programa
************************************************ *************/
void loop() {
//Comprueba el buffer de entrada
state = slave.poll( au16data, 9 ); //Parámetros: Tabla de registros para el intercambio de info
// Tama?o de la tabla de registros
//Devuelve 0 si no hay pedido de datos
//Devuelve 1 al 4 si hubo error de comunicación
//Devuelve mas de 4 si se procesó correctamente el pedido

if (state> 4) {//Si es mayor a 4 = el pedido fué correcto
tempus = millis() + 50; //Tiempo actual + 50ms
digitalWrite(13, HIGH);//Prende el led
}
if (millis()> tempus) digitalWrite(13, LOW );//Apaga el led 50ms despu és

//Actualiza los pines de Arduino con la tabla de Modbus
io_poll();

}

/**
* pin maping :
* 2-digital input
* 3-digital input
* 4-digital input
* 5-digital input
* 6-digital output
* 7-digital output< br> * 8-digital output
* 9-digital output
* 10-analog output
* 11-analog output
* 14-analog input
* 15-analog input
*
* pin 13 reservado para ver el estado de la comunicación
*/
void io_setup() {
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, INPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(13, OUTPUT);

digitalWrite(6, LOW );
digitalWrite(7, LOW );
digitalWrite(8, LOW );
digitalWrite(9, LOW );
digitalWrite(13, HIGH ); //Led del pin 13 de la placa
analogWrite(10, 0 ); //PWM 0%
analogWrite(11, 0 ); //PWM 0%
}

/**************************** *****************************
Enlaza la tabla de registros con los pines
******* ************************************************** /
void io_poll() {
long temp;
// digital inputs -> au16data[0]
// Lee las entradas digitales y las guarda en bits de la primera variable del vector
// (es lo mismo que hacer una máscara)
bitWrite( au16data[0], 0, digitalRead( 2 )); //Lee el pin 2 de Arduino y lo guarda en el bit 0 de la variable au16data[ 0]
bitWrite( au16data[0], 1, digitalRead( 3 ));
bitWrite( au16data[0], 2, digitalRead( 4 ));
bitWrite( au16data[0], 3, digitalRead( 5 ));

// digital outputs -> au16data[1]
// Lee los bits de la segunda variable y los pone en las salidas digitales
digitalWrite( 6, bitRead (au16data[1], 0 )); //Lee el bit 0 de la variable au16data[1] y lo pone en el pin 6 de Arduino
digitalWrite( 7, bitRead( au16data[1], 1 ));
digitalWrite( 8, bitRead( au1 6data[1], 2 ));
digitalWrite( 9, bitRead( au16data[1], 3 ));

// Cambia el valor del PWM
analogWrite( 10, au16data[ 2] ); //El valor de au16data[2] se escribe en la salida de PWM del pin 10 de Arduino. (siendo 0=0% y 255=100%)
analogWrite( 11, au16data[3]) ;

temp=au16data[4];
// Serial.write(temp>>16);
// Serial.write(temp>>8);
// Serial.write(temp);

// Lee las entradas analógicas (ADC)

temp=(long)temp+(long)(random(-3,4)) ;
//temp=-1;
// Serial.write(temp>>24);
// Serial.write(temp>>16);
// Serial.write( temp>>8);
// Serial.write(temp);

temp=temp<0?0:temp;
temp=temp>65535?65535:temp ;

//temp=temp<0?0:temp;
//temp=temp>65535?65535:temp;
au16data[4] = temp;
//au16data[4] = byte(random(65530,65535));//analogRead( 0 ); //El valor anaalógico leido en el pin A0 se guarda en au16data[4]. (siendo 0=0v y 1023 =5v)
au16data[5] = 0xffff;

// Diagnóstico de la comunicación (par a debug)
au16data[6] = slave.getInCnt(); //Devuelve cuantos mensajes se recibieron
au16data[7] = slave.getOutCnt(); //Devuelve cuantos mensajes se transmitieron
au16data[ 8] = slave.getErrCnt(); //Devuelve cuantos errores hubieron
}

   

    

#So far the basic framework has been built, The communication between the upper computer and the lower computer is also opened up. The hardware problem has been basically solved

I started to focus on GUI writing.

  

      

Author: geokai

Source: https://www.cnblogs.com/geokai/

< p>The copyright of this article belongs to the author geokai and blog garden. Reprinting and commercial use are welcome, but this statement must be retained without the author’s consent, and the original link must be given in an obvious place on the article page, otherwise the right to pursue legal responsibility is reserved.

If you have any questions, please email ([email protected]) for consultation.

    ser =serial.Serial()
    ser.baudrate= 19200
    ser.port=’COM3′
    ser.timeout=1

    try:
    open( )
      print(‘Opened’)
    except serial.SerialException:
      print

div

    time.sleep(5) #Pause, unplug the serial device
     if ser.is_open and len(list(lp.grep(ser.port))) !=0: #
      print(‘able to send’)
      

       :          try in range(3)                                   :

ser.write (b’aaaaaaaaaaaaaaaaaaaa ‘)

print (‘ send ok ‘)

break

exce pt serial.SerialException:
          print(‘re-try’)
                                                                          print > if i == 2:

ser.close ()

print ( ‘port error’)

else:
      ser.close()
      print(‘port error’)

    ser =serial.Serial()

>    ser.baudrate=19200

    ser.port=’COM3′

    ser.timeout=1

    try:

      print(‘Opened’)

    except serial.SerialException:

      print(‘error’)

p>

    time.sleep(5) #Pause, unplug the serial device

    if ser.is_open and len(list(lp.grep(ser.port) )) !=0: #

      print(‘able to send’)

      

      for i in range(3): try:
          ser.write(b’aaaaaaaaaaaaaaaaaaaa’)
         )(‘sdivend ok div> break

except serial.SerialException:

print ( ‘re-try’)

ser.close ()

ser .open()
        if i==2:
                               error                     >

      for i in range(3):
        try:
aaaaaaaaaaaaa print ( ‘send ok’)

break

except serial.SerialException:

print ( ‘re-try’)

ser.close ()

ser.open ()

if i == 2:

ser.close ()

print (‘port error’)

      for i in range(3):

        try:

aaaaaaaaaaaaa   .

          print(‘send ok’)

                 serial serial lException:

print ( ‘re-try’)

ser.close ()

ser.open ()

if i ==2:

          ser.close()

                                  close          close(‘port error’)          : )

      print(‘port error’)

import modbus_tk
import modbus_tk.defines as cst
import serial < /div>

from modbus_tk import modbus_rtu
import time

PORT =’COM3′

def main(master):

  try:
    #Connect to the slave
    master.set_timeout(1)
   _ ose verbmaster.set
    x = master.execute(1, cst.READ_INPUT_REGISTERS, 4,1) #Read the register value of the lower computer, the address is 4, and the length is 1, using cst.READ_INPUT_REGISTERS and cst.READ_HOLDING_REGISTERS The effect is the same.
    if len(x)>0:
      print(x[0]) #Here is the value obtained, pay attention to the symbol, in this example, the lower computer is also Use 16-bit unsigned number

    
  except:
    print(‘unknown’ error )

if __name__ == “__main__”:
  master = modbus_rtu.RtuMaster(
    serial.Serial(port=PORT, baudrate=19200 , bytesize=8, parity=’N’, stopbits=1, xonxoff=0))
  while True:
    main(master)
    tme. sleep(1)

import modbus_tk

import modbus_tk.defines as cst

import serial

from modbus_tk import modbus_rtu

import time

PORT =’COM3′

def main(master):

  try:

    #Connect to the slave

    master.set_timeout(1)

    master.set_verbose(True)

  x = master.execute (1, cst.READ_INPUT_REGISTERS, 4,1) #Read the register value of the lower computer, the address is 4, and the length is 1, using cst.READ_INPUT_REGISTERS and cst.READ_HOLDING_REGISTERS The effect is the same

    if len(x)>0:

      print(x[0]) #here is the value obtained, pay attention to the sign, in this example the lower computer also uses 16-bit unsigned numbers

    

  except :

    print(‘unknown’ error)

if __name__ == “__main__”:

  master = modbus_rtu. RtuMaster(

    serial.Serial( port=PORT, baudrate=19200, bytesize=8, parity=’N’, stopbits=1, xonxoff=0))

  while True:

    main(master)

    tme.sleep(1)

Leave a Comment

Your email address will not be published.