• Willkommen im Geoclub - dem größten deutschsprachigen Geocaching-Forum. Registriere dich kostenlos, um alle Inhalte zu sehen und neue Beiträge zu erstellen.

Reaktivlicht mit 7-Segmentanzeige

ksbender

Geocacher
thomas_st schrieb:
PS: Könntest Du mir bitte einen Gefallen tun und rechnest die Bilder etwas etwas herunter, bevor Du sie postest. Vielen Dank!

Erledigt. Ich hatte die Fotos schon verkleinert, wollte aber, daß die weißen Drähte auf weißem Grund noch erkennbar sind.

Gruß
Stephan

PS: auch mit umgesteckem LDR noch kein Erfolg.
 

#ammensleben

Geocacher
ich hab mich heut mal kurz hingesetzt und das ganze nochmal bei 0 anfangen lassen. also ab reaktiv licht nochmal neu angefangen den code zu schreiben. Die Ports sind die gewaehlt, dass man den Tiny und die 7 segment anzeige (ziffernhöhe 10mm http://www.reichelt.de/?;ACTION=3;LA=4;GROUP=A51;GROUPID=3002;ARTICLE=6917;START=0;SORT=preis;OFFSET=16;SID=294dtYb6wQAR0AAANnHgAfc697fa165521a8fcfc5ceee57080704) "gegenseitig" auf eine Lochrasterplatine loeten kann ohne irgendwo noch lange mit drahtbruecken hin und her zu rangieren. kleiner wirds erstmal nicht. die Belegung sollte aus der Port Definition am Anfang hervorgehen.

Config Portb.0 = Output 'A
Config Portb.1 = Output 'B
Config Portb.2 = Output 'C
Config Porta.7 = Output 'DP
Config Porta.4 = Output 'D
Config Porta.3 = Output 'E
Config Porta.1 = Output 'F
Config Porta.0 = Output 'G
Config Porta.6 = Input 'LDR

http://rafb.net/p/qePOjc30.html hier in "Langform" (alle Ports einzeln angesprochen)
http://rafb.net/p/wfJYr763.html hier in "Kurzform"

Die Fuses sehen so bei mir aus.

http://www.pichost.nl/uploads/9fbc4a266d.jpg

viel Spass damit.
 
OP
K

kirby27b

Geocacher
Hi,

na das schaut doch viel besser aus wie mein zurechtgebastelter Code. werd ich auch mal versuchen.

Danke dafür.

Grüße Olaf
 

ksbender

Geocacher
Hallo,
bei mir funktioniert es immer noch nicht.
Ich glaube den Fehler dahin (durch versuchsweise andere Programmierung) eingegrenzt zu haben, daß ich keinen Wert über die Zeile
Ldr = Getadc(2)
bekomme.

Programmiere ich eine Abfrage
IF Ldr = 0 Then Gosub Error
blinkt die ganze Zeit der Error-Code.
Kann mir bitte einmal jemand auf die Sprünge helfen?
So blöd bin ich doch eigentlich nicht :irre:
Gruß
Stephan
 

#ammensleben

Geocacher
schonmal nen anderen adc probiert? ich hatte mit dem 2er auch meine probleme. mit dem 6er ohne probleme

hier nochmal die programme:
kurz:
Code:
$regfile = "ATtiny24.DAT"
$crystal = 128000                                           'Frequenz des internen Oszillators
$hwstack = 32                                               ' default use 32 for the hardware stack
Config Adc = Single , Prescaler = Auto
Stop Ac

Config Porta = &B10011111
Config Portb = &B00000111

Porta = 0
Portb = 0

Wdtcr = &B11010011                                          'Watchdog definieren: 0.125 Sekunden, Interrupt auslösen, kein Reset
Enable Interrupts

Const Schwelle = 50                                         'je größer der Schwellwert, desto unempfindlicher
Const Tagschwelle = 800                                     'Schwellwert für Schlafmodus
Dim A As Byte                                               'Variablen definieren
Dim Tagzaehler As Byte
Dim Ldr As Integer                                          '0 = Dunkel, 1023 = Hell
Dim Alt As Integer
Dim Merker As Integer
Dim K As String * 21
Dim Z As String * 1
Declare Sub Disp(byval T As String)

K = "n52g15p236xe11g24p601"

Do
   Reset Watchdog
   Powerdown                                                'prozessor bremsen da sonst lichtänderung nicht erkannt wird
   Start Adc                                                'A/D-Wandler starten
   Ldr = Getadc(6)                                          'Helligkeitswert einlesen
   Stop Adc                                                 'A/D-Wandler zum Stromsparen wieder stoppen
   Merker = Ldr - Alt                                       'Unterschied zwischen letzter und aktueller Messung ermitteln
   Alt = Ldr                                                'letzten LDR-Wert sichern
   If Merker > Schwelle Then Gosub Koord                    'Bei großer Änderung Dunkel->Hell: Blinken
   If Ldr > Tagschwelle Then                                'prüfen ob helligkeit über tagschwelle liegt
   If Tagzaehler < 255 Then                                 'int-variable geht nur bis 255
   Tagzaehler = Tagzaehler + 1
   End If
   Else
   Tagzaehler = 0                                           'wenn wieder dunkel tagzähler löschen
   End If
   If Tagzaehler > 200 Then Gosub Pause                     'wenn mehr als x zyklen hell dann schlafmodus
Loop

Koord:
   For A = 1 To 20
      Call Disp( "p")
      Reset Watchdog
      Powerdown
      Call Disp( "x")
      Reset Watchdog
      Powerdown
   Next A
   Wdtcr = &B11010110                                       ' 1000 ms einstellen
   For A = 1 To Len(k)
      Z = Mid(k , A , 1)
      Call Disp(z)
      Reset Watchdog
      Powerdown
      Call Disp( "x")
      Reset Watchdog
      Powerdown
   Next A
   Wdtcr = &B11010011                                       'Watchdog definieren: 0.125 Sekunden, Interrupt auslösen, kein Reset
   Alt = 1023                                               'Doppelauslösung verhindern
Return

Pause:
   Wdtcr = &B11110001                                       'Watchdog auf 8 Sekunden stellen
   Reset Watchdog
   Powerdown
   Wdtcr = &B11010011                                       'Watchdog wieder auf 0,125 Sekunden zurückstellen
   Return
End

Sub Disp(byval T As String)
   Porta = 0
   Portb = 0
   Select Case T
      Case "0" :
         Porta = &B00011010
         Portb = &B00000111
      Case "1" :
         Portb = &B00000110
      Case "2" :
         Porta = &B00011001
         Portb = &B00000011
      Case "3" :
         Porta = &B00010001
         Portb = &B00000111
      Case "4" :
         Porta = &B00000011
         Portb = &B00000110
      Case "5" :
         Porta = &B00010011
         Portb = &B00000101
      Case "6" :
         Porta = &B00011011
         Portb = &B00000101
      Case "7" :
         Portb = &B00000111
      Case "8" :
         Porta = &B00011011
         Portb = &B00000111
      Case "9" :
         Porta = &B00010011
         Portb = &B00000111
      Case "g" :
         Porta = &B00000011
         Portb = &B00000011
      Case "p" :
         Porta = &B10000000
      Case "n" :
         Porta = &B00001001
         Portb = &B00000100
      Case "e" :
         Porta = &B00011011
         Portb = &B00000001
   End Select
End Sub

lang:
Code:
$regfile = "ATtiny24.DAT"
$crystal = 128000                                           'Frequenz des internen Oszillators
Config Adc = Single , Prescaler = Auto
Stop Ac

Config Portb.0 = Output                                     'A
Config Portb.1 = Output                                     'B
Config Portb.2 = Output                                     'C
Config Porta.7 = Output                                     'DP
Config Porta.4 = Output                                     'D
Config Porta.3 = Output                                     'E
Config Porta.1 = Output                                     'F
Config Porta.0 = Output                                     'G
Config Porta.6 = Input                                      'LDR

Porta = 0
Portb = 0

Wdtcr = &B11010011                                          'Watchdog definieren: 0.125 Sekunden, Interrupt auslösen, kein Reset
Enable Interrupts

Const Schwelle = 50                                         'je größer der Schwellwert, desto unempfindlicher
Const Tagschwelle = 800                                     'Schwellwert für Schlafmodus
Dim A As Byte                                               'Variablen definieren
Dim Tagzaehler As Byte
Dim Ldr As Integer                                          '0 = Dunkel, 1023 = Hell
Dim Alt As Integer
Dim Merker As Integer
Dim K As String * 21
Dim Z As String * 1
Declare Sub Disp(byval T As String)

K = "n52g15p236xe11g24p601"                                 'Koordinaten

Do
   Reset Watchdog
   Powerdown                                                'prozessor bremsen da sonst lichtänderung nicht erkannt wird
   Start Adc                                                'A/D-Wandler starten
   Ldr = Getadc(6)                                          'Helligkeitswert einlesen
   Stop Adc                                                 'A/D-Wandler zum Stromsparen wieder stoppen
   Merker = Ldr - Alt                                       'Unterschied zwischen letzter und aktueller Messung ermitteln
   Alt = Ldr                                                'letzten LDR-Wert sichern
   If Merker > Schwelle Then Gosub Koord                    'Bei großer Änderung Dunkel->Hell: Koordinaten ausgeben
   If Ldr > Tagschwelle Then                                'prüfen ob helligkeit über tagschwelle liegt
   If Tagzaehler < 255 Then                                 'int-variable geht nur bis 255
   Tagzaehler = Tagzaehler + 1
   End If
   Else
   Tagzaehler = 0                                           'wenn wieder dunkel tagzähler löschen
   End If
   If Tagzaehler > 200 Then Gosub Pause                     'wenn mehr als x zyklen hell dann schlafmodus
Loop

Koord:                                                      'Koordinaten Funktion
   Wdtcr = &B11010110                                       ' 1000 ms einstellen
   For A = 1 To Len(k)                                      'Schleife laufen lassen von 1 bis Länge des angegebenen Strings
   Z = Mid(k , A , 1)                                       'gibt den "A.ten" Buchstaben/Zahl des Strings zurueck
   Call Disp(z)                                             'Funktion aufrufen für gefundenen Buchstaben/Zahl
   Reset Watchdog
   Powerdown
   Call Disp( "x")                                          'Funktion aufrufen für "Leerzeichen" (keine Case gefunden = nix anzeigen)
   Reset Watchdog
   Powerdown
   Next A
   Wdtcr = &B11010011                                       'Watchdog definieren: 0.125 Sekunden, Interrupt auslösen, kein Reset
   Alt = 1023                                               'Doppelauslösung verhindern
Return

Pause:
   Wdtcr = &B11110001                                       'Watchdog auf 8 Sekunden stellen
   Reset Watchdog
   Powerdown
   Wdtcr = &B11010011                                       'Watchdog wieder auf 0,125 Sekunden zurückstellen
   Return
End

Sub Disp(byval T As String)                                 'mögliche Ausgabewerte in dieser Funktion
   Portb.0 = 0                                              'A
   Portb.1 = 0                                              'B
   Portb.2 = 0                                              'C
   Porta.7 = 0                                              'DP
   Porta.4 = 0                                              'D
   Porta.3 = 0                                              'E
   Porta.1 = 0                                              'F
   Porta.0 = 0                                              'G
   Select Case T
      Case "0" :
         Portb.0 = 1                                        'A
         Portb.1 = 1                                        'B
         Portb.2 = 1                                        'C
         Porta.4 = 1                                        'D
         Porta.3 = 1                                        'E
         Porta.1 = 1                                        'F
      Case "1" :
         Portb.1 = 1                                        'B
         Portb.2 = 1                                        'C
      Case "2" :
         Portb.0 = 1                                        'A
         Portb.1 = 1                                        'B
         Porta.4 = 1                                        'D
         Porta.3 = 1                                        'E
         Porta.0 = 1                                        'G
      Case "3" :
         Portb.0 = 1                                        'A
         Portb.1 = 1                                        'B
         Portb.2 = 1                                        'C
         Porta.4 = 1                                        'D
         Porta.0 = 1                                        'G
      Case "4" :
         Portb.1 = 1                                        'B
         Portb.2 = 1                                        'C
         Porta.1 = 1                                        'F
         Porta.0 = 1                                        'G
      Case "5" :
         Portb.0 = 1                                        'A
         Portb.2 = 1                                        'C
         Porta.4 = 1                                        'D
         Porta.1 = 1                                        'F
         Porta.0 = 1                                        'G
      Case "6" :
         Portb.0 = 1                                        'A
         Portb.2 = 1                                        'C
         Porta.4 = 1                                        'D
         Porta.3 = 1                                        'E
         Porta.1 = 1                                        'F
         Porta.0 = 1                                        'G
      Case "7" :
         Portb.0 = 1                                        'A
         Portb.1 = 1                                        'B
         Portb.2 = 1                                        'C
      Case "8" :
         Portb.0 = 1                                        'A
         Portb.1 = 1                                        'B
         Portb.2 = 1                                        'C
         Porta.4 = 1                                        'D
         Porta.3 = 1                                        'E
         Porta.1 = 1                                        'F
         Porta.0 = 1                                        'G
      Case "9" :
         Portb.0 = 1                                        'A
         Portb.1 = 1                                        'B
         Portb.2 = 1                                        'C
         Porta.4 = 1                                        'D
         Porta.1 = 1                                        'F
         Porta.0 = 1                                        'G
      Case "g" :
         Portb.0 = 1                                        'A
         Portb.1 = 1                                        'B
         Porta.1 = 1                                        'F
         Porta.0 = 1                                        'G
      Case "p" :
         Porta.7 = 1                                        'DP
      Case "n" :
         Portb.2 = 1                                        'C
         Porta.3 = 1                                        'E
         Porta.0 = 1                                        'G
      Case "e" :
         Portb.0 = 1                                        'A
         Porta.4 = 1                                        'D
         Porta.3 = 1                                        'E
         Porta.1 = 1                                        'F
         Porta.0 = 1                                        'G
   End Select
End Sub
 

ksbender

Geocacher
#ammensleben schrieb:
schonmal nen anderen adc probiert? ich hatte mit dem 2er auch meine probleme. mit dem 6er ohne probleme

ja, ich habe andere Ports, andere 24er und auch zwei 44er ausprobiert. Negativ. Bald kommt aber wieder eine Bestellung von Reichelt und dann kann ich noch mehr ausprobieren.
 

ksbender

Geocacher
ERFOLGSMELDUNG!!!!

Es funktioniert - auch bei mir.
Was habe ich gemacht: ich habe ja erkannt, daß mir der GETADC immer eine Null als Wert ausgegeben hat. Auf dem Steckbrett konnte ich aber unterschiedliche Spannungen bei unterschiedlichen Helligkeiten reproduzierbar messen. Also habe ich 2 kleine "Waitms 1"-Zeilen vor bzw. hinter Ldr = Getadc(2) eingefügt. Angefangen hatte ich mit 200 ms, konnte aber runter gehen. Ohne die Zeilen läuft es bei mir nicht.
Ausprobiert habe ich das ganze an den verbliebenen drei 24er Tiny´s.
Jetzt erkläre mir das Verhalten mal einer. :irre:
Ich freue mich zunächst einmal :D und habe schon angefangen ein nettes Gehäuse zu bauen.
Dann wird die Ausgabe vielleicht noch etwas modifiziert, aber erst mal bin ich glücklich ;)
 

