-         

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 34

Thema: Eine RGB-Led und ein AtTiny13

  1. #1
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638

    Eine RGB-Led und ein AtTiny13

    Anzeige

    Hallo!


    Nach längerer Elektronik-Abstinenz wieder ein Projekt von mir. Eigentlich nur eine RGB-Led und ein AtTiny13 sowie etwas Hühnerfütter. Genannt habe ich dieses etwas "TinyRGB".

    Allerdings scheinen meine Programmierkenntnisse massiv eingerostet zu sein. Die von mir geschriebene Software läuft tadellos, die RGB-Led blendet wunderbar alle Farben durch (im Modus0) und fährt auch das Programm (Modus1) durch. Allerdings möchte ich die Software wesentlich schlanker machen, meine Variante benötigt nämlich jede Menge Flash. Auch gefallen mir die ganzen IF-Abfragen nicht.

    Aber mir fällt einfach nichts ein.

    tinyrgb_v1_0.bas
    Grüße
    Thomas

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    20.10.2004
    Ort
    Thüringen
    Beiträge
    133
    Is doch Wurscht...

    Passt rein in den Controller und funktioniert...
    Also wozu noch Lebenszeit vernichten und abändern??
    Schaltung aufbauen, Glücklichsein und ab zum nächsten Projekt.

    MfG, dl1akp

  3. #3
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    28
    Beiträge
    3.517
    Blog-Einträge
    9
    Das hier:

    Code:
    If Modus = 0 Then
          If State = 0 Then
             Incr C_r
             Decr C_b
             If C_r = 255 Then State = 1
          End If
          If State = 1 Then
             Decr C_r
             Incr C_g
             If C_g = 255 Then State = 2
          End If
          If State = 2 Then
             Decr C_g
             Incr C_b
             If C_b = 255 Then State = 0
          End If
       End If
       If Modus = 1 Then
          If State = 0 Then
             If C_r < 255 Then Incr C_r
             If C_r = 255 Then State = 1
          End If
          If State = 1 Then
             If C_b < 255 Then Incr C_b
             If C_b = 255 Then State = 2
          End If
          If State = 2 Then
             If C_g < 255 Then Incr C_g
             If C_g = 255 Then State = 3
          End If
          If State = 3 Then
             If C_r > 1 Then Decr C_r
             If C_g > 50 Then Decr C_g
             If C_b > 1 Then Decr C_b
             If C_r = 1 Then State = 4
          End If
          If State = 4 Then
             If C_g < 255 Then Incr C_g
             If C_b < 255 Then Incr C_b
             If C_b = 255 Then State = 5
          End If
          If State = 5 Then
             If C_g > 1 Then Decr C_g
             If C_b > 1 Then Decr C_b
             If C_g = 1 Then State = 0
          End If
       End If
    Kannst du z.B. so umändern:

    Code:
    If Modus = 0 then
    Select Case State
    Case 0 : Incr C_r
             Decr C_b
             If C_r = 255 Then State = 1
    Case 1 : Decr C_r
             Incr C_g
             If C_g = 255 Then State = 2
    Case 2 : Decr C_g
             Incr C_b
             If C_b = 255 Then State = 0
    End Select
    Und für Modus = 1 ersetzt du die ganzen If-Abfragen ebenfalls durch Select-Case. Ob es das Programm nun wirklich kleiner macht weiß ich nicht aber auf jedenfall wird es übersichtlicher.
    Den Rest wüsste ich nun nicht wie man den noch optimieren kann. Das Hauptprogramm beinhaltet nicht soviel Code, wobei ich die ISR vom Timer noch schlanker machen würde. In etwa so:

    Code:
    ISR_Timer0:
    
    Interruptflag_Timer0 = 1
    
    Return
    Und dann im Hauptprogramm:

    Code:
    Do
    If Interruptflag_Timer0 = 1 then
       If Pwm_count = 255 Then Pwm_count = 0       'PWM-Variable bei 255 resetten
       Incr Pwm_count                       'PWM-Variable erhöhen
       If Div = 10000 Then                  'Teilervariable bei 10000 resetten
          Div = 0
          Gosub Fading                      'Springe bei 10000 zu Fading
       End If
       Incr Div                             'Teilervariable erhöhen
    End if
    Loop
    End
    Dies machst du aus dem Grund, weil man eine ISR möglichst kurz halten sollte (gut in deinem Programm macht das nun nichts aus, weil du nur eine ISR hast).
    Weil wenn du mehrere Interruptquellen in einem Programm hast können eventuell Interrupts verschluckt werden, weil deine ISRs zu lang sind.
    Deswegen mach ich das immer so das ich in den ISRs (wenn möglich) nur ein Bit setze, weil das schön schnell geht.
    Wenn du in ISRs sowas wie "Print" Befehle o.ä. reinknallst kann es gut sein, dass der Controller beim ausführen der ISR einen anderen Interrupt ignoriert, weil so ein "Print" Befehl richtig viel Zeit braucht.
    So würde ich das optimieren....ich weiß allerdings nicht in wie weit das eine Optimierung ist, weil ich selber nicht so der eingefleischte Programmierer bin
    Aber das Select-Case macht das Programm auf jedenfall überschaubarer.

    Edit: Hab gerade gesehen, dass du von der ISR in ein Unterprogramm springst.....versuch sowas zu vermeiden
    Wie gesagt nutze die Methode wo du in den ISR einfach nur Bits setzt und die Auswertung macht dann das Hauptprogramm.
    Geändert von Kampi (08.03.2012 um 09:38 Uhr)
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo Thomas,
    Ich würde das auch so sehen, dass wenn es funktioniert es doch ok ist.
    Wenn du beim nächsten Mal etwas verbessern möchtest, dann würde ich das gar nicht mal so sehr in deinen IF-Abfragen sehen, obwohl die Variante von Kampi sicherlich besser zu lesen ist.
    Vielmehr würde ich die SoftPWM mal überdenken.
    Dein µC läuft mit 9,6MHz, dein Timer ist 8-bit, läuft also 9.600.000 / 256 = 37500 mal pro Sekunde über. Das ist viel mehr als nötig. Es führt dazu, dass dein µC fast nichts anderes mehr tut, als andauernd die ISR aufzurufen. Hätte er jetzt noch andere Aufgaben, würde dies sicherlich schiefgehen.
    Ich bin sicher, dass du für den Timer einen Prescaler von 8 oder 64 angeben könntest, ohne die Funktion zu verschlechtern. Dann müsstest du allerdings auch den Div-Wert von 10000 entsprechend auf 1250 bzw. 160 ändern.
    Damit würde dein µC auf einen Schlag nur noch etwa 1% seiner Leistung in die PWM stecken.
    Vielleicht probierst du es mal aus.

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.410
    Blog-Einträge
    101
    Hallo,
    Code:
    Config Timer0 = Timer , Prescale = 1
    On Timer0 Isr_timer0
    Enable Timer0
    Start Timer0
    In diesem Fall ist Start Timer0 überflüssig, da der Timer schon durch Config Timer0 gestartet wird.

    Es gibt eine ISR und von der ISR wird nochmal ein Unterprogramm aufgerufen. Nach der Berechnung von dieser Seite: http://halvar.at/elektronik/kleiner_...swstack_frame/ oder auch nach der englischen mcs Seite wäre der $hwstack bei Dir viel zu klein bemessen.

    Ich hab mir angewöhnt, in den Programmkopfbemerkungen immer die Bascom Version mit reinzuschreiben, in der das Programm läuft. Es gibt von Version zu Version manchmal sehr einflußreiche Änderungen.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638
    Hallo!


    Vielen Dank für eure Antworten.

    Zitat Zitat von dl1akp Beitrag anzeigen
    Is doch Wurscht...

    Passt rein in den Controller und funktioniert...
    Also wozu noch Lebenszeit vernichten und abändern??
    Schaltung aufbauen, Glücklichsein und ab zum nächsten Projekt.
    Diese Einstellung will ich nicht teilen. Ich möchte nicht nur ein Projekt nach dem anderen machen, sondern ich möchte auch meine Programmierkenntnisse verbessern sowie auch verstehen, warum und wieso etwas funktioniert, gut funktioniert, schlecht funktioniert oder überhaupt nicht funktioniert. Für mich gehört dies genauso zum Prozess des Lernens. Es bedeutet einen Ansporn, gute und ressourcensparende Programme zu entwicklen und ich gebe mich nicht mit einem "funktioniert, ab in die Schublade" zufrieden.

    Zitat Zitat von Kampi Beitrag anzeigen
    Und für Modus = 1 ersetzt du die ganzen If-Abfragen ebenfalls durch Select-Case. Ob es das Programm nun wirklich kleiner macht weiß ich nicht aber auf jedenfall wird es übersichtlicher.
    Den Rest wüsste ich nun nicht wie man den noch optimieren kann. Das Hauptprogramm beinhaltet nicht soviel Code, wobei ich die ISR vom Timer noch schlanker machen würde. Dies machst du aus dem Grund, weil man eine ISR möglichst kurz halten sollte (gut in deinem Programm macht das nun nichts aus, weil du nur eine ISR hast). [...]
    Ob das Ersetzen der If-Abfragen durch Select-Case Flash spart, werde ich sofort testen. Aber eines stimmt mit Sicherheit, es macht den Code übersichtlicher. Danke für den Hinweis!

    Zitat Zitat von Kampi Beitrag anzeigen
    Weil wenn du mehrere Interruptquellen in einem Programm hast können eventuell Interrupts verschluckt werden, weil deine ISRs zu lang sind.
    Deswegen mach ich das immer so das ich in den ISRs (wenn möglich) nur ein Bit setze, weil das schön schnell geht.
    Wenn du in ISRs sowas wie "Print" Befehle o.ä. reinknallst kann es gut sein, dass der Controller beim ausführen der ISR einen anderen Interrupt ignoriert, weil so ein "Print" Befehl richtig viel Zeit braucht.
    Ich dachte, der Controller speichert Interrupts ab und führt sie direkt im Anschluss aus, wenn er noch in der Abarbeitung eines Interrupts steckt?

    Zitat Zitat von for_ro Beitrag anzeigen
    Hallo Thomas,
    Ich würde das auch so sehen, dass wenn es funktioniert es doch ok ist.
    Wenn du beim nächsten Mal etwas verbessern möchtest, dann würde ich das gar nicht mal so sehr in deinen IF-Abfragen sehen, obwohl die Variante von Kampi sicherlich besser zu lesen ist.
    Vielmehr würde ich die SoftPWM mal überdenken.
    Dein µC läuft mit 9,6MHz, dein Timer ist 8-bit, läuft also 9.600.000 / 256 = 37500 mal pro Sekunde über. Das ist viel mehr als nötig. Es führt dazu, dass dein µC fast nichts anderes mehr tut, als andauernd die ISR aufzurufen. Hätte er jetzt noch andere Aufgaben, würde dies sicherlich schiefgehen.
    Ich bin sicher, dass du für den Timer einen Prescaler von 8 oder 64 angeben könntest, ohne die Funktion zu verschlechtern. Dann müsstest du allerdings auch den Div-Wert von 10000 entsprechend auf 1250 bzw. 160 ändern.
    Damit würde dein µC auf einen Schlag nur noch etwa 1% seiner Leistung in die PWM stecken.
    Vielleicht probierst du es mal aus.
    Eine interessante Idee. Das werde ich versuchen. Danke!

    Zitat Zitat von Searcher Beitrag anzeigen
    Es gibt eine ISR und von der ISR wird nochmal ein Unterprogramm aufgerufen. Nach der Berechnung von dieser Seite: http://halvar.at/elektronik/kleiner_...swstack_frame/ oder auch nach der englischen mcs Seite wäre der $hwstack bei Dir viel zu klein bemessen.
    Also bei mir reicht der Stack aus, aber ich werde trotzdem den Sprung von der ISR in die Sub ändern. Danke für den Hinweis!
    Grüße
    Thomas

  7. #7
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    28
    Beiträge
    3.517
    Blog-Einträge
    9
    mmmh das mit den Interrupts speichern ist ein guter Einwand.....da weiß ich gerade nicht so recht bescheid drüber ob das so ist.
    Mir wurde während meiner Ausbildung öfters gesagt, dass man nicht soviel Code in die ISR packen soll, damit die ISR nicht zu lang wird.
    Vielleicht kann jemand anders hier Licht ins dunkel bringen ob der Controller sich die Interrups merkt wenn er eine ISR abarbeitet oder nicht
    Würde ich auch gerne wissen.
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  8. #8
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638
    Hallo!


    Ich habe nun folgende Änderungen vorgenommen:
    • If-Abfragen durch Select-Abfragen ersetzen
    • Sprung von der Timer-ISR zur Sub Fading über ein Flag in die Hauptschleife verlegt

    Durch die Änderung der If-Abfragen nach Select-Abfragen konnte ich etwa 1% Flash sparen, was anschließend durch den veränderten Sprung zur Sub Fading wieder belegt wurde. Somit stehe ich wieder bei 90% Speicherbelegung.

    Eine Veränderung des Timer-Prescalers brachte flackern mit sich, so wie ich mir das gedacht habe.
    Grüße
    Thomas

  9. #9
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    28
    Beiträge
    3.517
    Blog-Einträge
    9
    Im Endeffekt rufst du mit GoSub Fading ja nur das Programm auf.
    Lass das GoSub weg und pack das Unterprogramm direkt dahin wo dein GoSub stand. Und in der Timer ISR setzt du nur das Flag, welches du im Mainprogramm auswertest.
    Das sieht dann etwa so aus:
    Code:
    '#########
    '## EDT ##
    '#########
    '---------
    'TinyRGB
    'V1.0
    '04.03.2012
    '---------
    'schaltplan_tinyrgb_v1_0.dsn
    '---------
    'AtTiny13 @ 9,6 Mhz internal RC-Clock
    'Jp1 gesetzt: Modus 0 aktiv
    'Jp2 gesetzt: Modus 1 aktiv
    'Modus 0: Farbwechsel über alle drei Grundfarben (R-G-B)
    'Modus 1: Effekt-Farbwechsel
    '---------
    
    
    $regfile = "attiny13.dat"
    $crystal = 9600000                      '9,6 Mhz
    $hwstack = 8
    $swstack = 4
    $framesize = 10
    
    
    'CONFIG IN/OUT
    Config Portb.0 = Output                                     'Blau
    Config Portb.1 = Output                                     'Grün
    Config Portb.2 = Output                                     'Rot
    Config Pinb.3 = Input                                       'Jp1
    Config Pinb.4 = Input                                       'Jp2
    Portb.3 = 1                                                 'Pullup Jp1 einschalten
    Portb.4 = 1                                                 'Pullup Jp2 einschalten
    
    'ALIAS
    R Alias Portb.2
    G Alias Portb.1
    B Alias Portb.0
    Jp1 Alias Pinb.3
    Jp2 Alias Pinb.4
    
    'CONFIG TIMER
    Config Timer0 = Timer , Prescale = 1
    On Timer0 Isr_timer0
    Enable Timer0
    Start Timer0
    
    'VARIABLEN
    Dim Pwm_count As Byte                                       'PWM-Variable
    Dim C_r As Byte                                             'Channel Rot
    Dim C_g As Byte                                             'Channel Grün
    Dim C_b As Byte                                             'Channel Blau
    Dim Div As Word                                             'Teilervariable
    Dim State As Byte                                           'Status
    Dim Modus As Bit                                            'Modus
    Dim Timerflag As Bit                                        'Flag für die Timer ISR
    
    'INTERRUPTS EIN
    Enable Interrupts
    
    '### HAUPTSCHLEIFE ###
    Do
       'Vergleich Channel kleiner PWM:
       If C_r < Pwm_count Then R = 1 Else R = 0
       If C_g < Pwm_count Then G = 1 Else G = 0
       If C_b < Pwm_count Then B = 1 Else B = 0
    
       'Jumperabfrage:
       If Jp1 = 0 Then Modus = 0
       If Jp2 = 0 Then Modus = 1
    
       If Timerflag = 1 Then
          If Pwm_count = 255 Then Pwm_count = 0                    'PWM-Variable bei 255 resetten
          Incr Pwm_count                                        'PWM-Variable erhöhen
             If Div = 10000 Then                                'Teilervariable bei 10000 resetten
             Div = 0
    
                If Modus = 0 Then
                Select Case State
    
                Case 0 : Incr C_r
                         Decr C_b
                         If C_r = 255 Then State = 1
    
                Case 1 : Decr C_r
                         Incr C_g
                         If C_g = 255 Then State = 2
    
                Case 2 : Decr C_g
                         Incr C_b
                         If C_b = 255 Then State = 0
    
                End Select
                End If
    
                If Modus = 1 Then
                   Select Case State
    
                   Case 0 : If C_r < 255 Then Incr C_r
                            If C_r = 255 Then State = 1
    
                   Case 1 : If C_b < 255 Then Incr C_b
                            If C_b = 255 Then State = 2
    
                   Case 2 : If C_g < 255 Then Incr C_g
                            If C_g = 255 Then State = 3
    
                   Case 3 : If C_r > 1 Then Decr C_r
                            If C_g > 50 Then Decr C_g
                            If C_b > 1 Then Decr C_b
                            If C_r = 1 Then State = 4
    
                   Case 4 : If C_g < 255 Then Incr C_g
                            If C_b < 255 Then Incr C_b
                            If C_b = 255 Then State = 5
    
                   Case 5 : If C_g > 1 Then Decr C_g
                            If C_b > 1 Then Decr C_b
                            If C_g = 1 Then State = 0
    
                   End Select
                End If
             End If
    
          Incr Div                                              'Teilervariable erhöhen
          Timerflag = 0                                         'Flag für die Timer ISR zurücksetzen
       End If
    
    Loop
    
    
    
    
    'ISR TIMER0
    Isr_timer0:
    
       Timerflag = 1
    
    Return
    Das ist jetzt dein alter Code ohne das "Select Case" also nicht wundern
    So sparst du dir auch das Unterprogramm, weil das alles im Hauptprogramm ausgeführt wird (statt Gosub schreibst du da halt den Code hin).

    Edit: Hab einen aktuellen Code eingefügt. So in etwa meinte ich das. Musst du mal gucken ob er für dich in Ordnung ist
    Geändert von Kampi (11.03.2012 um 13:50 Uhr)
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  10. #10
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638
    Hallo Kampi!


    Dadurch würde ich mir ja nur die Befehle Gosub und Return, sowie die Zeit zum Speichern aller wichtigen Register in den SRAM ersparen. Der benötigte Platz für die eigentlichen in "Fading" enthaltenen Befehle würde somit ja nicht kleiner werden, sondern steht nur an anderer Stelle im Flash. So zumindest meine Gedanken dazu.
    Grüße
    Thomas

Seite 1 von 4 123 ... LetzteLetzte

Ähnliche Themen

  1. Samarai: Eine Drohne wie eine Ahornfrucht
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 15.08.2011, 16:20
  2. ATTiny13 PWM
    Von Jacob2 im Forum AVR Hardwarethemen
    Antworten: 1
    Letzter Beitrag: 13.05.2009, 19:08
  3. attiny13
    Von epos im Forum AVR Hardwarethemen
    Antworten: 8
    Letzter Beitrag: 05.10.2007, 22:39
  4. Antworten: 5
    Letzter Beitrag: 02.02.2007, 11:03
  5. Antworten: 7
    Letzter Beitrag: 17.10.2006, 17:10

Berechtigungen

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