Fragen zur Software

Basteleien analog und digital mit Strom und Spannung.

Moderator: radioscout

Benutzeravatar
upigors
Geowizard
Beiträge: 2342
Registriert: Mo 24. Sep 2007, 15:52
Wohnort: 39326 Hohenwarsleben
Kontaktdaten:

Re: Fragen zur Software

Beitrag von upigors » Do 18. Nov 2010, 10:12

upigors hat geschrieben: das probier ich gleich mal....
:D klappt :D
Danke :gott:
Bild..Bild

Werbung:
Finckenbande
Geocacher
Beiträge: 48
Registriert: Fr 12. Nov 2010, 20:34

Re: Fragen zur Software

Beitrag von Finckenbande » Do 30. Dez 2010, 19:33

So,

nach dem Hinweis von thomas_st ist meine Frage wohl hier besser aufgehoben.

Ich schrieb in dem Thread "Frage zu Programmiergeräten und Programmierung":
Ich denke mal, der Thread ist der richtige für meine Frage:
ich möchte (eigentlich relativ einfach) 8 Taster an einem yController (genauer: Attiny 2313) erkennen. Prinzipiell soll in Abhängigkeit der Taster etwas auf dem Display (hängt an Port D) ausgegeben werden bzw. eine Aktion passieren (hängt an mehreren seriellen Schieberegistern).
Mein Gedanke dazu war, den Interrupt PCINT an Port B zu benutzen und immer wenn er ausgelöst wird irgendwie die gerade anliegenden Tasten zu lesen und eine Hilfsvariable zu setzen.

Versuch 1:
(einfach nach dem auslösen des Interrupts die Pineingänge lesen) schlug fehl:
On Pcint On_pcint
Enable Pcint
Enable Interrupts
Pcmsk = &B11111111
On_pcint:
if pinb.0 = 1 then
hilfsmerker =1
endif
if pinb.1=1 then
hilfsmerker=2
endif
usw....

Versuch 2:
liefert in der Hauptschleife immer komische Werte, die auch "0" sein können, obwohl nie auf "0" mit nem Interrupt gesetzt wird ...

On Pcint On_pcint
Enable Pcint
Enable Interrupts
Pcmsk = &B11111111 On_pcint:
Debounce Pinb.0 , 0 , 8press , Sub
Debounce Pinb.1 , 0 , 1press , Sub
Debounce Pinb.2 , 0 , 2press , Sub
Debounce Pinb.3 , 0 , 3press , Sub
Debounce Pinb.4 , 0 , 4press , Sub
Debounce Pinb.5 , 0 , 5press , Sub
Debounce Pinb.6 , 0 , 6press , Sub
Debounce Pinb.7 , 0 , 7press , Sub
Return

1press:
Zahl = 1
Return

2press:
Zahl = 2
Return

3press:
Zahl = 3
Return

4press:
Zahl = 4
Return

5press:
Zahl = 5
Return

6press:
Zahl = 6
Return

7press:
Zahl = 7
Return

8press:
Zahl = 8
Return


Wer kann mir helfen ?? Wer hat vielleicht einen sinnvollen Codeschnippsel, um mehrere Tasten nach einem (Soft- d.h. PCINT-)Interrupt abzufragen ??

Ich hoffe, ich bin hier richtig, sonst gebt mir einen Hinweis ...

Gruß
Henrik
worauf thomas_st schon ein paar Anmerkungen hatte.

Die Debounce-Routine von ver.2 habe ich genommen, da die Einfache von ver.1 einfach nicht zuverlässig geklappt hat. Trotzdem sagte auch er, dass ver.1 eigentlich der richtige Weg ist.
Daher nochmal etwas mehr info dazu:

Ich möchte mit 8 Tastern (und KEINER Matrixtastatur) prinzipiell einen mehrstelligen Code eingeben lassen. Der wird also Stelle für Stelle eingegeben. Wenn er eine bestimmte Länge hat, kommt ein Check und gegebenfalls werden verschiedene Aktionen ausgelöst.
Der folgende Code funktioniert leider nicht; die Portb-Pins werden dabei auf Ground gezogen. Der Interrupt löst in dieser Variante nicht aus.

Code: Alles auswählen

$regfile = "ATtiny2313.dat"
$crystal = 1000000

Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , _
   Db7 = Portd.5 , E = Portd.6 , Rs = Portd.0

Config Lcd = 16 * 2

