Forum: Mikrocontroller und Digitale Elektronik Temperatur über CAN Bus übertragen


von Tobias R. (elkokiller)


Lesenswert?

Hallo,

ich möchte gerne verschiedene Temperaturen im Haus erfassen und über 
einen eigenen CAN Bus übertragen.
Meine Frage ist, ob es eine besondere Syntax gibt an der ich mich 
orientieren kann.
Ich habe ja 8 Byte. Ich würde jetzt mal ganz plump so vorgehen dass im 
ersten das Vorzeichen steht, im zweiten die Vorkommazahl und im dritten 
die Nachkommazahl.
Hat jemand einen besseren, vielleicht auch genormten Vorschlag?

Tobias

von dummschwaetzer (Gast)


Lesenswert?

deine Temperaturen werden bestimmt auch mal zwei Vorkommastellen haben.
Da du eh schon Kommazahlen hast Übertrage doch gleich float.

Die Messstelle decodierst du in der ID?

von Wolfgang (Gast)


Lesenswert?

dummschwaetzer schrieb:
> Da du eh schon Kommazahlen hast Übertrage doch gleich float.

Du machst deinem Namen alle Ehre. Der Dynamikbereich von Temperaturen im 
Haus ist fest definiert. Alle Bits, die bei float für den Exponenten 
benötigt werden, sind "rausgeschmissenes Geld". Der DS18B20 macht vor, 
wie man Temperaturwerte datensparsam mit 12 Bit kodieren und dabei mit 
einer Auflösung von 1/16K übertragen kann.

von Sebastian (Gast)


Lesenswert?

Tobias R. schrieb:
> Hat jemand einen besseren Vorschlag?

Ich benuzte für solche Daten JSON.
Datenframes sind immer 8 Bytes lang. Der Schlussframe ist kürzer und 
enthält die genaue Länge und eine Prüfsumme.

Tobias R. schrieb:
> Hat jemand einen besseren Vorschlag?

JSON. Mit ein bisschen Protokoll.

LG, Sebastian

von dummschwaetzer (Gast)


Lesenswert?

ER HAT 8BYTE 64BIT, der braucht nicht mit Bits zu sparen.
Er will sein eigenes Protokoll festlegen. Derzeit Temperaturen, aber 
morgen villeicht schon andere Werte.
Dazu kann mann natürlich auf Sender und Empfängerseite irgendwelche 
Bitschubsereien machen, die aber alle nur Rechenzeit brauchen, aber in 
meinen Augen keinen praktischen nutzen haben.

von Kevin M. (arduinolover)


Lesenswert?

Sebastian schrieb:
> Ich benuzte für solche Daten JSON.
> Datenframes sind immer 8 Bytes lang. Der Schlussframe ist kürzer und
> enthält die genaue Länge und eine Prüfsumme.

Dir ist aber schon bewusst wie CAN funktioniert?

Wolfgang schrieb:
> "rausgeschmissenes Geld"

schade nur das er onehin alles schon bezahlt hat, also kann er die Bytes 
auch nutzen, ist das gleiche mit RAM und Flash, geld zurück für nicht 
genutzt gibt es nämlich nicht.

Tobias R. schrieb:
> Hat jemand einen besseren, vielleicht auch genormten Vorschlag?

Wenn du mehrere Messtellen hast wird jede ein CAN Teilnehmer sein, 
demnach hat jedes seine eigene ID, wieviele Datenbytes du verschickst 
ist diene sache das geht von 1 bis 8. Du musst wissen wie genaud eine 
Messung ist / sein soll. 16 Bit reichen vermutlich, du kannst also deine 
Temperatur als int16 versenden (multipliziert mit 10 oder 100, je nach 
gewünschten Nachkommastellen) oder nimmst gleich float, weil es sowieso 
egal ist.

von Sebastian (Gast)


Lesenswert?

Kevin M. schrieb:
> Dir ist aber schon bewusst wie CAN funktioniert?