thomas_st

Geowizard
ksbender schrieb:
[...] Also habe ich 2 kleine "Waitms 1"-Zeilen vor bzw. hinter Ldr = Getadc(2) eingefügt. Angefangen hatte ich mit 200 ms, konnte aber runter gehen. Ohne die Zeilen läuft es bei mir nicht.
Ausprobiert habe ich das ganze an den verbliebenen drei 24er Tiny´s.
Jetzt erkläre mir das Verhalten mal einer. :irre:
Nachher ist man immer schlauer :D Die AD-Wandlung benötigt eine bestimmte Zeit: 13 ADC-Takte bei einer normalen Wandlung und 25 ADC-Takte bei der ersten Wandlung nach dem Einschalten des ADC (ist vermutlich bei Dir der Fall). Je nachdem, wie schnell der ADC läuft (max. ist Systemtakt / 2) und wie schnell Dein µC läuft (ich vermute 128kHz) dauert eine Wandlung 0,4ms. Vielleicht liegt da der Grund (ok. 200ms sind nun Welten größer als 0,4ms - aber Du konntest ja noch weiter runter gehen. Wie weit? ... und stimmen die 128kHz?)

HTH,
Thomas(_st)
 

waste1

Geocacher
Hallo ksbender,

ich hatte ein ähnliches Problem mit dem ATtiny45. Ob es das Gleiche war, weiß ich jetzt nicht mehr so genau, ist schon ne Weile her. Hier der Beitrag. Musst nur die Adressen auf deinen AVR-Typ anpassen.
 

wenzelbub

Geocacher
thomas_st schrieb:
.... Tiny24 = 11 problemlos verwendbare Ports ...

Da ich die 7-Segment-Anzeige etwas größer brauche, um sie auch aus einigen Metern Entfernung eindeutig lesen zu können, würde ich gern jedes Segment durch 3 LEDs ersetzen.

Sehe ich das richtig, dass ich einen Port brauche fürs LDR und 7 für die LED-Segmente, sprich es sind noch 3 Ports frei, mit denen ich weitere 3 Segmente (hier rot, grün, blau) basteln könnte?

Dann wären zusätzlich "N", "R" und "t" für "Nord" und "OSt" möglich
 

Anhänge

  • 10segment.JPG
    10segment.JPG
    23,9 KB · Aufrufe: 960

Windi

Geoguru
wenzelbub schrieb:
Sehe ich das richtig, dass ich einen Port brauche fürs LDR und 7 für die LED-Segmente, sprich es sind noch 3 Ports frei, mit denen ich weitere 3 Segmente (hier rot, grün, blau) basteln könnte?
Ja, das siehst Du richtig.
 

jekejaerfi

Geocacher
Hallo und gutes neues Jahr an alle Leser,

ich hatte mich ja bereits als Programmier- und Elektroniklaie geoutet und einen Versuch gestartet, die "reaktive 7-Segmentanzeige" einstellbar zu programmieren. Gestern habe ich mich endlich mal daran gemacht und einen ersten Versuch gestartet, den eeprom zu "beschreiben".
Dazu habe ich einfach erstmal port A des attiny24 auf Ausgang und port b als eingang gesetzt.
pin0 des Ports B soll als "Programm-Mode-Schalter" dienen
pin1 des Ports B zum Hochtasten der Ziffer und
pin2 des Ports B zur Übernahme der Ziffer in den eeprom an entsprechender Stelle.