Ddrb = &B00000000                                           ' alle PortB Pins auf Eingang definieren
Portb = &B11111111                                          ' alle PortB Pins auf High setzen / Pullup

On Pcint On_pcint
Enable Pcint
Enable Interrupts
Pcmsk = &B11111111                                          'alle pcint´s anmachen

Dim Initcounter As Byte
Dim Bt As Byte
Dim S As String * 2
Dim Zahl As Byte


Initlcd
Do

      Locate 1 , 1
      Lcd "Zaehlen: "
      Lcd Zahl
      For Bt = 1 To 100
         S = Str(bt)
         S = Format(s , "000")
         Locate 2 , 1
         Lcd S
         Waitms 50
      Next Bt
   Initlcd
Loop

On_pcint:
if pinb.0 = 1 then
Zahl = 1
endif
if pinb.1=1 then
Zahl = 2
End If
If Pinb.2 = 1 Then
Zahl = 3
endif
If Pinb.3 = 1 Then
Zahl = 4
End If
If Pinb.4 = 1 Then
Zahl = 5
endif
If Pinb.5 = 1 Then
Zahl = 6
End If
If Pinb.6 = 1 Then
Zahl = 7
endif
If Pinb.7 = 1 Then
Zahl = 8
End If
Return
Wer kann mir noch sachdienliche Hinweise geben oder hat sowas schonmal gemacht ??

Danke sagt
Henrik

Ranseiher
Geocacher
Beiträge: 20
Registriert: Do 29. Okt 2009, 22:07

Re: Fragen zur Software

Beitrag von Ranseiher » Fr 31. Dez 2010, 00:10

Ich bin auch Anfänger, aber ich hab vorgestern sowas ähnliches programmiert.
Allerdings sind es bei mir 2 Taster und eine 7 Segment Anzeige.
Auch erfolgt kein Längenabgleich. Wird der Code richtig eingegeben, so schaltet ein Eingang. Wenn was falsch ist kann man weiter eingeben und es wird nichts passieren.

Die Profis wollen mir den Code verzeihen, das geht bestimmt viel besser. Aber ich bin Laie und das ganze funktioniert bei mir.
Die Pinbelegung ist deshalb noch so komisch, da ich es für mein Expermentierboard programmiert habe. Da sind bestimmte Pins schon auf den Tastern.
Vielleicht hilft es dir ja.

Code: Alles auswählen

' Codeeingabe mit einer 7-Segment Anzeige


$regfile = "m8def.dat"                    'Atmega 8-Deklarationen

$hwstack = 8
$swstack = 8
$framesize = 24

$crystal = 8000000
$baud = 9600

Dim A As Byte
Dim B As Byte
Dim C As String * 9
Dim D As Integer

Config Portd.2 = Input                                      'Taster 1 - auf
Config Portd.5 = Output                                     ' Ausgang für Relais
Config Portd.4 = Input                                      'Taster 3 Enter
Config Portb.0 = Output                                     ' Strich in der Mitte
Ddrc = &B11111111                                           'Port C komplet auf Output

Pind.2 = 0                                                  'Taster 1 auf Low
Pind.4 = 0                                                  'Taster 3 auf Low


Afg:
A = 0                                                       'Variable A auf 0 setzen
Gosub Sub0                                                  '0 ausgeben

Do


Debounce Pind.2 , 1 , Cnt , Sub                             'Wenn Taster 1 gedrückt gehe zum zählen
Debounce Pind.4 , 1 , Entr , Sub                            'Wenn Taster 3 gedrücht gehe zum übernehmen
If C = "135798642" Then                                     'Abfrage ob String vollständig und richtig ist dann
Gosub Sub9                                                  ' Countdown Ausgabe
Waitms 150                                                  '9
Gosub Sub8                                                  '8 usw.
Waitms 150
Gosub Sub7
Waitms 150
Gosub Sub6
Waitms 150
Gosub Sub5
Waitms 150
Gosub Sub4
Waitms 150
Gosub Sub3
Waitms 150
Gosub Sub2
Waitms 150
Gosub Sub1
Waitms 150
Gosub Sub0
Portd.5 = 1                                                 'Ausgang einschalten
C = "1"                                                     'String zurücksetzen damit der Countdown nicht weiterläuft
End If
Loop