Ja klar, wieso?

LG, Sebastian

von dummschwaetzer (Gast)


Lesenswert?

In der Industrie ist üblich:
Wert=a*x+b
x: wird übertragen, unsigned char(8Bit) oder int(16Bit)
a und b sind Konstanten für Auflösung und Wertebereich.
a und b können auch negativ und/oder Fließkommazahlen sein.

von Tobias R. (elkokiller)


Lesenswert?

Hi,
Danke für die anregende Diskussion.

Kevin M. schrieb:
> Wenn du mehrere Messtellen hast wird jede ein CAN Teilnehmer sein,
> demnach hat jedes seine eigene ID, wieviele Datenbytes du verschickst
> ist diene sache das geht von 1 bis 8. Du musst wissen wie genaud eine
> Messung ist / sein soll. 16 Bit reichen vermutlich, du kannst also deine
> Temperatur als int16 versenden (multipliziert mit 10 oder 100, je nach
> gewünschten Nachkommastellen) oder nimmst gleich float, weil es sowieso
> egal ist.

Vollkommen Richtig!
Genau so wollte ich es auch machen. Bevor ich jetzt aber in diese 
Richtung weiter gehe dachte ich, fragst mal ob es da vielleicht schon 
etwas gibt.
Gut möglich dass meine Sensoren dann auch noch weitere Informationen 
sammeln.

Ich würde dann so vorgehen: (Dezimalwerte)
ID 120 überträgt +37,5°C
Byte1: 100 (als Kennzeichen für Temperatur)
Byte2: 001 (Positiv)
Byte3: 037 (Vor Komma)
Byte4: 005 (Nach Komma)

von Tobias R. (elkokiller)


Lesenswert?

dummschwaetzer schrieb:
> In der Industrie ist üblich:
> Wert=a*x+b
> x: wird übertragen, unsigned char(8Bit) oder int(16Bit)
> a und b sind Konstanten für Auflösung und Wertebereich.
> a und b können auch negativ und/oder Fließkommazahlen sein.

Wie würde dann die Übertragung von +37,5°C aussehen?

von dummschwaetzer (Gast)


Lesenswert?

je nach deiner gewünschten auflösung/wertebereich
Auflösung: 0,1°C -->a=0,1
Wertebereich: wenn du ab -40°C anfangen willst: b=-40
37,5=0,1*can_wert-40
darft du dir selber nach can_wert umstellen.

von dummschwaetzer (Gast)


Lesenswert?

>Byte1: 100 (als Kennzeichen für Temperatur)
ist eigentlich bereits aus der CAN-ID ersichtlich, kann weg

von Rudolph R. (rudolph)


Lesenswert?

Aus dem Auto kenne ich das als skalierten unsigned Wert mit Offset.
Wenn man eine Auflösung von 0,2° haben will multipliziert man halt mit 
5.
Wenn man von -40°C bis 125°C darstellen will braucht man einen Offset 
von 200 und der maximal-Wert ist dann 825.
Temperaturen im Haus wird man eher nicht so breit erfassen müssen, 0°C 
bis 40°C sollten doch reichen? Mit 0,2° Auflösung ist das ein Wert von 0 
bis 200.

24,4°C -> 24,4 * 5 = 122 -> 122 * 2 = 244

von Tobias R. (elkokiller)


Lesenswert?

dummschwaetzer schrieb:
>>Byte1: 100 (als Kennzeichen für Temperatur)
> ist eigentlich bereits aus der CAN-ID ersichtlich, kann weg

Die 100 würde ich als Kennzeichen für einen Temperaturwert nehmen.
Eine 200 z.B. für eine Schalterstellung


@dummschwaetzer und @Rudolph R.
danke für eure Erläuterung. Die lasse ich mir mal durch den Kopf gehen

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

dummschwaetzer schrieb:
> ist eigentlich bereits aus der CAN-ID ersichtlich, kann weg

