-         

Ergebnis 1 bis 7 von 7

Thema: Funkmodule 130428-99 von Conrad

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    473

    Funkmodule 130428-99 von Conrad

    Anzeige

    Ich verwende das 130428 Sende-Empfangsset von Corad.
    Allerdings habe ich eben gesehen, dass die Dinger gut an Preis zugelegt haben...
    Bis jetzt habe ich nur den Empfangsseitigen Teil beschrieben. Hoffe, dass ist was geworden. Wenn das jemand komplett ließt, bin ich für eine kurze Meinung zu haben - also von wegen sinnvoller Aufbau der Beschreibung etc. Das Prog ist sicher noch nicht optimal, aber es arbeitet. Vor dem lesen am besten erst mal das Bild ansehen, ich weiß leider nicht, wie ich das mache, dass man es nicht extra öffnen muss, sondern so sehen kann.

    Normalerweise muss man den Sender mit Manchestercode versorgen, den ich aber nicht codieren kann.
    Da ich dann raugefunden habe, dass es auch möglich ist, bis zu einer bestimmten Frequenz HIGH LOW
    Signale zu übertragen, bin ich dazu übergegangen, über Pulsweiten log. einsen und nullen zu
    übertragen. Zudem ist die Eigenschaft wichtig, dass durch dauerhaftes anlegen eines High Signales am Sender
    der Empfänger definiert LOW gehalten werden kann, außerdem wird der Empfänger ohne Signal von anderen Quellen
    gestört.

    Grobes Prinzip der Übetragung:

    Das Prinzip des Senders ist, dass in ein Register ein Bitmuster geladen wird.
    An diesem Register wird das MSB auf eins oder null getestet. Anhand vom Ergebnis wird die nächste
    Pulsweite entweder lang oder kurz. Danach wird ein logic left shift ausgeführt. Das Ganze dann acht mal.

    Im Empfänger wird auf ein Register ERST (und das ist wichtig) ein lsl angewendet und dann
    je nach Pulslänge das Register mit einer ori 0b00000001 Operation erhöht oder auch nicht. Auch
    dass muss sinngemäß achtmal passieren. Gemessen wird
    die Dauer zwischen zwei externen Interrupten. Dabei wird bei jedem logik Wechsel getriggert.
    Sind die achtmal erreicht, wird das Register ausgelesen und entsprechend der Kodierung eine Aktion
    ausgeführt.


    Für das Verständis des Systems ist es am besten auf der Empfangsseite anzufangen.
    Bei der Entwicklung des Sederprog´s wurde auch hier begonnen.
    Das erste Problem das es zu behandeln gilt ist, dass solange der Sender kein Signal gibt, der Empfänger
    undefiniert schaltet. Deshalb befinden sich die prozessrelevanten Register in einem
    undefinierten Zustand.
    Das sind:
    TCCR wird nicht im INIT Code gesetzt
    TCNT zur Teitmessung
    shf das Register aus dem das gesendete Bitmuster ausgelesen wird
    shfc in diesem Register wird gezählt, wie oft der ext. INT. erfolgte (das c steht für counter)

    Um genau das zu beheben, dient die lange Pulsdauer zu Beginn des Sigales. Im Empfänger wird bei einem
    Comparematch mit OCR2 = 100 ein Interrupt ausgelößt, in dessen ISR (definiren) die oben genannten
    Register = 0 gesetzt werden.


    Ab dem ersten LOW Pegel danach sind die Intervalle zu kurz, um einen Comparematch zu triggern
    und es läuft nur noch die ISR des ext Int. (inter). Zu jedem Anfang wird der TIMER mit Prescaler = 64 gestartet,
    obwohl das nur beim ersten mal nötig währe.
    Das nullsezten von TCNT passiert "manuell" am Edne der ISR.
    Für das spätere verstehen der Programme ist es wichtig, zu beachten, das shfc nach dem Fall der ersten
    Flanke bereits = 1 ist, ohne das schon ein Bit übertragen wurde.

    Steigt die Flanke wieder, passiert das selbe. Erst ab dem Fallen des rot makierten HIGH Pegels findet
    die erste relevante Zeitmessung statt. Diese Zeit wird aber erst während des grün makierten LOW Pegels ausgewertet.
    Aus diesem Zusammenhang folgert bereits, das ein Pegel mehr existiert (gelb), als man vielleicht erstmal für nötig hält.
    Daher endet shfc letztendlich auch bei 11, die sich im Sendeprogramm wiederfinden wird!

    Diese 11 sind 3 mehr, als für das einlesen von 8 Bit nötig sind und OH, welch wunder, diese Differenz findet sich
    im Proramm des Empfängers. (Kommentar dazu im Code)

    Hat shfc den WERT 11 errreicht, wird shf ausgelesen.

    Code:
    .include "m8def.inc"
    
    .def shf = r20
    .def tmp = r16
    .def shfc = r21
    .def aus = r22
    .def zeit = r23
    .def merker = r24
    .def an = r25
    .def timer = r17
    
    
    .org 0x0000
    	rjmp reset
    .org INT1addr	
        rjmp inter
    .org OC2addr
        rjmp definieren
    reset:
    
    	;Stack wird bei Interrupts benötigt!
    	ldi r16,HIGH(RAMEND)
    	out SPH,r16
    	ldi r16,LOW(RAMEND)
    	out SPL,r16
        ldi tmp,0b00000100
    	out MCUCR,tmp       ;int @ ext logicchange
    	ldi tmp,0b10000000
    	out GICR,tmp
    	ldi tmp,0b11110111
    	out DDRD,tmp
    	com tmp
    	out PORTD,tmp
    	ldi tmp,0b00001000
    	out DDRB,tmp
    	ldi tmp,0b10000000
    	out TIMSK,tmp       ;int @ OCR2    
    	ldi timer,0b00000100
        ;out TCCR2,timer
    	ldi tmp,100
    	out OCR2,tmp
    	sei
    
    ldi aus,0
    ldi an,255
    mainloop:
    
    ; wie cool, das Programm läuft
    ; ohne einen MAIN Code - BÄM!
    
    
    
    rjmp mainloop
    
    definieren:
    out TCCR2,aus
    ldi shf,0
    ldi shfc,0
    ;out PORTD,aus
    out TCNT2,aus
    reti
    
    
    inter:
    inc shfc
    out TCCR2,timer
    cpi shfc,2         ;da der shfc Wert des letzten Pegels keine Rolle spielt,
    brlo later		   ;da dort nur die letzte Zeit verarbeitet wird,
       lsl shf 		   ;ergibt sich mit der 2 die Different von drei
       in tmp,TCNT2
       cpi tmp,45      ;Schwellwert für log eins oder null
       brlo lognull
       ori shf,1
       lognull:
    
       
                          	;________________________________________
       cpi shfc,10          ; 
       brlo later			;wenn shfc 10 ist,
               				;wurden die 8 BIT in shf 
       cpi shf,0b00010001	;eingelesen und können verarbeitet
       breq on				;werden. Hier mit dem setzten oder
       cpi shf,0b00010010	;löschen vom PINB 3
       breq off				;
       rjmp nocommand		;	
    						;
       on:					;
       ldi tmp,0b00001000	;
       out PORTB,tmp		;
       rjmp nocommand		;
       off:					;
       ldi tmp,0			;
       out PORTB,tmp		;
    
       nocommand:			;_________________________________________
    
       mov tmp,shf
       andi tmp,0b11110111
       out PORTD,tmp        ;dient zur visuellen Kontrolle des eingegangenen Befehls
       ldi shfc,0			; und während der Entwicklungszeit für so manche Überraschung^^
       ldi shf,0
       out TCCR2,aus
    
    later:
    out TCNT2,aus
    reti
    [/url]
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken signal2.jpg  
    Chuck Norris kann Windows Vista auf einem Atmel in Assembler implementieren!
    Chuck Norris coded mit 3 Tasten:"1","0" und "compile"

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    473
    M´kay, nachdem jetzt der Empfänger abgehandelt ist,
    wollen wir uns mal der Generierung des Sendesingnales zuwenden.
    Bei dem ersten Blick, fälllt bereits auf, dass es hier etwas wüster zugeht,
    als im Empfänger.


    Als Kern der eigentlichen Senderroutine wird hier der Comparematch mit dem OCR2 Register
    zur Pulsweiten Variation genutzt. Dazu an gegebener Stelle mehr.

    Der erste Teil in der Mainschleife soll den Befehl aufnehemen,
    der gesendet werden soll. In diesem ersten Prog ist das nur einmal das Bitmuster
    00010001 oder 00010010. Der eine Befehl schaltet eine Lampe ein, der andere aus.
    Es ist auf jeden Fall ratsam, immer min. zwei BIT´s 1 zu setzen, um eine gewisse
    Störsicherheit zu erreichen. Jedoch reicht auch das auf längere Zeit nicht. Ich werde
    daher dazu übergehen, 16 BIT´s zu kodieren.


    Nach diesem ersten Teil wird getestet, ob der neue Befehl auch tatsächlich neu ist und nicht
    bereits gesendet wurde, wovon abhängt, ob dann überhaupt gesendet wird. Da muss man sich aber
    überlegen, ob das nötig ist. Z.B. würden erhöhende und erniedrigende Befehle
    auch mehrmals Sinn machen.

    Nachdem das alles abgehandlet ist, wird der PIN, an dem der Sender hängt HIGH gesetz,
    und eine Warteschleife aufgerufen, die bis TCNT2 = 250 dauert. An dieser Stelle ist
    der Interrupt Enable für OCR2 noch inaktiv.
    Nach dieser Funktion wird der zu sendende Befehl in einem zweiten Register zum späteren
    vergleichen abgespeichert.

    Darauf folgt die INIT Funktion, in welcher der Interrupt des Comparematches aktiv wird, der TNCT2
    wird null gesetzt, an OCR2 der Wert 60 übergeben und der zu sendede Befehl in das shift Register shf
    kopiert. Auf dieses wird später die LSL Operation angewendet.

    Nun kommt endlich der interessante Teil, die eigentliche Senderoutine.
    In diese ist eine Schleife progammiert, die elf mal durchlaufen wird.
    In shfc wird festgehalten, wie oft die ISR aufgerufen wurde.

    mehr1:
    cpi shfc,11 (aus irgendeinem Grund
    brlo mehr1 ist die doppelte abfrage
    cpi shfc,11 nötig, sonst wird die Schleife
    brlo mehr1 einen Zyklus zu früh verlassen -
    ldi shfc,0 hat was mit einem der Statusbits zu tun)

    Die Erklärung für die elf Mal
    findet sich in der Erläuterung des Empfangprog´s.
    Diese Schleife kann erst nach dem senden aller Datenbits verlassen werden. Vorher
    wird sie mit der Verarbeitungsgeschwindigkeit wiederholt. Unterbrochen wird das nur
    durch einen Comparematch mit OCR2, also beim ersten Mal bei TCNT2 = 60.
    Daraufhin wird die ISR "hitvalue" aufgerufen.

    Dort wird als erstes der logische Pegel, an dem der Sender sitzt, ivertiert. Das geht
    Hand in Hand mit der Einstellung des Empfängers, der bei einem logischen Wechsel an INT1
    interruptet.
    Als zweites wird geprüft, ob die ISR im ersten Durchlauf ist, denn dann war der Interrupt zum
    initialisieren des Empfängers.
    Ist es jedoch mindestens der zweite Durchlauf, wird in Abhängigkeit des M(ost) S(inificant) B(it)
    von shf die nächste Pulsdauer bestimmt und die besagte LSL Op auf shf gemacht.

    ldi dauer,60
    sbrs shf,7
    ldi dauer,30
    lsl shf

    Als letztes wird shfc um eins erhöht.
    Dann wird über reti wieder in die Schleife der Funktion senden1

    cpi shfc,11
    brlo mehr1
    cpi shfc,11
    brlo mehr1

    zurückgesprungen.

    Sind die elf Mal erreicht, wird der Interrupt durch OCR2 wieder deaktiviert und eine Warteschleife
    auf Basis von TCNT0 bis 30 ausgeführt.
    Danach wird der PIN wierder LOW gesetzt und nach MAIN zurückgekehrt.

    Die Ganze Fummelei mit dem TIMSK könnte man im Prinzip auch mit sei; und cli machen, aber villeicht will man ja mal noch andere Interrupte nutzten, Tastermatrix z.B.

    Code:
    .include "m8def.inc"
    
    .def shf = r17
    .def shfc = r18
    .def dauer = r19
    .def zwischen = r20
    .def tmp = r21
    .def timermaskon = r22
    .def timermaskoff = r23
    .def befehl = r24
    .def t = r25
    .org 0x0000
    	rjmp reset
    .org OC2addr	; OCR2 Interrupt Vector Address
        rjmp hitvalue
    reset:
    
    	;Stack wird bei Interrupts benötigt!
    	ldi r16,HIGH(RAMEND)
    	out SPH,r16
    	ldi r16,LOW(RAMEND)
    	out SPL,r16
        ldi r16,0b01100000 ;internal Vref - Channel 0
    	out ADMUX,r16
    	ldi r16,0b10001110 ;singleconversion - prescaler 32 - int.enable 
    	out ADCSRA,r16
    	ldi r16,0b11111110
        out DDRC,r16
    	;out PORTC,r16
        ldi r16,0b11110111
    	out DDRD,r16
    	ldi r16,0b00000011
    	out TCCR0,r16
    	ldi timermaskoff,0
        ldi tmp,0b00001100  ;interuppt on comparematch - presc 128
        out TCCR2,tmp
    	;ldi r16,255
    	;out OCR2,r16
    	ldi timermaskon,0b10000000
        sei
    
    mainloop:
    wdr
    
    sbic PIND,3
    rjmp open
    sbis PINB,5
    ldi befehl,0b00010001
    sbis PINB,4
    ldi befehl,0b00010010
    open:
    
    
    
    cp zwischen,befehl
    breq unten
    ldi tmp,255
    out PORTC,tmp
    rcall pause
    mov zwischen,befehl
    rcall init
    rcall senden1
    ldi t,0
    hoch:
    sbic PIND,3
    rjmp hoch
    unten:
    rjmp mainloop
    
    pause:
    ldi tmp,0
    out TCNT0,tmp
    warten:
         in tmp,TCNT0
         cpi tmp,250
         brlo warten
    	 ldi tmp,0
    	 out TCNT0,tmp
    
    ret
    
    init:
    ldi tmp,0
         out TCNT2,tmp
    	 ldi tmp,60
    	 out OCR2,tmp
    	 mov shf,befehl 
    	 out TIMSK,timermaskon
    ret
    
    senden1:
    mehr1:
    cpi shfc,11
    brlo mehr1
    cpi shfc,11
    brlo mehr1
    ldi shfc,0
    	 out TCNT0,shfc
         out TIMSK,timermaskoff
    warten2:
         in tmp,TCNT0
         cpi tmp,30
         brlo warten2
    	 ldi tmp,0
    	 out TCNT0,tmp
    ldi tmp,0
    out PORTC,tmp
    ret
    
    hitvalue: 
       in tmp,PORTC
       com tmp
       out PORTC,tmp
       
       cpi shfc,1
       brlo senden 
       
       ldi dauer,60
       sbrs shf,7
       ldi dauer,30
       lsl shf
      
    out PORTD,dauer
       out OCR2,dauer
       senden:
       inc shfc
    reti
    Kommentar:

    Nch dem schreiben sind mir einoge Dinge aufgefallen, die noch nicht perfekt sind. Zum ersten kann ich sicher das erste INIT Bit schon als Datenbit nutzten und zum anderen in der senden1 Funktion die Warteschleife mit dem TCNT0 müsste auch wie zuvor über den Interrupt gehen.
    Und wenn jemand weiß, woran das liegt, das ich die elfer Schleife zweimal brauche, bin ich dankbar für eine Erklärung.

    Wenn ich dann mal die Zeit habe, mache ich mal eine Schaltungsskizze.

    The Man
    Chuck Norris kann Windows Vista auf einem Atmel in Assembler implementieren!
    Chuck Norris coded mit 3 Tasten:"1","0" und "compile"

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    sau teuer die dinger bei c , wer die jetzt kauft hat selber schuld.
    ausserdem sind die nicht sehr leistungsfähig.
    hatte ich auch mal wo die sehr günstig waren, habe die bald aus dem fenster geschmissen, der letzte dreck.

    habe mir funk-rs232 von Robotikhardware geholt.

    mf

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    473
    Also ich finde nicht, dass der Ton Not tut.
    Das man seine Meinung hat ist natürlich in Ordnung,
    nur ein bisschen differenzierter darf´s schon sein.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    habe ich nicht deutlich geschrieben. du wirst deine erfahrungen da noch mit machen, wenn es um eine sichere übertragung gehen soll und nicht nur eben mal einpaar bytes rüberschieben nach dem motto : oh, guck mal die 16 euro-dinger machen ja etwas !

    mfg

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    473
    Da hast du natürlich Recht, als ich mich an die max Frequenz rangetastet habe, war bald klar, das ich von Kib/s weit weg bin. Bei mir geht´s auch letztendlich nur um ein paar an aus etc. Signale.
    Aber seit dem die an Preis zugelegt haben, werde ich doch auf die POLLIN rfm 12 zurückgreifen...

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    ...SPI-Schnittstelle kann das Modul leicht mit einem Microcontroller programmiert und angesteuert werden......


    leicht ist übertrieben.

    hier gibt es ein thread dafür, der ist schon über 455 antworten lang.
    machen auch schön schwierigkeiten.

    http://www.mikrocontroller.net/forum...k?filter=rfm12

    http://www.mikrocontroller.net/topic/65984#new

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •