Archiv verlassen und diese Seite im Standarddesign anzeigen : IR-Schaltung geht nicht
ShadowPhoenix
22.05.2004, 13:40
Hallo!
Ich benutze den ATmega8, und habe eine korrekt angesteuerte IR Sende Diode und einen TSOP1376 IR Empfänger, der auch korrekt angesteuert ist.
Dann habe ich einen 12MHz Quarz, der zwei AVR's versorgt. (Das geht doch, oder?)
Nun hier den SENDECODE:
$regfile = "m8def.dat"
$crystal = 12000000
Const Startbyte = 00000001
Dim Zusenden as byte
Ddrb.1 = 0
Senden:
Zusenden = Startbyte
Portb.1 = Zusenden
Goto senden
Hier der EMPFÄNGERCODE:
$regfile = "m8def.dat"
$crystal = 12000000
Dim gelesen as byte
Ddrd.2 = 0
Do
Gelesen = Portb.2
if gelesen = 00000001 then portb.5 = 1 else portb.5 = 0
loop
Warum funktioniert das nicht?
Die LED an portb.5 flackert nur manchmal, aber das auch, wenn die IR-Strecke unterbrochen ist!
@Gottfreak: Dein Code funktioniert auch irgendwie nicht.
Ich bin total am verzweifeln, es geht garnichts.
MfG,
ShadowPhoenix[/code]
Hallo
Was willst du denn erreichen ??
Bei der Sende Routine solltest du denn Port auch auf Ausgang schalten.
Beim Empfangen solltest du anstatt PORTB.2 mal PINB.2 versuchen.
Ist dir klar, was das Programm macht, wenn es dann läuft ?
Mfg
ShadowPhoenix
22.05.2004, 13:52
@Gast
Sorry, ich kenne mich eben noch nicht so gut aus.
Ja, das Programm sendet dann ständig das Byte "00000001" an den
Empfänger. Dieser lässt dann die LED leuchten.
Wie siehst du das?
MfG,
ShadowPhoenix
Wie kommst du denn darauf ??
"Ja, das Programm sendet dann ständig das Byte "00000001" an den "
Beim senden wird dein dein Port aus 1 gesetzt und das wars.
Modulierst du die LED denn mit 36 KHz ? Sonst empfängt der TSOP 1736 eh nichts.
"Gelesen" kann doch nur 0 oder 1 werden
ShadowPhoenix
22.05.2004, 14:00
Ich dachte, es wird dann 10000000 gesendet!
Wie kann man denn Bytes senden?
MfG,
ShadowPhoenix
Wieso soll er das denn senden ? Weil die Variable zusenden heißt ?
So einfach geht das mit bascom aber auch nicht.
Du mußt deine Variable, die du senden willst, Bit für Bit abfragen, ob 1 oder 0 und dann entsprechend reagieren.
Beim Empfang genau so, da hast du aber noch andere Probleme. Finden des Starts, Timming, Fehler und so.
Versuche erstmal, nur zu senden. So langsam, das du an einer normalen LED sehen kannst ob es klappt.
ShadowPhoenix
22.05.2004, 14:06
Hmm, eigentlich habe ich vor, den ADDLink zu benutzen, und dann bytes zu übertragen.
So hätte ich eine Fernsteuerung mit vielen Kanälen.
Weisst du wie das realisierbar ist?
MfG,
ShadowPhoenix
Habe mit ADD Link noch nicht gearbeitet, ist mir auch zu teuer.
Du kannst auch mit der LED soviele Kanäle steuern wie du willst.
Aber ein paar Grundlagen, mußt du dir schon erabeiten. Dazu gehört halt auch, wie man ein Byte seriell sendet und empfängt. Brauchst du eh immer wieder. Und so schwer ist das nicht. Es hilft dir nichts, wenn das eine nicht klappt, das nächste auszu probieren.
Bleib an der seriellen Übertragung dran. Verbinde doch erstmal die beiden PINs mit einem Draht und versuche, ein Byte zu übertragen.
ShadowPhoenix
22.05.2004, 14:21
Problem ist: WIE sende ich ein byte und empfange es richtig?
MfG,
ShadowPhoenix
Ganz grob als Anregung
Du willst ein Bytes senden, hat ja 8 Bits. Du kannst immer nur ein Bit nach dem sende. Also prüfst du, ob BIT 0 deiner Variablen 1 oder 0 ist.
Wenn1 dann sendest du eine 1, wenn nicht eine 0.
Danach schiebst du die Variable um eine Stelle nach rechts. Damit steht jetzt BIT1 an Stelle BIT0 und du kannst wieder abfragen ob 1 oder 0.
Nach 8 mal schiebben bist du mit deinem Byte durch.
daten = 23
for a = 1 to 8
if daten.0 = 1 then
sende 1
else
sende 0
end if
shift daten , right ,1
next a
So sollte es ganz grob abgehen. Nicht getestet, so aus dem Kopf
ShadowPhoenix
22.05.2004, 14:33
Was meinst du mit "daten = 23" ?
Ich wollte doch bytes versenden .. keine Zahlen. Das verstehe ich nicht :-O
MfG,
ShadowPhoenix
PS: Wie rückt man in einem Byte weiter
daten war ein Beispiel für eine Variable
Weiterrücken kann man mit dem Shift oder rotate
Man kann auch anstatt daten.0 daten.a schreiben, wodei a dann auch ein
Variable sein muß
ShadowPhoenix
22.05.2004, 14:38
Ja, aber kann daten nicht auch "00000001" sein?
Weil wie soll man bei der Zahl "23" abfragen, ob eine ziffer "1" oder "0" ist ?
MfG,
ShadowPhoenix
Also - du musst deine Sende LED zu erst einmal mit 36kHz modulieren.
D.h. du initialisierst deinen Timer und schaltest die led alle 13,9 us an und alle 13,9 us später wieder aus. Dann sendet das Teil immer eine 1.
Wenn du nun eine Null senden willst, dann musst du die LED einfach ausschalten.
Um nun ein Byte zu übertragen, musst du vom MSB (most significant bit), also das oberste Bit zuerst übertragen, dann rotierst du das Byte eins nach links und sendest dann wieder das MSB. Das machst du insgesamt 8 Mal - dann hast du dein Byte übertragen.
Nun musst du nur noch ein Timing beachten, d.H. zum Beispiel eine 1 bedeutet, wenn die led 200 us lang mit 36 kHz. blinkt. Eine 0 bedeutet, wenn die LEd 200 us lang abgeschaltet ist.
Damit jetzt der Empfänger weiß, wann deine Übertragung beginnt brauchst du noch einen Syncronisationsbefehl. Zum Beispiel sendest du 50 us lang eine 1. (also 50us lang blinkt die LED mit 36 kHz).
Ich würde dir empfehlen das ganze aufzubauen, wie es bei den Phillips Fernsehgeräten ist. Die verwenden RC5. Da ist das alles geregelt.
Hier kriegst du alle Infos über RC5.
http://home.t-online.de/home/Holger.Heinemann/homepage.htm?rc5.htm
Falls dir das nicht ganz so passt kannst du es ja ein bisschen abändern, aber vom Prinzip, ist hier bereits alles vorhanden.
Grüße
Flite
Naja - hab ein bisschen zu lang gebraucht.
Wie wärs, wenn du dir mal das binäre, hexadezimale und dezimale Zahlensystem zu Gemüte führst. Mit der wissenschaftlichen VErsion des Standard Rechners von Windows (in Zubehör) kannst du 23 ganz einfach in eine binäre Zahl umwandeln:
23 dezimal = 00010111
Grüße
Flite
ShadowPhoenix
22.05.2004, 14:47
@Flite
Danke!
23 = 00010111
Jop, jetzt verstehe ich ;)
Nur:
Wie wird dann nach dem Schema...
daten = 23
for a = 1 to 8
if daten.0 = 1 then
sende 1
else
sende 0
end if
shift daten , right ,1
next a
...wieder EMPFANGEN?
MfG,
ShadowPhoenix
Also erst mal musst du das ganze verzögern.
Sonst läuft das viel zu schnell ab.
Dann musst du bei sende 1 implementieren, dass die LED mit 36 kHz moduliert wird. Sonst gibt der TSOP immer 0 zurück.
Was dir jetzt noch fehlt ist ein Startbefehl, der vor dem ganzen gesendet wird. Dieser muss eindeutig sein, darf also während der Übertragung nicht nochmals auftreten.
Wenn du nun am Empfänger diesen empfängst, musst du nur soviele us warten, wie du beim Senden auch wartest und dann den Status des TSOPs abfragen.
Also gewissermaßen:
Startbefehl erkannt.
for 1 to 8
Wenn TSOP = 1 Dann
empfang.0 = 1
else
empfang.0 = 0
rotate empfang, left, 1
warte XX us
next
So etwa sollte die empfangsroutine aussehen.
Am besten lässt sich sowas natürlich mit einem Speicheroszi überprüfen, aber ich denke, sowas besitzt du nicht ...
Grüße
Flite
ShadowPhoenix
22.05.2004, 15:15
Danke!
Eine Frage noch:
Kann ein Fehler auch daran liegen, dass mein 12MHz Quarz ZWEI AVR's versorgt?
Oder ist das egal?
MfG,
ShadowPhoenix
Hm - ein Quarz, der zwei AVRs versorgt sollte eigentlich gar nicht gehen.
Oder ist das ein Quarzoszillator.
Ich würde es mit 2 Quarzen versuchen, aber wenn du beide Programmieren kannst laufen die AVRs ja.
Probier es mal mit dem Code aus, wie ich ihn ober gepostet hab.
Evtl. laufen die AVRs auch noch mit dem inneren Takt (1 MHz), falls du die MEGA Reihe verwendest und die FUsebits noch nicht umgestellt hast.
Grüße
Flite
ShadowPhoenix
22.05.2004, 15:30
Ich meinte natürlich Quarzoszillatoren!
Naja, ich verwende ein externes Programmiergerät.
Hier meine aktuellen Codes, die leider nicht funktionieren:
SENDER:
$regfile = "m8def.dat"
$crystal = 12000000
Dim Daten As Byte
Dim A As Integer
Config Portb = Output
Mainloop:
Daten = 170
For A = 1 To 8
If Daten.0 = 1 Then
Gosub Send1
Else
Gosub Send0
End If
rotate Daten , Right , 1
Waitms 500
Next A
Goto Mainloop
Send1:
Portb.1 = 1
Waitms 500
Portb.1 = 0
Goto Mainloop
Send0:
Portb.1 = 0
Waitms 500
Portb.1 = 0
Goto Mainloop
EMPFANG:
$regfile = "m8def.dat"
$crystal = 12000000
Dim A As Integer
Dim Rxdaten As Byte
Dim Zustand As Integer
Config Portd = Input
Config Portb = Output
Zustand = Pind.2
Mainloop:
For A = 1 To 8
If Rxdaten.0 = 0 Then
Gosub Write0
Else
Gosub Write1
End If
rotate Rxdaten , Left , 1
Waitms 500
Next A
Goto Mainloop
Write1:
Portb.5 = 1
Waitms 500
Portb.5 = 0
Goto Mainloop
Write0:
Portb.5 = 0
Waitms 500
Portb.5 = 0
Goto Mainloop
Was ist da falsch programmiert?
MfG,
ShadowPhoenix[/code]
Ich habe noch nie in Bascom programmiert und habe mir gerade mal nur den Sendecode angeschaut.
Das kann so nicht funktionieren.
Erstens: Wie ich schon zweimal erwähnt habe. Die Sende LED darf nicht dauernd leuchten. Du musst sie mit 36 kHz modulieren - sonst liefert dein TSOP Empfänger IMMER nur 0 zurück.
In den Sende routinen musst du nicht 500 ms warten (was sogar falsch ist) und du musst auch nicht dien PORTb.0 wieder auf Null zurück setzen.
Zur Modulation.
$regfile = "m8def.dat"
$crystal = 12000000
Dim Daten As Byte
Dim A As Integer
Config Portb = Output
Mainloop:
Daten = 170
For A = 1 To 8
If Daten.0 = 1 Then
Gosub Send1
Else
Gosub Send0
End If
rotate Daten , Right , 1
Waitms 500
Next A
Goto Mainloop
Send1:
Send = 1
Goto Mainloop
Send0:
Send = 0
Goto Mainloop
Timer [der alle 1/ 72 000 s aufgerufen wird]:
if send = 1 Then
if toggle = 0 Then
toggle = 1
PORTb.0 = 1
else
toggle = 0
PORTb.0 = 0
end if
else
Portb.0 = 0
end if
So etwa sollte die Senderoutine aussehen.
Ich schau mir gleich noch die Empfangsroutine an.
Grüße
Flite
EDIT: Ach ja: eine Startbedingung fehlt natürlich auch. Sonst empfängt dein Empfänger nachher immer nur müll ...
Ähnliches gilt auch für deine Empfangsroutine:
$regfile = "m8def.dat"
$crystal = 12000000
Dim A As Integer
Dim Rxdaten As Byte
Dim Zustand As Integer
Config Portd = Input
Config Portb = Output
Zustand = Pind.2 // WAS IST DAS ?!?
Mainloop:
StartLoop:
If NOT Startbedingung = True Then
Goto StartLoop
' Auf Startbedinung warten
For A = 1 To 8
If PINb.0 = 0 Then
Rxdaten.0 = 0
Else
Rxdaten.1 = 1
End If
rotate Rxdaten , Left , 1
Waitms 500
Next A
PORTC = Rxdaten 'Ausgabe des gesendeten Bytes
Goto Mainloop
So könnte es schon eher funktinieren.
ShadowPhoenix
22.05.2004, 16:01
Das funktioniert auch nicht :-(
Was mache ich nur falsch...
Hab die Codes, so wie sie sind, je in einen AVR eingeflashed.
Aber es geht nicht ;-(
MfG,
SHadowPhoenix
...Was könnte ich nur falsch machen...
Was hast du jetzt als Startbedinung genommen?
Das sie so nicht gehen ist ja klar.
Wann soll die Variable Startbedinung auch auf True gesetzt werden?
Hast du den Timer richtig initialisiert?
Was für einen AVR verwendest du denn?
Grüße Flite
ShadowPhoenix
22.05.2004, 16:08
Startbedingung habe ich noch keine, sorry aber ich weiß nicht, wie ich das programmieren soll.
Ich benutze einen AVR ATmega8.
Der Timer sollte richtig initialisiert sein, habe den Code ja abgeschrieben.
MfG,
ShadowPhoenix
Also zum senden Startbedingung:
Vielleicht so:
send = 1
waitms 10
send = 0
Zum empfangen der Startbedingung:
startLoop:
if PORTB.0 = 1 Then
waitms(52)
if NOT PORTB.0 = 0 Then
goto startLoop
end if
else
goto startLoop
end if
Ich kann den Code hier nicht ausprobieren.
Versuch ihn zu verstehen und dann reinzukopieren (natürlich an die richtige Stelle).
Zur Initialisierung des Timers.
Kannst du mir mal posten, wie du den Timer initialisert hast?
Grüße
Flite
ShadowPhoenix
22.05.2004, 16:27
Den Timer initialisieren hast du doch eh schon gepostet:
Timer [der alle 1/ 72 000 s aufgerufen wird]:
if send = 1 Then
if toggle = 0 Then
toggle = 1
PORTb.0 = 1
else
toggle = 0
PORTb.0 = 0
end if
else
Portb.0 = 0
end if
So habe ich das auch hingeschrieben!
MfG,
ShadowPhoenix
Timer [der alle 1/ 72 000 s aufgerufen wird]:
SO HAST DU DAS DA REIN GESCHRIEBEN ?!?!?!
Dat geht logischerweise nicht.
Ich weiß nicht wie man den Timer in BASCOM initialisiert. Aber dazu gibts doch im Netz bestimmt genug Infos (oder auch in der Bedienungsanleitung von Bascom).
Du brauchst eine Funktion, die alle 1 / 72 000 s aufgerufen wird um dein Signal zu modulieren. Diese kann man mit dem Timer machen.
Und das obere Beispiel hast du so rein kopiert und kompiliert. Kann mir irgendwie nicht vorstellen, dass der so einen Schwachsinn überhaupt kompiliert.
Vielleicht solltest du dir erstmal ein wenig die Grundlagen aneignen?
Versuch doch mal eine LED mittels des Timers zum blinken zu kriegen, so dass die jede Sekunde einmal und einmal aus geht ...
Das soll dich nicht von dem Projekt hier abhalten (das ist nämlich echt einfach zu realisieren). Aber wenigstens die Grundfunktionen solltest du beherrschen, weil ich ohne je Bascom programmiert zu haben dir hier kein völlig funktinierendes Proghramm reinstellen kann.
In Codevision C könnte ich dir so ein prgramm schreiben, aber das ist ja nicht Sinn der Sache. Dabei lernst du ja nichts.
grüße
Flite
ShadowPhoenix
22.05.2004, 16:38
Oh sorry, diese Zeile:
Timer [der alle 1/ 72 000 s aufgerufen wird]:
hatte ich natürlich nicht eingefügt. !
Flite, es ist nicht so, dass ich die Grundlagen des AVR's nicht beherrsche.
Eine Led per Taster zum blinken zum bringen ist wohl das einfachste.
7Segment Anzeigen usw. habe ich auch schon angesteuert.
Eh nicht schwer, nur das mit den Bytes usw. kapiere ich leider nicht!
Da bin ich totaler Anfänger, aber da ich nun so etwas für den ADDLink zum fernsteuern meines Roboterfahrzeuges brauche, muss ich langsam
anfangen, mich mit diesen Funktionen vertraut zu machen :-O
MfG,
ShadowPhoenix
PS: Bitte tu mir einen gefallen:
Schreibe mir bitte den kompletten Sendecode sowie den kompletten Empfängercode auf (exklusive der Timer funktion, da blättere ich noch einmal nach, ok?)
Danke, weil dann flashe ich die AVR's mal damit und dann mal sehen !
So ich habs jetzt mal zusammenkopiert, wie ich mir das vorstelle.
Ich glaube jedoch nicht, dass das jetzt aufs erste Mal funktioniert - vielleicht sieht ja jemand anderes den Thread hier noch und kann schnell mal drüber schauen.
Aber probieren kann mans ja:
Der Sendecode:
$regfile = "m8def.dat"
$crystal = 12000000
Dim Daten As Byte
Dim A As Integer
Dim Send as Byte
Dim toggle as Byte
Config Portb = Output
Mainloop:
Waitms 1000
Daten = 170
'Sende Startbedingung
send = 1
waitms 10
send = 0
For A = 1 To 8
If Daten.0 = 1 Then
Send = 1
Else
Send = 0
End If
rotate Daten , Right , 1
Waitms 500
Next A
Goto Mainloop
[[[[ DIESE FUNKTION MUSS ALLE 1 / 72000 s AUFGERUFEN WERDEN ]]]]]
if send = 1 Then
if toggle = 0 Then
toggle = 1
PORTb.0 = 1
else
toggle = 0
PORTb.0 = 0
end if
else
Portb.0 = 0
end if
Und der Empfangscode:
$regfile = "m8def.dat"
$crystal = 12000000
Dim A As Integer
Dim Rxdaten As Byte
Dim Zustand As Integer
Config Portd = Input
Config Portb = Output
Mainloop:
startLoop:
if PORTB.0 = 1 Then
waitms(52)
if NOT PORTB.0 = 0 Then
goto startLoop
end if
else
goto startLoop
end if
waitms 10
For A = 1 To 8
If PINb.0 = 0 Then
Rxdaten.0 = 0
Else
Rxdaten.0 = 1
End If
rotate Rxdaten , Left , 1
Waitms 500
Next A
PORTD = Rxdaten 'Ausgabe des gesendeten Bytes
Goto Mainloop
Der Sendecode sendet alle 5050 ms die Befehle.
Dabei dauert ein Bit 500 ms und die Startbedinung 50 ms.
Vor jedem senden wird 1000 ms gewartet.
Das empfangene Byte wird an PORT D angelegt. D.h. den musst du noch auf Ausgang schalten (weiß ich nicht wie ...).
Grüße
Flite
ShadowPhoenix
23.05.2004, 09:20
Danke,funktioniert so in etwa.
Ich werde mich nun an das ADDLink Modul ranmachen,
MfG,
ShadowPhoenix
Kein Problem!
Aber was funktioniert denn jetzt genau nicht? Würde mich einfach nur interessieren.
Grüße
Flite
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.