Wenn der Sensorknoten auch andere Werte übermitteln soll und die ID nur 
den Knoten beschreibt, könnte ein Wertetyp sinnvoll sein. Jedoch würde 
ich dies auch in der ID kodieren, da dafür Filter gesetzt werden können. 
Der Empfänger (oder nennen wir es besser Konsument) reagiert dann nur, 
wenn es wirklich ein Temperaturwert einer ihm genehmen Messstelle ist.

: Bearbeitet durch User
von dummschwaetzer (Gast)


Lesenswert?

>Eine 200 z.B. für eine Schalterstellung
hätte bei mir eine andere ID.

von Wolfgang (Gast)


Lesenswert?

Christian H. schrieb:
> Wenn der Sensorknoten auch andere Werte übermitteln soll und die ID nur
> den Knoten beschreibt, könnte ein Wertetyp sinnvoll sein.

Bei CAN kennzeichnet der Objekt-Identifier normalerweise den Inhalt der 
Nachricht und nicht den Knoten. Sonst muss der CAN-Frame, mit dem die 
Temperatur von einem Gerät übertragen wird, dass Temperatur und Feuchte 
misst, anders dekodiert werde, als der von einem reinen 
Temperatursensor.
Die 2048 Identifier des Base Frame Formats sollten für die Messstellen 
im Haus evtl. doch reichen.

von dummschwaetzer (Gast)


Lesenswert?

>Aus dem Auto kenne ich das als skalierten unsigned Wert mit Offset.
Wert=a*x+b a: Skalierung,b: Offset

von Kevin M. (arduinolover)


Lesenswert?

Tobias R. schrieb:
> Ich würde dann so vorgehen: (Dezimalwerte)
> ID 120 überträgt +37,5°C
> Byte1: 100 (als Kennzeichen für Temperatur)
> Byte2: 001 (Positiv)
> Byte3: 037 (Vor Komma)
> Byte4: 005 (Nach Komma)

Das wäre nun wirklich Verschwendung, bei CAN Nachrichten enthält idr. 
die ID die Information über den Inhalt, es gibt auch gemultiplexte 
Werte, wobei ich persönlich das nicht so schön finde, das ist aber 
Geschmackssache.

An deiner Stelle würde ich sowas machen:
ID: XYZ (pro Messtelle eben einen)
Byte 1/2 -> int16 -> Temperaturmesswert*10
Byte 3/4 -> int16 -> Feuchtewert*10
usw.

Alternativ:
Byte 1 -> Multiplexor
Byte 2/3 -> Entsprechender Messwert

von Sebastian W. (wangnick)


Lesenswert?

Kevin M. schrieb:
> Sebastian schrieb:
>> Ich benuzte für solche Daten JSON.
>> Datenframes sind immer 8 Bytes lang. Der Schlussframe ist kürzer und
>> enthält die genaue Länge und eine Prüfsumme.
>
> Dir ist aber schon bewusst wie CAN funktioniert?

Ich sollte vielleicht meinen Vorschlag, JSON zu benutzen, etwas 
erläutern.

Ich benutze CAN als Haus- und Gartenbus, sowohl für Sensoren 
(Temperatur, Stand Öltank, Bodenfeuchte, ...) als auch für Aktoren (in 
meinem Fall bis dato Bewässerungsventile). Einer der Knoten vermittelt 
zwischen MQTT und CAN. Gesteuert wird über node-red, dort werden alle 
Messdaten auch in eine PostgreSQL-Datenbank geschrieben. Messdatenpakete 
werden im JSON-Format auf dem CAN-Bus übertragen und 1:1 an MQTT 
weitergereicht. Die Haupttabelle in der Datenbank hat auch nur genau 
drei Spalten: ROWID, TIMESTAMP und JSON.