Mein Programmcode funktioniert leider nicht. D.h. im bascom-Simulator funktioniert es imho, nur auf dem Steckbrett komme ich nicht in die entsprechende "Programmierschleife".
Hier nun das Programm. Bitte nicht über die sicher sehr laienhafte und umständliche Programmierung lachen. Habe eben keine Erfahrung darin.
'---------------------------------------------------------------------------------------------------------------------
$regfile = "attiny24.dat" ' specify the used micro
$crystal = 128000 ' used crystal frequency
$hwstack = 20 ' default use 32 for the hardware stack
Config Portb = &B00000000 '
Config Porta = &B11111111 '

Dim B As Byte
Dim A As Byte 'Eram Byte
Dim Eingang As Byte

Dim Nmz As Eram Byte
Dim Nme As Eram Byte
Dim Nn1 As Eram Byte
Dim Nn2 As Eram Byte
Dim Nn3 As Eram Byte
Dim Emz As Eram Byte
Dim Eme As Eram Byte
Dim En1 As Eram Byte
Dim En2 As Eram Byte
Dim En3 As Eram Byte

Portb = 0
Porta = 1
Wait 2

$eeprom
Nmz = &B00111111
Nme = &B00000110
Nn1 = &B01011011
Nn2 = &B01001111
Nn3 = &B01100110
Emz = &B01101101
Eme = &B01111100
En1 = &B00000111
En2 = &B01111111
En3 = &B01100111
$data

Do
Porta = &B01000000
Wait 2
Porta = 0
If Portb.0 = 1 Then Gosub Koordinaten
Porta = Nmz
Wait 1
Porta = Nme
Wait 1
Porta = Nn1
Wait 1
Porta = Nn2
Wait 1
Porta = Nn3
Wait 1
Porta = Emz
Wait 1
Porta = Eme
Wait 1
Porta = En1
Wait 1
Porta = En2
Wait 1
Porta = En3
Wait 1

Loop
End

Koordinaten:
A = 0

$eeprom

While Portb.0 = 1 'solange programmieren, bis portB(0) wieder losgelassen wird
Eingang = 0

While Portb.2 = 0 'solange Daten für Koordinate aufnehmen, bis Taste gedrückt wird
If Portb.1 = 1 Then
Eingang = Eingang + 1
While Portb.1 = 1 ' abfangen von mehrfachzählungen
Wend
End If
Select Case Eingang
Case 0 : B = &B00111111
Case 1 : B = &B00000110
Case 2 : B = &B01011011
Case 3 : B = &B01001111
Case 4 : B = &B01100110
Case 5 : B = &B01101101
Case 6 : B = &B01111100
Case 7 : B = &B00000111
Case 8 : B = &B01111111
Case 9 : B = &B01100111
End Select
Porta = B

Wend

If A = 0 Then Gosub P0
If A = 1 Then Gosub P1
If A = 2 Then Gosub P2
If A = 3 Then Gosub P3
If A = 4 Then Gosub P4
If A = 5 Then Gosub P5
If A = 6 Then Gosub P6
If A = 7 Then Gosub P7
If A = 8 Then Gosub P8
If A = 9 Then Gosub P9
A = A + 1 ' nach Schreiben Hochzählen für nächste Stelle


Wend


P0:
$eeprom
Nmz = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P1:
$eeprom
Nme = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P2:
$eeprom
Nn1 = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P3:
$eeprom
Nn2 = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P4:
$eeprom
Nn3 = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P5:
$eeprom
Emz = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P6:
$eeprom
Eme = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P7:
$eeprom
En1 = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P8:
$eeprom
En2 = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return

P9:
$eeprom
En3 = B
$data
While Portb.2 = 1 ' abfangen von mehrfachzählungen
Wend
Return
'------------------------------------------

die waits habe ich eingebaut, um ersteinmal eine einfach Lösung zu bekommen, um auch die Anzeige vernünftig ablesen zu können. die while-wend-schleifen als "Prellschutz".
Geht sicher eleganter, aber das müsstet ihr mir dann auch zeigen!

Wo liegt mein Fehler? Warum springt das Programm, wenn ich Pin 0 des Ports B auf high (5V) setze nicht in die Programmierschleife "Koordinaten"?

ich würde mich über einen (oder mehrere Tipps) sehr freuen. Vielen Dank

Jens
 

jekejaerfi

Geocacher
Hallo nocheinmal,

ich habe nun noch ein kleines bischen gelesen und noch eine andere Variante ausprobiert. Aber auch die funktioniert nicht.
Folgende Schaltung habe ich auf dem Steckbrett aufgebaut.
Testschaltung.jpg
und nun noch folgendes Programm ausprobiert:
'name : eeprom schreiben.bas
'purpose : Versuchsschaltung
'micro : attiny24
'-------------------------------------------------------------------------------
$regfile = "attiny24.dat" ' specify the used micro
$crystal = 128000 ' used crystal frequency
$hwstack = 20 ' default use 32 for the hardware stack

Config Adc = Single , Prescaler = Auto
Config Portb = &B00000000 ' oder lieber ddrb = &B00000000 ?
Config Porta = &B11111111 ' oder lieber ddra = &B00000000 ?
' 7-Segment-Anzeige Zuordnung zu den Pins:
' a -> Pinb.0
' b -> Pinb.1
' c -> Pinb.2
' d -> Pinb.3
' e -> Pinb.4
' f -> Pinb.5
' g -> Pinb.6
' dp-> Pinb.7

