Hi, ich beschäftige mich seit einiger Zeit Mikrocontroller und hab auch schon einige Sachen mit Sensoren und Co. gemacht. Für viele Sachen die ich noch machen möchte benötige ich aber eine Kommunikation zwischen den einzelnen Mikrocontrollern. Da ich Funksteckdosen mit den Micocontroller geschaltet habe, habe ich noch XY-MK-5V und FS1000A da. Die Module sind recht billig und ich könnte diese auch sehr gut dazu benutzen um mehrere Sender zu basteln. Diese schicken dann Sachen wie Temperatur und Co. an einen Empfänger und der schickt es an den PC weiter und dort wird es dann in die Datenbank geschrieben. Problem ist die Umsetzung, auch weil ich in der Elektronik- und Micocontrollerecke nicht so bewandert bin. Es gibt mehrere Beispiele im Netz die vermutlich funktionieren, aber dann Libarys benutzen die nur für Arduino und Co. gedacht sind. Ich würde das ganze selber aufbauen, damit auch auch verstehe was ich da mache. Bisher habe ich zwei Atmega8 wo ein Sender und ein Empfänger dranhängt. Beide mit 5V versorgt und bei Beiden steckt ein ca. 17cm langer Draht als Antenne im dazu vorgesehenen "Loch". Die beiden sind direkt nebeneinander. Ich habe mir das so vorgestellt, dass ich erstmal ein Signal (z.B. High, Low, Low) erzeuge was dann vom Empfänger aufgenommen wird. Das hab ich schon bei der Funksteckdose so gemacht. "Einfach" das Signal genau angeschaut und dann versucht mit Pin auf 1 oder 0 den Sender anzusprechen um das gleiche Signal zu erzeugen. Das Signal habe ich mir wie hier beschrieben (http://gimlie.net/433-mhz-signale-auslesen-und-auswerten) angesehen. Das Problem ist jetzt das Empfangen. Es sollten erstmal mehrere Bits über die Leitung geschickt und vom Empfänger empfangen werden. Ein Bit (0 oder 1) liegt dabei in der Manchester-Codierung vor. Das Signal kann ich dann auch über den schnell zusammengebastelten Empfänger mit Audacity anschauen und es wird auch korrekt erzeugt. Das Empfangen habe ich mir vom Prinzip so vorgestellt, dass eine Schleife läuft die testet ob der Pin, an dem der Empfänger hängt, 0 oder 1 ist. Falls er 1 oder 0 ist, läuft solange eine Schleife bis der Pin wieder auf 0 oder 1 schaltet. Durch einen Timer kann ich dann ermitteln wie lange das Signal am Pin angelegen hat. Aus der Dauer kann ich dann dann ermitteln ob es Rauschen war (kurze Spitzen) oder es sich um das Signal vom Sender handelt (längeres High-Signal). Momentan bin ich soweit, dass ich eine LED mit der Fernbedienung der Funksteckdose bzw. meinen Sender anschalten kann. Der Empfänger erkennt einfach, dass ein längeres High Signal ankommt. Das Ziel ist aber, dass er mehrere Bits erkennt. Dann hätte ich es geschafft. Würde das vom Prinzip so gehen? Kann ich mir nicht vorstellen, da die Tutorials zu dem Thema teilweise so viel Quellcode enthalten.
Seb Wagner schrieb: > dass eine Schleife läuft die testet ob der Pin, an dem der Empfänger > hängt, 0 oder 1 ist. Falls er 1 oder 0 ist, läuft solange eine Schleife > bis der Pin wieder auf 0 oder 1 schaltet. Normalerweise würde man sowas über Interrupts machen. Ideal wäre timer input capture, dann bekommst du direkt die zeitlichen Abstände der Flanken heraus. Ggf. muss man eine Totzeit einprogrammieren, um bei völlig unsinnigem „Herumzappeln“ des Pins einen Interruptsturm zu vermeiden.
Danke für den Hinweis mit den Interrupt. Ich bin dann durch die Interrupts noch mal auf einige kleine Beispiele mit UART gestoßen, wo ich dann auch endlich die Funktionsweise von Uart verstanden habe. Ich hatte die letzten Tage dann mal versucht die Sache auch über UART zu realisieren, weil dort das Problem der Auswertung der Funksignale quasi schon gelöst ist und ich theoretisch nur auslesen muss. Ich hab dazu Bascom AVR genutzt, da es zum rumprobieren einfacher als C finde. Einzelne gesendete Zeichen zu empfangen war möglich, die sind meist angekommen und ich konnte halt wenn ein bestimmtes Zeichen ankam eine LED leuchten lassen. Hat zwar nicht immer geklappt. Strings konnte ich ebenfalls senden und das Signal sah auch gut aus, aber da hab ich es nicht hin bekommen den kompletten String auszulesen. Mit dem Befehl INPUT hat er auf Jedenfall erkannt, dass immer CARRIAGE RETURN angekommen ist. Zumindest der Teil vom String ist immer zuverlässig angekommen. Ich werde mich noch mal an meine ursprüngliche Idee ran setzen und die Signale selber über high/Low erzeugen und auswerten.
Seb Wagner schrieb: > Es gibt mehrere Beispiele im > Netz die vermutlich funktionieren, aber dann Libarys benutzen die nur > für Arduino und Co. gedacht sind. Ich würde das ganze selber aufbauen, > damit auch auch verstehe was ich da mache. Arduinos sind bis auf wenige Ausnahmen ganz normale ATmega Prozessoren. Auf den Boards sind nur die Pins anders bezeichnet, als im ATmega Datenblatt. Die Arduino Bibliotheken kannst du dir einfach ansehen oder auch in Atmel-Studio benutzen und z.B. im Simulator angucken, was passiert.
Ich bin jetzt an einen Punkt den ich nicht ganz verstehe. Wie empfohlen nutze ich für die Auswertung der Signale die Input Capture Funktion vom Timer1 was prinzipiell super klappt. Zu Testzwecken habe ich alles erstmal in Bascom AVR programmiert und der Empfänger empfängt auch zu Testzwecken eine Folge von 10 High-Signalen. Das Signal sollte auch gut aussehen (Siehe Bild im Anhang). Der Empfänger arbeitet mit 1Mhz. Timer1 ist so konfiguriert, dass ein Interrupt ausgelöst wird wenn eine aufsteigende Flanke kommt. Bei 10 High-Bits würde also theoretisch 9 mal ein Interrupt ausgelöst werden. Das klappt auch super und ich kann auch eine LED blinken lassen wenn die 10 High-Signale empfangen werden. Bei Timer1 hab ich Prescale = 8 gewählt und Noise Cancel eingestellt damit nicht auf alle High Signale, die durch Rauschen entstehen reagiert wird. Jetzt wollte ich eine Folge von High und Low Signalen empfangen. Meine Idee war, die Signale anhand der Zeit bis zur nächsten aufsteigenden Flanke zu erkennen. Je nachdem ob es sich um eine 1 oder 0 handelt ist die Zeit bis zur nächsten Flanke nach einem High oder Low Signal um eine halbe Signallänge länger. Das sollte theoretisch auch funktionieren, dazu ist es aber nötig die Zeit genau zu messen und da gibt es momentan ein Problem. Die Unterbrechungsroutine zum Testen sieht bei mir momentan so aus:
1 | Config Timer1 = Timer , Prescale = 8 , Capture_edge = Rising , Noise Cancel = 1 |
2 | |
3 | ...
|
4 | ...
|
5 | |
6 | Icp_isr: |
7 | Zeitstempel = Icr1 #ICR auslesen um Zeitpunkt des Interrupts zu ermitteln |
8 | Timer1 = 0 #Timer auf 0 setzen um Zeit bis zur nächsten Flanke zu ermitteln |
9 | |
10 | If Zeitstempel > 200 And Zeitstempel < 1500 Then |
11 | I = I + 1 #Bei Jedem High-Signal um 1 erhöhen |
12 | If I > 8 Then #Wenn mehr als 8 High-Signale angekommen sind LED blinken |
13 | Portd.7 = 1 |
14 | Waitms 15 |
15 | Portd.7 = 0 |
16 | Waitms 15 |
17 | End If |
18 | Else
|
19 | I = 0 #Falls kein High Signal erkannt wird I auf 0 setzen |
20 | End If |
21 | Return
|
Das klappt wie geschrieben super, aber mein Problem ist der Zeitstempel der von 200 bis 1500 reicht. Sobald ich da Versuche den Bereich enger zu machen blinkt die LED teilweise nicht mehr. Ein Toleranzbereich muss sein, aber der Bereich ist doch deutlich zu groß? Irgendwas muss da schon bei der Zeiterfassung schief laufen?
:
Bearbeitet durch User
Hm, falsches Pferd! Auf Fragen zu Bascom wird Dir hier niemand antworten können, weil's keiner benutzt und damit niemand lesen kann. WinAVR wäre das richtige Pferd gewesen um von Arduino wegzukommen. So wie's aussieht sehe ich nirgendwo den Start/Stopp der Stoppuhr. Richtige Programmierer machen auch das nicht, sondern lassen einen 8- oder 16-bit-Zähler einfach immer durchlaufen und messen ZeitDIFFERENZEN:
1 | static int tlast; |
2 | int t = ICR; |
3 | int dt = t-tlast; |
4 | tlast = t; |
5 | if (800<=dt && dt<1000) ... |
Das interessante an der Subtraktion in Zeile 3 ist, dass diese auch bei Zählerüberläufen das richtige Ergebnis liefert. C-Programmierer verlassen sich darauf. In Basic kann das schief gehen. Weil niemand weiß wie Basic sich verhält. Das hat man vergessen zu definieren.
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.