Hallo, ich nutze in meinem Haus diverse Funksensoren im ISM Band, die ich in meiner Hausautomatisierung integriert habe. Um mehr ueber die darunterliegende Technik zu verstehen, habe ich mir nun ein CC1101 Module gekauft und experimentiere damit. Besonders geht es mir auch um den Aspekt, das Signal mit einem SDR aufzufangen und zu decodieren um zu verstehen "was da eigentlich passiert".
Ich habe folgenden simplen Sketch, der auf 433.92 MHz die Nachricht "Hello World" in Endlossschleife sendet. Es handelt sich dabei um das Beispiel, dass man in der Arduino IDE unter Examples->CC1101 default examples->New transmit method Hello World Advanced findet.
1
// These examples are from the Electronics Cookbook by Simon Monk
ELECHOUSE_cc1101.setMHZ(433.92);// Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).The cc1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ. Read More info from datasheet.
34
ELECHOUSE_cc1101.setDeviation(47.60);// Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
35
ELECHOUSE_cc1101.setChannel(0);// Set the Channelnumber from 0 to 255. Default is cahnnel 0.
36
ELECHOUSE_cc1101.setChsp(199.95);// The channel spacing is multiplied by the channel number CHAN and added to the base frequency in kHz. Value from 25.39 to 405.45. Default is 199.95 kHz.
37
ELECHOUSE_cc1101.setRxBW(812.50);// Set the Receive Bandwidth in kHz. Value from 58.03 to 812.50. Default is 812.50 kHz.
38
ELECHOUSE_cc1101.setDRate(99.97);// Set the Data Rate in kBaud. Value from 0.02 to 1621.83. Default is 99.97 kBaud!
39
ELECHOUSE_cc1101.setPA(10);// Set TxPower. The following settings are possible depending on the frequency band. (-30 -20 -15 -10 -6 0 5 7 10 11 12) Default is max!
ELECHOUSE_cc1101.setSyncWord(211,145);// Set sync word. Must be the same for the transmitter and receiver. (Syncword high, Syncword low)
42
ELECHOUSE_cc1101.setAdrChk(0);// Controls address check configuration of received packages. 0 = No address check. 1 = Address check, no broadcast. 2 = Address check and 0 (0x00) broadcast. 3 = Address check and 0 (0x00) and 255 (0xFF) broadcast.
43
ELECHOUSE_cc1101.setAddr(0);// Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF).
44
ELECHOUSE_cc1101.setWhiteData(0);// Turn data whitening on / off. 0 = Whitening off. 1 = Whitening on.
45
ELECHOUSE_cc1101.setPktFormat(0);// Format of RX and TX data. 0 = Normal mode, use FIFOs for RX and TX. 1 = Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins. 2 = Random TX mode; sends random data using PN9 generator. Used for test. Works as normal mode, setting 0 (00), in RX. 3 = Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins.
ELECHOUSE_cc1101.setPacketLength(0);// Indicates the packet length when fixed packet length mode is enabled. If variable packet length mode is used, this value indicates the maximum packet length allowed.
48
ELECHOUSE_cc1101.setCrc(1);// 1 = CRC calculation in TX and CRC check in RX enabled. 0 = CRC disabled for TX and RX.
49
ELECHOUSE_cc1101.setCRC_AF(0);// Enable automatic flush of RX FIFO when CRC is not OK. This requires that only one packet is in the RXIFIFO and that packet length is limited to the RX FIFO size.
50
ELECHOUSE_cc1101.setDcFilterOff(0);// Disable digital DC blocking filter before demodulator. Only for data rates ≤ 250 kBaud The recommended IF frequency changes when the DC blocking is disabled. 1 = Disable (current optimized). 0 = Enable (better sensitivity).
51
ELECHOUSE_cc1101.setManchester(0);// Enables Manchester encoding/decoding. 0 = Disable. 1 = Enable.
52
ELECHOUSE_cc1101.setFEC(0);// Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode. 0 = Disable. 1 = Enable.
53
ELECHOUSE_cc1101.setPRE(0);// Sets the minimum number of preamble bytes to be transmitted. Values: 0 : 2, 1 : 3, 2 : 4, 3 : 6, 4 : 8, 5 : 12, 6 : 16, 7 : 24
54
ELECHOUSE_cc1101.setPQT(0);// Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time a bit is received that is different from the previous bit, and decreases the counter by 8 each time a bit is received that is the same as the last bit. A threshold of 4∙PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted.
55
ELECHOUSE_cc1101.setAppendStatus(0);// When enabled, two status bytes will be appended to the payload of the packet. The status bytes contain RSSI and LQI values, as well as CRC OK.
56
57
Serial.println("Tx Mode");
58
}
59
60
voidloop(){
61
62
//3 different methods to send data
63
64
//Transmitt "Hello World" from byte format.
65
ELECHOUSE_cc1101.SendData(transmitt_byte,11);
66
delay(2000);
67
68
//Transmitt "Hello World" from char format.
69
ELECHOUSE_cc1101.SendData(transmitt_char);
70
delay(2000);
71
72
//Transmitt "Hello World" from char format directly.
73
ELECHOUSE_cc1101.SendData("Hello World");
74
delay(2000);
75
76
}
Mit gqrx finde ich mein Signal, allerdings nicht bei 433.92 MHz, sondern auf 433.964 MHz. Hier die erste Frage: Warum? Ist das Billig-CC1101 Board so schlecht, dass es da eine solche Verschiebung gibt?
Ich sehe, dass es definitiv mein Signal ist, da es in exakt 2000ms Abstand im Wasserfall zu sehen ist. Ändere ich die Zeit, ändern sich die Abstände entsprechend.
Mit dem Tool Universal Radio Hacker (https://github.com/jopohl/urh) zeichne ich nun das Signal auf und demoduliere es.
Dabei viel mir auf, dass ich, wenn ich das Signal in AM sende (ELECHOUSE_cc1101.setModulation(2)) ich immer wieder Fehler habe, sende ich es in FM (setModulation(0)) kann es immer perfekt demoduliert werden.
Ein Zoom In auf das Signal zeigte mir, dass in AM die Trägerwelle einen Nulldurchgang macht und die Fehler immer dann auftraten, wenn dort ein Symbol codiert wurde. Bei FM war dies nicht der Fall, das Signal wurde immer perfekt demoduliert. Jetzt frage ich mich natürlich: Ist dann AM überhaupt nicht dafür geeignet Daten zu versenden, wenn es bei den Nulldurchgängen des Signals zu solchen Problemem kommen? Ich habe aber trotz einiger Google-Recherche nichts dazu gefunden, insofern bin ich mir nicht sicher, ob ich nicht einfach was falsch mache?
Zur Interpretation der Screenshots: Das was man unter "hex decode" sieht sind 4 Byte preamble AAAA, dann 4 Byte Syncword d391, dann die Länge 0b und dann die ASCII-Hexwerte von H,e,l,l,o, ...
Man sieht oben das AM demodulierte Signal und unten das FM demodulierte Signal. Es sind natuerlich auch pro Signal unterschiedliche Aufzeichnungen, einmal von einem Signal mit setModulation(0) und einmal von setModulation(2).
Der Restfehler stammt wohl von SDR und/oder vom CC1101
(Frequenzungenauigkeiten der Quarz-Referenzen oder Ungenauigkeit
beim Einstellen der Empfangsfrequenz).
Mit gqrx finde ich mein Signal, allerdings nicht bei 433.92 MHz, sondern
auf 433.964 MHz.
Wird vermutlich daran liegen:
Markus schrieb:
ELECHOUSE_cc1101.setMHZ(433.92);
Markus schrieb:
ELECHOUSE_cc1101.setDeviation(47.60);
433.92 + 0.0476 = 433.967
Der Restfehler stammt wohl von SDR und/oder vom CC1101
(Frequenzungenauigkeiten der Quarz-Referenzen oder Ungenauigkeit
beim Einstellen der Empfangsfrequenz).
Danke! Stimmt, das könnte es erklären! Und das macht man.... damit nicht alle auf 433.92 senden und sich gegenseitig ins Gehege kommen, sondern man von vornherein einen gewissen Jitter hat?
Welche Breite muss mein Filter denn haben, wenn ich das möglichst exakt mit dem SDR rausschneiden will? Ich gehe auf 433.967 rechne nochmal die Ungenauigkeit drauf und dann...? Vordefiniere Filter sind ja z.B. 10kHz, 20kHz (Narrow, Wide, ...)?
Und wie erklärt sich jetzt das "Problem" bei AM? Ist das eine inherente Problematik warum man dann eher FM verwenden würde?
Ist das Billig-CC1101
Board so schlecht, dass es da eine solche Verschiebung gibt?
Dass du ein Billig-SDR haben könntest, auf die Idee bist du
nicht gekommen? Zu einer problematischen Funkübertragung
gehören immer zwei, ein Sender und ein Empfänger, beide
können "schlecht" sein. Was das vermutliche Problem ist
habe ich ja bereits vorher beschrieben.
Doch, das habe ich schon verstanden, und ja auch als mögliche Erklärung selbst erkannt.
Im Kern geht es mir ja aber in der Frage um die unterschiedliche Darstellung zwischen AM und FM und ob ich überhaupt erwarten darf, dass eine längere Nachricht problemlos via AM übertragen werden kann aufgrund dessen, dass beim Nulldurchgang die Demodulation doch nicht mehr sicher möglich ist - zumindest meine Vermutung?
Falls ich gänzlich falsch liege, bitte gerne korrigieren
Wenn du dir mal den Unterschied zwischen AM (genauer OOK - on-off-keying) und FM klar machst, kommst du vielleicht selbst drauf: bei OOK wird der Unterschied Signal - kein Signal ausgewertet, bei FM hast du immer ein Signal und kannst den Empfänger per Squelch schalten und eine AGC zum Regeln verwenden.
Meinem Verständnis nach ist aber die Frage nach der Empfänger HW nicht die Erklärung dafür, wie sich das Signal prinzipiell darstellt, sondern nur Unterschiede im SNR, generelle Qualität, usw.?
Wenn du dir mal den Unterschied zwischen AM (genauer OOK -
on-off-keying) und FM klar machst, kommst du vielleicht selbst drauf:
bei OOK wird der Unterschied Signal - kein Signal ausgewertet, bei FM
hast du immer ein Signal und kannst den Empfänger per Squelch schalten
und eine AGC zum Regeln verwenden.
OK, d.h. dann interpretiere ich daraus also dass ich für eine Datenübertragung eher nicht AM nutzen sollte, sondern FM, da am Nulldurchgang bei AM eben nicht unterschieden werden kann ob das Signal 0 ist oder die Trägerwelle, wie im Screenshot oben zu sehen?
Wenn du dein Signal so codierst, dass "kein Träger" eine 0 bedeuten soll, hast du eine falsche Codierung verwendet. Bei ASK (=OOK) sollte man halt Manchestercodierung oder PWM oder sowas verwenden, etwas, das für eine logische 0 und 1 einen Signalwechsel beinhaltet. Die üblichen Wettersensoren verwenden z.B. 100µs Signal und 200µs kein Signal als 0 und 200µs Signal und 100µs kein Signal für 1. Und eine ausreichend lange Präambel zur Synchronisierung vorher nicht vergessen!
Wenn du dein Signal so codierst, dass "kein Träger" eine 0 bedeuten
soll, hast du eine falsche Codierung verwendet. Bei ASK (=OOK) sollte
man halt Manchestercodierung oder PWM oder sowas verwenden, etwas, das
für eine logische 0 und 1 einen Signalwechsel beinhaltet. Die üblichen
Wettersensoren verwenden z.B. 100µs Signal und 200µs kein Signal als 0
und 200µs Signal und 100µs kein Signal für 1. Und eine ausreichend lange
Präambel zur Synchronisierung vorher nicht vergessen!
Vielen Dank für diesen Hinweis Helmut, das war "wertvoll" und ja auch genau ein Punkt, warum ich frage!
OK, dann liegt der "Fehler" also hier, dass in dem Beispiel gesetzt wurde:
1
ELECHOUSE_cc1101.setManchester(0);
und ein Wechsel auf 1 sollte es mir dann auch mit AM immer erfolgreich sein? Eine Präambel wird ja bereits gesendet (
1
ELECHOUSE_cc1101.setSyncMode(2);
)
Würde ich das gleiche Ziel nicht aber auch erreichen, indem ich die Geschwindigkeit, mit der die Daten gesendet werden, deutlich herabsetze?
Dann sollte es doch sehr viel seltener zu der Situation kommt, dass ein übertragenes Symbol genau (nur) in dem Zeitpunkt übertragen wird, indem der Träger 0 ist?
Das wäre dann wohl
1
ELECHOUSE_cc1101.setDRate(99.97);// Set the Data Rate in kBaud. Value from 0.02 to 1621.83. Default is 99.97 kBaud!
was ich dann einfach mal auf einen viel kleineren Wert setze und schaue wie es sich dann darstellt?
Oder wird es in der Praxis dann auch so gemacht, das man eine CRC mit überträgt und am Empfänger prüft und sicherheitshalber das Signal mehrfach aussendet, so dass man etwaige Übertragungsfehler kompensieren kann?
Dass AM unzuverlässig ist ist doch bekannt - hast du einen Grund das zu
nutzen statt FSK?
Der Grund ist lediglich, dass ich blutiger Anfänger bin und mir dachte ein AM Signal zu "verstehen" (auch im Sinne des URH Tools, siehe Screenshot) wäre einfacher. Störungen, was ja einer der Gründe gegen AM ist(?), verhinderten ja hier offenbar nicht, dass die Demodulation erfolgreich war.
Im Grunde wäre dann also die Erkenntnis aus diesem Thread:
Ausser es gibt triftige Gründe, grundsätzlich immer FM verwenden
Wenn doch AM (Modus ASK/OOK), dann immer auch Manchester mit aktivieren, ansonsten kommt es zu dem beobachteten Verhalten.
Immer eine CRC und/oder mehrfach aussenden, da ein einzelnes Aussenden immer gestört werden könnte und somit der Empfänger im Zweifelsfall es nicht sauber decodieren kann
Oder wird es in der Praxis dann auch so gemacht, das man eine CRC mit
überträgt und am Empfänger prüft und sicherheitshalber das Signal
mehrfach aussendet, so dass man etwaige Übertragungsfehler kompensieren
kann?
Ein CRC ist zwar schon mal gut damit Schrott in der Übertragung
erkannt wird, aber was hilft ein CRC wenn das Datenpaket gar
nicht ankommt? Bei Funkübertragung kann ich ein Datenpaket x-mal
schicken und es können alle Pakete von anderen Funkteilnehmern
gestört sein. Daher ist eine (Funk-)Datenübertragung erst dann
sicher wenn der Sender auch eine Bestätigung über den Erhalt
eines Datenpaketes vom Empfänger bekommt.
Diese Funktionalität ist übrigens bei den NRF24 Chips (ja, wir
reden hier von 433MHz Modulen) automatisch enthalten wenn man
das Acknowledge aktiviert. Dieses Ack wird nur dann gesendet
wenn ein Datenpaket vollständig und fehlerfrei beim Empfänger
angekommen ist. Eine sehr komfortable Art der Datensicherung.
Es ist halt auch keine besonders gute Idee, bei einer AM-Modulation
den Traeger bis auf 0% abzusenken. Das bekommt "einfachen"
Demodulatoren nicht besonders. Uebliche Werte liegen eher bei 20 - 30%.
Zur Reichweiteoptimierung kann man auch noch hoehere Werte probieren.
Es ist halt auch keine besonders gute Idee, bei einer AM-Modulation
den Traeger bis auf 0% abzusenken. Das bekommt "einfachen"
Demodulatoren nicht besonders. Uebliche Werte liegen eher bei 20 - 30%.
Zur Reichweiteoptimierung kann man auch noch hoehere Werte probieren.
Beziehst Du Dich darauf, dass ich in dem Beispiel einfach mal naiv von FM zu ASK/OOK gewechselt habe ohne zeitgleiche andere Parameter zu ändern? (Ich habe verstanden, das Manchester Encoding zu aktivieren wäre eine gute Idee gewesen?)
Ich habe jetzt jedenfalls nichts gefunden, dass ich so etwas wie die Absenkung in dem ASK/OOK Modus einfach beeinflussen könnte und offenbar ist hier auch nicht ein sinnvoller Default wie von Dir geschrieben 20-30% gesetzt?
Wie schon eingangs geschrieben bin ich Neuling in dem Thema und wollte vor allem verstehen WARUM es Probleme gibt. Das ist mir soweit gelungen, denke ich.
Beziehst Du Dich darauf, dass ich in dem Beispiel einfach mal naiv von
FM zu ASK/OOK gewechselt habe ohne zeitgleiche andere Parameter zu
ändern? (Ich habe verstanden, das Manchester Encoding zu aktivieren wäre
eine gute Idee gewesen?)
Da ich den CC1101 nicht kenne, kann ich mich nicht auf dein
Beispiel beziehen. Man kann aber mit sinnvoll gewaehlten
Modulationsparametern bereits asynchron Zeichen senden und
empfangen.
Eine Manchestercodierung sorgt fuer ein Signal ohne Gleichanteil,
0 und 1 treten gleich haeufig auf.
Die behebt das Modulationsproblem bei AM aber nicht.
Ich habe jetzt jedenfalls nichts gefunden, dass ich so etwas wie die
Absenkung in dem ASK/OOK Modus einfach beeinflussen könnte und offenbar
ist hier auch nicht ein sinnvoller Default wie von Dir geschrieben
20-30% gesetzt?
Das wirst du selbst herausfinden muessen.
Man koennte das Modulationssignal statisch anlegen und die
Ausgangsspannung/leistung messen.
Wie schon eingangs geschrieben bin ich Neuling in dem Thema und wollte
vor allem verstehen WARUM es Probleme gibt. Das ist mir soweit gelungen,
denke ich.
Das es bei 100%iger AM-Modulation Probleme gibt, hast du ja schon
herausgefunden. :)
Was mir jetzt aber noch nicht klar ist: Wenn doch ASK/OOK doch offenbar so "schlecht" ist, Manchester-Codierung auch das Problem nicht löst - warum wurde das dann wohl integriert? Natürlich kann das am Ende nur TI beantworten, aber was kann denn der Use-Case sein, wenn doch FM eigentlich in allen Varianten überlegen ist? Einfach "weil man das halt auch braucht"?
Damit es kompatibel mit existierenden (sehr einfachen/billigen) Geräten ist die nur ASK/OOK haben. Wenn man auf beiden Seiten FSK zur Verfügung hat sollte man es wohl auch nutzen.
Was mir jetzt aber noch nicht klar ist: Wenn doch ASK/OOK doch offenbar
so "schlecht" ist,
Ist sie ja nicht. Ich wuerde auch nicht glauben, dass man den
CC1101 dabei nur mit 100% Modulation betreiben kann.
Das fehlt womoeglich einfach in den Libraries (aka verhackstueckten
Include-Files).
Hast du denn schon einmal Datenblatt/Manual zum CC1101 bemueht?
Manchester-Codierung auch das Problem nicht löst -
Manchester setzt auf die gewaehlte Modulation auf. Es kann also
etwas schlecht konfiguriertes nicht verbessern.
Manchester kann man im uebrigen mit einfachster Hardware
sowohl kodieren als auch dekodieren. Was so einfach ist, kann
nicht schlecht sein. :)
warum wurde das dann wohl integriert? Natürlich kann das am Ende nur TI
beantworten, aber was kann denn der Use-Case sein, wenn doch FM
eigentlich in allen Varianten überlegen ist? Einfach "weil man das halt
auch braucht"?
Im Moment redest du noch von Dingen, zu denen dir jedes Verstaendnis
fehlt. Und das wird sich auch mit der Benutzung von zusammenkopierten
Code nicht verbessern.
Ich empfehle mal g'schwind ein Studium der elektrischen Nachrichtentechnik. Da werden genau so Sachen, wie verschiedene Modulationsverfahren, ihre Eigenschaften, verschiedene Kanalcodierungen, ihre Eigenschaften, Fehlerschutzverfahren und ihre Eigenschaften, Kommunikationskanaele, ihre Eigenschaften wie z.b. Bandbreite, Kapazitaet, Fehlereigenschaften, etc. bla. sehr gruendlich durchgekaut...
Ich habe meine Versuche mit dem am Anfang erwähnten Beispielcode jetzt noch ein wenig fortgesetzt:
Aktiviere ich Manchester Encoding so war es in jedem Fall moeglich in wenigstens 1 von 3 Übertragungen die ursprüngliche Nachricht erfolgreich zu dekodieren.
Setze ich allerdings die Datenrate drastisch herunter, so dass die Übermittlung einer "1" bereits mehrere komplette Schwingen umfasst - war und es somit nicht zu dem Fall kommt, dass ein Symbol genau zum Nulldurchgang der Amplitude moduliert wird - so war mit reinem ASK/OOK auch ohne Manchester Encoding die Demodulation stets erfolgreich.
@motopick: Ja, ich habe mir gestern noch das gesamte Datenblatt zu Gemüte geführt und auch das dagegen gehalten, was die Library macht. Ich gebe zu, dass ich - Überraschung - nicht alles verstanden habe, was das Datenblatt beschreibt. Das was noch am ehesten in Frage kommt ist m.E. der Punkt 10.6 im Datenblatt auf Seite 33 (https://www.ti.com/lit/ds/symlink/cc1101.pdf). Ich vermute aber, dass es hierbei mehr um die generelle Sendeleistung geht. Ansonsten habe ich tatsaechlich nichts gefunden. "By programming the PATABLE, controlled PA power ramp-up and ramp-down can be achieved, as well as ASK modulation shaping for reduced bandwidth" sowie "The ASK variant supported by the CC1101 allows programming of the modulation depth
(the difference between 1 and 0), and shaping of the pulse amplitude. Pulse shaping" - allerdings scheint da nicht mehr weiter darauf eingegangen zu werden. Eventuell ist es aber Seite 59 "If OOK modulation is used, the logic 0 and logic 1 power levels shall be programmed to index 0 and 1 respectively." im Bereich der PA_POWER Tabellen.
..."If OOK modulation
is used, the logic 0 and logic 1 power levels shall be programmed to
index 0 and 1 respectively." im Bereich der PA_POWER Tabellen.
Naja siehste. Eine Sendeleistung fuer die '0' und eine fuer die '1'.
Wenn man fuer die '0' da eine Null hineinschreibt, ist man halt
selber zu doof. :)
Und Rampen fuer die Flanken...