Välkommen till linuxportalen.se!

Linuxportalen.se är Sveriges största och aktivaste webbplats för användare av öppen- och fri programvara.

Du besöker Linuxportalen.se som gäst vilket begränsar din möjlighet att använda webbplatsens alla funktioner. Genom att registera dig som medlem får du inte bara möjlighet att söka bland webbplatsens innehåll, skapa nya och delta i befintliga diskussioner, skapa din egen blogg, kommunicera med andra medlemmar genom privata meddelanden och delta i omröstningar. Du får också tillgång till Veckans Kadavro - en seriestrip unikt skapad för Linuxportalen.se!

Registeringen sker snabbt och är helt kostnadsfri - tveka inte, bli medlem idag!

purge och handflow med pyserial?

Har vi en serieports- och pythonprogrammerare ibland oss? Tacksam för hjälp, i sådana fall. Jag har sniffat trafiken över serieporten i Windows mellan ett program och en klocka, där sniffloggen visar att programmet öppnar porten och gör vissa inställningar, och sedan skickar en 11 byte kommandosekvens till klockan. Klockan svarar med data. Se logg längre ned.

När jag försöker göra samma inställningar och skicka samma kommandosekvens får jag ingen data till svar. Antingen lyckas jag inte implementera inställningsfasen ordentligt, eller så skickar jag hexkoder på fel sätt. Alternativt har jag gjort fel i koden som läser från porten. Var felet än ligger, är jag tacksam för all hjälp jag kan få. Jag har stångats med detta ett tag nu.

Snifflogg från Windows, innan data skickas och tas emot:

COM port is opened
In/out queue size 1024/1024
Purge the serial port: RXABORT, RXCLEAR, TXABORT, TXCLEAR
Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=5000
Baud rate 2400
RTS off
DTR on
Data bits=8, Stop bits=2, Parity=None
Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL), FlowReplace=(), XonLimit=256, XoffLimit=256

Min pythonkod, framför allt funderar jag på hur jag implementerar "Purge the serial port: RXABORT, RXCLEAR, TXABORT, TXCLEAR" och "Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL), FlowReplace=(), XonLimit=256, XoffLimit=256" från loggen ovan i python:

import serial, time, sys
ser = serial.Serial("/dev/ttyUSB0")
ser.flushInput()
ser.flushOutput()
ser.timeout = 5
ser.baudrate = 2400
ser.dsrdtr = 1
ser.bytesize = serial.EIGHTBITS
ser.stopbits = 2
ser.parity = serial.PARITY_NONE
ser.xonxoff = 1
print ser
print ser.portstr

ser.write(serial.XON)
ser.write(serial.XOFF)
ser.setDTR(True)
# sending command "get data": "00 AA 55 02 00 00 00 00 00 00 01"
ser.write('\x00\xaa\x55\x02\x00\x00\x00\x00\x00\x00\x01')

Och i en annan terminal kör jag ett lässkript, med samma inställningar som i skriv-skriptet men med nedanstående loop:

    while True:
        data = ser.read()
        if len(data) > 0:
            print 'Got:', data

        time.sleep(0.5)

Alternativ för kommentarvisning

Välj ditt önskade sätt att visa kommentarerna och klicka på "Spara" för att verkställa dina ändringar.

forslunds bild

Enligt vad jag kan förstå görs RX_ABORT i samband med RX_CLEAR (.flushInput() ) och respektive för TX. RX/TX_ABORT clearar pågående skrivningar till respektive kö i windows, linux/posix verkar inte ha lika finkorning kontroll. Detta grundar jag på kod jag hittade för wine (rad 408-420), men det kan fungera olika beroende på hur termios är implementered i ditt valda os.

Är du säker på att get-kommandot är riktigt? Har du någon USB->serial som du kan använda för att köra ett loopback-test? (DVS koppla ihop Rx med Tx och se ifall du får tillbaka det du skickat)

/Åke

 

I am not a number, I am a free man!

paraxelssons bild

Hej Åke! Nä, jag har ingen sådan, men jag kanske kan skapa virtuella portar som jag sedan kan koppla ihop för att testa; jag får titta på det. Tack för tipset!

forslunds bild

Angående XON/XOFF's värden verkar det vara default som används. Eof, Break, Error och Event är lurigare jag har aldrig ens hört om dessa tidigare.

Du skulle kanske kunna porta över koden till windows och sniffa den för att jämföra hur nära du kommer? Experimentera tills det funkar där och sedan porta över den till Linux?

vad gör

ser.write(serial.XON)

ser.write(serial.XOFF)

Vad använder du för program för att få den fina loggen över inställningarna? Det ser riktigt praktiskt ut.

/Åke

 

I am not a number, I am a free man!

paraxelssons bild

ser.write(serial.XON) resp XOFF skickar XON och XOFF, en del i mitt försök att implementera handshake. Men jag har testat utan det också, ingen skillnad.

Programmet kommer från http://www.kmint21.com/serial-port-monitor/ men är varken öppet eller gratis. Jag använder 15-dagars provversionen. I linux har jag sniffat med http://wiki.freaks-unidos.net/weblogs/arhuaco/rs232-serial-sniffer och qemu:

qemu ... -serial udp:127.0.0.1:2000@127.0.0.1:2001

 

forslunds bild

Där ser man, jag har bara använt de enklaste funktionerna i pyserial ser jag. Det är ett smidigt paket som har fungerat riktigt bra för mina behov, som inte har involverat flödeskontroll hitintills...

Jag tror fortfarande på att köra python-scriptet i windows och använda samma sniffer för att kontrollera hur nära du kommer det önskade resultatet. Jag är lite paraniod, men det kan hända att qemu-sniffern utelämmnar viss information som serialport monitor visar.

Ifall du vill ha mer förståelse för vad pyserial gör så kolla källkoden, den är inte alls särskillt svår att förstå.

Håll mig gärna uppdaterad om dina framsteg, det är alltid roligt att lära sig något nytt =)

/Åke

 

I am not a number, I am a free man!