PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm zu langsam?



Hübi
28.02.2009, 13:21
Hallo,
Ich möchte einen Drehencoder auslesen, um klein anzufangen möchte ich ersteinmal alle die High/low zustände zählen.

ich hab ein Programm geschrieben, mit dem das auch theoretisch möglich ist. Aber leider nur wenn man der Encoder sehr langsam dreht... wenn man zu schnell dreht ändert sich der wert nicht mehr.

ich denke mein Programm ist villeicht etwas komisch aufgebaut, aber mir ist keine andere Lösung eingefallen (bin absoluter anfänger)

kann es daran leigen das der AVR mit dem zählen nicht mehr hinterher kommt?
Oder kann es auch am Schalttransistor liegen? BC337-40

Mfg Hübi



'Encoder test
'--------------------------------------------------------------
$regfile = "attiny2313.dat" 'ATTINY 2313
$crystal = 8000000 'TACKT 8Mhz


'******** Deklarationen ********


Dim Zaehlwert As Word

'******** Initialisierung ******** '

Ddrd = &B11100000
Portd = &B00000000

Zaehlwert = 1

'******** Hauptprogramm ********

Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portb.2 'LCD configurieren (datenleitung)

Dim A As Byte
Config Lcd = 16 * 2 ' 16*2 Zeilen


Main: 'hauptprogramm
Cls 'display löschen
Do

Locate 1 , 1 'cursor in Zeile 1, Reihe 1
Lcd Zaehlwert 'schreibe "Zählwert"
Cursor Off 'cursor off


If Pind.2 = 1 Then 'wenn taster gedrückt, dann
Zaehlwert = Zaehlwert + 1 'addiere 1 zu Zähltwert
Goto Unterprogramm 'gehe zu Unterprogramm

End If 'end if


Loop




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





Unterprogramm: 'Unterprogramm

Do

If Pind.2 = 0 Then 'wenn Taster losgelasse wird
Goto Main 'springe zurück ins Hauptprogramm
End If 'end if



Loop

ThomasW
28.02.2009, 13:54
Hallo Hübi

Wenn du das so Programmierst ist das wirklich alles zu langsam.

z.B in ein Lcd schreiben braucht viel Zeit , genau so wie ein Print befehl ...
sowas musst du mit einem Interrupt lösen sei es mit Interrupt an einem Pin z.B INT0 aber ich finde eine Timer Lösung besser.

Timerlösung = es wird immer in einen Timer gesprungen und dort die Tasterstellung abgefragt ....

Mfg Thomas

Gento
28.02.2009, 13:57
99 % Leistung wird am LCD verplempert.

und sehr unlogisch deine Goto.

Wenn LCD Ausgabe dann:
if Zaehlwert<>Zaehlwert_Alt then
Locate 1,1
LCD Zaehlwert
end if

dann kann man auch das LCD besser lesen.
Und da Du ja hochzahlst , muß das LCD nur beim Starten 1x Cls werden.

Gento

Pyro-Mike
28.02.2009, 15:24
Die LCD-Abfrage braucht wahrscheinlich zu lang, probier doch mal, ob es geht, wenn du die nur alle 10 Änderungen oder so machst.


OK, man sollte aktualisieren, bevor man antwortet ;)

Hübi
01.03.2009, 10:53
Danke für eure Hilfe,
ich habe versucht möglichst alles richtig umzusetzten und hoffe ich habe es richtig gemacht/bzw. alles verstanden

wert <> wert then 'heißt doch wenn sich wert verändert, dann: oder?

leider klappt es immer noch nicht richtig... es ist sogar etwas schlechter geworden, aber vom Prinzip her funktioniert das Programm denk ich


'Encoder test
'--------------------------------------------------------------
$regfile = "attiny2313.dat" 'ATTINY 2313
$crystal = 8000000 'TACKT 8Mhz


'******** Deklarationen ********


Dim Zaehlwert As Word

'******** Initialisierung ******** '

Ddrd = &B11100000
Portd = &B00000000

