Probleme mit vier Tastern

technicus123

Neues Mitglied
13. Feb. 2009
118
0
0
Sprachen
Hi,

hab ein kleines Problem und ich hoffe ihr könnt mir helfen. Ich habe vier Taster an einem Atmega32 an dem PortA von 0-3. Alle funktionieren bis auf taster zwei, der am Eingang A.1 sitzt. Verdrahtung ist ok. Vielleicht findet jemand einen Fehler in meinem Code.

Gruß
Jens


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

Config Portb = Output

Config Pina.0 = Input
Config Pina.1 = Input
Config Pina.2 = Input
Config Pina.3 = Input

Config Lcdbus = 4
Config Lcd = 16 * 2
Config 1wire = Portd.5

Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0

Config Debounce = 100

Dim Ds1820 As Integer
Dim Halb As Byte

Cursor Off
Cls
Locate 1 , 1
Lcd "Temp:"

Do

Debounce Pina.0 , 0 , Schalter1 , Sub
Debounce Pina.1 , 0 , Schalter2 , Sub
Debounce Pina.2 , 0 , Schalter3 , Sub
Debounce Pina.3 , 0 , Schalter4 , Sub


1wreset
1wwrite &HCC
1wwrite &H44
Waitms 300
1wreset
1wwrite &HCC
1wwrite &HBE
Ds1820 = 1wread(9)
1wreset
Halb = Ds1820 And 1
Locate 1 , 7
Shift Ds1820 , Right
If Ds1820 > 127 Then
Lcd "-"
Ds1820 = 256 - Ds1820
If Halb = 1 Then Ds1820 = Ds1820 - 1
Else
Lcd " "
End If
Lcd Ds1820 ; ".";
If Halb = 1 Then
Lcd "5"
Else
Lcd "0"
End If
Lcd "C "
Wait 1

Loop

Schalter1:
Toggle Porta.0
Locate 2 , 1
Lcd "Taster1"
Waitms 500
Return

Schalter2:
Toggle Porta.1
Locate 2 , 1
Lcd "Taster2"
Waitms 500
Return

Schalter3:
Toggle Porta.2
Locate 2 , 1
Lcd "Taster3"
Waitms 500
Return

Schalter4:
Toggle Porta.3
Locate 2 , 1
Lcd "Taster4"
Waitms 500
Return

End
 
Hallo Jens,

ich programmiere zwar nicht mit Bascom, aber vielleicht kann ich dir trotzdem helfen.

Ausschnitt aus deinem Code:


CodeBox bascom


Schalter1:
Toggle Porta.0
Locate 2 , 1
Lcd "Taster1"
Waitms 500
Return



Mit Zeile 2 toggelst du PA0. Das heißt, du aktivierst einmal den internen Pullup, dann schaltest du ihn wieder aus. Wenn er ausgeschaltet ist und du keinen externen PullUp-Widerstand nutzt, ist der Zustand bei geöffnetem Taster nicht sicher high. Bei den Subroutinen Schalter2..4 ist das ebenfalls so, dass du das Portregister toggelst. Schaltest du die Taster von Portpin gegen GND, sollte das Bit im Portregister immer 1 sein (PullUp aktiviert).

Noch einen Hinweis:
Bitte nutze den Button Code einfügen oben in der Editorleiste, wenn du Code im Forum posten möchtest, dies wird dann übersichtlicher.
Alternativ kannst du auch
[noparse]


CodeBox bascom

hier dein code

[/noparse]
eingeben, dann sieht die Ausgabe aus wie oben, Vorteil ist hier, man hat Zeilennummern, auf die man sich beziehen kann.

Grüße,
Dirk
 
Hallo Jens,

ich programmiere zwar nicht mit Bascom, aber vielleicht kann ich dir trotzdem helfen.

Ausschnitt aus deinem Code:


CodeBox bascom


Schalter1:
Toggle Porta.0
Locate 2 , 1
Lcd "Taster1"
Waitms 500
Return



Mit Zeile 2 toggelst du PA0. Das heißt, du aktivierst einmal den internen Pullup, dann schaltest du ihn wieder aus. Wenn er ausgeschaltet ist und du keinen externen PullUp-Widerstand nutzt, ist der Zustand bei geöffnetem Taster nicht sicher high. Bei den Subroutinen Schalter2..4 ist das ebenfalls so, dass du das Portregister toggelst. Schaltest du die Taster von Portpin gegen GND, sollte das Bit im Portregister immer 1 sein (PullUp aktiviert).

