2016-05-07 11 views
1

Ich arbeite mit Canbus in Python (Pcan grundlegende API) und möchte es einfacher zu bedienen.High Level/Abstract Canbus Schnittstelle in Python

Über den Bus werden viele Geräte/Module angeschlossen. Sie dürfen alle Daten senden, wenn eine Kollision eintritt, wird die niedrigste ID gewonnen.

Die Daten werden in Rahmen organisiert mit ID, SubID, hexvalues ​​

das Problem zu veranschaulichen, ich bin versucht, Adresse, die Amplitude eines Signals vorstellen.

Um den Wert ein Rahmen senden

  • QuestionID QuestionSUBID QuestionData

zu lesen Wenn es keine Meldung mit höherer Priorität (= lowerID) ist die Antwort auf den Bus geschrieben wird:

  • answerID AnswerSubID AnswerData

Da jedes Modul/Gerät auf den Bus schreiben darf, wissen Sie nicht im Voraus, welche Antwort Sie als nächstes bekommen. Einen Wert zu setzen morks den gleichen Weg, nur mit verschiedenen IDs. So für das obige Beispiel würde die Amplitude:

  1. 4-IDs und SubIDs Verbunden mit Lese/Schreib-Frage/Antwort
  2. Zusätzlich wird die Länge der Daten hat (0-8) hat angegeben/gespeichert werden.
  3. Da die Daten all hex-Werte ein Parser den für Menschen lesbaren Wert (zB Spannung in Dezimaldarstellung) zu spezifizieren hat

Um diese Informationen zu erhalten, zu speichern I nested dicts verwenden:

parameters = {'Parameter_1': {'Read': {'question_ID': ID, 
             'question_SUBID': SubID, 
             'question_Data': hex_value_list, 
             'answer_ID': ..., 
             'answer_subID': ..., 
             'answer_parser': function}, 
           'Write': {'ID': ..., 
             'SubID': ..., 
             'parser' ..., 
             'answer_ID': ..., 
             'answer_subID': ...}}, 
       'Parameter_2': ... }} 

Es gibt viele Tools, die zeigen, welcher Wert wann eingestellt wurde, aber für die Hardwaresteuerung ist die Reihenfolge, in der die Parameter gelesen werden, nicht relevant, solange sie aktuell sind. Somit ist ein Teil einer möglichen Lösung wäre, den gesamten Verkehr in einem dict von dicts Speicherung:

