- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 25

Thema: Ansteuerung RC LED Scheinwerfer

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    06.03.2016
    Beiträge
    9
    Hi,
    einen vorgekauten Code, will ich ja gar nicht haben

    Wenn ich mich jetzt nicht allzu dolle verrechnet habe, sollte bei 4,8 Mhz und einem Prescaler von 64 ein timerüberlauf nach 3,4 ms stattfinden, was ja aussreicht um die 2ms vom Empfänger zu erkennen.
    Daher sollte der Timer bei 1ms einen Wert von ca. 75 haben und bei 2 ms einen Wert von 150.


    Nur als Info, da nicht jeder Empfänger als High Pegel um die 5 V ausgibt sondern manchmal deutlich weniger, schalte ich mit der Impulsleitung einen kleinen NPN Transistor und ziehe mit diesem den Int0 auf GND. ansonsten benutze ich den Internen Pullup Widerstand.

    Von der Theorie her dachte ich daran mit dem Int0 einen Interrupt auzulösen und in eine ISR zu springen. Dort Frage ich den Pin ab ob er 1 oder 0 ist und merke mir das. Nur müßte ich dann bei ausgelößter ISR und Gemerkter steigender Flanke den Timer starten und bei fallender Flanke auslesen und den Timer wieder stoppen.

    Aber wie verwende ich den Timer dann noch für die anderen Funktionen?

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.065
    Was bedeutet deutlich weniger Spannung als 5V? Hast du das nachgemessen? Vielleicht benötigst du keinen Transistor. Und beim messen kein Multimeter sondern ein Oszilloskop verwenden.

    Beim Timer darfst du nichts ändern, sonst funktioniert der Timer Interrupt und die PWM Funktion nicht richtig. Du liest nur den aktuellen Zählerstand aus. Du musst nur bedenken das es einen Überlauf geben kann. Bei einem Überlauf musst du die Berechnung etwas anpassen.

    MfG Hannes

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Genau so ist es, der Timer zählt zwischen 75 und 150 Schritte weiter. Und man darf ihn nicht starten und stoppen, wenn er gleichzeitig ein PWM-Signal generieren soll, auch das ist richtig. Und bei dieser Anzahl an Zählschritten ist es sogar sehr wahrscheinlich, dass der Timer regelmäßig während des Impulses überläuft. Aber das ist nicht schlimm:

    Da Bytes ja keine negativen Werte haben können, gibt es sozusagen einen "Rückwärts-Überlauf", wenn Du von einem kleineren Byte ein größeres subtrahierst. Klingt jetzt vielleicht ein wenig abstrakt, aber an einem Beispiel wird es sicher verständlich:

    Nehmen wir mal an der Impuls ist so lang, dass der Timer um 80 Schritte weiterzählt. In der ISR weist Du bei steigender Flanke einer Variablen (z.B. "Alt") den aktuellen Zählerstand zu, und bei fallender Flanke einer anderen (z.B. "Neu"). Anschließend subtrahierst Du Neu-Alt. Ist der Timer zwischen den Flanken nicht übergelaufen, ist alles klar: Neu ist grölßer als Alt, und die Differenz ist immer 80.

    Aber was passiert wenn der Timer während des Impulses überläuft und Neu somit kleiner ist als Alt? Wenn Alt z.B. 200 ist, hätt Neu nach 80 Takten und einem Überlauf einen Wert von 24. Die Rechnung 24 - 200 ergibt auf Byte-Ebene aber nicht -176, sondern genau 80 (weil's nach der Null wieder bei 255 anfängt).

    Der langen Rede kurzer Sinn: Lass den Timer ganz ungerührt durchlaufen, lese den Zählerstand bei steigender und fallender Flanke ab, subtrahiere die beiden Werte, und Du hast IMMER die Impulslänge

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    06.03.2016
    Beiträge
    9
    Hallo Hannes,

    es ist wirklich so, es gibt bei Empfängern große Unterschiede und das teilweise auch bei gleichen Herstellern.
    Wenn man einen Empfänger mit den z. B. typichen 4,8V betreibt, gibt es keine Garantie das an einem Servoausgang auf der Impulsleitung auch 4,8V anliegen.
    Ganz klar, das läßt sich nur mit dem Oszi messen.

    Ich hatte schon Schaltungen aus dem Internet nachgebaut, an einem Servotester haben diese dann funktioniert und an einem Empfänger nicht.
    Seit dem bau ich mir einen Tansistor davor, den bekommt man immer noch unter und es funktioniert zuverlässiger.

    @Daniel

    Ok das mit dem Überlauf hab ich verstanden Ich bin es nur nicht gewohnt, ich programmier in 16 Bit Systemen da findet ein Byte nicht so die Verwendung und mit der Variable WORD läßt sich nur beschränkt rechnen. Und Integers sind vorzeichenbehaftet. Manchmal kann die Lösung doch so einfach sein

    Ich habe bisher nur ganz kleine Sachen selbst gemacht. Wie ist das mit den Interrupts. Ich möchte den Int0 verwenden mehr hat der Tiny eh nicht. Das ist Pin B.1 ok wie genau funktioniert das? Springt der bei jedem Flankenwechsel in die ISR routine und bearbeitet diese genau einmal?
    Also sowohl bei steigender als auch bei fallender Flanke?

    Ich bin übersa Wochenende nicht zuhause und komme mal wieder nicht zum testen.

    Aber könnte das so funktionieren? Wenn die Routine Zaehlung bei Int0 ausgelößt wird.

    Zaehlung:
    If Pinb.1 = 0 Then Signal_alt = Timer0 Else Signal_neu = Timer0
    Return

    Soweit ok den Timer Konfiguriere ich dann auch also nur als "Config Timer0 = Timer ; Prescaler 8"

    Das heißt ich kann dann um ne PWM zu erzeugen einen vergleichswert nehmen, beim erreichen den Ausgang einschalten und wenn der Timer überläuft den Ausgang wieder auf null setzen. Das kommt dann im Endeffekt diesem Fast-PWM Mode ungefähr gleich.

    Da hab ich jetzt ja mal ne paar anhaltspunkte.

    Vielen Dank euch bis hierher schon mal

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.065
    Wie das in Bascom funktioniert weiß ich nicht. Ich würde die normale PWM einstellen (egal welchen PWM Mode), also Prescaler, und die anderen Register für den PWM Mode, den du verwenden willst. Zusätzlich gibst du den Timer Interrupt frei. Dieser wird immer ausgelöst wenn der Timer überläuft (von Zähler max auf 0 springt).


    Wie der Int 0 reagiert musst du einstellen (mit den Registern). Ich müsste nachschauen wie das bei dem uC ist, ich weiß ich nicht. Aber normalerweise kann ma wählen zwischen Flanke steigend, Flanke fallend, Flanke steigend und fallend bzw Pegel high bzw Pegel low.

    MfG Hannes

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Ich habe bisher nur ganz kleine Sachen selbst gemacht. Wie ist das mit den Interrupts. Ich möchte den Int0 verwenden mehr hat der Tiny eh nicht. Das ist Pin B.1 ok wie genau funktioniert das? Springt der bei jedem Flankenwechsel in die ISR routine und bearbeitet diese genau einmal?
    Also sowohl bei steigender als auch bei fallender Flanke?
    Es gibt ein paar Register mit denen man einstellen kann, ob der Interrupt bei steigender Flanke, fallender Flanke, bei jeder Flanke, einem High-Level oder einem Low-Level ausgelöst wird. Bascom erledigt das Setzen dieser Register, so dass man sie gar nicht im einzelnen kennen muss, sondern nur die richtige (und einfache!) Bascom-Syntax braucht. In der Bascom-Hilfe steht beim Befehl "Config INT0" alles wesentliche.

    Dann muss man noch wissen, dass man Interrupts aus- und einschalten kann, denn mitunter kann es ja mal sein, dass das Hauptprogramm für eine Zeit eben nicht durch Interrupts gestört werden darf. Dieses Aus- und Einschalten geschieht auf zwei Ebenen:
    Erstens muss man jeden einzelnen Interrupt aktiv freigeben, damit er ausgeführt werden kann. in diesem Falle wäre der Befehl Enable INT0.
    Zweitens muss man eine "globale" Aktivierung aller Interrupts vornehmen, und zwar mit dem Befehl Enable Interrupts.
    Nur wenn der einzelne Interrupt freigegeben ist UND die globale Freigabe erfolgt ist, werden Interrupts auch ausgeführt. Sinn dieser doppelten Freigabe-Ebene ist es, die Interrupts sowohl einzeln und gezielt ein- und ausschalten zu können, aber auch mit einem einzigen Befehl (disable Interrupts) global alle Interrupts zu deaktivieren, z.B. wenn der Controller gerade eine zeitkritische Aufgabe abarbeitet, bei der er nicht gestört werden darf.

    Interrupt-Routinen (ISR) sollte so kurz wie möglich sein, um den Ablauf des Hauptprogramms nicht allzusehr aufzuhalten. In Deinem Fall könnte man das Subtrahieren der Werte aber auch gleich mit der fallenden Flanke mit erledigen und dem Hauptprogramm durch setzen eines Flag-Bits singalisieren, dass es eine neu gemessene Pulsdauer gibt. Dein Code war schon nahe dran:

    Code:
    ...
    Dim Signal_alt as Byte
    Dim Signal_neu as Byte
    Dim Flag as Bit
    Dim Impulsdauer as Byte
    
    Config INT0 = change
    On INT0 Flanke
    enable INT0
    Enable Interrupts
    
    Do
    ...
    ...
    
     If Flag = 1 then
      Flag = 0
      ...
      (Schauen, ob der neue Impuls anders war als der zuletzt gemessene)
      ...
     End if
    
    Loop
    
    ISR_Flanke:
     If PINB.1 = 1 then 
      Signal_alt = Timer0
     Else
      Signal_neu = Timer0
      Impulsdauer = Signal_neu - Signal_alt
      Flag = 1
     End if
    Return

    So könntest Du erstmal einen einfachen Code stricken der zunächst einmal nur überprüft, ob sich die Impulslänge nennenswert verändert hat. Wenn dieser Code läuft, könnte man den PWM-Teil dazubasteln!
    Geändert von Sauerbruch (14.03.2016 um 20:53 Uhr)

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    06.03.2016
    Beiträge
    9
    Also irgendwie komme ich nicht weiter.

    Habe den ganzen Tag rumexperimentiert mit bescheidenem Ergebnis.

    Ich habe jetzt einen Servotester vom Conrad als Empfängerersatz genommen, dieser bringt einen 1 -2 ms Sekunden langen Impuls raus aber nur mit 3 V. Deswegen hab ich wie bereits erwähnt einen kleinen Transistor davor gebaut der mir den PinB.1 auf GND zieht und hab den internen Pullup aktivierten. An PortB.0 hängt eine LED gegen GND.

    Ich habe jetzt folgendes Problem, die LED leuchtet immer schwach. Warum auch immer ist der Ausgang für 1ms an und dann 6ms aus wo das auch immer her kommt. Wenn ich den Servotester verstelle, gibt es irgendwo einen Punkt da wird die LED heller aber flackert manchmal und manchmal auch nicht. Ich kann es nicht nachvollziehen.

    Das hier hab ich jetzt mal zusammen geschrieben:

    $regfile = "attiny13a.dat" 'Attiny 13a
    $crystal = 4800000 'Attiny @ 4,8 Mhz
    $hwstack = 26 'HardwareStack
    $swstack = 20 'SoftwareStack
    $framesize = 10 'Framesize
    '$baud = 4800

    Config Portb.0 = Output 'Schaltausgang für LED an B.0

    Config Pinb.1 = Input 'Anschluss am Empfänger B.2
    Portb.1 = 1 'Pullupwiderstand einschalten

    Config Timer0 = Timer , Prescale = 64 'Timer0 als Timer mit prescaler 64 laufen lassen

    Config Int0 = Change

    Enable Interrupts 'generell Interrupts Zulassen
    Enable Int0 'Int0 freigeben

    On Int0 Zaehlung 'Zaehlung Routine anspringen bei Signalwechsel an Int0

    Dim Signal_alt As Byte 'Variable für die Empfänger Impulsbreite
    Dim Signal_neu As Byte
    Dim Signal As Byte


    Wait 1 'einfach Mal Abwarten

    Do 'Start Hauptschleife

    Signal = Signal_alt - Signal_neu
    If Signal >= 120 Then Portb.0 = 1 Else Portb.0 = 0


    Loop



    Zaehlung:

    If Pinb.0 = 0 Then Signal_alt = Timer0 Else Signal_neu = Timer0

    Return

    Ziel soll erst mal sein die Impulslänge zu messen.

    Eine PWM zu erzeugen hab ich geschafft ist aber hier nicht mehr mit drin, wollte vermeiden das es irgendwie daran liegt.

    Wenn einer eine Idee hat, bin für alles Dankbar

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Ich sehe einen kleinen "Schönheitsfehler":
    Wenn der Impuls beginnt, wird die Variable Signal_alt zwar aktualisiert, aber die Subtraktion in der Hauptschleife wird noch mit dem alten Wert von Signal_neu ausgeführt. Auch wenn dieser Zustand nur 1-2ms lang dauert, kommt in dieser Zeit nichts sinnvolles heraus.
    Mach die Subtraktion doch in der ISR nach dem Impulsende:

    Code:
    Zaehlung:
     If Pinb.0 = 0 then
      signal_alt = timer0
     else
      signal_neu = timer0
      Signal = Signal_neu - Signal_alt
     end if
    Return
    Dann hast Du schon mal immer einen "sauberen" Wert für die Variable Signal.

    Und spannend ist natürlich auch die Frage, ob der Controller auch tatsächlich mit 4,8 MHz läuft! Hast Du das mit den Fusebits korrekt eingestellt?

Ähnliche Themen

  1. LED-Scheinwerfer mit 3.000 Lumen
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 10
    Letzter Beitrag: 18.04.2013, 14:57
  2. Scheinwerfer und Blaulicht
    Von markus788 im Forum Robby RP6
    Antworten: 3
    Letzter Beitrag: 26.10.2012, 16:12
  3. LED- und IR- Scheinwerfer
    Von fabqu im Forum Robby RP6
    Antworten: 18
    Letzter Beitrag: 15.02.2011, 19:43
  4. Dmx RGB Led Scheinwerfer
    Von Maxtronik im Forum Vorstellungen+Bilder von fertigen Projekten/Bots
    Antworten: 7
    Letzter Beitrag: 07.06.2010, 22:39
  5. DMX-LED-RGB Scheinwerfer
    Von rideyourstyle im Forum Vorstellung+Bilder+Ideen zu geplanten eigenen Projekten/Bots
    Antworten: 5
    Letzter Beitrag: 24.10.2008, 13:55

Berechtigungen

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

12V Akku bauen