COM端口上的读写字节数组



我目前正在编写一个python脚本,通过COM端口与rs485中的压力调节器进行通信。我可以读取它的内部变量并写入它的变量但如果我写入它的一个变量,然后读取一个变量,它总是会给我0xff(255)作为答案,不管这个变量是什么。如果我重新启动我的脚本,我不写变量,我可以读取尽可能多的我想要的正确的值,每次响应。

我不明白为什么会这样,有人能帮帮我吗?脚本如下:


from PyCRC.CRCCCITT import CRCCCITT #Librairie pour calcul du CRC (modifiée)
import serial           # import du module serial pour la communication série
readChoice = 'o'

########################################### FONCTIONS ###########################################
def serial_init():              # initialise les paramètres de la communication avec serial
global ComPort
ComPort = serial.Serial('COM3') # Ouvre le COM 3
ComPort.baudrate = 9600 # initialise le baud rate à 9600
ComPort.bytesize = 8    # Nombre de bits pour les data = 8
ComPort.parity   = 'N'  # Pas de parité
ComPort.stopbits = 1    # Nombre de bits pour le stop = 1
serial.Serial.TimeoutError = 1  # Timeout


def menu():                     # affiche le menu et lis le choix de l'utilisateur
global readChoice
print("nn//////////////////////////////////////////////////")     # Menu
print("// Voulez vous lire un registre ?  : r          //")
print("// Voulez vous ecrire dans un registre ?  : w   //")
print("// Voulez vous quitter ? : q                    //")
print("//////////////////////////////////////////////////")
readChoice = input()    # Lecture du choix

def data_to_string(data):       # renvoie une chaine contenant les valeurs hexa de data pour faciliter l'affichage
s=""                        # var avec chaine de carac
for d in data:              # d parcourt le tableau data
s+=hex(d)[2:]           # on slice pour se débarasser du 0x
s+=' '                  # Rajoute un espace entre les valeurs pour la lisibilité

#   s="0x"+s                    # rajoute 0x au début
return s                    # notre fonction renverra la chaine s contenant nos valeurs hexa

def crc_calc():                 # calcule le crc en fonction de "data" puis rajoute ce crc à la fin de "data"
global data
print(CRCCCITT().calculate(bytes(data)))    # calcul du CRC (sur 2 octet donc je le coupe en 2 pour le répartir comme pour les deux octets de valeur à écrire décris plus haut)
print(hex(CRCCCITT().calculate(bytes(data))))
crc1 = '0x'+hex(CRCCCITT().calculate(bytes(data)))[2:4]
crc2 = '0x'+hex(CRCCCITT().calculate(bytes(data)))[4:]
print(crc1+'n'+crc2)
data.extend(bytearray([int(crc1, 16)]))     # on rajoute le crc dans data
data.extend(bytearray([int(crc2, 16)]))


def read_command():             # permet d'envoyer une commande demandant à l'ER5000 pour lire une de ses var d'index puis de lire sa réponse
global data
global ComPort

print("nQuel registre voulez-vous lire ?")
choice = input()
data = switch[choice]                      # on choisis la commande adéquate dans le dictionnaire switch

ComPort.write(data)                        # écris data sur le COM3 affin d'envoyer notre commande
print("nEnvoyé :",data_to_string(data))   # print ce qui a été envoyé pour vérifier avec une fonction transformant data en chaine pour une bonne lecture (faire un simple print de data affiche parfois des caractères ASCII à la place de la valeure correspondante en hexa)

dataIn = ComPort.read(6)                # lire data sur le com (6 octets)
print("Recu :",data_to_string(dataIn))  # print les data recus après les avoir convertis en une chaine pour faciliter l affichage
print("Recu brut :",dataIn)
if dataIn[2] < 10 :                     # Si la valeur de la case 2 dans dataIn est plus petit que 10 (elle va de 0 à F)
val1 = '0' + hex(dataIn[2])[2:]     # Ajouter un 0 devant la valeur en hexa (sans le 0x en faisant un slice) et stocker le tout dans val1 afin qu elle fasse tjs 2 carac (ex: f -> 0f)