busdata = {'firstID' : {'first_subID': {'data': data, 
             'timestamp': timestamp}, 
         'second_subID': {'data': data, 
             'timestamp': timestamp}, 

         }, 
      secondID': ...} 

Aufgrund der Natur des Busses, erhalte ich eine Menge Antworten andere Geräte gefragt - der Bus ist ziemlich voll - Diese sollten nicht verworfen werden, da sie möglicherweise die Werte sind, die ich als nächstes brauche, und es besteht keine Notwendigkeit, zusätzlichen Verkehr zu erzeugen - ich könnte den Zeitstempel mit einem Ablaufdatum verwenden, aber darüber habe ich bisher nicht viel nachgedacht.

Das funktioniert, aber es ist schrecklich mit zu arbeiten. Im Allgemeinen werde ich ungefähr 300 Parameter haben. Das letzte Ziel besteht darin, die Geräte über ein (pyqt) Gui zu steuern, einige Werte wie Seriennummern zu lesen, aber auch Messaufgaben auszuführen.

Die große Frage ist also, wie man eine bessere Datenstruktur definiert, die leicht zugänglich und verständlich ist? Ich freue mich auf jeden Vorschlag für ein sauberes Design.

Das Hauptziel wäre etwas wie los von der ganzen Nachricht basierte Ansatz.

EDIT: Mein Ziel ist die gesamten CAN-basierte aproach bestimmte Nachricht loszuwerden:

ich, dass ich für die Kommunikation einen Thread muß davon ausgehen, soll es:

  1. die Puffer lesen und aktualisieren meine Variablen
  2. senden Anfragen (Nachrichten) an andere Werte/Variablen erhalten
  3. einige Werte senden periodisch

vom gui Also ich würde gerne derte:

  1. get Parameter nach Namen -> str (name), Wert -> einen String mit Parameternamen
  2. Einstellparameterregister Signal senden (als displayedin die gui)
  3. get Werte in regelmäßigen Abständen -> Name, Intervall, Dauer (10s oder unendlich)

Der Faden müßte:

  1. Log alle Daten auf dem Bus für interne Speicher
  2. Prozessanforderungen von Nachrichten von Name, Wert zu erzeugen und lesen, bis Ergebnis
  3. Senden periodischer Signale

erhalten wird Ich mag diesen Entwurf idependant haben der tatsächlichen Hardware:

  • die Lösung, die ich dachte, ist das oben parameters_dict

für den internen Speicher dachte ich über die bus_data_dict

Noch ich bin nicht sicher, wie man:

  1. Pass Daten vom Bus Thread zu dem gui (alle Werte vs. neu/angeforderter Wert)
  2. So implementieren Sie es mit Signalen und Steckplätzen in pyqt
  3. Speichern Sie Daten intern (Diktat oder einige neue bessere Idee)
  4. Wenn dieser Entwurf eine gute Wahl
+0

machen Sie eine Klasse, die dies abstrahiert ... Canbus basiert vollständig auf Nachrichtenpakete, so dass ich glaube nicht, Sie können es beseitigen ... aber Sie können es sicherlich abstrahieren ... –

+0

Ja, natürlich. Vielleicht habe ich das deutlich genug gesagt. Die Frage ist, wie dies zu implementieren ist. Ich dachte über Eigenschaften mit richtigen Gettern und Setter nach - trotzdem würde ich eine interne Darstellung der Daten benötigen. – slepton

Antwort

0
class MySimpleCanBus: 
     def parse_message(self,raw_message): 
      return MyMessageClass._create(*struct.unpack(FRAME_FORMAT,msg)) 
     def recieve_message(self,filter_data): 
      #code to recieve and parse a message(filtered by id) 
      raw = canbus.recv(FRAME_SIZE) 
      return self.parse_message(raw) 
     def send_message(msg_data): 
      # code to make sure the message can be sent and send the message 
      return self.recieve_message() 

class MySpecificCanBus(MySimpleCanBus): 
    def get_measurement_reading(): 
     msg_data = {} #code to request a measurement 
     return self.send_message(msg_data) 
    def get_device_id(): 
     msg_data = {} # code to get device_id 
     return self.send_message(msg_data) 

ich nicht wahrscheinlich Ihre Frage richtig verstehen ... vielleicht könnten Sie es mit weiteren Details aktualisieren

1

die python-can Bibliothek können Sie Zeit die Vernetzung erhalten thread - gibt Ihnen eine gepufferte Warteschlange von eingehenden Nachrichten. Die Bibliothek unterstützt unter anderem die PCAN-Schnittstelle.

Dann würden Sie einen Middleware-Layer erstellen, der diese can.Message-Typen in pyqt-Signale konvertiert und routet. Stellen Sie sich dies als eine von vielen Quellen von Ereignissen/Signalen vor.

Ich würde einen anderen Controller verwenden, der für das Senden von Nachrichten an den Bus verantwortlich ist. Es könnte Aufgaben wie periodische Messungen vom Bus anfordern, sowie Anfragen auf Anfrage, die von der GUI gesteuert werden.

In Bezug auf die interne Speicherung der Daten hängt es wirklich von Ihrem Programmierstil und der Komplexität ab. Ich habe Projekte gesehen, bei denen jede CAN-Nachricht ihre eigene Klasse hat.

Endlich sind Warteschlangen Ihr Freund!

+0

Danke. Ich habe einen ziemlich ähnlichen Weg genommen, immer noch versucht, es zu einem mvc-Muster zu abstrahieren. Python-can funktioniert nur mit dem gleichen Beispiel wie das Peak-System. Ich habe ihren Code korrigiert, indem ich Unicode in Byte-Strings umgewandelt habe. – slepton

+0

Was meinst du mit "Python-kann nur mit"? In jedem System müssen Sie sicherstellen, dass Sie Bytes an den Bus senden. – Hardbyte

0

Vereinbaren Sie mit @Hardbyte auf die Verwendung von python-can. Es ist exzellent.

Soweit Messaging zwischen App-Schichten, hatte ich viel Glück mit Zero MQ - Sie können Ihre Module als ereignisbasiert, von der Canbus-Ereignis bis hin zu aktualisieren eine UI oder was auch immer.

Für Datenspeicherung/Persistenz, ich lasse Nachrichten in SQLite und parallel (mit ZMQ Pub/Sub Muster) die Daten an einen IoT-Hub (über MQTT) übergeben.

Verwandte Themen