Fragen zu PySerial und Basisdatentypen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
suho
User
Beiträge: 5
Registriert: Montag 14. Januar 2008, 20:59

Fragen zu PySerial und Basisdatentypen

Beitragvon suho » Donnerstag 28. Februar 2008, 17:03

Hallo!

Ich habe ein Programm für einen AVR 8-bit Mikrocontroller geschrieben welches unter anderem Daten über sie serielle Schnittstelle überträgt. Zur fehlerfreien Übertragung wird auch ein CRC Wert der Daten gesendet der mit folgender C-Funktion berechnet wird:

Code: Alles auswählen

uint16_t crc_xmodem_update(uint16_t crc, uint8_t data) {
   int i;
   crc = crc ^ ((uint16_t)data << 8);
   for (i=0; i<8; i++) {
      if(crc & 0x8000)
         crc = (crc << 1) ^ 0x1021;
      else
         crc <<= 1;
   }
   return crc;
}


Ich möchte jetzt ein Prgramm in Python schreiben um mit dem Mikrocontroller zu kommunizieren. Dazu 2 Fragen:
1. Gibt es mit PySerial eine Möglichkeit eine Liste der zur Verfügung stehenden seriellen Schnittstellen zu bekommen?
2. Ich habe die CRC Funktion folgendermaßen in Python umgesetzt finde die Lösung aber ineffizient, da ich "unnötige" Formatierungen vornehmen muss da Python keinen reinen 8-bit char oder 16-bit int datentyp besitzt mit dem man logisches rechts/links-schieben betreiben kann:

Code: Alles auswählen


def crc_xmodem_update(crc, data):
   crc = crc ^ (data << 8)
   for i in range(8):
      if(crc & 0x8000):
         crc = (crc << 1) ^ 0x1021
      else:
         crc = crc << 1
   crc -= (crc >> 16)*(1 << 16)
   return crc

def get_crc(data):
   crc = 0xFFFF
   for c in data:
      crc = crc_xmodem_update(crc, ord(c))
   return crc


Meine Frage ist ganz einfach: Würdet ihr das so machen oder etwa anders? Es ist für mich schon recht interessant da ich bei der Datenübertragung immer 8-bit Zeichen sende und dann ständig mit chr, odr, int usw die typen wandeln muss.
BlackJack

Beitragvon BlackJack » Donnerstag 28. Februar 2008, 17:33

Sieht ganz okay aus.

Bis auf Zeile 10, die ziemlich kompliziert ``crc &= 0xfff`` implementiert. :-)

Eventuell bringt es etwas eine ganze Zeichenkette mit dem `array`-Modul in Zahlen um zu wandeln, statt die einzelnen Zeichen mit `ord()`, aber ansonsten sieht das schon ganz gut aus.

Falls das doch ein Flaschenhals im Programm werden sollte, kannst Du's ja immer noch mit Psyco, Cython, oder C via `ctypes` angebunden versuchen. :-)
BlackJack

Beitragvon BlackJack » Donnerstag 28. Februar 2008, 17:40

Ungetestet:

Code: Alles auswählen

from itertools import imap

def crc_xmodem_update(crc, data):
    crc ^= data << 8
    for dummy in xrange(8):
        crc <<= 1
        if crc & 0x8000:
            crc ^= 0x1021
    return crc & 0xffff

def get_crc(data):
    return reduce(crc_xmodem_update, imap(ord, data), 0xffff)
suho
User
Beiträge: 5
Registriert: Montag 14. Januar 2008, 20:59

Beitragvon suho » Donnerstag 28. Februar 2008, 18:04

Hmm ok, besten dank, die Funktion reduce() kannte ich noch nich
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Re: Fragen zu PySerial und Basisdatentypen

Beitragvon HWK » Freitag 29. Februar 2008, 16:59

suho hat geschrieben:1. Gibt es mit PySerial eine Möglichkeit eine Liste der zur Verfügung stehenden seriellen Schnittstellen zu bekommen?
Vielleicht so:

Code: Alles auswählen

from serial import Serial
ports = []
for port in range(8):
    try:
        s = Serial(port)
        ports.append(str(port))
    except:
        pass
print 'Vorhandene COM-Ports:', ', '.join(ports)
MfG
HWK
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Samstag 1. März 2008, 14:52

Die 1. Variante berücksichtigt einen vorhandenen Port nicht, wenn auf ihn nicht zugegriffen werden kann, weil er z.B. schon verwendet wird. Es sollten deshalb alle Ports, die beim Öffnen nicht Fehler Nr. 2 ('Das System kann die angegebene Datei nicht finden.') auslösen, in die Liste aufgenommen werden. Deshalb ein neuer Versuch:

Code: Alles auswählen

from serial import Serial, SerialException
ports = []
for port in range(8):
    try:
        s = Serial(port)
    except SerialException, error:
        if error[0].startswith('could not open port: (2,'):
            continue
    ports.append(port)
print 'Vorhandene COM-Ports:', ', '.join(str(x) for x in ports)
MfG
HWK

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder