Traducido del English por IA ·
Soy nuevo en el lado del hardware, pero llevo años trabajando con protocolos serie por software, y esto se puede simular con paridad. El noveno bit se envía en el lugar donde iría el bit de paridad. Linux admite paridad «stick» mediante el indicador CMSPAR: con PARENB|CMSPAR|PARODD el bit de paridad siempre es 1 (mark); sin PARODD, siempre es 0 (space).Así que: configurar paridad mark, escribir el byte de dirección, esperar a que salga (tcdrain), cambiar a paridad space y escribir los bytes de datos. En Python:
import termios, serial
CMSPAR = 0o10000000000
s = serial.Serial('/dev/ttyAMA0', 9600)
def set_bit9(on):
a = termios.tcgetattr(s.fd)
a[2] |= termios.PARENB | CMSPAR
a[2] = a[2] | termios.PARODD if on else a[2] & ~termios.PARODD
termios.tcsetattr(s.fd, termios.TCSADRAIN, a)
set_bit9(True); s.write(bytes([0x03])); s.flush()
set_bit9(False); s.write(bytes([0x10, 0x00]))
La recepción es la parte más incómoda: active PARMRK e INPCK, y un byte con la paridad «incorrecta» llega precedido por 0xFF 0x00, lo que indica su noveno bit. A 9600 baudios, el tiempo entre el byte de dirección y los de datos tiene una pequeña pausa por el cambio, aunque a la mayoría de los dispositivos antiguos no les importa. Use el UART PL011 (disable-bt), no el mini UART, porque el mini UART no tiene paridad.Luego, cada indicador se envía como un hijo, algo como {«scale-1»: {«values»: {«kg»: 12.45}}} en v1/gw/telemetry.
I’m new to the hardware side but I did serial protocol work in software for years, and you can fake this with parity. The 9th bit is sent where the parity bit would be. Linux supports «stick» parity through the CMSPAR flag: with PARENB|CMSPAR|PARODD the parity bit is always 1 (mark), without PARODD it’s always 0 (space).
So: set mark parity, write the address byte, wait for it to leave (tcdrain), switch to space parity, write the data bytes. In Python:
import termios, serial
CMSPAR = 0o10000000000
s = serial.Serial('/dev/ttyAMA0', 9600)
def set_bit9(on):
a = termios.tcgetattr(s.fd)
a[2] |= termios.PARENB | CMSPAR
a[2] = a[2] | termios.PARODD if on else a[2] & ~termios.PARODD
termios.tcsetattr(s.fd, termios.TCSADRAIN, a)
set_bit9(True); s.write(bytes([0x03])); s.flush()
set_bit9(False); s.write(bytes([0x10, 0x00]))
Receiving is the uglier half: turn on PARMRK and INPCK and a byte with the «wrong» parity arrives prefixed with 0xFF 0x00, which tells you its 9th bit. At 9600 the timing between the address and the data bytes gets a small gap from switching, most old devices don’t care. Use the PL011 UART (disable-bt), not the mini UART, the mini UART has no parity.
Then each indicator goes out as a child, something like {«scale-1»: {«values»: {«kg»: 12.45}}} on v1/gw/telemetry.