Dim B As Byte
Dim A As Byte
Dim Eingang As Byte
Dim Nmz As Eram Byte ' 10er Minute Nord
Dim Nme As Eram Byte ' einer Minute Nord
Dim Nn1 As Eram Byte ' erste Nachkommastelle
Dim Nn2 As Eram Byte ' zweite Nachkommastelle
Dim Nn3 As Eram Byte ' dritte Nachkommastelle
Dim Emz As Eram Byte ' 10er Minute Ost
Dim Eme As Eram Byte ' einer minute Ost
Dim En1 As Eram Byte ' erste Nachkommastelle
Dim En2 As Eram Byte ' zweite Nachkommastelle
Dim En3 As Eram Byte ' dritte Nachkommastelle

Declare Sub Progmodus
Declare Sub Zahl
Declare Sub Speichern

Portb = 1 ' Taster auf Ground schalten, so den Pullup Widerstand nutzbar
Porta = 1 ' erstmal alles leuchten lassen!
Wait 2

$eeprom ' eeprom-Variablen mit Werten füllen
Nmz = &B00111111
Nme = &B00000110
Nn1 = &B01011011
Nn2 = &B01001111
Nn3 = &B01100110
Emz = &B01101101
Eme = &B01111100
En1 = &B00000111
En2 = &B01111111
En3 = &B01100111
$data

' Hier beginnt die Hauptschleife
Do
Porta = 0 ' Licht wieder ausknipsen -> nun soll es in die Subroutine gehen
debounce Portb.0, 0, Progmodus
Porta = Nmz
Wait 1
Porta = Nme
Wait 1
Porta = Nn1
Wait 1
Porta = Nn2
Wait 1
Porta = Nn3
Wait 1
Porta = Emz
Wait 1
Porta = Eme
Wait 1
Porta = En1
Wait 1
Porta = En2
Wait 1
Porta = En3
Wait 1
Loop
End

Sub Progmodus
A = 0
$eeprom ' Aktivieren des Eeproms
Eingang = 0
while portb.0 = 0
debounce portb.2 , 0 , Speichern , Sub
debounce portb.1 , 0 , Zahl , Sub
wend
End Sub

Sub Zahl
If A = 0 Then Gosub P0
If A = 1 Then Gosub P1
If A = 2 Then Gosub P2
If A = 3 Then Gosub P3
If A = 4 Then Gosub P4
If A = 5 Then Gosub P5
If A = 6 Then Gosub P6
If A = 7 Then Gosub P7
If A = 8 Then Gosub P8
If A = 9 Then Gosub P9
A = A + 1 ' nach dem Schreiben hochzählen für die nächste Stelle
End Sub

Sub Speichern
Select Case Eingang ' Wertezuordnung gem. Hochzählung von Eingang
Case 0 : B = &B00111111
Case 1 : B = &B00000110
Case 2 : B = &B01011011
Case 3 : B = &B01001111
Case 4 : B = &B01100110
Case 5 : B = &B01101101
Case 6 : B = &B01111100
Case 7 : B = &B00000111
Case 8 : B = &B01111111
Case 9 : B = &B01100111
End Select
Porta = B
End Sub

P0:

$eeprom
Nmz = B
$data
Return

P1:
$eeprom
Nme = B
$data
Return

P2:
$eeprom
Nn1 = B
$data
Return

P3:
$eeprom
Nn2 = B
$data
Return

P4:
$eeprom
Nn3 = B
$data
Return

P5:
$eeprom
Emz = B
$data
Return

P6:
$eeprom
Eme = B
$data
Return

P7:
$eeprom
En1 = B
$data
Return

P8:
$eeprom
En2 = B
$data
Return

P9:
$eeprom
En3 = B
$data
Return


Ich habe mir nun auch drei Tiny24 gesperrt (durch disablen des Resets) und festgestellt, dass ich die mit meinem Programmer auch nicht mehr reaktiviert bekomme. Ob ich die nun "abschreibe" oder noch zusätzliche Investitionen vornehme, muss ich ersteinmal sehen. Kommt darauf an, ob ich noch lange Lust auf diesen "Kram" habe. ;)

Ich habe noch einige Varianten in Schaltung und Programm ausprobiert, insbesondere um zu erkennen, ob überhaupt in die Unterroutine gesprungen wird, oder nicht. So wie es aussieht wird der Befehl debounce nicht ausgeführt. Aber warum?

Ich hoffe, es kann und will mir jemand helfen. Ich denke, wenn wir diese Lösung hinbekommen, ist dies auch für Leute interessant, die weder programmieren können und wollen, noch die erforderliche Hardware besitzen.

Schöne Grüße

Jens

P.S. Hinweis zum Schaltplan:
ich habe ja die internen pullup genutzt, daher sieht die reale Schaltung natürlich etwas anders aus. D.h. ich "taste mittels kabelbrücken nach Gnd.
 

jekejaerfi

Geocacher
mühsam ernährt sich das Eichhörnchen:
Habe nun gelesen, dass der debounce-Befehl erst nach dem loslassen in die Unterroutine springt. Habe daher noch mal meine 3 Zeilen Code (meinetwegen auch mit K und t und ohne e) durchgesehen und kleine Korrekturen eingebaut. Ob dies nun Verschlimmbesserungen sind, weiss ich nicht. Ich packe das nun lieber ans Ende, da ansonsten alles nur noch unleserlich wird.
Ich befürchte nur, da ich wieder auf die simple Pin-Abfrage zurück gekommen bin, dass dies auch wieder nicht funktioniert. Aber das kann ich dann frühestens heute Abend probieren.
Ausserdem weiss ich nicht, ob die Parameterübergabe in der gewählten Form überhaupt funktioniert!

Aber scheinbar hält sich das weitere Interesse an der Schaltung doch in Grenzen ;)
Schöne Grüße

Jens

'name : eeprom schreiben.bas

'purpose : Versuchsschaltung

'micro : attiny24


'-------------------------------------------------------------------------------


$regfile = "attiny24.dat" ' specify the used micro
$crystal = 128000 ' used crystal frequency
$hwstack = 20 ' default use 32 for the hardware stack

Config Adc = Single , Prescaler = Auto
Config Portb = &B00000000 ' oder lieber ddrb = &B00000000 ?
Config Porta = &B11111111 ' oder lieber ddra = &B00000000 ?

