SceneSwitch-Lampen

Fragen zu Schaltungen, Elektronik, Elektrik usw.

Moderator: T.Hoffmann

dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Mo, 05.06.17, 17:56

So ein Regentag ist auch zu was gut, ich konnte fast durchgängig coden. Im großen und ganzen funktionieren die Hauptfunktionen, also letzter Wert aus dem Speicher laden, hochdimmen und wieder Resetten, soweit ganz ordentlich. Nur am Code selber kann sicherlich noch einiges verbessert werden oder vereinfachen, bin da für Vorschläge ganz offen. Ich habe mich auch bemüht, soweit als möglich mit Text zu kommentieren. Power-Erkennung an Pin3 habe ich bisher noch per Drahtbrücke gemacht, da steht jetzt dann mal Realelektronik an, aber das geht nicht mehr vom Wohnzimmertisch aus :D

Und ich hatte bisher noch die Hoffnung in Hochsprache zu programmieren, und mich deshalb nicht um Register kümmern zu müssen. :( Aber so ist es wohl nun mal.

Code: Alles auswählen

    $regfile = "atTiny85.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 1000000
    $prog &HFF , &H62 , &HDF , &HFF                         ' generated. Take care that the chip supports all fuse bytes.
                                                             ' EEprom nicht löschen

    Dim R As Integer , S As Integer , T As Integer , Dim_level As Integer , I As Integer
    Dim Ee_dim_level As Eram Integer


    ' Pins:
    '                     RESET 1  v  8  +5V
    '                     PB3   2     7  PB2(SCK)
    ' high Level Input    PB4   3     6  PB1(MISO)  -> Widerstand -> LED2 -> Masse
    '                     GND   4     5  PB0(MOSI)  -> Widerstand -> LED1 -> Masse

    Config Portb.0 = Output                                 'LED1
    Config Portb.1 = Output                                 'LED2
    Config Portb.4 = Input
    Config Timer0 = Pwm , Prescale = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up       'Timer für PWM
    Config Timer1 = Timer , Prescale = 64

On Timer1 On_timer1_overflow                                'Timer für Zeitmessung Input
Enable Timer1

Enable Interrupts


' Initialisierung

T = 0                                                       ' Flag für Abfolgemarkierung Eingangspin
Dim_level = Ee_dim_level                                    ' Wert auslesen aus EEprom
If Dim_level < 0 Or Dim_level > 100 Then Dim_level = 1      'Erstinitialisierung


' Hauptroutine
Do
   If T = 2 Then                                            ' Start wenn Flag auf zweiter Stufe

      If R > 1 And R < 16 Then                              ' kleiner 0,1s, auf Resetwert setzen
        Dim_level = 1
      Elseif R > 32 And R < 256 Then                        ' zwischen 0,5 und 4s => 1 Stufe hochdimmen
         Incr Dim_level
         If Dim_level > 5 Then Dim_level = 1                'bei Max-Stufe wieder reset auf Stufe 0
      Else
         ' do nothing
      End If

      I = Dim_level * 51                                    ' Anpassung an PWM Bereich

          Pwm0a = I                                         ' PWM value an PB0
          Pwm0b = 255 - I                                   ' PWM value an PB1

   Goto Ende

   End If
Loop


Ende:
     If Ee_dim_level <> Dim_level Then Ee_dim_level = Dim_level       ' Neuer Dim-Level Wert in EEprom speichern

End


On_timer1_overflow:                                         ' ca. 61Hz Abtastfrequenz
   If Pinb.4 = 1 Then
      Incr R                                                ' ca. 16ms / Inkrement
      T = 1                                                 ' Flag=1 setzen wenn Eingang auf "1"
   Else
      If T = 1 Then
         T = 2                                              ' Flag=2 setzen wenn Eingang wieder auf "0"
         Stop Timer1                                        ' Re-Trigger verhindern
      End If
   End If
Return
Borax
Star-Admin
Star-Admin
Beiträge: 11980
Registriert: Mo, 10.09.07, 16:28

Mo, 05.06.17, 23:34

Und ich hatte bisher noch die Hoffnung in Hochsprache zu programmieren, und mich deshalb nicht um Register kümmern zu müssen.
Sehr viel musst Du ja auch nicht darüber wissen. Aber bei Hardware-naher Programmierung (die ist im embedded Bereich ja auch gerade das schöne) kommt man natürlich auch nicht völlig drum rum. So was wie 'Treiber' gibt es schließlich nicht.
Der Code sieht doch schon recht gut aus. Aber jetzt ist es mir doch ein wenig zu spät um den noch genauer anzuschauen.
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Sa, 01.07.17, 12:10

So, das Programm läuft nun im großen und ganzen wie gewünscht. Auch die Hardware ist noch etwas optimiert worden, nachdem ich festgestellt hatte, dass bei obiger Dimensionierung beim Abschalten kurze Strompikes mit dem rund 3-fachen Nennstrom durch den Optokoppler entstehen. Den Tip, für die Simulation innerhalb einer Halbwelle abzubrechen habe ich übrigens aus einem anderen Forum.

Vorher:
Bildschirmfoto vom 2017-07-01 1.png
Nachher:
Bildschirmfoto vom 2017-07-01 2.png
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Sa, 01.07.17, 13:20

Und das Board von oben und unten.
2017-07-01 1.jpg
Nur um der Frage zuvorzukommen: 0.1µF, 630V-, die 1000V Variante fand ich doch zu abgehoben
2017-07-01 2.jpg
Den Bereich mit Netzspannung habe ich mal rot umkreist, ich bin mir noch nicht klar, ob da eine Verbesserung bzgl. Spannungsfestigkeit nötig ist. Was meint ihr.
Klar ist das ganze nachher nicht mehr zugänglich verbaut, dennoch möchte ich die Lampenseite ganz ordentlich vom Netz getrennt haben.
Benutzeravatar
Achim H
Star-Admin
Star-Admin
Beiträge: 13067
Registriert: Mi, 14.11.07, 02:14
Wohnort: Herdecke (NRW)
Kontaktdaten:

So, 02.07.17, 20:06

Nur um der Frage zuvorzukommen: 0.1µF, 630V-, die 1000V Variante fand ich doch zu abgehoben

Die 630V ist nur eine Angabe der Spannungsfestigkeit. Der Kondensator wird nicht auf diese Spannung geladen. Eine noch höhere Spannungsfestigkeit wäre auch unnötig gewesen.

Ausgereicht hätte:
Max. mögliche Eingangsspannung: 230V~ +/-15% = max. 253V~ --> aufgerundet auf die nächst höhere Spannungsklasse: mind. 275V~.

Bei Verwendung von einem Gleichspannungskondensator:
253V~ x Wurzel[2] = 357,74...V --> aufgerundet auf die nächst höhere Spannungsklasse: mind. 400V.
Den Bereich mit Netzspannung habe ich mal rot umkreist, ich bin mir noch nicht klar, ob da eine Verbesserung bzgl. Spannungsfestigkeit nötig ist.
Nicht benötigte Lötpunkte solltest Du entfernen, mindestens jedoch 1 Reihe Kontakte um L und N.
Der Minimalabstand bei Leiterbahnen ohne Lötstopplack sollte mindestens 5µm (0,005mm) pro Volt betragen.
Aufgrund schwankender Umgebungseinflüsse (Luftfeuchtigkeit, Schmutz, usw.) können größere Abstände erforderlich sein.
Ich habe mal irgendwo gelesen (bin mir aber nicht sicher), dass 8mm erforderlich sein sollen.

Ich habe früher (als ich noch mit Silberdraht meine Leiterbahnen verlegt hatte) die Spitze des Lötkolben ins Loch gesteckt, kurz angeheizt und dann die Lötpunkte heraus geknebelt (ca. 2sek. Takt).

Alternativ ausbohren (Ø3mm, nur senken bis das Kupfer weg ist).
Hierbei besteht allerdings die Gefahr, dass man den Bohrer nicht schnell genug weg bekommt. Ruckzuck hast Du dann ein Loch in dieser Größe.
Borax
Star-Admin
Star-Admin
Beiträge: 11980
Registriert: Mo, 10.09.07, 16:28

Mo, 03.07.17, 09:49

Ich nehme dafür einfach einen Dremel (o.ä.) mit einer kleinen Trennscheibe. Damit sind die Lötpunkte (oder auch sonstige Leiterbahnen) ruckzuck weg gefräst :) Das Board sieht aber sehr ordentlich aus.
Wie klappt's mit der Programmierung? Alles ok? Oder brauchst Du an irgendeiner Stelle noch Hilfe?
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Mo, 03.07.17, 21:43

