Python + Serial (Raspberry - Raspbian)
Publicado por Jose (1 intervención) el 21/01/2017 23:30:45
Buenos días
Estoy implementando una comunicación serial por medio de Raspberry
Inicialmente declaro lo siguiente:
Para lo que necesito, debo enviar una serie de números por dicho puerto, por ejemplo:
126 0 19 16 0 0 0 0 0 0 0 255 255 255 254 0 0 1 32 6 101 1 103
Para hacerlo estuve buscando en internet y me topé con esta solución:
Debo decir que esta solución me funcionó correctamente, y el receptor de los datos opera correctamente según lo que se le envía
Ahora bien, en este momento tengo el problema de que varios de esos datos cambian y para hacerlo debo ir al código y hacer esas modificaciones, lo cual no es nada práctico realmente; adicionalmente el último dato corresponde a un checksum el cual se obtiene haciendo una operación de sumas y restas de los datos anteriores, pero solo tiene en cuenta los 8 primeros bits de cada número.
Esto quiere decir que si el resultado de una suma es 280, el valor a tomar solo debe ser 24.
145 + 135 = 280
0b10010001 + 0b10000111 = 0b000100011000
Como sólo se tienen en cuenta los primeros 8 bits, el resultado real sería:
145 + 135 = 24
0b10010001 + 0b10000111 = 0b000100011000
Para el primer problema lo solucioné de la siguiente forma:
Para el último error lo solucioné de la siguiente forma:
No es la forma más optimizada pero fue la única que me funcionó
En otros lenguajes de programación lo que hacía era o bien trabajar con datos de máximo 8 bits, o bien realizar las operaciones en base binaria o en base hexadecimal, pero en python no se cómo realizar estos procedimientos, porque solo he podido operar en base decimal, lo que no me permite modificar los bits que desee de un número.
Ahora, el problema real que tengo viene a la hora de generar la trama completa para enviarla por el puerto serial.
Primero que todo quisiera saber si existe alguna forma de enviar estos datos uno a uno como número, ya que así podría hacerlo de una forma más fácil porque en este punto conozco todos los datos que voy a enviar y sé exáctamente el valor que van a tener cada uno de ellos.
En este momento lo que estoy haciendo es generar una cadena de strings correspondientes al valor hexadecimal de cada uno de los números que tengo, de esta forma:
Usando la solución inicial lo que obtengo al hacer print es:
~ÿÿÿþ eg
Y eso es lo que debe enviar, ya que al hacer las pruebas por otros medios de qué es lo que se envía y transmite de forma serial por el otro dispositivo obtengo estos mismos valores
Ahora bien, cuando implemento mi solución lo que obtengo en pantalla es lo siguiente:
\X7E\X0\X13\X10\X0\X0\X0\X0\X0\X0\X0\XFF\XFF\XFF\XFE\X0\X0\X1\X20\X1\X1\X1\XD0
Los valores no coinciden, pero eso no es lo importante, ya que lo realmente importante es que el "tipo" de respuesta no es exactamente lo que yo espero.
Estoy implementando una comunicación serial por medio de Raspberry
Inicialmente declaro lo siguiente:
1
2
3
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
Para lo que necesito, debo enviar una serie de números por dicho puerto, por ejemplo:
126 0 19 16 0 0 0 0 0 0 0 255 255 255 254 0 0 1 32 6 101 1 103
Para hacerlo estuve buscando en internet y me topé con esta solución:
1
2
3
thestring = "\x7E\x00\x13\x10\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFE\x00\x00\x01\x20\x06\x65\x01\x67"
data = thestring
ser.write(data)
Debo decir que esta solución me funcionó correctamente, y el receptor de los datos opera correctamente según lo que se le envía
Ahora bien, en este momento tengo el problema de que varios de esos datos cambian y para hacerlo debo ir al código y hacer esas modificaciones, lo cual no es nada práctico realmente; adicionalmente el último dato corresponde a un checksum el cual se obtiene haciendo una operación de sumas y restas de los datos anteriores, pero solo tiene en cuenta los 8 primeros bits de cada número.
Esto quiere decir que si el resultado de una suma es 280, el valor a tomar solo debe ser 24.
145 + 135 = 280
0b10010001 + 0b10000111 = 0b000100011000
Como sólo se tienen en cuenta los primeros 8 bits, el resultado real sería:
145 + 135 = 24
0b10010001 + 0b10000111 = 0b
Para el primer problema lo solucioné de la siguiente forma:
1
2
3
4
5
6
D1= int(input("Ingrese D1: "))
#print D1
D2= int(input("IngreseD2: "))
#print D2
D3= int(input("Ingrese D3: "))
#print D3
Para el último error lo solucioné de la siguiente forma:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def calc_checksum():
checksum = 16 + 255
checksum = checksum & 255
checksum = checksum + 255
checksum = checksum & 255
checksum = checksum + 255
checksum = checksum & 255
checksum = checksum + 254
checksum = checksum & 255
checksum = checksum + 1
checksum = checksum & 255
checksum = checksum + 32
checksum = checksum & 255
checksum = checksum + D1
checksum = checksum & 255
checksum = checksum + D2
checksum = checksum & 255
checksum = checksum + D3
checksum = checksum & 255
checksum = 255 - checksum
return checksum
No es la forma más optimizada pero fue la única que me funcionó
En otros lenguajes de programación lo que hacía era o bien trabajar con datos de máximo 8 bits, o bien realizar las operaciones en base binaria o en base hexadecimal, pero en python no se cómo realizar estos procedimientos, porque solo he podido operar en base decimal, lo que no me permite modificar los bits que desee de un número.
Ahora, el problema real que tengo viene a la hora de generar la trama completa para enviarla por el puerto serial.
Primero que todo quisiera saber si existe alguna forma de enviar estos datos uno a uno como número, ya que así podría hacerlo de una forma más fácil porque en este punto conozco todos los datos que voy a enviar y sé exáctamente el valor que van a tener cada uno de ellos.
En este momento lo que estoy haciendo es generar una cadena de strings correspondientes al valor hexadecimal de cada uno de los números que tengo, de esta forma:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
def send_frame(ID1, CMD1, OP1, data_c):
d = "\\"
start = hex(126)
start = start.lstrip("0")
lenght_1 = hex(0)
lenght_1 = lenght_1.lstrip("0")
lenght_2 = hex(19)
lenght_2= lenght_2.lstrip("0")
frame_type = hex(16)
frame_type = frame_type.lstrip("0")
frame_ID = hex(0)
frame_ID = frame_ID.lstrip("0")
address_64_1 = hex(0)
address_64_1 = address_64_1.lstrip("0")
address_64_2 = hex(0)
address_64_2 = address_64_2.lstrip("0")
address_64_3 = hex(0)
address_64_3 = address_64_3.lstrip("0")
address_64_4 = hex(0)
address_64_4 = address_64_4.lstrip("0")
address_64_5 = hex(0)
address_64_5 = address_64_5.lstrip("0")
address_64_6 = hex(0)
address_64_6 = address_64_6.lstrip("0")
address_64_7 = hex(255)
address_64_7 = address_64_7.lstrip("0")
address_64_8 = hex(255)
address_64_8 = address_64_8.lstrip("0")
address_16_1= hex(255)
address_16_1 = address_16_1.lstrip("0")
address_16_2 = hex(254)
address_16_2 = address_16_2.lstrip("0")
broadcast_radius = hex(0)
broadcast_radius = broadcast_radius.lstrip("0")
options = hex(0)
options = options.lstrip("0")
RF_1 = hex(1)
RF_1 = RF_1.lstrip("0")
com_const = hex(32)
com_const = com_const.lstrip("0")
ID1 = hex(ID1)
ID1 = ID1.lstrip("0")
CMD1 = hex(CMD1)
CMD1 = CMD1.lstrip("0")
OP1 = hex(OP1)
OP1 = OP1.lstrip("0")
data_c = hex(data_c)
data_c = data_c.lstrip("0")
data_s = d + start + d + lenght_1 + d + lenght_2 + d + frame_type + d + frame_ID + d + address_64_1 + d + address_64_2 + d + address_64_3 + d + address_64_4 + d + address_64_5 + d + address_64_6 + d + address_64_7 + d + address_64_8
data_s = data_s + d + address_16_1 + d + address_16_2 + d + broadcast_radius + d + options + d + RF_1 + d + com_const + d + ID1 + d + CMD1 + d + OP1 + d + data_c
print 'START'
ser.write(data_s)
print data_s
print 'END'
Usando la solución inicial lo que obtengo al hacer print es:
~ÿÿÿþ eg
Y eso es lo que debe enviar, ya que al hacer las pruebas por otros medios de qué es lo que se envía y transmite de forma serial por el otro dispositivo obtengo estos mismos valores
Ahora bien, cuando implemento mi solución lo que obtengo en pantalla es lo siguiente:
\X7E\X0\X13\X10\X0\X0\X0\X0\X0\X0\X0\XFF\XFF\XFF\XFE\X0\X0\X1\X20\X1\X1\X1\XD0
Los valores no coinciden, pero eso no es lo importante, ya que lo realmente importante es que el "tipo" de respuesta no es exactamente lo que yo espero.
Valora esta pregunta


0