Zaehlwert = 1

'******** Hauptprogramm ********

Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portb.2 'LCD configurieren (datenleitung)

Config Int0 = Falling 'INT0 = wenn taster gedrückt wurde
Enable Int0 ' erlaube INT0
Enable Interrupts ' erlaube Interrupts
On Int0 Unterprogramm ' gehe zu Unterprogramm

Dim A As Byte
Config Lcd = 16 * 2 ' 16*2 Zeilen

Cls 'display löschen
Main: 'hauptprogramm

Do


If Zaehlwert <> Zaehlwert Then 'wenn sich zählwert ändert
Locate 1 , 1 'cursor in Zeile 1, Reihe 1
Lcd Zaehlwert 'schreibe "Zählwert"
Cursor Off 'cursor off

End If 'end if


Loop




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





Unterprogramm: 'Unterprogramm

Do
Zaehlwert = Zaehlwert + 1 'addiere 1 zu Zähltwert

Return 'zurück zu Main


Loop

Che Guevara
01.03.2009, 11:21
hallo hübi,

versuch mal folgenden code:



$regfile = "attiny2313.dat"
$crystal = 8000000


Dim Zaehlwert As Word
Dim Zaehlwert_old As Word
Zaehlwert_old = 65000

Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portb.2
Initlcd
Cursor Off Noblink

Cls

Config Int0 = Falling
Enable Int0
On Int0 Isr_von_int0

Config Pind.2 = Input
Portd.2 = 1

Enable Interrupts

Locate 1 , 1
Lcd "Zaehlwert = "

Do

If Zaehlwert_old <> Zaehlwert Then
Locate 1 , 13
Lcd Zaehlwert
Zaehlwert_old = Zaehlwert
End If

Loop

End

Isr_von_int0:
Incr Zaehlwert
Return


wenn du fragen dazu hast, dann frag einfach ;-)

gruß
chris

Gento
01.03.2009, 11:29
Fünf Zeilen geändert und sollte jetzt gehen.
Gento



Dim Zaehlwert As Word
Dim Zaehlwert_alt AS Word
'******** Initialisierung ******** '

Ddrd = &B11100000
Portd = &B00000000

'******** Hauptprogramm ********

Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portb.2 'LCD configurieren (datenleitung)

Config Int0 = Falling 'INT0 = wenn taster gedrückt wurde
Enable Int0 ' erlaube INT0
Enable Interrupts ' erlaube Interrupts
On Int0 Unterprogramm ' gehe zu Unterprogramm

Dim A As Byte
Config Lcd = 16 * 2 ' 16*2 Zeilen

Cls 'display löschen
Zaehlwert=0
Zaehlwert_Alt=1000
Main: 'hauptprogramm

Do


If Zaehlwert <> Zaehlwert_Alt Then 'wenn sich zählwert ändert
Locate 1 , 1 'cursor in Zeile 1, Reihe 1
Lcd Zaehlwert 'schreibe "Zählwert"
Cursor Off 'cursor off

End If 'end if


Loop




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





Unterprogramm: 'Unterprogramm

Do
Zaehlwert_alt=Zaehlwert
Zaehlwert = Zaehlwert + 1 'addiere 1 zu Zähltwert

Return 'zurück zu Main


Loop

war einer scheller ;-)

TomEdl
01.03.2009, 11:35
Gebt doch bitte das "Cursor Off" aus der Schleife raus.
Was macht ein weiteres "Do" im Unterprogramm?

Grüße
Thomas

Pyro-Mike
01.03.2009, 11:40
Und gleich nochmal ne Version! :)

'Encoder test
'--------------------------------------------------------------
$regfile = "attiny2313.dat" 'ATTINY 2313
$crystal = 8000000 'TACKT 8Mhz


'******** Deklarationen ********


Dim Zaehlwert As Integer
Dim Zaehlwert_alt As Integer

'******** Initialisierung ******** '

Ddrd = &B11100000
Portd = &B00000000