' 7-Segment-Anzeige Zuordnung zu den Pins:
' a -> Pinb.0
' b -> Pinb.1
' c -> Pinb.2
' d -> Pinb.3
' e -> Pinb.4
' f -> Pinb.5
' g -> Pinb.6
' dp-> Pinb.7
'
'

Dim B As Byte
Dim A As Byte
Dim Eingang As Byte

Dim Nmz As Eram Byte ' 10er Minute Nord
Dim Nme As Eram Byte ' einer Minute Nord
Dim Nn1 As Eram Byte ' erste Nachkommastelle
Dim Nn2 As Eram Byte ' zweite Nachkommastelle
Dim Nn3 As Eram Byte ' dritte Nachkommastelle
Dim Emz As Eram Byte ' 10er Minute Ost
Dim Eme As Eram Byte ' einer minute Ost
Dim En1 As Eram Byte ' erste Nachkommastelle
Dim En2 As Eram Byte ' zweite Nachkommastelle
Dim En3 As Eram Byte ' dritte Nachkommastelle

Declare Sub Progmodus
Declare Sub Zahl
Declare Sub Speichern

Portb = 1 ' Taster auf Ground schalten, so den Pullup Widerstand nutzbar
Porta = 1 ' erstmal alles leuchten lassen!
Wait 2

$eeprom ' eeprom-Variablen mit Werten füllen
Nmz = &B00111111
Nme = &B00000110
Nn1 = &B01011011
Nn2 = &B01001111
Nn3 = &B01100110
Emz = &B01101101
Eme = &B01111100
En1 = &B00000111
En2 = &B01111111
En3 = &B01100111
$data

' Hier beginnt die Hauptschleife
Do
Porta = &B01000000 ' nur für mich zur Kontrolle
Wait 1
Porta = 0 ' Licht wieder ausknipsen -> nun soll es in die Subroutine gehen

if Portb.0 = 0 then gosub Progmodus
' hier einfach nur die Eeprom-Speicher ausgeben
Porta = Nmz
Wait 1
Porta = Nme
Wait 1
Porta = Nn1
Wait 1
Porta = Nn2
Wait 1
Porta = Nn3
Wait 1
Porta = Emz
Wait 1
Porta = Eme
Wait 1
Porta = En1
Wait 1
Porta = En2
Wait 1
Porta = En3
Wait 1

Loop
End

Progmodus:
A = 0
B = 0 ' richtig und erforderlich?
Eingang = 0
while portb.0 = 0
debounce portb.2 , 0 , Speichern , Sub
debounce portb.1 , 0 , Zahl , Sub
wend

Return

Sub Zahl

Eingang = Eingang + 1 ' Zahl hochsetzen

Select Case Eingang ' Wertezuordnung gem. Hochzählung von Eingang
Case 0 : B = &B00111111
Case 1 : B = &B00000110
Case 2 : B = &B01011011
Case 3 : B = &B01001111
Case 4 : B = &B01100110
Case 5 : B = &B01101101
Case 6 : B = &B01111100
Case 7 : B = &B00000111
Case 8 : B = &B01111111
Case 9 : B = &B01100111
' Case Else: gosub Ueberlauf ' noch auskommentiert, da nicht sicher ob es funktionieren kann
End Select
Porta = B

End Sub

Sub Speichern

If A = 0 Then Gosub P0
If A = 1 Then Gosub P1
If A = 2 Then Gosub P2
If A = 3 Then Gosub P3
If A = 4 Then Gosub P4
If A = 5 Then Gosub P5
If A = 6 Then Gosub P6
If A = 7 Then Gosub P7
If A = 8 Then Gosub P8
If A = 9 Then Gosub P9
If A > 9 Then Gosub PA
Porta = B
A = A + 1 ' nach dem Schreiben hochzählen für die nächste Stelle



End Sub

P0:

$eeprom
Nmz = B
$data
Return

P1:
$eeprom
Nme = B
$data
Return

P2:
$eeprom
Nn1 = B
$data
Return

P3:
$eeprom
Nn2 = B
$data
Return

P4:
$eeprom
Nn3 = B
$data
Return

P5:
$eeprom
Emz = B
$data
Return

P6:
$eeprom
Eme = B
$data
Return

P7:
$eeprom
En1 = B
$data
Return

P8:
$eeprom
En2 = B
$data
Return

P9:
$eeprom
En3 = B
$data
Return

PA:
A = 0
PortA = &B11111111
wait 1
PortA = 0
wait 1
PortA = &B11111111
Return

Ueberlauf:
Eingang = 0
B = &B00111111
Return
 

jekejaerfi

Geocacher
So Erfolgsmeldung!
Habe es nun (größtenteils) hinbekommen. Habe mich mit der Nase auf einen Fehler aufmerksam machen lassen (ein anderes Forum) und so dann die Schaltung hinbekommen.
Ich muss nur noch eine Kleinigkeit überprüfen, bevor ich Entwarnung gebe. Bei Interesse werde ich mein Programm und die Schaltung zur Verfügung stellen. PM reicht!

Schöne Grüße

Jens
 

wenzelbub