Ja, an ein paar kritischen Stellen werde ich ein paar Augen entfernen. Mal sehen welche Methode sich als praktischer erweist.

BTW, auf 357,5V komme ich auch, aber anders gerechnet:) Us=325V + 10% ergibt komischerweise das gleiche Resultat. Da ich aber einen 400V Kondensator schon mal so zerblasen habe, die größere Variante.

Das Programm läuft, sprich es tut gerade was es soll. Aber ich habe keine Ahnung, ob es auch stabil ist, und immer tut was es soll. Siehe auch die Hardwareoptimierung wegen der Spikes.
Borax
Star-Admin
Star-Admin
Beiträge: 11980
Registriert: Mo, 10.09.07, 16:28

Di, 04.07.17, 07:55

ob es auch stabil ist, und immer tut was es soll
Hierzu erst mal nachdenken, was es überhaupt an Zuständen geben kann. Die Platine verhindert ja z.B. schon so was wie 'prellen', also musst Du diesen Punkt gar nicht betrachten.
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Di, 04.07.17, 22:14

OK, prellen war jetzt meine kleinste Sorge. Eher wie oft wird ungewollt ein Schreibzyklus ins Eeprom gemacht. Wäre ja blöd, wenn das bei jedem Mal anschalten passiert, oder noch öfters.
Obiges Programm musste ich nämlich noch "geringfügig" modifizieren, da es beim Einschalten dunkel blieb :oops:
Borax
Star-Admin
Star-Admin
Beiträge: 11980
Registriert: Mo, 10.09.07, 16:28