if dataIn[3] < 10 :                     # Pareil pour la case 3 puisque la valeur est stoquée en case 2 et 3
val2 = '0' + hex(dataIn[3])[2:]

if dataIn[2] >= 10 :
val1 = hex(dataIn[2])[2:]

if dataIn[3] >= 10 :
val2 = hex(dataIn[3])[2:]
x = '0x'+val1+val2                      # Pour écrire la valeur en décimal, j'en fais une valeur Hex reconnaisable par python
y = int(x,16)                           # Je transforme cette valeur en décimal
print("Valeur hex recue :", x)          # J'affiche la valeure en hexa
print('Valeur recue en decimal :', y)   # J'affiche la valeure en decimal


def write_command():            # permet de calculer puis d'envoyer une commande pour écrire dans une var de l'index du ER5000
global data

print("nN° du registre dans lequel ecrire :")
inReg = int(input())                            # on récupère en int le numéro du registre dans lequel écrire

if inReg == 37:                                 # si on veut changer le setpoint (index 37)
print("nEntrez une valeur en mBar")
inValW = hex(int(convert_mbar_to_val()))    # convertit la valeur entrée en mBar en une valeur equivalente pour le ER5000

else:
print("nValeur à écrire :")
inValW = hex(int(input()))                      # on récupère en hexa la valeur à écrire

data = bytearray(b'xfax04x01')               # on met déjà le début de la requete dans data car ce morceau sera tjs le même (adresselongueurcommande "écrire")
data.extend(bytearray([inReg]))                 # avec un extend on rajoute le numéro de registre entré par l'utilisateur
if int(inValW, 16) < 256:                       # si la valeur hex va de 0x00 à 0xff alors il y aura 2 cara sur 4 a mettre donc je remplis le premier octet avec 00
data.extend(bytearray([0]))                 # la commande "bytearray([0])" renverras "bytearray(b'x00')", on l'ajoute à data pour remplir le premier des deux octets de valeur puisque ici la valeur est <= à FF
data.extend(bytearray([int(inValW, 16)]))   # on rajoute la valeur entrée par l utilisateur à data
elif 255 < int(inValW, 16) < 4096:  # si elle est comprise entre 0x100 et 0xfff alors il y a 3 carac a mettre sur 4 donc je sépare en deux et répartis dans les 2 octets
a = str(inValW)[:3]             # on slice la valeur pour stocker uniquement le 1er carac précédé de 0x dans "a"
b = '0x'+str(inValW)[3:]        # on slice la valeur pour stocker uniquement les deux derniers carac dans "b" tout en rajoutant "0x" au début pour qu'il apparaisse sous la forme hexa 0x00
print(a+"n"+b)                 # maintenant la valeur est séparée de sorte que si la valeur de base était "0xf2a", a contiendra "0xf" et b contiendra "0x2a"
data.extend(bytearray([int(a, 16)]))    # on rajoute a et b à data, ainsi en reprenant l'exemple précédent on l'aura prolongé de sorte : "x0fx2a"
data.extend(bytearray([int(b, 16)]))
else:                               # sinon, elle est supérieur et donc les deux octets sont pleins et je le coupe en deux pour le mettre dans les deux octets
a = str(inValW)[:3]             # meme logique que pour le précédent
b = '0x'+str(inValW)[3:]
print(a+"n"+b)
data.extend(bytearray([int(a)]))
data.extend(bytearray([int(b)]))
crc_calc()
ComPort.write(data)                        # écris data sur le COM3 affin d'envoyer notre commande
print("nEnvoyé :",data_to_string(data))        # print ce qui a été envoyé pour vérifier avec une fonction transformant data en chaine pour une bonne lecture (faire un simple print de data affiche parfois des caractères ASCII à la place de la valeure correspondante en hexa)


def convert_mbar_to_val():      # convertis une valeur entrée par l utilisateur de mBar à valeur équivalente pour l'ER5000
mbar = int(input())
val_mbar = (mbar * 11 + 8000)/20
return val_mbar