Cnt:                                                        'Zählen
A = A + 1                                                   'hochzählen
If A = 1 Then Gosub Sub1                                    '1 ausgeben
If A = 2 Then Gosub Sub2                                    '2 ausgeben usw.
If A = 3 Then Gosub Sub3
If A = 4 Then Gosub Sub4
If A = 5 Then Gosub Sub5
If A = 6 Then Gosub Sub6
If A = 7 Then Gosub Sub7
If A = 8 Then Gosub Sub8
If A = 9 Then Gosub Sub9
If A = 10 Then Gosub Sub0
If A = 10 Then Goto Afg                                     ' Zähler wieder zurück auf 0
Return





Sub0:
Portc = &B00111111                                          'Zahl 0 darstellen
Portb.0 = 0
Return

Sub1:
Portc = &B00000110                                          'Zahl 1 darstellen
Portb.0 = 0
Return                                                      'usw.

Sub2:
Portc = &B01011011
Portb.0 = 1
Return
Sub3:
Portc = &B01001111
Portb.0 = 1
Return
Sub4:
Portc = &B01100110
Portb.0 = 1
Return
Sub5:
Portc = &B01101101
Portb.0 = 1
Return
Sub6:
Portc = &B01111101
Portb.0 = 1
Return
Sub7:
Portc = &B00000111
Portb.0 = 0
Return
Sub8:
Portc = &B01111111
Portb.0 = 1
Return
Sub9:
Portc = &B01101111
Portb.0 = 1
  Return

Entr:                                                       'Zahl übernehmen
 Select Case A
  Case 1                                                    'Wenn A =1
  D = 1                                                     'setze D = 1
    C = C + Str(d)                                          'übernehme D zum Vorhandenen String C
    For B = 1 To 3                                          'Zahl 3x blinken lassen
    Portc = &B00000110
    Portb.0 = 0
    Waitms 20                                               'analog zu den anderen Werten
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B00000110
    Portb.0 = 0
    Next B


  Case 2
  D = 2
    C = C + Str(d)
 For B = 1 To 3
    Portc = &B01011011
    Portb.0 = 1
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B01011011
    Portb.0 = 1
  Next B

  Case 3
  D = 3
    C = C + Str(d)
   For B = 1 To 3
    Portc = &B01001111
    Portb.0 = 1
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B01001111
    Portb.0 = 1
  Next B


  Case 4
  D = 4
    C = C + Str(d)
 For B = 1 To 3
    Portc = &B01100110
    Portb.0 = 1
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B01100110
    Portb.0 = 1
  Next B

  Case 5
   D = 5
    C = C + Str(d)
 For B = 1 To 3
    Portc = &B01101101
    Portb.0 = 1
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B01101101
    Portb.0 = 1
  Next B

  Case 6
     D = 6
    C = C + Str(d)
   For B = 1 To 3
    Portc = &B01111101
    Portb.0 = 1
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B01111101
    Portb.0 = 1
  Next B


  Case 7
   D = 7
    C = C + Str(d)
   For B = 1 To 3
    Portc = &B00000111
    Portb.0 = 0
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B00000111
    Portb.0 = 0
  Next B


  Case 8
  D = 8
    C = C + Str(d)
  For B = 1 To 3
    Portc = &B01111111
    Portb.0 = 1
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B01111111
    Portb.0 = 1
  Next B


  Case 9
   D = 9
    C = C + Str(d)
For B = 1 To 3
    Portc = &B01101111
    Portb.0 = 1
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B01101111
    Portb.0 = 1
  Next B


  Case 10
  D = 0
    C = C + Str(d)
 For B = 1 To 3
    Portc = &B00111111
    Portb.0 = 0
    Waitms 20
    Portc = &B00000000
    Portb.0 = 0
    Waitms 20
    Portc = &B00111111
    Portb.0 = 0
  Next B


  End Select

Return

Cache on
Ranseiher

Benutzeravatar
upigors
Geowizard
Beiträge: 2342
Registriert: Mo 24. Sep 2007, 15:52
Wohnort: 39326 Hohenwarsleben
Kontaktdaten:

Re: Fragen zur Software

Beitrag von upigors » Mo 31. Jan 2011, 08:04

Kappler hat geschrieben: Also folgendermaßen:

**** hier mal gekürzt wegen der übersichtlichkeit....****

Config Portb = &B00110000 'Pinb.4+5 auf 'Ausgang', Rest auf 'Eingang' schalten
Portb = &B00001110 'Ausgänge 1-3auf Low setzen
Stop Ac 'Analog-Komparator abschalten, um Strom zu sparen

**** hier mal gekürzt wegen der übersichtlichkeit....****

Do
Reset Watchdog
Powerdown

If Pinb.1 = 0 Then
Gosub A
End If