Noch einen Hinweis:
Bitte nutze den Button Code einfügen oben in der Editorleiste, wenn du Code im Forum posten möchtest, dies wird dann übersichtlicher.
Alternativ kannst du auch
[noparse]


CodeBox bascom

hier dein code

[/noparse]
eingeben, dann sieht die Ausgabe aus wie oben, Vorteil ist hier, man hat Zeilennummern, auf die man sich beziehen kann.

Grüße,
Dirk

Hi Dirk,

habe schon externe PullUps davorgeschaltet. Hätte ich besser dabeischreiben sollen. Ansonsten klappt alles bis auf den zweiten Taster.

Gruß
Jens
 
Hallo Technicus!

Zu deinem eingestellten Code hätte ich noch diverse Fragen, aber es geht ja hier nur um den Taster. ;)


Allerdings muss ich mich Knickohr anschließen...........
WOZU soll das Toggeln denn überhaupt gut sein? :confused:

Gehen wir mal davon aus, dass dein Code einen Sinn ergibt, dann müssten alle Taster auch arbeiten...... einschließlich der an PINA.1 !

Im Code scheint also der Fehler nicht zu sein.
Auch hat der PINA.1 nur den ADC1 als alternative Anschlussmöglichkeit..... Sollte daher auch keine Fehler produzieren.
Bist du sicher, dass die Hardware in Ordnung ist?

Wichtig wäre aber erst einmal, WARUM du den zugehörigen Port togglen möchtest!




Nun möchte nur dir noch mal eine andere Variante vorstellen, mit der du die Temperatur des DS1820 genauer berechnen kannst.
Vielleicht probierst du es mal aus. Damit kann der DS1820 dann nicht nur 0,5Grad Schritte anzeigen..... und das Minus an kalten Tagen wird automatisch berücksichtigt! ;)
Code:
1wreset
1wwrite &HCC
1wwrite &H44
Waitms 100

1wreset
1wwrite &HCC
1wwrite &HBE

For I = 1 To 9
Scratch(i) = 1wread()
Next

Temp = Scratch(2)
Shift Temp , Left , 8

Temp = Temp + Scratch(1)
Temp1 = Temp
Temp1 = Temp1 / 2
Ist_temp = Scratch(8) - Scratch(7)
Ist_temp = Ist_temp / Scratch(8)
Ist_temp = Ist_temp + Temp1
Ist_temp = Ist_temp - 0.25


Am besten packst du es in eine Subroutine und rufst dann nur die Sub zwischendurch mal auf. ;)



Folgende Variablen benötigst du dafür im Rumpf deines Programmes:
Code:
Dim Ist_temp As Single       ' Die reale Ist-Temperatur                      
Dim Temp As Word                                         
Dim Temp1 As Integer                                        
Dim Scratch(9) As Byte                                      
Dim I As Byte


Viel Spaß beim ausprobieren!

Gruß,
Cassio
 
Hi @All,

hmmm, melde mich auch noch zu Wort.

Bzgl. Toggeln giobt es von mir nix neues. Cassio und Thomas haben alles gesagt was gesagt werden muss, das Ding MUSS raus!

Bzgl. Konfiguration sieht alles OK aus und mit fällt auch kein weiterer Fehler im Code auf.

Schließe mich Cassio an, dass der Fehler zunächst in der HW zu suchen ist. Zunächst würde ich hier sicherstellen, dass die externen PullUps sauber verlötet sind und auch ihren Dienst erfüllen. Weiter würde ich dann sicherstellen, dass die internen PullUps abgeschaltet sind da sie nicht benötigt werden.

Meiner Meinung nach, wenn der Taster funzt, sollte es auch funktionieren.

Grüße,
Markus
 
Hi,

erstmal Danke für die schnellen Antworten. Habe alles so gemacht, wie ihr es gesagt hat. Trotzdem war das nicht der Fehler. Sobald ich den Code für den Temperatursensor entferne, funktionieren alle Taster:eek: . Ich kann mir nicht erklären warum, wieso, weshalb:confused: . Hat jemand eine Idee. Es liegt definitiv am Sensorcode.

Gruß Jens
 
?????

Hi Jens,

ich kann es mir wirklich auch nicht erklären. Keine Ahnung! Der Code sieht plausibel aus!
Poste Doch bitte nochmals den aktuellen und in der Zwischenzeit von Dir geänderten kompletten Code in diesem Thread. Ich schau nochmal drüber ob mir vielleicht nicht doch etwas auffällt.

Du verwendest einen Mega32, richtig? Die im Code enthaltenen Compilerdirektiven passen zu Deiner HW. Sollten sie, sonst würde es ohne 1Wire-Code auch nicht funktionieren. Hmmm, zunächst macht sich Ratlosigkeit bei mir breit!

