Von English mit KI übersetzt ·
Ich bin neu auf der Hardware-Seite, habe aber jahrelang serielle Protokolle in Software umgesetzt, und man kann das mit Parität nachbilden. Das 9. Bit wird dort gesendet, wo das Paritätsbit stehen würde. Linux unterstützt „Stick“-Parität über das CMSPAR-Flag: Mit PARENB|CMSPAR|PARODD ist das Paritätsbit immer 1 (Mark), ohne PARODD immer 0 (Space).Also: Mark-Parität setzen, das Adressbyte schreiben, warten bis es hinaus ist (tcdrain), auf Space-Parität umschalten, die Datenbytes schreiben. 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]))
Der Empfang ist die unangenehmere Hälfte: PARMRK und INPCK aktivieren, dann kommt ein Byte mit der „falschen“ Parität mit dem Präfix 0xFF 0x00 an, das dir sein 9. Bit verrät. Bei 9600 entsteht zwischen Adress- und Datenbytes durch das Umschalten eine kleine Lücke, die meisten alten Geräte stört das nicht. Verwende den PL011-UART (disable-bt), nicht den Mini-UART, denn der Mini-UART hat keine Parität.Dann wird jeder Indikator als Kind gesendet, etwa so: {„scale-1“: {„values“: {„kg“: 12.45}}} auf 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.