########################################### Dictionary ###########################################    
# Dans le dictionnaire, en fin de commentaire, |V| : Renvoie une valeure sencée
#                                              |?| : Renvoie une valeure dont je ne sais pas ou ne suis pas certain de sa pertinence
#                                              |!| : Renvoie une valeure incohérente ou abérante
#                                              |o| : Pas encore testé
# commandes de lecture :
switch = {      # dictionary of read commands (a sort of switch)
'1' : bytearray(b'xfax02x02x01x6bx05'),   # Command "Read Index 01" (What is your ID_AD_SETPOINT ? 0 - 65535)          |V|
'3' : bytearray(b'xfax02x02x03x4bx47'),   # Command "Read Index 03" (What is your ID_INNER_D_COEF1 ? -32768 - 32767)   |V|
'5' : bytearray(b'xfax02x02x05x2bx81'),   # Command "Read Index 05" (What is your ID_COMPENS_EXT_SENSOR ? 0 - 65535)   |V|
'6' : bytearray(b'xfax02x02x06x1bxe2'),   # Command "Read Index 06" (What is your ID_COMPENS_INTERN_SENS ? 0 - 65535)  |V|
'9' : bytearray(b'xfax02x02x09xeax0d'),   # Command "Read Index 09" (What is your ID_CONTROL_MODE ? 0 - 3)             |V|
'12' : bytearray(b'xfax02x02x0cxbaxa8'),  # Command "Read Index 12" (What is your ID_PWM_SHUTOFF_FLAG ? 0 - 1)         |V|
'13' : bytearray(b'xfax02x02x0dxaax89'),  # Command "Read Index 13" (What is your ID_RTTASK_DELAY ? 0 - 65535)         |o|
'16' : bytearray(b'xfax02x02x10x69x15'),  # Command "Read Index 16" (What is your ID_OUT_D_COEF1 ? -32768 - 32767)     |o|
'19' : bytearray(b'xfax02x02x13x59x76'),  # Command "Read Index 19" (What is your ID_INNER_SENSOR_MIN ? 0 - 4095)      |o|
'20' : bytearray(b'xfax02x02x14x29x91'),  # Command "Read Index 20" (What is your ID_INNER_SENSOR_MAX ? 0 - 4095)      |o|
'21' : bytearray(b'xfax02x02x15x39xb0'),  # Command "Read Index 21" (What is your ID_OUT_INTEG_CONST ? -32768 - 32767) |o|
'22' : bytearray(b'xfax02x02x16x09xd3'),  # Command "Read Index 22" (What is your ID_OUT_INTEG_MAX ? -32768 - 32767)   |o|
'23' : bytearray(b'xfax02x02x17x19xf2'),  # Command "Read Index 23" (What is your ID_OUT_INTEG_SUM ? -32768 - 32767)   |o|
'25' : bytearray(b'xfax02x02x19xf8x3c'),  # Command "Read Index 25" (What is your ID_OUT_PROP_CONST ? -32768 - 32767)  |o|
'28' : bytearray(b'xfax02x02x1cxa8x99'),  # Command "Read Index 28" (What is your ID_IN_INTEG_CONST ? -32768 - 32767)  |o|
'29' : bytearray(b'xfax02x02x1dxb8xb8'),  # Command "Read Index 29" (What is your ID_IN_INTEG_MAX ? -32768 - 32767)    |o|
'30' : bytearray(b'xfax02x02x1ex88xdb'),  # Command "Read Index 30" (What is your ID_IN_INTEG_SUM ? -32768 - 32767)    |o|
'34' : bytearray(b'xfax02x02x22x7fx04'),  # Command "Read Index 34" (What is your ID_OUTPUT ? -32768 - 32767)          |o|
'35' : bytearray(b'xfax02x02x23x6fx25'),  # Command "Read Index 35" (What is your ID_IN_PROPOR_CONST ? -32768 - 32767) |o|
'37' : bytearray(b'xfax02x02x25x0fxe3'),  # Command "Read Index 37" (What is your ID Setpoint ? 0 - 4095)              |V|
'39' : bytearray(b'xfax02x02x27x2fxa1'),  # Command "Read Index 39" (What is your ID_GAIN ? 0 - 65535)                 |o|
'40' : bytearray(b'xfax02x02x28xdex4e'),  # Command "Read Index 40" (What is your ID_OSET ? 0 - 65535)                 |o|
'42' : bytearray(b'xfax02x02x2axfex0c'),  # Command "Read Index 42" (What is your adress ? 0 - 250)                    |V|
'43' : bytearray(b'xfax02x02x2bxeex2d'),  # Command "Read Index 43" (What is your ID Setpoint Flag ? 0 - 4)            |o|
'44' : bytearray(b'xfax02x02x2cx9exca'),  # Command "Read Index 44" (What is your ID Feedback ? 0 - 4095)              |V|
'45' : bytearray(b'xfax02x02x2dx8exeb'),  # Command "Read Index 45" (What is your ID_PROFILE_LOOP_COUNT ? 0 - 30000)   |o|
'46' : bytearray(b'xfax02x02x2exbex88'),  # Command "Read Index 46" (What is your ID_SOLENOID_DIRECTION ? 0 - 1)       |o|
'47' : bytearray(b'xfax02x02x2fxaexa9'),  # Command "Read Index 47" (What is your ID_MIN_INLET ? 0 - 250)              |o|
'48' : bytearray(b'xfax02x02x30x4dx77'),  # Command "Read Index 48" (What is your ID_MIN_EXHAUST ? 0 - 250)            |o|
'49' : bytearray(b'xfax02x02x31x5dx56'),  # Command "Read Index 49" (What is your ID_OUT_INTEG_MIN ? -32768 - 32767)   |o|
'50' : bytearray(b'xfax02x02x32x6dx35'),  # Command "Read Index 50" (What is your ID_IN_INTEG_MIN ? -32768 - 32767)    |o|
'52' : bytearray(b'xfax02x02x34x0dxf3'),  # Command "Read Index 52" (What is your ID_SERIAL_NUMBER ? 0 - 65535)        |o|
'53' : bytearray(b'xfax02x02x35x1dxd2'),  # Command "Read Index 53" (What is your ID_VERSION_NUMBER ? 0 - 65535)       |o|
'64' : bytearray(b'xfax02x02x40x33xe0'),  # Command "Read Index 64" (What is your ID_PWM_ CONTROL_LIMIT_STATE ? 0 - 3) |o|
'65' : bytearray(b'xfax02x02x41x23xc1'),  # Command "Read Index 65" (What is your ID_PWM_VALUE ? -250 - 250)           |o|
'66' : bytearray(b'xfax02x02x42x13xa2'),  # Command "Read Index 66" (What is your ID_IN_INTEG_DEADBAND ? 0 - 4095)     |o|
'67' : bytearray(b'xfax02x02x43x03x83'),  # Command "Read Index 67" (What is your ID_OUT_INTEG_DEADBAND ? 0 - 4095)    |o|
'69' : bytearray(b'xfax02x02x45x63x45'),  # Command "Read Index 69" (What is your ID_PROFILE_TYPE ? 0 - 11)            |o|
'70' : bytearray(b'xfax02x02x46x53x26'),  # Command "Read Index 70" (What is your ID_PROFILE_STATE ? 0 - 2)            |o|
'71' : bytearray(b'xfax02x02x47x43x07'),  # Command "Read Index 71" (What is your ID_PROFILE_STEP ? 0 - 31)            |o|
'73' : bytearray(b'xfax02x02x49xa2xc9'),  # Command "Read Index 73" (What is your ID_PULSE ? 1798 - 2298)              |o|
'77' : bytearray(b'xfax02x02x4dxe2x4d'),  # Command "Read Index 77" (What is your ID_COMPENS_EXTRA_AD1 ? 0 - 65535)    |o|
'78' : bytearray(b'xfax02x02x4exd2x2e'),  # Command "Read Index 78" (What is your ID_COMPENS_EXTRA_AD2 ? 0 - 65535)    |o|
'81' : bytearray(b'xfax02x02x51x31xf0'),  # Command "Read Index 81" (What is your ID_PULSE_PERIOD ? 0 - 200)           |o|
'82' : bytearray(b'xfax02x02x52x01x93'),  # Command "Read Index 82" (What is your ID_PULSE_WIDTH ? 0- 250)             |o|
'83' : bytearray(b'xfax02x02x53x11xb2'),  # Command "Read Index 83" (What is your ID_PULSE_DEADBAND ? 0 - 330)         |o|
'84' : bytearray(b'xfax02x02x54x61x55'),  # Command "Read Index 84" (What is your ID_PULSE_ENABLE ? 0 - 1)             |o|
'85' : bytearray(b'xfax02x02x55x71x74'),  # Command "Read Index 85" (What is your ID_AD_EXTRA1_TOGGLE ? 0 - 4095)      |o|
'86' : bytearray(b'xfax02x02x56x41x17'),  # Command "Read Index 86" (What is your ID_AD_EXTRA2_TOGGLE ? 0 - 4095)      |o|
'87' : bytearray(b'xfax02x02x57x51x36'),  # Command "Read Index 87" (What is your ID_EXT_FEEDBACK_SOURCE ? 0 - 1)      |o|
'88' : bytearray(b'xfax02x02x58xa0xd9'),  # Command "Read Index 88" (What is your ID_DIGITAL_OUTPUT1 ? 0 - 1)          |o|
'89' : bytearray(b'xfax02x02x59xb0xf8'),  # Command "Read Index 89" (What is your ID_DIGITAL_OUTPUT2 ? 0 - 1)          |o|
'90' : bytearray(b'xfax02x02x5ax80x9b'),  # Command "Read Index 90" (What is your ID_DIGITAL_OUT1_INIT ? 0 - 1)        |o|
'91' : bytearray(b'xfax02x02x5bx90xba'),  # Command "Read Index 91" (What is your ID_DIGITAL_OUT2_INIT ? 0 - 1)        |o|
'92' : bytearray(b'xfax02x02x5cxe0x5d'),  # Command "Read Index 92" (What is your ID_DA_ANALOG_OUT ? 0 - 4095)         |o|
'93' : bytearray(b'xfax02x02x5dxf0x7c'),  # Command "Read Index 93" (What is your ID_TTL_ERR0 ? 0 - 4095)              |o|
'94' : bytearray(b'xfax02x02x5exc0x1f'),  # Command "Read Index 94" (What is your ID_TTL_ERR4095 ? 0 - 4095)           |o|
'96' : bytearray(b'xfax02x02x60x17x82'),  # Command "Read Index 96" (What is your ID_TTL_FLAG ? 0 - 1)                 |o|
'119' : bytearray(b'xfax02x02x77x75x54'), # Command "Read Index 119" (What is your ID_PROFILE_STARTRUN ? 0 - 1)        |o|
'120' : bytearray(b'xfax02x02x78x84xbb'), # Command "Read Index 120" (What is your ID_MODE_ER3000_ER5000 ? 0 - 1)      |V|
'121' : bytearray(b'xfax02x02x79x94x9a'), # Command "Read Index 121" (What is your ID_SUSPEND ? 0 - 1)                 |o|
'122' : bytearray(b'xfax02x02x7Axa4xf9'), # Command "Read Index 122" (What is your ID_SETPONT_RESET ? 0 - 1)           |o|
}

########################################### MAIN PROGRAM ###########################################
serial_init()
while 1:        # Boucle du programme

menu()      # Affiche le menu et permet le choix


if readChoice == 'q':   # Si on choisis de quitter
break               # Sortir de la boucle

if readChoice == 'r':   # si on choisis de lire
read_command()      # pour lire un index

if readChoice == 'w':   # si on choisis d'écrire
write_command()     # pour créer la commande d'écriture


ComPort.flush()         # nettoie le port

ComPort.close()         # ferme le port
print('n|fin|')                # ecris "fin" pour confirmer que le programme s'arret.

我知道为什么它不起作用了。我写完后读到的只是压力调节器的响应,以确认它已收到写请求。

最新更新