Geocacher
Wie kann es anders sein, beim Conrad gibts keinen ATtiny24 :(
Welche kann ich denn noch verwenden, wollte morgen vorbeifahren und mir ne Alternative besorgen.

ATTINY2313 ?
ATTINY26 ?
ATTINY45 ?

hab nicht wirklich Ahnung und wollte am WE mal ein bisschen ausprobieren.
 

Windi

Geoguru
Der 2313 geht zum Ansteuern einer 7-Segemnt-Anzeige wunderbar.
Allerdings hat er keinen A/D-Wandler, somit kann man ihn nicht für ein ordentliches Reaktivlicht verwenden.

Der 45 hat insgesamt nur 6 Ports. 7-Segement-Anzeige geht damit nicht.

Der 26 würde sowohl für die 7-Segment-Anzeige als auch für ein Reaktivlicht gehen.
 

jekejaerfi

Geocacher
Attiny24/44/84 unterscheiden sich wohl nur in der Größe des Speichers. Daher alle geeigent. Nur kostenmäßig sollte man es sich überlegen.

Wenn du dir mehr als einen Tiny zulegen willst, dann würde ich über Alternativen zu Conrad nachdenken. Conrad ist echt eine Apotheke!

Hier nun mein Programm. Das ist bzgl. der Ausgabe noch sehr gut optimierbar. Ich wollte aber erstmal alles für mich leicht gestaltet haben. Daher ist das Programm eben noch sehr dankbar für Verbesserungen.
Beim "Programmieren" der Koordinaten bekommt man bzgl. der aktuellen Position leider keine Rückmeldung. Daher muss man konzentriert vorgehen. Das z.B. wäre noch zusätzlich eine mögliche Verbesserung (z.B. durch kleine LED auf der Rückseite). Da ich mir den Tiny nicht gem. ISP sperren wollte, ist PinB.3 (noch) nicht im Einsatz. Alle meine Versuche ergaben bei Verwendung irgendwann eben den befürchteten Reset und die Schaltung war "in Ruhestellung". Die Pausen zwischen den Zahlen bei der Ausgabe habe ich eingefügt, da es ja vorkommen wird, dass mal zwei gleiche Ziffern aufeinander folgen und man würde dies sonst nicht erkennen.
Die Schleife für die "Ruhestellung" und Ausgabe habe ich ansonsten einfach nur kopiert.
Am Anfang beschriebe ich erstmal den eeprom mit den Zahlen 1 bis 9. ist sicher auch noch verbesserbar, da irgendwann (nach etlichen 1000 Zyklen) beim Abknipsen und wieder einknipsen der Stromversorgung der Eeprom verbraucht ist. Wohl eher ein theoretisches Problem, aber eben nicht optimal!
o.k. für Verbesserungen bin ich aufgeschlossen ;)

-----------------------------programm anfang ---------------------------------------
'name : Reaktives 7-Segment eeprom schreiben.bas
'purpose :
'micro : attiny24
'-------------------------------------------------------------------------------
$regfile = "attiny24.dat" ' specify the used micro
$crystal = 128000 ' used crystal frequency
$hwstack = 20 ' default use 32 for the hardware stack
Config Adc = Single , Prescaler = Auto
Ddrb = &B00000000
Ddra = &B11111011
Stop Ac 'Analog-Komparator abschalten, Strom zu sparen

Wdtcsr = &B11010011 'Watchdog def: 0.125 Sekunden, Interrupt , kein Reset
Enable Interrupts 'Interrupts freigeben
Const Schwelle = 50 'je größer der Schwellwert, desto unempfindlicher
Const Tagschwelle = 800 'Schwellwert f�r Schlafmodus
Const Zwangsimpuls = 8 'LED-Impuls tagsüber alle X Schlafzyklen (ca. 8 Sek.)

' 7-Segment-Anzeige Zuordnung zu den Pins:
' a -> Pina.0
' b -> Pina.1
' c -> Pina.3
' d -> Pina.4
' e -> Pina.5
' f -> Pina.6
' g -> Pina.7
' dp-> Pinb.3 - noch nicht implementiert

'Variablen definieren
Dim K As Byte
Dim Tagzaehler As Byte
Dim Schlafzaehler As Byte
Dim Ldr As Integer '0 = Dunkel, 1023 = Hell
Dim Alt As Integer
Dim Merker As Integer
Dim Zeichen As String * 1
Dim B As Byte
Dim A As Byte
Dim Eingang As Byte

Dim Nmz As Eram Byte ' 10er Minute Nord
Dim Nme As Eram Byte ' einer Minute Nord
Dim Nn1 As Eram Byte ' erste Nachkommastelle
Dim Nn2 As Eram Byte ' zweite Nachkommastelle
Dim Nn3 As Eram Byte ' dritte Nachkommastelle
Dim Emz As Eram Byte ' 10er Minute Ost
Dim Eme As Eram Byte ' einer minute Ost
Dim En1 As Eram Byte ' erste Nachkommastelle
Dim En2 As Eram Byte ' zweite Nachkommastelle
Dim En3 As Eram Byte ' dritte Nachkommastelle
Dim Nnn As Eram Byte
Dim Enn As Eram Byte

Declare Sub Zahl
Declare Sub Speichern

Portb = &B00000111
$eeprom ' eeprom-Variablen mit Werten füllen
Nmz = &B01111011
Nme = &B00001010
Nn1 = &B10110011
Nn2 = &B10011011
Nn3 = &B11001010
Emz = &B11011001
Eme = &B11111000
En1 = &B00001011
En2 = &B11111011
En3 = &B11001011
Nnn = &B10101000
Enn = &B11110001
$data
' hier wird nun gekreist bis die Welt untergeht ;)

Do
Reset Watchdog
Powerdown 'prozessor bremsen da sonst licht�nderung nicht erkannt wird
Start Adc 'A/D-Wandler starten
Ldr = Getadc(2) 'Helligkeitswert einlesen
Stop Adc 'A/D-Wandler zum Stromsparen wieder stoppen
Merker = Ldr - Alt 'Unterschied zwischen letzter und aktueller Messung ermitteln
Alt = Ldr 'letzten LDR-Wert sichern
If Merker > Schwelle Then Gosub Koordinaten 'Bei Änderung Dunkel->Hell: Blinken
If Ldr > Tagschwelle Then 'prüfen ob Helligkeit über tagschwelle liegt
If Tagzaehler < 255 Then 'int-variable geht nur bis 255
Tagzaehler = Tagzaehler + 1
End If
Else
Tagzaehler = 0 'wenn wieder dunkel tagzähler löschen
End If
If Tagzaehler > 200 Then Gosub Pause 'wenn mehr als x zyklen hell dann schlafmodus
If Pinb.0 = 0 Then Gosub Progmodus ' zum Koordinaten einlesen springen
Loop
End

Pause:
Wdtcsr = &B11110001 'Watchdog auf 8 Sekunden stellen
Reset Watchdog
Powerdown
Wdtcsr = &B11010011 'Watchdog wieder auf 0,125 Sekunden zurückstellen
Schlafzaehler = Schlafzaehler + 1 'merken wie oft Schlafmodus durchlaufen wurde
If Schlafzaehler = Zwangsimpuls Then 'als Funktionskontrolle tagsüber LED auslösen
Porta.1 = 1
Reset Watchdog
Powerdown
Porta.1 = 0
Schlafzaehler = 0
End If
Return