Mi, 05.07.17, 09:28

Eher wie oft wird ungewollt ein Schreibzyklus ins Eeprom gemacht. Wäre ja blöd, wenn das bei jedem Mal anschalten passiert, oder noch öfters.
Ich habe das bei einem meiner Programme mit einem 'Ringbuffer' gelöst: Ich verwende nicht ein EEPROM Byte sondern 16. Diese werden der Reihe nach verwendet. Das ergibt mehr als eine Million mögliche Schreibzyklen (laut Datenblatt max. 100.000 pro Byte). Bei täglich 100 Schreibzyklen reicht das für mehr als 40 Jahre ;) (ist hier genauer erklärt: https://www.mikrocontroller.net/attachm ... oc2526.pdf )
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Fr, 07.07.17, 15:00

Borax hat geschrieben: Das ergibt mehr als eine Million mögliche Schreibzyklen (laut Datenblatt max. 100.000 pro Byte). Bei täglich 100 Schreibzyklen reicht das für mehr als 40 Jahre ;)
Nun eigentlich brauche ich eigentlich ja gar keine höhere Anzahl an Schreibzyklen, weil bei schon extrem überschätzten 2 Änderungen / Tag sind die 100.000 Zyklen mehr als ausreichend. Auch bei kleinerem Programmierfehler und Speichern bei jedem An-Schalten (was er eigentlich nicht tun sollte) reicht es Dicke.
Ist im Programm aber ein Bockmist, den ich nicht erkannt habe und das Eeprom-speichern wird aus einer Schleife aus aufgerufen, reicht auch die Verzehnfachung des Ringspeichers womöglich nicht. Mal davon abgesehen, da mit Spatzen auf Kanonen zu schießen.

Für MS-Makros konnte man ja schön mitlesen, was der so treibt. Das habe ich dem Bascom-Simulator bisher noch nicht entlocken können, aber bin da offen für Tipps.
Borax
Star-Admin
Star-Admin
Beiträge: 11980
Registriert: Mo, 10.09.07, 16:28

Fr, 07.07.17, 23:40

Das klappt aber eigentlich recht gut mit dem Bascom Simulator. Was genau klappt denn nicht? Für sehr präzise Aussagen (hier IMHO definitiv nicht nötig) muss man das aber mit dem AVR Studio Simulator durch testen (ist dann aber in ASM).
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

So, 09.07.17, 17:44

Nun, das Programm läuft im Einzelstep-Modus bis in die Hauptschleife. Da wird ein Flag überprüft, das sich in einer Timer-Überlaufschleife ändern soll. Aber in diese springt er gar nicht rein, auch nicht mit "Sim Timers" auf "on".
Borax
Star-Admin
Star-Admin
Beiträge: 11980
Registriert: Mo, 10.09.07, 16:28