Ein Messpaket sieht z.B. so aus:
1
2021-06-20T19:10:32.229092Z iot/status/10 {"topic":"haus","ms":80400158,"id":12810,"no":10,"sw":"iot_haus01.ino,Jun  5 2021 12:52:14,10813","hw":"iom328pb.h,16000000L,8000000,SPI1","cycle":1341,"valve":"ON","hlst":0,"hlms":67445639,"hl":345,"oelus":4920,"oelmm":843.5,"oelliter":2516.6,"S1F":49.6,"S1T":26.2,"S4F":59.3,"S4T":23.8,"S6F":53.4,"S6T":27.4,"S7F":45.8,"S7T":27.4,"S8F":49.7,"S8T":26.6,"S9F":1.4,"S9T":20.1,"oams":80390158,"oems":80392771,"Tim":"2021062007210149","AuT":22.7,"KeT":74.2,"SpT":62.0,"AuI":22.8,"AuG":23.6,"KeI":74.2,"SpI":62.1,"MaT":170.5,"BrU":0,"BrE":0,"B1Z":0,"B2Z":0,"BrN":199229,"B1S":92417920,"B2S":1956158,"SpP":0,"ZiP":0,"H1P":0,"SaE":0,"B1X":"020000000000460001060001C8000000004600FFFFFF","W1A":0,"Sp1":0,"Py1":0,"Fr1":255,"SpS":60,"ci":1}

Ich habe für die Übertragung per CAN-Bus drei Datenarten definiert. 
Erstens sendet jeder Knoten alle 10 Sekunden einen Heartbeat. Das ist 
ein einzelner CAN-Frame mit Knoten-Id und Laufzeit seit Reboot. Zweitens 
kann jeder Knoten JSON-Daten senden. Dabei wird der JSON-Text in jewils 
8 Byte lange CAN-Frames zerhackt und im Anschluss ein Kontrollframe mit 
genauer Länge und Prüfsumme gesendet. Die Kommandos für die 
Aktor-Befehle sende ich ebenfalls auf diese Weise als JSON; das 
Dekodieren der JSON-Befehle ist nicht so aufwändig wie zunächst gedacht. 
Drittens gibt es noch ein Protokoll für die Übertragung neuer Software 
auf die Knoten. Über MQTT werden HEX-Dateien im Klartext übertragen und 
dann binär auf den CAN-Bus übergesetzt und am Zielknoten von einem 
CAN-Bootloader verarbeitet.

Nicht alles ist das Gelbe vom Ei, aber bisher würde ich es wieder so 
oder so ähnlich machen. Ich würde mit Sicherheit nicht für jedes Datum 
eine separate Kodierung handhaben wollen.

LG, Sebastian

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Sebastian W. schrieb:
> Das ist ein einzelner CAN-Frame mit Knoten-Id und Laufzeit seit Reboot.
> Zweitens kann jeder Knoten JSON-Daten senden. Dabei wird der JSON-Text
> in jewils 8 Byte lange CAN-Frames zerhackt und im Anschluss ein
> Kontrollframe mit genauer Länge und Prüfsumme gesendet.

CAN wurde im Jahr 1983 für schnelle Datenübertragung entwickelt, aber 
bestimmt nicht, um "mehrbändige" Prosa von einem Ort zum anderen zu 
transferieren.

von Kevin M. (arduinolover)


Lesenswert?

Sebastian W. schrieb:
> Nicht alles ist das Gelbe vom Ei, aber bisher würde ich es wieder so
> oder so ähnlich machen.

JSON mag zwar nett sein wenn man in einer Serverumgebung arbeitet und 
Rechenpower keine Rolle spielt, auf einem embedded System hat es aber 
imho nichts zu suchen. Gerade die Verarbeitung der Daten auf den Knoten 
hat so unnötg viel Overhead. Man schickt ja auch nicht 8 Byte um 8 
Zustände (Ein/Aus) zu verschicken.

von Flip B. (frickelfreak)


Lesenswert?

