Hallo, Ich habe vor kurzem die nachfolgende (http://www.seeedstudio.com/wiki/433Mhz_RF_link_kit ) 433Mhz RF-Modul gekauft um ein Fernbedienung zu bauen. Da ich ein Hobby Bastler bin besitze ich wenig Erfahrung im bereich RF und PIC. Ich will eigentlich nur Taste => LED_ON oder Taste => LED_OFF Es klappt auch aber irgendwie nur einmal hin und wieder nicht stabil. SENDER: void main() setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_comparator(NC_NC); setup_vref(FALSE); while(1) { int8 c=0; int TasteY; int Tastex; Tastex=input(PIN_A1); if(Tastex==1) { c=1; printf("%x\n\r",c); } TasteY=input(PIN_A4); if (TasteY==1) { c=2; printf("%x\n\r",c); } } EMPFÄNGER: void main() { int8 c=0; setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_comparator(NC_NC); setup_vref(FALSE); // TODO: USER CODE!! while(1) { c=getc(); if (c==1) { output_high(PIN_A1); } else if (c==2) { output_low(PIN_A1); } } Bitte um Hilfe :)
Mal ganz abgesehen von Deinem Code, von dem ich als Arduino-Programmierer nicht alles verstehe, ein paar Anmerkungen zu den Fehlerquellen und Hintergründen, die mir zu diesen Sendesets einfallen. Der Empfänger in Deinem Set ist ein sogenannter "Regenerativempfänger", der nach dem Prinzip eines automatisch geregelten Rückkopplungs-Audions arbeitet. Das heißt: Der Empfänger regelt seine Empfangsempfindlichkeit selbst immer nach, je nachdem, was er empfängt. Empfängt er nichts, weil gerade kein starker Sender sendet, dann regelt er die Empfangsempfindlichkeit so weit hoch, bis er was empfängt. Sofern das dann nicht gerade das Nutzsignal ist, empfängt er also regelmäßig Datenmüll. Viel Datenmüll. Wertest Du nur ein einziges Byte aus, dann brauchst Du nur lange genug warten, bis im Datenmüll-Strom irgendwann das gewünschte Byte kommt - voila! Das kann dann das absichtlich gesendete Byte sein. Oder auch nicht. Auf die Art kannst Du nichts schalten. Und es geht weiter: Der Empfänger regelt nicht nur seine Empfindlichkeit automatisch bis zum Empfang von irgendwelchem Datenmüll hoch, wenn nichts gesendet wird, sondern je nach empfangenen Daten regelt er nach: kommen viele kurze Null-Bits im Datenstrom, geht die Empfängeremfindlichkeit hoch. Aber kommen im Datenstrom viele lange Eins-Bits, regelt er die Empfängerempfindlichkeit runter. Um dieses laufende Hoch- und Runterregeln der Empfängerempfindlichkeit zu vermeiden, solltest Du für diese Art Empfängertyp aus dem Set am besten eine "ausgeglichene Bitfolge" senden, bei der Null-Bits und Eins-Bits immer schön gemischt gesendet werden, in gleicher Anzahl und möglichst nur höchstens drei gleiche Bits in Folge bis wieder ein Bitwechsel auftritt. Schlechte Bit-Sendefolge für so einen Regenerativempfänger (mehr als drei Bits in Folge identisch): 00000001 11111110 11110000 Gute Bit-Sendefolgen (ausgeglichene Bitfolgen): 01010101 10101010 01101100 10101001 Für diese Art Empfänger mußt Du immer ein bestimmtes Sendeprotokoll aussenden, mit schönen, ausgeglichenen Bitfolgen. Nur dann ist eine vernünftige Reichweite mit solchen Sende-/Emfpängersets erzielbar. Und auf der Empfangsseite mußt Du ein paar Plausibilitätsprüfungen durchführen, ob die empfangenen Bytes auch tatsächlich das sein können, was empfangen werden soll. Beispiel für ein Sendeprotokoll: Sende ein paar schöne "Start-Bits" als Folgen von 0-Bits und 1-Bits, zum Beispiel fünfmal das Byte 0x2a gefolgt von zwei Start-Bytes, vielleicht 0xcc und 0x96, danach Deinen Schaltcode, und zwar einen, bei dem die Bits schön gemischt vorkommen, nicht gerade 0x01, sondern vielleicht 0x93 zum Einschalten und 0xd2 zum Ausschalten. Am Ende möglichst noch eine Prüfsumme zur Absicherung des Protokolls, aber das lasse ich mal weg. Dann sendest Du zum Einschalten: 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0xcc, 0x96, 0x93 und zum Ausschalten: 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0xcc, 0x96, 0xd2 Also schön gemischte Bitfolgen, und zu Anfang immer die Trainingsbits aus 0x2a, zwei Startbytes und dann erst das Nutz-Byte Auf der Empfängerseite sähe die Empfangslogik dann so aus: - Lauern auf die Startbits in Form von Zeichen 0x2a (die ersten davon werden möglicherweise nicht sauber empfangen) - Egal wie oft 0x2a kommt, danach müssen 0xcc, 0x96 kommen - und dann ist das nächste Byte Dein zu übertragender Schaltbefehl Ohne ein von Dir festgelegtes Sendeprotokoll, ohne ausgeglichene Bitfolgen, ohne Trainingsbits am Anfang der Aussendung, kannst Du mit diesen billigen Modulen keine Reichweite und keine sichere Datenübertragung erzielen, sondern nur ganz viel Datenmüll im Empfänger empfangen. Ich finde diese Transmitter-Receiver-Sets ja klasse, insbesondere des Preises wegen: Bei China-Versendern im Set für zusammen zwei Euro, billiger als damit bekommt man eine Funkstrecke nicht hin. Aber um mit diesen Modulen auch eine ordentliche Reichweite zu erzielen und "sichere" Daten zu übertragen, kann man eben nicht nur einfach seine Nutzdaten in den Sender geben und erwarten, dass diese vom Empfänger genau so empfangen werden, sondern man muß sich bemühen, ein Funkprotokoll mit ausgeglichenen Bitfolgen zu übertragen. Vielleicht helfen dir diese Angaben ja, Deine Übertragung "sichererer" zu bekommen.
Hier noch ein Nachtrag noch zu meinem Posting von gestern, in dem ich gestern erklärt habe, was man über ASK/OOK-Funkmodule mit Regenerativempfänger am besten per Funk sendet und wie ein Übertragungsporotokoll für solche billigen Module aussehen könnte. Nun noch zum Anschluss der Module und zu Deinem Code, den ich wie gesagt nicht komplett verstehe, weil ich nirgends erkennen kann, dass die Daten über eine serielle Schnittstelle gehen sollen. Am einfachsten programmierbar (aber nicht unbedingt für eine gute Reichweite am besten) schliesst man diese Module doch an einer seriellen Schnittstelle an. Dann braucht man sich um das Timing der Bits beim Senden und Empfangen nämlich keinen Kopf zu machen, das erledigt die serielle Schnittstelle. Beim Sender Data Pin des Sendermoduls ==> Serial TX am Controller Beim Empfänger: Data Pin des Empfängermoduls ==> Serial RX am Controller Und dann haust Du beim Sender die Daten über die serielle Schnittstelle raus, bzw. sie trudeln beim Empfänger über die serielle Schnittstelle rein. In Deinem Code sehe ich beim Sender: printf("%x\n\r",c); Und beim Empfänger: c=getc(); Mal eine Rückfrage zu Deinem Entwicklungssystem: Wo hast Du in Deiner Entwicklungsumgebung festgelegt, dass im Programm die Standardausgabe auf TX einer seriellen Schnittstelle umgeleitet werden soll und wo, dass die Standardeingabe von RX einer seriellen Schnittstelle kommen soll? Geht das bei Deinem Programmiersystem? Ich als Arduino-Programmierer müßte die Ein-/Ausgabeumleitung in den Code meines Programms reinschreiben, damit es funktioniert. Ich sehe aber nirgends etwas in Deinem Code, mit dem: - die Standardein-/ausgabe auf eine serielle Schnittstelle umlenkt wird - irgendwo eine Baudrate gesetzt wird Wo passiert das? Kannst Du bei Deinem Entwicklungssystem für die serielle Schnittstelle irgendwelche Compiler-Direktiven in der Entwicklungsumgebung einstellen, dass standardmäßig eine serielle Schnittstelle als Standardein-/ausgabekanal verwendet wird? Ohne eine einzige Codezeile? Bei mir unter Arduino müßte ich eine Ein-/Ausgabeumleitung auf eine serielle Schnittstelle per Code erstmal im Programm definieren. Oder ein "Serial" Objekt aus der Arduino-Library im Programm initialisieren und die Daten darüber senden und empfangen. Und welche Baudrate hast Du eingestellt? Diese billigen Sender/Empfänger können meist nicht viel mehr als 4800 Baud. Falls Du versuchst, die Daten mit deutlich mehr als 4800 Baud zu senden, also mal die Baudrate auf 4800 oder weniger einstellen.
Hallo Jürgen , Ich danke dir zuerst für die Informationen. Jetzt habe ich wenigstens mein Fehler eingekreist. Klar der Code sieht nicht informativ aus es sollte ja auch nur ein Beispiel sein. Die serielle Schnittstelle ist in der Header Datei deklariert die baudrate auch. Der pic16f688 hat die pins RC5 (rx) und RC4 (tx).
wie gesagt die Deklarationen finden in einem anderen Datei statt. Ich bin zufällig auf diese Module gestoßen dachte mir das es einfach wäre aber leider. Werde heute Abend erneut versuchen und dein Rat befolgen. Hast du Erfahrung mit solchen Modulen wenn ja welche würdest du mir empfehlen?
Ugur Onur schrieb: > Hast du Erfahrung mit solchen Modulen wenn ja welche würdest du mir > empfehlen? Ja, ich finde diese billigen Module sind super. Genau solche funken bei mir die Wetterdaten wie Temperatur, Luftfeuchte und Regenmenge aus dem Garten ins Haus, wo sie weiter verarbeitet und ausgewertet werden. Alerdings habe ich mit dem Funken extrem wenig Aufwand: Für die Arduino-Plattform gibt es eine sehr schöne C++-Library ("VirtualWire"), die den gesamten Programmieraufwand in Library-Funktionen kapselt und das eigentliche "Funken mit Protokoll" ist dann quasi nur noch ein Einzeiler im selbstgeschriebenen Programm.
Du hast oben die Prüfsumme erwähnt dies habe ich schon öfters gehört was bewirkt es
Ugur Onur schrieb: > Du hast oben die Prüfsumme erwähnt dies habe ich schon öfters gehört was > bewirkt es Zusätzliche Sicherheit bei der Datenübertragung. Wenn Du über Deine Nutzdaten eine Prüfsumme bildest und hinter den Nutzdaten mitsendest, dann kann der Empfänger die Nutzdaten und Prüfsumme empfangen und ebenfalls die Prüfsumme anhand der empfangenen Nutzdaten nochmals selbst errechnen. Wenn die im Empfänger errechnete Prüfsumme nicht mit der per Funk empfangenen Prüfsumme übereinstimmt, ist die Übertragung fehlerhaft gewesen.
Wenn soviele Daten sende dann müsste ich die ja beim empfànger in einem Array sammeln oder
Ugur Onur schrieb: > Wenn soviele Daten sende dann müsste ich die ja beim empfànger in einem > Array sammeln oder Die Trainings-Bytes (0x2a) speicherst Du nie in einem Array. Die Trainings-Bytes dienen nur dazu, dass der Empfänger seine Empfangsverstärkung auf die Feldstärke Deines Senders optimal einregeln kann, um den Sender mit so einem billigen Regenerativempfänger klar und stark und bitgenau zu empfangen. In Sachen Trainings-Bytes prüfst Du auf Empfängerseite nur, ob eine ausreichende Anzahl von Trainingsbytes in Folge empfangen wurde und zählst mit. Mein Vorschlag (siehe oben) wäre, senderseitig sechs Trainings-Bytes 0x2a zu senden und empfängerseitig zu prüfen, ob mindestens vier dieser Trainings-Bytes in Folge fehlerfrei empfangen wurden. In einem Array sammelst Du dann ggf. ab dem ersten Nicht-Trainingsbyte. Das muss immer das festgelegte erste Startbyte sein. Als zusätzliche Sicherheit empfehle ich die Verwendung von zwei Startbytes. Ich poste nochmal meinen Vorschlag von oben mit 6x Trainings-Bytes, 2 verschiedene Start-Bytes und ein Nutz-Byte: Zum Einschalten senden: 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0xcc, 0x96, 0x93 und zum Ausschalten senden: 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0xcc, 0x96, 0xd2 Du sammelst Bytes dann in einem 3-Bytes Array nur "alles nach 0x2a", und zwar erst, nachdem mindestens viermal 0x2a empfangen wurde. Programmlogik des Empfängers: - empfange vier oder mehr Trainings-Bytes 0x2a in Folge - dann packe die drei nächsten Bytes in ein 3-Byte-Array (also erst ab dem ersten Nicht-Trainingsbyte im Array sammeln) - wenn die ersten zwei Bytes im Array dann 0xcc, 0x96 sind, ist das dritte Byte das "Schalt-Byte" (und wenn nicht, starte die Programmlogik neu) Damit hast Du eine recht hohe Sicherheit für die Erkennung Deiner Schaltimpulse sogar ohne Prüfsummen oder CRC-Prüfung. Um es nochmal klar zu sagen: Diese billigen Regenerativ-Empfänger empfangen immer einen ständigen Strom von Datenmüll, weil sie einfach ihre Empfangsempfindlichkeit automatisch so weit hochregeln, bis sie was empfangen, auch wenn nichts da ist außer Rauschen. Deshalb ist es keine gute Strategie, einfach nur zu lauschen, ob nützliche Signale kommen. Stattdessen ist die passende Strategie, den Sender zuerst Trainings-Bytes mit "guten Bitfolgen" senden zu lassen, die der Empfänger dafür nutzt, die Empfindlichkeit so zu regeln, dass er genau das Signal dieses einen Senders gut empfängt, des jeweils stärksten Senders im Umkreis. Und erst wenn der Empfänger die Folge der festgelegten Trainings-Bytes klar und deutlich empfängt, lauscht er auf die nachfolgenden Daten, üblicherweise nach einem (oder besser zwei) fest vereinbarten Start-Bytes mit vorab festgelegtem Wert.
Ich habe gestern Nacht dein Rat befolgt aber ein ganz anderer Problem ist aufgetreten und zwar auf der Empfänger Seite.ich sende Hex oder Byt empfangen wird ein Bit .ich versuche die ganze zeit den Syntax zum empfangen der Daten herauszufinden aber erfolglos
Ugur Onur schrieb: > Ich habe gestern Nacht dein Rat befolgt aber ein ganz anderer Problem > ist aufgetreten und zwar auf der Empfänger Seite.ich sende Hex oder Byt > empfangen wird ein Bit .ich versuche die ganze zeit den Syntax zum > empfangen der Daten herauszufinden aber erfolglos Seit wann gibt es für eine serielle Schnittstelle Routinen zum Empfang von nur einzelnen Bits? Ich kenne nur Routinen zum Einlesen ganzer Bytes über die serielle Schnittstelle. Du verwendest doch die serielle Schnittstelle zum Senden/Empfangen, oder nicht?
Ja klar ich benutze die serielle Schnittstelle bei Pic Controller ist es so. Nach der Einstellungen wird in der Schleife auf die Daten gewartet die über die Schnittstelle kommen.Da ich unter C programmiere haben ich die Befehle getc() für ein Bit gets(String ) für ein String gefunden.get() läuft aber nur ein Bit das andere nicht.ist ja zum verrückt werden den Internet habe ich schon rauf und runter durchsucht.
Ugur Onur schrieb: > Ja klar ich benutze die serielle Schnittstelle bei Pic Controller ist es > so. "Es ist so"? Man KANN diese billigen Sender und Empfänger an die serielle Schnittstelle hängen, dann hat man extrem wenig Arbeit mit dem Programmieren des Funks. Maximale Reichweite erzielt man auf diese einfache Art und über Anschluss an den seriellen Schnittstellen beim Senden und Empfangen aber NICHT. Meine batteriebetriebenen Wettersensoren, die mir mit genau solchen Modulen Daten zu Temperatur, Luftfeuchte und Regenmenge vom Garten ins Haus funken, hängen mit ihren Modulen daher auch NICHT an der seriellen Schnittstelle des Mikrocontrollers, sondern werden softwaretechnisch intelligenter und aufwändiger angesteuert. Mehr Reichweite nur durch intelligentere Ansteuerung bei gleicher Sendeleistung. Leider gewinne ich mit zunehmender Länge des Threads den Eindruck, dass die eigentlichen Probleme bei Dir nicht erst beim Funken anfangen, sondern schon beim Auslesen von Zeichen über die serielle Schnittstelle irgendwas nicht klappt. Ich hege zum Beispiel die starke Vermutung, dass > wird in der Schleife auf die Daten gewartet > die über die Schnittstelle kommen überhaupt nicht zutrifft. Es wird zwar ausgelesen, aber es wird beim Ausgelesen nicht gewartet, bis überhaupt ein Zeichen zum Auslesen an der seriellen Schnittstelle anliegt. Also tatsächlich: Ständiges Auslesen ohne dass was zum Auslesen vorhanden ist. Nur so eine Vermutung von mir, ich kenne Dein Entwicklungssystem und Deine Funktion getc() nicht. Bedauere, ich kann Dir leider nicht weiterhelfen und wollte eigentlich auch nur ein paar grundsätzliche Dinge zu diesen billigen Sender-Empfänger-Pärchen mitgeteilt haben.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.