Mo, 10.07.17, 11:58

Du meinst den Interrupt? Den musst Du quasi 'Händisch' auslösen:
Im Simulator den Tab Interrupts auswählen und (während der Schleife) den Interrupt auslösen (drauf klicken)
BascomInterupts.png
BascomInterupts.png (8.57 KiB) 8375 mal betrachtet
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Mo, 10.07.17, 20:23

Ja, ich meinte den Interrupt. Okay, werde ich probieren wenn ich wieder am Rechner bin.
dieterr
Hyper-User
Hyper-User
Beiträge: 1142
Registriert: Mo, 04.01.16, 18:16

Di, 03.04.18, 18:09

Der Vollständigkeit halber: hier die damit realisierte Lampe.

Und hier der Code:

Code: Alles auswählen

    $regfile = "atTiny85.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 1000000
    $prog &HFF , &H62 , &HDF , &HFF                         ' generated. Take care that the chip supports all fuse bytes.
                                                             ' EEprom nicht löschen

    Dim R As Integer , S As Integer , T As Integer , Dim_level As Integer , I As Integer
    Dim Ee_dim_level As Eram Integer


    ' Pins:
    '                     RESET 1  v  8  +5V
    '                     PB3   2     7  PB2(SCK)
    ' high Level Input    PB4   3     6  PB1(MISO)  -> Widerstand -> LED2 -> Masse
    '                     GND   4     5  PB0(MOSI)  -> Widerstand -> LED1 -> Masse

    Config Portb.0 = Output                                 'LED1
    Config Portb.1 = Output                                 'LED2
    Config Portb.4 = Input
    Config Timer0 = Pwm , Prescale = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up       'Timer für PWM
    Config Timer1 = Timer , Prescale = 64

On Timer1 On_timer1_overflow                                'Timer für Zeitmessung Input
Enable Timer1

Enable Interrupts


' Initialisierung

T = 0                                                       ' Flag für Abfolgemarkierung Eingangspin
Dim_level = Ee_dim_level                                    ' Wert auslesen aus EEprom
If Dim_level < 0 Or Dim_level > 100 Then Dim_level = 1      'Erstinitialisierung
Gosub Dimmer
Gosub Speichern

' Hauptroutine
Do
   If T = 2 Then                                            ' Start wenn Flag auf zweiter Stufe

      If R > 1 And R < 16 Then                              ' kleiner 0,1s, auf Resetwert setzen
        Dim_level = 1
      Elseif R > 32 And R < 256 Then                        ' zwischen 0,5 und 4s => 1 Stufe hochdimmen
         Incr Dim_level
         If Dim_level > 2 Then Dim_level = 1                'bei Max-Stufe wieder reset auf Stufe 0
      Else
         ' do nothing
      End If

      Gosub Dimmer


   Gosub Speichern

   T = 0                                                    'Neu, Test ob Schleife korrekt abbricht

   End If
Loop


Speichern:

     If Ee_dim_level <> Dim_level Then
      Ee_dim_level = Dim_level                              ' Neuer Dim-Level Wert in EEprom speichern
     End If
Return

Dimmer:
      Select Case Dim_level
      Case Is = 1
          Pwm0a = 128                                       ' PWM value an PB0
          Pwm0b = 64                                        ' PWM value an PB1

      Case Is = 2
          Pwm0a = 255                                       ' PWM value an PB0
          Pwm0b = 255                                       ' PWM value an PB1

      Case Is = 3
          Pwm0a = 255                                       ' PWM value an PB0
          Pwm0b = 255                                       ' PWM value an PB1

      End Select

'      I = Dim_level * 85                                    ' Anpassung an PWM Bereich, 255 % Max. Dim_Level


      R = 0                                                 'Neu zum Test

Return



On_timer1_overflow:                                         ' ca. 61Hz Abtastfrequenz
   If Pinb.4 = 1 Then
      Incr R                                                ' ca. 16ms / Inkrement
      T = 1                                                 ' Flag=1 setzen wenn Eingang auf "1"
   Else
      If T = 1 Then
         T = 2                                              ' Flag=2 setzen wenn Eingang wieder auf "0"
'         Stop Timer1                                        ' Re-Trigger verhindern
      End If
   End If
Return
Antworten