If Pinb.2 = 0 Then
Gosub B
End If
Loop

**** hier mal gekürzt wegen der übersichtlichkeit....****

End[/code]
ich muß das jetzt nochmal aufwärmen.
gibt es eine direkte möglichkeit durch ergänzung eines weiteren eingangs folgendes zu erreichen:
wenn Pinb1 =0 und danach Pinb2=0 dann Gosub A
wenn falsche Reihenfolge oder Pinb3=0 dann Gosub B
oder anders, gibt es einen befehl der beide If's in kombination verstehen lässt?
weiß nicht wie ich das besser erklären soll.... :???: aber vielleicht verstehts ja jemand...

edit: ich weiß das oben die configs nicht stimmen, ist nur zur verdeutlichung....
Bild..Bild

Ranseiher
Geocacher
Beiträge: 20
Registriert: Do 29. Okt 2009, 22:07

Re: Fragen zur Software

Beitrag von Ranseiher » Mo 31. Jan 2011, 12:49

Ok, ich versuch mich mal.
Die Profis sollen mich bitte korrigieren, nur so lernt man was.

As dem Bauch raus würde ich folgendes schreiben.

Code: Alles auswählen

Do

Hilfsvariable = 0

If Pinb.1 = 0 Then
Hilfsvariable = 1
End If

If Pinb.2 = 0 And Hilfsvariable = 1 Then
Gosub A
Elseif
Gosub B
End If

If Pinb.3 = 0 Then
Gosub B
End If

Loop
Ahh. Hab gerade gesehen da ist noch ein Fehler drin. Der Springt gleich nach B wenn b.2 gedrückt wird.

lg
Ranseiher

Benutzeravatar
Kappler
Geowizard
Beiträge: 1437
Registriert: So 31. Dez 2006, 16:51
Wohnort: 77876 Kappelrodeck

Re: Fragen zur Software

Beitrag von Kappler » Mo 31. Jan 2011, 13:51

Eher so:

Code: Alles auswählen

Do

Hilfsvariable = 0

If Pinb.1 = 0 Then
  Hilfsvariable = 1
End If

If Hilfsvariable = 1 Then
   If Pinb.2 = 0 Then
      Gosub A
   Else
      Gosub B
   End If
End If

If Pinb.3 = 0 Then
  Gosub B
End If

(jetzt sollte noch irgendwas hierhin, das die Hilfsvariable
nach einer bestimmten Zeit auf 0 zurück setzt...
In den Unterprogrammen sollte die Hilfsvariable auch auf
0 gesetzt werden)

Loop
Gruß aus dem (badischen) Schwarzwald, Andreas (1/4 Kappler)
Bekennender Fremdlogleser und Rosinenpicker

Benutzeravatar
upigors
Geowizard
Beiträge: 2342
Registriert: Mo 24. Sep 2007, 15:52
Wohnort: 39326 Hohenwarsleben
Kontaktdaten:

Re: Fragen zur Software

Beitrag von upigors » Di 1. Feb 2011, 11:59

Kappler hat geschrieben:Eher so:

Code: Alles auswählen

Do
....................
Loop
Erstmal TFTC (Thanks For The Code) :D

Sooooo, ich hab das nun mal versucht und nach anpassung funktioniert das auch soweit das ich es nutzen kann. Trotzdem hätte ich eine Frage zu einem Phänomen welches mir aufgefallen ist.
Starte ich das ganze zum ersten mal (Spannung anlegen) passiert erstmal nichts - was ja sicher auch so sein soll da der ja auf den ersten Input wartet. Der Ablauf ist dann ok wenn entweder PB1 und PB2 hintereinander (mit wait 1) oder gleichzeitig betätigt werden (Taster) folgt A (grüne LED), kommt irgendwie PB0 ins Spiel folgt B(rote LED). ABER:
Warum warum springt der nach Ablauf von A und der Pause gleich wieder zu B (B blinkt dauerhaft bis A mal aktiviert wird)? Beim Erststart halt nicht, läuft das Programm weiter dann ja.... Sollte der nicht wieder auf die erste Eingabe warten? In meiner Anwendung ist das gut so aber interessiert mich halt trotzdem :???:

Aber was noch wichtiger ist, gibt es eine einfache Variante zu verhindern das wenn alle 3 PB's gleichzeitig 0 sind auch A gestartet wird?

Danke für nen denkanstoß.....

Code: Alles auswählen