Koordinaten:
' Ausgabe der Koordinaten sich mit einem Array besser machbar!
Alt = 1023 'Doppelauslösung verhindern
Wdtcsr = &B11010111 'Watchdog auf 2s stellen
Porta = Nnn
Reset Watchdog
Powerdown
Porta = 0
Porta = Nmz
Reset Watchdog
Powerdown
Porta = 0
Porta = Nme
Reset Watchdog
Powerdown
Porta = 0
Porta = Nn1
Reset Watchdog
Powerdown
Porta = 0
Porta = Nn2
Reset Watchdog
Powerdown
Porta = 0
Porta = Nn3
Reset Watchdog
Powerdown
Porta = 0
Porta = Enn
Reset Watchdog
Powerdown
Porta = 0
Porta = Emz
Reset Watchdog
Powerdown
Porta = 0
Porta = Eme
Reset Watchdog
Powerdown
Porta = 0
Porta = En1
Reset Watchdog
Powerdown
Porta = 0
Porta = En2
Reset Watchdog
Powerdown
Porta = 0
Porta = En3
Reset Watchdog
Powerdown
Porta = 0
Wdtcsr = &B11010011 'Watchdog wieder auf 125ms stellen
Porta = 0
Return

Progmodus: ' Einlesen der neuen Koordinaten
A = 0
B = 0
Eingang = 0
While Pinb.0 = 0
Select Case Eingang ' Wertezuordnung gem. Hochzählung von Eingang
Case 0 : B = &B01111011
Case 1 : B = &B00001010
Case 2 : B = &B10110011
Case 3 : B = &B10011011
Case 4 : B = &B11001010
Case 5 : B = &B11011001
Case 6 : B = &B11111000
Case 7 : B = &B00001011
Case 8 : B = &B11111011
Case 9 : B = &B11001011
Case Else : Gosub Ueberlauf ' mehr als 10 Zahlen noch nicht gewollt
End Select
Porta = B
Debounce Pinb.2 , 0 , Speichern , Sub ' Taster für Speicherung gedrückt?
Debounce Pinb.1 , 0 , Zahl , Sub ' Taster für höhere Zahl gedrückt?
Wend
Porta = 0
Return

Sub Zahl
Eingang = Eingang + 1 ' Zahl hochsetzen
Porta = B
End Sub

Sub Speichern
If A = 0 Then Gosub Z1
If A = 1 Then Gosub Z2
If A = 2 Then Gosub Z3
If A = 3 Then Gosub Z4
If A = 4 Then Gosub Z5
If A = 5 Then Gosub Z6
If A = 6 Then Gosub Z7
If A = 7 Then Gosub Z8
If A = 8 Then Gosub Z9
If A = 9 Then Gosub Za
If A > 9 Then Gosub Zz
Porta = B
A = A + 1 ' nach dem Schreiben Hochzählen für die nächste Stelle
Eingang = 0
End Sub

Z1: 'Schreiben 10er Minute Nord
$eeprom
Nmz = B
$data
Return

Z2: 'Schreiben einer Minute Nord
$eeprom
Nme = B
$data
Return

Z3: 'Schreiben erste Nachkommastelle
$eeprom
Nn1 = B
$data
Return

Z4: 'Schreiben zweite Nachkommastelle
$eeprom
Nn2 = B
$data
Return

Z5: 'Schreiben dritte Nachkommastelle
$eeprom
Nn3 = B
$data
Return

Z6: 'Schreiben 10er Minute Ost
$eeprom
Emz = B
$data
Return

Z7: 'Schreiben einer minute Ost
$eeprom
Eme = B
$data
Return

Z8: 'Schreiben erste Nachkommastelle
$eeprom
En1 = B
$data
Return

Z9: 'Schreiben zweite Nachkommastelle
$eeprom
En2 = B
$data
Return

Za: 'Schreiben dritte Nachkommastelle
$eeprom
En3 = B
$data
Return

Zz: ' Was zu viel ist ist einfach zu viel!
A = 0
Porta = &B11111011
Wait 1
Porta = 0
Wait 1
Porta = &B11111011
Return

Ueberlauf: 'zurück zum Anfang und gehen sie nicht über Los und ziehen sie nicht....
Eingang = 0
B = &B01111011
Return
--------------------------Ende Programm-------------------------------------------

Wer will kann es ja ausprobieren und verbessern.
Schaltung sollte soweit klar sein. Da ich am Anfang die Zuordnung der Pin der beiden Ports angegeben habe. PinA.2 wie bei der "Originalschaltung" für das Reaktivlicht.

soviel von mir. Ich werde ggf. noch die Schaltung (Pinzuordnung) optimieren. Mein erster kurzer Versuch mit Eagle ergab dann leider, dass einige Verbindungen so nicht auf einer einseitigen Platine machbar sind.

Schöne Grüße

Jens
 

thomas_st

Geowizard
wenzelbub schrieb:
Wie kann es anders sein, beim Conrad gibts keinen ATtiny24 :(
Welche kann ich denn noch verwenden, wollte morgen vorbeifahren und mir ne Alternative besorgen.
Zu Deinen Alternativen hat ja windi schon was gesagt. Allgemein für solche Fragen verweise ich mal auf folgende Tabelle von Atmel - da kann man die verschiedenen µC gut miteinander vergleichen. Den Tiny 26 finde ich da allerdings nicht, sondern nur den Tiny 261. Ist der abgekündigt worden? Früher war er nämlich drin.
Unterschied zwischen Tiny 26 und 261 laut dieser (alten) Tabelle: Tiny 261 hat zusätzlich einen 16 bit Timer, 2 IRQs mehr und einen zusätzlichen externen IRQ. Außerdem ist er als DIL 20 zu erhalten während der Tiny 26 dort nur als QFN 32 angegeben ist. Ach so, der Spannungsbereich ist auch noch etwas größer beim 261: 1,8V bis 5,5V.

HTH,
Thomas(_st)
 
Oben