Grüße,
Markus
 
Hi Markus,

ja, ich verwende den Atmega32. Hier habe ich den neuen Code. Da funktioniert auch nur alle Taster, wenn ich den Sensorcode entferne.

Gruß
Jens

Code:
$regfile = "m32def.dat"
$crystal = 1000000

Config Portb = Output
Config Porta = Input


Config Lcdbus = 4
Config Lcd = 16 * 2
Config 1wire = Portd.5

Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0

Config Debounce = 100

Dim Ds1820 As Integer
Dim Halb As Byte

Cursor Off
Cls
Locate 1 , 1
Lcd "Temp:"
Declare Sub Temp

Do
Call Temp
Debounce Pina.0 , 0 , Schalter1 , Sub
Debounce Pina.1 , 0 , Schalter2 , Sub
Debounce Pina.2 , 0 , Schalter3 , Sub
Debounce Pina.3 , 0 , Schalter4 , Sub
Loop

Temp:
 1wreset
  1wwrite &HCC
  1wwrite &H44
  Waitms 300
  1wreset
  1wwrite &HCC
  1wwrite &HBE
  Ds1820 = 1wread(9)
  1wreset
  Halb = Ds1820 And 1
  Locate 1 , 7
  Shift Ds1820 , Right
  If Ds1820 > 127 Then
    Lcd "-"
    Ds1820 = 256 - Ds1820
    If Halb = 1 Then Ds1820 = Ds1820 - 1
  Else
    Lcd " "
  End If
  Lcd Ds1820 ; ".";
  If Halb = 1 Then
    Lcd "5"
  Else
    Lcd "0"
  End If
  Lcd "C "
  Wait 1
Return

Schalter1:
Locate 2 , 1
Lcd "Taster1"
Waitms 500
Return

Schalter2:
Locate 2 , 1
Lcd "Taster2"
Waitms 500
Return

Schalter3:
Locate 2 , 1
Lcd "Taster3"
Waitms 500
Return

Schalter4:
Locate 2 , 1
Lcd "Taster4"
Waitms 500
Return

End
 
Könnte das Problem vielleicht an diesen Befehlen liegen?
Hab den mir nur rauskopiert:D .

Code:
1wwrite &HCC 
1wwrite &H44 
Waitms 300 
1wreset 
1wwrite &HCC 
1wwrite &HBE
 
Hallo Jens,

mein Tip bei solchen Problemen: zunächst mal Stack erhöhen. Das wirkt manchmal Wunder :)
Das "call Temp" würde ich durch "gosub Temp" ersetzen, da du Temp nicht als Unterprogramm deklariert hast.
 
Hallo zusammen,

nur mal so eine Idee (als nicht Bascom-Experte ;)) ...

Kann es einen negativen Effekt auf Debounce haben, wenn man in Bascom viele Pausen verwendet?

In jeder Tasten-Subroutine wird 500ms pausiert und in der Subroutine für den Temperatursensor/LCD-Ausgabe sind es mindestend 300ms.

Grüße,
Dirk
 
Hallo Technicus!

Also, dass ist doch alles etwas seltsam.....

Wie StevieL schon geschrieben hat, solltest du die Subroutine einfach mit einem
Gosub Temp
aufrufen.
Das Declare und das spätere Call kannst du dann entfernen.

Wenn du einmal dabei bist, versuch dein Programm doch mal etwas zu struckturieren. ;)

Das du die Temperatur in eine Sub gestellt hast und nur bei Bedarf die Sub aufrufst, ist ja schon mal ein Anfang.
Mit deinen Schaltern passiert ja eigentlich nichts anderes. Also hast du die auch schon separiert.
Nun würde ich noch die Anzeigen auf dem Display zusammenfassen.
Dafür musst du die Anzeige-Befehle aus der Sub "Temp" entfernen mit in die Sub für die Anzeige stellen.

Natürlich wird sich das Programm dadurch nicht wirklich ändern, aber es wird lesbarer und Änderungen sowie Fehler schneller sichtbar.

Kommen wir wieder auf dein Tasterproblem zurück.
Sorry, auch wenn dein Programmcode ziemlich "durcheinander" wirkt, so sind dort eigentlich keine Fehler erkennbar.... also muss der Taster an PINA.1 auch funktionieren. Zumal das Programm auch nur durch den Debounce in eine eigene Sub geschickt wird.

