Lire un bus multipoint 9 bits via une passerelle Pi : l'UART peut-elle vraiment le faire ?
Traduit de English par IA ·
Usine agroalimentaire et boissons, ancienne ligne de remplissage. Quatre indicateurs de pesée communiquent sur un bus multipoint RS-485 propriétaire des années 90 : 9600 bauds, 9 bits de données, le 9e bit marquant un octet d’adresse. L’automate d’origine qui les interrogeait tombe en panne, et je souhaite utiliser un Pi 4 avec un HAT RS-485 pour reprendre l’interrogation et remonter chaque indicateur vers Hermetry comme un appareil distinct.La partie Hermetry, je pense la comprendre : le Pi est une passerelle et envoie v1/gw/telemetry avec les quatre indicateurs comme enfants. Ce que je ne sais pas, c’est comment obtenir des trames à 9 bits depuis une UART Linux. pyserial ne propose que 5 à 8 bits de données. Est-ce possible sur un Pi, ou faut-il un matériel différent ?
Food and beverage plant, old filling line. Four weighing indicators talk on a proprietary RS-485 multidrop bus from the 90s: 9600 baud, 9 data bits, where the 9th bit marks an address byte. The original PLC that polled them is dying and I want a Pi 4 with an RS-485 HAT to take over the polling and report each indicator to Hermetry as its own device.
The Hermetry part I think I understand: the Pi is a gateway and sends v1/gw/telemetry with the four indicators as children. What I don’t know is how to get 9-bit frames out of a Linux UART. pyserial only offers 5 to 8 data bits. Is this possible on a Pi at all, or do I need different hardware?
Traduit de English par IA ·
À quoi sert exactement le 9e bit ? Je n’ai jamais vu autre chose que du 8N1.
What’s the 9th bit for exactly? I’ve only ever seen 8N1.
Traduit de English par IA ·
À quelle fréquence avez-vous besoin des relevés ? Si la cadence est lente, beaucoup de solutions de contournement deviennent acceptables.
How often do you need readings? If it’s slow, a lot of hacks become acceptable.
Traduit de English par IA ·
Une fois par seconde par indicateur, c’est largement suffisant. David, le 9e bit indique à chaque nœud « cet octet est une adresse, réveille-toi et vérifie si c’est la tienne ». Les octets de données l’ont à 0.
Once a second per indicator is plenty. David, the 9th bit tells every node « this byte is an address, wake up and check if it’s yours ». Data bytes have it at 0.
Traduit de English par IA ·
Beaucoup de STM32 gèrent nativement le 9 bits. Un Blue Pill servant de pont qui convertit en série 8 bits pour le Pi serait la réponse la plus simple et la plus fiable.
Lots of STM32s do 9-bit natively. A Blue Pill as a bridge that translates to 8-bit serial for the Pi would be the boring, reliable answer.
Traduit de English par IA ·
Je suis nouveau côté matériel, mais j’ai fait du travail sur les protocoles série en logiciel pendant des années, et on peut simuler cela avec la parité. Le 9e bit est envoyé à la place du bit de parité. Linux prend en charge la parité « stick » via le drapeau CMSPAR : avec PARENB|CMSPAR|PARODD, le bit de parité vaut toujours 1 (mark), sans PARODD il vaut toujours 0 (space).Donc : régler la parité mark, écrire l’octet d’adresse, attendre qu’il soit parti (tcdrain), passer en parité space, écrire les octets de données. 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 réception est la partie la plus pénible : activez PARMRK et INPCK, et un octet avec la « mauvaise » parité arrive précédé de 0xFF 0x00, ce qui vous indique son 9e bit. À 9600 bauds, le temps entre l’octet d’adresse et les octets de données présente un petit écart dû au changement de mode, mais la plupart des anciens appareils s’en moquent. Utilisez l’UART PL011 (disable-bt), et non le mini UART, car le mini UART n’a pas de parité.Ensuite, chaque indicateur est envoyé comme un enfant, par exemple {« scale-1 »: {« values »: {« kg »: 12.45}}} sur 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.
Traduit de English par IA ·
Kevin, ça marche. Octet d’adresse avec mark, données avec space, PARMRK côté réception. Les indicateurs 1, 2 et 4 ont répondu du premier coup, le numéro 3 voulait un intervalle de 2 ms après l’adresse, que j’ai ajouté. Les équipements enfants sont apparus dans Hermetry dès le premier v1/gw/telemetry. Je garde l’idée STM32 de Jason comme plan B si les gens de la ligne se plaignent.
Kevin, it works. Address byte with mark, data with space, PARMRK on the receive side. Indicators 1, 2 and 4 answered first try, number 3 wanted a 2 ms gap after the address, which I added. The children appeared in Hermetry on the first v1/gw/telemetry. Keeping Jason’s STM32 idea as plan B if the line people complain.
- Vous devez être connecté pour répondre à ce sujet.
Rejoignez la discussion
Connectez-vous pour poser et répondre à des questions, aimer les messages utiles et marquer la réponse qui a résolu votre problème. Chaque contribution rapporte des points et des niveaux.