leider wird das immer mehr zum trend. Zur strukturierten serialisierung 
empfehle ich stattdessen https://developers.google.com/protocol-buffers 
, damit werden sogar führende nullen an langen integertypen nicht mehr 
unnötig übertragen.
https://developers.google.com/protocol-buffers/docs/encoding

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Kevin M. schrieb:
> JSON mag zwar nett sein wenn man in einer Serverumgebung arbeitet und
> Rechenpower keine Rolle spielt

Spätestens wenn LoRa für weiter abgesetzte Sensoren ins Spiel kommt, 
wird man sich solche JSON-Weitschweifigkeiten verkneifen.

von Sebastian (Gast)


Lesenswert?

Wolfgang schrieb:
> CAN wurde im Jahr 1983 für schnelle Datenübertragung entwickelt, aber
> bestimmt nicht, um "mehrbändige" Prosa von einem Ort zum anderen zu
> transferieren.

Mag ja sein, aber ich habe mehrere Ventilkästen im Garten, und da bietet 
sich ein Softwareupdate über den Bus einfach an.

Kevin M. schrieb:
> Gerade die Verarbeitung der Daten auf den Knoten hat so unnötg viel
> Overhead.

Senden hat kaum Overhead. Das Parsen der Kommandos ist auch akzeptabel 
wenn man per Konvention nicht schachtelt.

Schwierig ist die fehlende Flusskontrolle. Macht zwar Broadcasts 
möglich, aber: Der MCP2515 z.B. hat nur zwei Empfangspuffer (plus MAB), 
heisst der Empfänger muss einen ersten Frame abholen bevor ein dritter 
angekommen ist. Und wenn am selben SPI-Bus noch ein Display hängt muss 
man ziemlich turnen um keines zu verpassen ...

LG, Sebastian

von (prx) A. K. (prx)


Lesenswert?

Wolfgang schrieb:
> CAN wurde im Jahr 1983 für schnelle Datenübertragung entwickelt, aber
> bestimmt nicht, um "mehrbändige" Prosa von einem Ort zum anderen zu
> transferieren.

Das hat mich nicht daran gehindert, den kompletten Inhalt eines 4 MBit 
Dataflash über CAN zu schieben. ;-)

von jo (Gast)


Lesenswert?

Tobias R. schrieb:
> ich möchte gerne verschiedene Temperaturen im Haus erfassen und über
> einen eigenen CAN Bus übertragen.
> Meine Frage ist, ob es eine besondere Syntax gibt an der ich mich
> orientieren kann.
> Ich habe ja 8 Byte. Ich würde jetzt mal ganz plump so vorgehen dass im
> ersten das Vorzeichen steht, im zweiten die Vorkommazahl und im dritten
> die Nachkommazahl.
> Hat jemand einen besseren, vielleicht auch genormten Vorschlag?

Wie schon mehrfach erwähnt spricht sehr viel für JSON.

Ich würde mir trotzdem mal
https://de.linkfang.orghttps://de.linkfang.org/wiki/Controller_Area_Network
anschauen, dort speziell das Kapitel "Objekt-Identifier".

Ich hatte früher mal mit NMEA-0183 zu tun, könnte mir vorstellen, dass 
ein an NMEA angelehtes Protokoll deine Anwendung abdecken könnte:
https://de.wikipedia.org/wiki/NMEA_0183  -> siehe auch Weblinks
https://de.linkfang.org/wiki/NMEA_0183  -> siehe Datensätze

Heute könnte NMEA-2000 besser passen:
https://de.wikipedia.org/wiki/NMEA_2000
https://de.linkfang.org/wiki/NMEA_2000

Zitat: "NMEA 2000 wurde im Jahr 2000 von der Normungsorganisation NMEA 
entwickelt, als Nachfolger für NMEA 0183. NMEA 2000 ist eine Erweiterung 
von SAE J1939, welches im Nutzfahrzeugbereich verwendet wird und auf dem 
von Bosch und Intel entwickelten Controller Area Network (CAN) basiert."

just my 2ct

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.