Es fuchst mich ja langsam und wenn ich heute Abend noch gute Laune habe, dann baue ich die Schaltung mal nach und probiere deinen Code aus.
Einen DS1820 habe ich sowieso immer hier und die Taster sind auch kein Thema....


Unabhängig davon bin ich aber jetzt schon auf die Lösung gespannt, wenn du dann den Fehler entdeckt hast. ;)

Gruß,
Cassio
 
Hi,

wenn ihr "Dim Halb As Single" anstelle von "Dim Halb as Byte" eingebt, funktioniert es:vollkommenauf: :vollkommenauf: . Leider wird dann nicht das angezeigt, was hinter der Kommastelle ist. Wie hängt das ganze zusammen?

Das ganze funktioniert noch besser mit der Kommastelle wenn man "Dim Halb as Long" eingibt.

Gruß
Jens
 
Hallo Jens,

folgende Dinge sind mir aufgefallen:

[1]
Du definierst die Routine zum Auslesen des Temperartursensors als Gosub-Routine, verwendest Sie aber als SUB. Soll heißen:

- Eine Gosub-Routine wird mit "Label:" und "Return" am Ende definiert und MUSS mit "GOSUB Label" angesprungen werden
- Du definierst eine Gosub-Routine und springst diese aber mit CALL wie eine SUB-Routine an.
- Subroutinen werden aber so defineirt:
Code:
Sub Test(bytevar1 As Byte , Byval bytevar2 As Byte, ...)
   ' Mache was
End Sub
- "Declare SUB Temp" ist so auf jeden Fall falsch.

Ich vermute, hier beißen sich zwei grundlegende Vorgehensweisen. Bitte verwende zum Aufruf von Temp "GOSUB Temp".
Ich weiß zwar nicht ob dieser Effekt eine Wechselwirkung verursacht was zum "Nichtfunktionieren" Deines Tasters führt aber es wäre mal ein Ansatz!


[2]
Warum wartest Du in der Temp-Routine eine Sekunde? Mann sollte prinzipiell nie in einer Unterroutine warten sondern immer in Hauptschleifen!

[3]
Prinzipiell finde ich die Lösung ungut, in Hauptschleifen wo auch Abfragen gemacht werden fest 1 Sekunde zu warten. Was kann ich also tun um nicht zyklisch den Temperatursensor zu quälen. Du könntest dazu folgendes machen:
- einen Timer aufziehen der Dir zyklisch einen Sekundentakt erzeugt (mittels Interruptroutine).
- In der Interrupt-Routine setzt Du ein Flag das Du in der Hauptschleife auswertest, was Dir sagt, dass wieder mal Temperatur eingelesen werden kann.
- Die Temperatur ändert sich in der Regel ja auch nicht so rapide dass Du mittels Timer die Abfrage durchaus erhöhen kannst.
- Vorteil: Du hast mehr Zeit in der Hauptschleife ide tastenauswertungen zu machen.


Ich habe mal nach den obigen Dingen Deinen Code etwas verändert. Probiers mal aus. Ich bin mir nicht sicher ob es dann funktioniert aber der Code ist auf jeden Fall richtiger. Bitte teile mir Dein Ergebnis mit.

Code:
$regfile = "m32def.dat"
$crystal = 1000000

Config Portb = Output
Config Porta = Input
Porta = &B00000000                                          ' PullUp abschalten


Config Lcdbus = 4
Config Lcd = 16 * 2
Config 1wire = Portd.5

Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0

Config Debounce = 100

Dim Ds1820 As Integer
Dim Halb As Byte

Cursor Off
Cls
Locate 1 , 1
Lcd "Temp:"
' Declare Sub Temp

Do
   Gosub Temp
   Debounce Pina.0 , 0 , Schalter1 , Sub
   Debounce Pina.1 , 0 , Schalter2 , Sub
   Debounce Pina.2 , 0 , Schalter3 , Sub
   Debounce Pina.3 , 0 , Schalter4 , Sub
Loop

Temp:
   1wreset
   1wwrite &HCC
   1wwrite &H44
   Waitms 300
   1wreset
   1wwrite &HCC
   1wwrite &HBE
   Ds1820 = 1wread(9)
   1wreset
   Halb = Ds1820 And 1
   Locate 1 , 7
   Shift Ds1820 , Right
   If Ds1820 > 127 Then
      Lcd "-"
      Ds1820 = 256 - Ds1820
      If Halb = 1 Then
         Ds1820 = Ds1820 - 1
      End If
   Else
      Lcd " "
   End If
   Lcd Ds1820 ; ".";
   If Halb = 1 Then
      Lcd "5"
   Else
      Lcd "0"
   End If
   Lcd "C "
   Wait 1
Return


Schalter1:
   Locate 2 , 1
   Lcd "Taster1"
   Waitms 500
Return

Schalter2:
   Locate 2 , 1
   Lcd "Taster2"
   Waitms 500
Return

Schalter3:
   Locate 2 , 1
   Lcd "Taster3"
   Waitms 500
Return

Schalter4:
   Locate 2 , 1
   Lcd "Taster4"
   Waitms 500
Return

End
Grüße,
Markus
 
Guten Morgen.

Wie Markus schon angemerkt hat, programmierst Du etwas "umständlich" ;) Einfach nur so warten ist nicht so dolle, da ja der Prozessor in dieser Zeit nichts anderes macht. Er reagiert auch in dieser Zeit nicht auf irgendwelche Tasten. Noch schlimmer, wenn Du mal ein GLCD am damit am Rennen hast und dann in einer zeitkritischen Ausgabe beim Schreiben auf das Display einen wait rein bringst, dann gibt es auf dem Display nur Müll !

Ähmm, Markus, Dein Code hat übrigens noch das gleiche Problem mit dem Wait.

Probier mal das aus :

Code:
$regfile = "m32def.dat"
$crystal = 1000000

Config Portb = Output
Config Porta = Input


Config Lcdbus = 4
Config Lcd = 16 * 2
Config 1wire = Portd.5

Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0

Config Debounce = 100

[COLOR="Red"]Config Clock = Soft , Gosub = Sectic[/COLOR]

Dim Ds1820 As Integer
Dim Halb As Byte
[COLOR="Red"]Dim Sekundentic as Bit
[/COLOR]
Cursor Off
Cls
Locate 1 , 1
Lcd "Temp:"

Do
	[COLOR="Red"]If Sekundentic = 1 then
		Gosub Temperatur
		Sekundentic = 0
	end if[/COLOR]

	Debounce Pina.0 , 0 , Schalter1 , Sub
	Debounce Pina.1 , 0 , Schalter2 , Sub
	Debounce Pina.2 , 0 , Schalter3 , Sub
	Debounce Pina.3 , 0 , Schalter4 , Sub
Loop

Temperatur:
  1wreset
  1wwrite &HCC
  1wwrite &H44
  Waitms 300
  1wreset
  1wwrite &HCC
  1wwrite &HBE
  Ds1820 = 1wread(9)
  1wreset
  Halb = Ds1820 And 1
  Locate 1 , 7
  Shift Ds1820 , Right
  If Ds1820 > 127 Then
    Lcd "-"

    Ds1820 = 256 - Ds1820
    If Halb = 1 Then Ds1820 = Ds1820 - 1
  Else
    Lcd " "
  End If
  Lcd Ds1820 ; ".";
  If Halb = 1 Then
    Lcd "5"
  Else
    Lcd "0"
  End If
  Lcd "C "

Return

Schalter1:
Locate 2 , 1
Lcd "Taster1"
Waitms 500
Return

Schalter2:
Locate 2 , 1
Lcd "Taster2"
Waitms 500
Return

Schalter3:
Locate 2 , 1
Lcd "Taster3"
Waitms 500
Return

Schalter4:
Locate 2 , 1
Lcd "Taster4"
Waitms 500
Return

[COLOR="Red"]Sectic:
	Sekundentic=1	
Return[/COLOR]

End

Ich habe eine Softclock eingebaut. Nicht vergessen, an TOSC1 und TOSC2 einen 32768Hz Uhrenquarz dran zu hängen ! Hat auch den Vorteil, das Du jetzt auch eine Realtimeclock mit drin hast ;). Warum ich das mache ? Nun ja, jetzt läuft die Do - Loop Hauptschleife immer ohne irgendwelche Unterbrechungen und Waits durch. Nichts stoppt den Prozessor oder läßt ihn warten. Wirst Du dann merken, das jetzt ein kurzer Druck auf die Taster genügt. In der "alten" Version konnte es unter Umständen sein, das Du eine ganze Sekunde lang auf den Taster gedrückt hast, bis was passierte.

Schau Dir mal den Code von meiner Wetterstation an, da "übertreibe" ich das Ganze sogar und mache ein Quasiparallele Verarbeitung im Sekundentakt -> Mutlitasking. Naja, richtiges Multitasking ist es nicht, aber es zeigt schon mal einen ersten Ansatz und guten Willen.

Ich hab auch noch die temp-Subroutine umbnannt, da temp mir so noch einem reservierten Schlüsselwort aussieht.

Thomas
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)