Zaehlwert = 1

'******** Hauptprogramm ********

Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portb.2 'LCD configurieren (datenleitung)

Config Int0 = Falling 'INT0 = wenn taster gedrückt wurde
Enable Int0 ' erlaube INT0
Enable Interrupts ' erlaube Interrupts
On Int0 Unterprogramm ' gehe zu Unterprogramm

Dim A As Byte
Config Lcd = 16 * 2 ' 16*2 Zeilen

Cls 'display löschen
Cursor Off

Do


If Zaehlwert > Zaehlwert_alt Then 'wenn sich zählwert ändert
Zaehlwert_alt = Zaehlwert
Locate 1 , 1 'cursor in Zeile 1, Reihe 1
Lcd Zaehlwert 'schreibe "Zählwert"
End If 'end if


Loop




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





Unterprogramm: 'Unterprogramm
Zaehlwert = Zaehlwert + 1 'addiere 1 zu Zähltwert
Return 'zurück zu Main

TomEdl
01.03.2009, 11:42
Jetzt nur noch der Schönheit wegen ein "End" nach "Return" einfügen, dann passts perfekt! ;)

Grüße
Thomas

repi64
01.03.2009, 12:18
Na ja, perfekt kann es so nicht sein:

"If Zaehlwert > Zaehlwert_alt Then "

da wird nur hoch gezäht und zwar bis wann? Bis die Variable überläuft?

Gento
01.03.2009, 13:07
Ich schrieb <> , und nach $ffff kommt $0000 8-[

Gento

Pyro-Mike
01.03.2009, 14:23
Na ja, perfekt kann es so nicht sein:

"If Zaehlwert > Zaehlwert_alt Then "

da wird nur hoch gezäht und zwar bis wann? Bis die Variable überläuft?

In dem Programm kann Zaehlwert ja nur größer werden, also braucht man auch nicht < abfragen...

Wenn man das Programm fortführt, muss man das noch ändern, richtig.

for_ro
01.03.2009, 14:29
Na ja, perfekt kann es so nicht sein:

"If Zaehlwert > Zaehlwert_alt Then "

da wird nur hoch gezäht und zwar bis wann? Bis die Variable überläuft?

In dem Programm kann Zaehlwert ja nur größer werden, also braucht man auch nicht < abfragen...

Dein Zaehlwert_alt wird so langsam aber sicher bis auf 32767 hoch geschoben. Von dort kommt er nicht mehr weg.
Zaehlwert läuft über und fängt danach wieder bei 0 an und wird nie mehr größer als zaehlwert_alt, d.h.es wird nichts mehr angezeigt.
Das meinten die beiden damit.

Gruß

Rolf

Pyro-Mike
01.03.2009, 16:30
Ja, mir ist schon klar, dass die Variable irgendwann überlaufen wird, da aber nicht die Richtung der Encoder-Bewegung abgefragt wird, kann Zaehlwert nicht ohne fehler kleiner werden (bis sie eben überläuft), aber wer dreht schon zum Testen 1092,33 mal an dem Teil. ;)
Sicherlich ist es nicht perfekt, wäre je schrecklich...

Hübi
05.03.2009, 17:20
soo, vielen dank erstmal für eure Hilfe, ich hab alle Programme ausprobiert, und sie liefen alle super (bis auf das von Che Guevara) hab leider noch nicht die Zeit gefunden mich näher mit der Logik der Programme auseinander zu setzten, kommt aber noch... dann meld ich mich wohl nochmal^^

letztendlich war es doch kein reines Softwareproblem. Den Schalttransistor und den Encoder selbst habe ich mit einem extra Netzteil, den AVR mit dem Experimentierbord betrieben... das hat anscheinend nicht so funktioniert, weiß zwar nicht warum aber wenn ich beides mit einer Stromquelle betreibe funktioniert es einwandfrei!

mfg

TomEdl
05.03.2009, 18:03
Warscheinlich waren die Massen nicht miteinander verbunden.
Grüße
Thomas
;)