$hwstack = 20                                               'hardwarestack herabsetzen damit genügend variablen zur verfügung stehen
$regfile = "ATtiny13.DAT"
$crystal = 128000                                           'Frequenz des internen Oszillators

Config Portb = &B00011000                                   'Pinb.4+3 auf 'Ausgang', Rest auf 'Eingang' schalten
Portb = &B00000111                                          'Ausgänge auf Low setzen
Stop Ac                                                     'Analog-Komparator abschalten, um Strom zu sparen

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

Dim H As Bit

Do
Wdtcr = &B11010101

Reset Watchdog
Powerdown

If Pinb.0 = 0 Then
Gosub B
End If

H = 0

If Pinb.1 = 0 Then
 H = 1
End If

If H = 1 Then

Wait 1

If Pinb.2 = 0 Then

Gosub A

Else

Gosub B

End If

End If

Loop

A:
   Wdtcr = &B11010101

   Portb = &B00010110                                       'grün
   Reset Watchdog
   Powerdown
   Portb = &B00000110
   Reset Watchdog
   Powerdown
   Wdtcr = &B11110001                                       'lange pause
   Reset Watchdog
   Powerdown

Return

B:
   Wdtcr = &B11010011

   Portb = &B00001110                                       'rot
   Reset Watchdog
   Powerdown
   Portb = &B00000110
   Reset Watchdog
   Powerdown

Return

End
Achso: H=Hilfsvariable
Bild..Bild

Ranseiher
Geocacher
Beiträge: 20
Registriert: Do 29. Okt 2009, 22:07

Re: Fragen zur Software

Beitrag von Ranseiher » Di 1. Feb 2011, 14:09

upigors hat geschrieben:
Kappler hat geschrieben:Eher so:

Starte ich das ganze zum ersten mal (Spannung anlegen) passiert erstmal nichts - was ja sicher auch so sein soll da der ja auf den ersten Input wartet. Der Ablauf ist dann ok wenn entweder PB1 und PB2 hintereinander (mit wait 1) oder gleichzeitig betätigt werden (Taster) folgt A (grüne LED), kommt irgendwie PB0 ins Spiel folgt B(rote LED). ABER:
Warum warum springt der nach Ablauf von A und der Pause gleich wieder zu B (B blinkt dauerhaft bis A mal aktiviert wird)? Beim Erststart halt nicht, läuft das Programm weiter dann ja.... Sollte der nicht wieder auf die erste Eingabe warten? In meiner Anwendung ist das gut so aber interessiert mich halt trotzdem :???:
Ich weiß es nicht, aber könnte das was mit dem prellen des Tasters zu tun hat.
Versuch mal mit debounce den Taster zu entprellen.

Zum Auslösen wenn alle 3 = 0 sind.
Wenn man Pb.0 als Int0 einliest, sollte es gehen.

lg
Tom

Benutzeravatar
upigors
Geowizard
Beiträge: 2342
Registriert: Mo 24. Sep 2007, 15:52
Wohnort: 39326 Hohenwarsleben
Kontaktdaten:

Re: Fragen zur Software

Beitrag von upigors » Di 1. Feb 2011, 14:27

Danke für deine Antwort,

na da sind noch keine taster dran, zzt nur drähte.
ich schau mal ob ich zu dem debounce was finde, kann mit dem Befehl garnichts anfangen. :???:
------------------------------------------
also "If Pinb.0 = Int0" ?????
-------------------------------------------

lg Uwe
Bild..Bild

Ranseiher
Geocacher
Beiträge: 20
Registriert: Do 29. Okt 2009, 22:07

Re: Fragen zur Software

Beitrag von Ranseiher » Di 1. Feb 2011, 14:47

Nein du nimmst am Besten den entsprechenden Eingang.
Beim 2313 ist das PD.2(INT0) oder PD.3 (INT1)

Und dann in etwa so

Code: Alles auswählen

Config Int0 = Falling                         'steigende (Rising) oder fallende Flanke (beim drücken oder beim loslassen)
Enable Interrupts                                        'einschalten Der Interrupts
Enable Int0                                                 'einschalten Von Interrupt Int0
On Int0 B                                                     ' Wenn Int0 dann gehe zu B
Der Vorteil vom Interrupt ist der, dass beim auslösen, ganz egal wo er gerade im Programmcode ist, sofort das ausführt was du angibst. z.B. zu B springen.
Das ganze ohne Garantie. Bin auch nur Laie und hab vor ein paar Monaten angefangen.

Lg Tom

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder