? 7-Segment Ausgabe eines Drehgebers (BASCOM) ?

uwe-ftechnik

Mitglied
31. Jan. 2009
71
1
8
Bekum
Sprachen
:adore: ---------------------------------------------- :adore:
Habe hier ein kleines Problem mit 4 Siebensegment Anzeigen.
Brauche noch eine umwandelung von Dezimalwert in Passenden
Binärwärt zur ausgabe 7-Segment.
Im Programm wierd ein Drehentcoder abgefragt und ein Zähler hoch-
gezählt der dann auf der Anzeige erscheinen soll.
Programmteile sind soweit wie möglich getestet und Funktionieren soweit
ganz gut nur halt die Umwandelung in Bin fehlt mir noch ganz.
Vieleicht kann mir ja hier einer weiterhelfen ????
Code:
$regfile = "M8def.dat"
$crystal = 16000000

'--------Segmente---------------
Config Portd = Output
Portd = 0

'----------Anode Display---------
Config Portb = Output
Portb = 0

'---------Pin fuer Tasteneingang---
Portc.2 = 1


Dim Stelle(4) As Byte
Dim I As Byte
Dim X(11) As Byte
Dim B As Byte
Dim C As Integer
Dim F As String * 5                                         'Anlegen eines Strings mit 5 Elementen
Dim D(5) As String * 1                                      'Anlegen eines Strings mit 5 Elementen je 1 Zeichen
Dim G As Integer
Restore Segmente
For I = 1 To 11
Read X(i)
Next I
Dim A As Byte
Dim E As Byte

'-------Timer----------------------
Config Timer0 = Timer , Prescale = 256
On Timer0 Timer_routine
Enable Timer0
Enable Interrupts

A = 1
E = 1

Anfang:

Do
   G = C
   F = Str(a)                                               'Zaehler Umwandeln in einen String
   D(1) = Mid(f , 1 , 1)                                    'Erstes Element von D 1.Zeichen
   D(2) = Mid(f , 2 , 1)                                    'Zweites Element von D 2.Zeichen
   D(3) = Mid(f , 3 , 1)                                    'Drietes Element von D 3.Zeichen
   D(4) = Mid(f , 4 , 1)                                    'Viertes Element von D 4.Zeichen
   D(5) = Mid(f , 5 , 1)                                    'Fuenftes Element von D 5.Zeichen
   B = Encoder(pinc.0 , Pinc.1 , Links , Rechts , 0)
   If Pinc.2 = 0 Then Goto Taste
 
              ' im folgendem Code fehlt die Umwandelung in Bin

  Stelle(1) = D(1)                                         'D(1)                                         'Hinter dem Komma wird abgeschnitten, enthält also die Zehner
   Stelle(2) = D(2)                                         'D(2)                                         'gibt den Rest, also die Einer
   Stelle(3) = D(3)                                         'D(3)                                         'Hinter dem Komma wird abgeschnitten, enthält also die Zehner
   Stelle(4) = D(4)                                         'D(4)
   Stelle(5) = D(5)                                         'D(4)





Loop


End


Timer_routine:
   Portd = Stelle(a)                                        'Neue Segmente ausgeben
   Incr A
   If A = 5 Then A = 1                                      '  X(stelle(a))
   Portb = E                                                'Neue Stelle einschalten
   E = E * 2
   If E > 8 Then E = 1
Return

Goto Anfang
' Unterprogramm Rechtsdrehung
Rechts:
  C = C + 1                                                 'Drehgeberwert + 1
  Return
' Unterprogramm Linksdrehung
Links:
  C = C - 1                                                 'Drehgeberwert - 1
  Return
' Unterprogramm Taste gedrueckt
Taste:
  Locate 2 , 1
  C = 0                                                     'bei Tastendruck Drehgeberwert=0

Goto Anfang


Segmente:
'         0             1            2           3            4            5
Data &B00111111 , &B00000110 , &B01011011 , &B01001111 , &B01100110 , &B01101101
'        6             7            8            9            DP
Data &B01111100 , &B00000111 , &B01111111 , &B01100111 , &B10000000

Die Hardware ist aufgebaut und mit anderen Programmteilen erfolgreich
Getestet.
Habe schon seit über 1Woche nach Info im Netz gesucht nur leider ohne
Erfolg :confused: .
Währe nett wenn sich das mal jemand anschauen könnte !
:adore:-----------------------:adore: ----------------------------:adore:
 
Hallo Uwe,
dir fehlt eigentlich nur die Lookup() Funktion. Schau mal in die Hilfe für Details.
Anstelle von
Stelle(1) = D(1) 'hier hast du z.B. den Wert 5 in Stelle(1) stehen
schreibst du dann
Stelle(1) = Lookup(D(1), Segmente) 'jetzt hast du die Segmente der 5 in Stelle(1) stehen
Für das Komma musst du eine separate Berechnung machen, da Lookup eine Zahl als Index haben möchte.

Ein Hinweis noch zu deiner Timer ISR. Du solltest dort erst alle Ausgaben abschalten, bevor du neue Werte lädst. Ansonsten bekommst du Geisterbilder.


HBA


Edit: Ach ich sehe gerade, dass du die Segment Werte schon in der Variablen X gespeichert hast. Dann kannst du wahrscheinlich einfach so schreiben:
Stelle(1) = X(D(1))
Evtl. meckert der Compiler und du musst den Wert zwischenspeichern.

Mist, scheint heute nicht mein Tag zu sein. Gerade ist mir die nächste Änderung gelöscht worden. Also hier nochmal.
Da D(5) ein Array von Strings ist, geht es so auch nicht. Habe ich übersehen.
Spätestens jetzt würde ich auf die Benutzung von Overlays umsteigen. Damit kannst du dir die ganze Konvertiererei der Strings ersparen.

Dim F As String * 5
Dim F_Ovly(5) As Byte At F Overlay
...
Do
F=Str(a) 'damit stehen in F_Ovly automatisch die ASCII Werte der Ziffern und des Kommas
Stelle(1) = Asc(F_Ovly(1)) - 46 '46 ist der ASCII Wert des Kommas '.'
'In Stelle(1) hat das Komma also den Wert 0, die 0 den Wert 2, die 1 den Wert 3 usw.

In der Timer_ISR schreibst du dann

PortD = X(Stelle(a))

Deine Segment Daten musst du dann auch noch ein wenig umsortieren.

Segmente:
' DP dummy 0 1 2 3 4 5
Data &B10000000, &B00000000, &B00111111 , &B00000110 , &B01011011 , &B01001111 , &B01100110 , &B01101101
' 6 7 8 9
Data &B01111100 , &B00000111 , &B01111111 , &B01100111
 
Danke erstmal für die Anwort HinterBlauenAugen :eek: .
Habe das Programm jetzt folgendermassen geändert :

Code:
Dim I As Byte
Dim X(12) As Byte
Dim B As Byte
Dim C As Integer
Dim F As String * 5                                         'Anlegen eines Strings mit 5 Elementen
Dim F_ovly(5) As Byte At F Overlay
Dim D(5) As String * 1                                      'Anlegen eines Strings mit 5 Elementen je 1 Zeichen
Dim G As Integer
Restore Segmente
For I = 1 To 12
Read X(i)
Next I
Dim A As Byte
Dim E As Byte

'-------Timer----------------------
Config Timer0 = Timer , Prescale = 256
On Timer0 Timer_routine
Enable Timer0
Enable Interrupts

A = 1
E = 1

Anfang:

Do

   C = C + 1
   'G = C                                                   'erstmal zum Test da Endcoder keine Funktion
   F = Str(c)                                               'Zaehler Umwandeln in einen String
   D(1) = Mid(f , 1 , 1)                                    'Erstes Element von D 1.Zeichen
   D(2) = Mid(f , 2 , 1)                                    'Zweites Element von D 2.Zeichen
   D(3) = Mid(f , 3 , 1)                                    'Drietes Element von D 3.Zeichen
   D(4) = Mid(f , 4 , 1)                                    'Viertes Element von D 4.Zeichen
   D(5) = Mid(f , 5 , 1)                                    'Fuenftes Element von D 5.Zeichen
'   B = Encoder(pinc.5 , Pinc.4 , Links , Rechts , 0)
'   If Pinc.3 = 0 Then Goto Taste




 Stelle(1) = Asc(f_ovly(1)) - 46                            '46 ist der ASCII Wert des Kommas '.'
 Stelle(2) = Asc(f_ovly(2)) - 46                            '
 Stelle(3) = Asc(f_ovly(3)) - 46                            '
 Stelle(4) = Asc(f_ovly(4)) - 46                            '
 Stelle(5) = Asc(f_ovly(5)) - 46                            'Error:263 Linie: 63 Array index out of range [5]
Waitms 500
Loop


End


Timer_routine:
   'Portd = Stelle(a)                                        'Neue Segmente ausgeben
   Portd = X(stelle(a))
   Incr A
   If A = 5 Then A = 1                                  '
   Portb = E                                                '
   E = E * 2
   If E > 8 Then E = 1
Return

Goto Anfang
' Unterprogramm Rechtsdrehung
Rechts:
  C = C + 1                                                 'Drehgeberwert + 1
  Return
' Unterprogramm Linksdrehung
Links:
  C = C - 1                                                 'Drehgeberwert - 1
  Return
' Unterprogramm Taste gedrueckt
Taste:
  Locate 2 , 1
  C = 0                                                     'bei Tastendruck Drehgeberwert=0

Goto Anfang


Segmente:
'          DP         dummy         0             1            2           3            4            5
Data &B10000000 , &B00000000 , &B00111111 , &B00000110 , &B01011011 , &B01001111 , &B01100110 , &B01101101
'               6                    7                   8                    9
Data &B01111100 , &B00000111 , &B01111111 , &B01101111


Anzeige Funktioniert leider noch nicht richtig, Zaelt jetzt von null bis acht
dann Zehnerstelle auf erstes Segment und Einer auf zweitem Segment bei hunderter wandern die Einer
dann ebenfals eine Stelle nach lincks usw.
Desweiteren habe ich immer ein Error in Zeile 63 ( Stelle(5) = Asc(f_ovly(5)) - 46 'Error:263 Linie: 63 Array index out of range [5] ) zuweisung Stelle(5) :banghead: !!!
Bin hier leider sehr ratlos bei beiden Fehlern :close_tema:

Habe noch einmal nachgeschaut Fehler für die unkorrekte Reihenfolge liegt im Teimer-Interupt bei
Portb = E '
E = E * 2
If E > 8 Then E = 1

aber wie ist das Korrekt ??
 
Stelle(1) = Asc(f_ovly(1)) - 46
war mal wieder Blödsinn, sorry. Im Ovly stehen ja schon die Ascii Werte, also einfach

Stelle(1) = f_ovly(1) - 45 'Nimm 45, weil das Array mit Index 1 anfängt.

In deinem letzten Post ist Stelle nicht dimensioniert, im ersten Post nur als 4 Byte Array. Mach mal da eine 5 draus.
Ist dein String (F = Str(a)) eigentlich immer 5 Zeichen lang, inklusive Dezimalpunkt? Ansonsten müssen da noch Vorkehrungen getroffen werden.

HBA
 
Danke Dier für die Antwort !!!!:flowers:

Im zweiten Post ist mir leider der Fehler unterlaufen das daß Listing nicht
kommplett rübergekommen ist, hast aber recht habe Stelle nur mit 4
Deklarierrt, werde das jetzt mal als erstes ändern und dann mal Versuchen was dabei rauskommt !!! :stupido3:
 
:flowers: Priemmmma HinterBlauenAugen Funktioniert soweit erstmal ganz gut :pleasantry:
Habe jatzt geändert :

Dim Stelle(5) As Byte
E = 8
Stelle(1) = F_ovly(1) - 45
Stelle(2) = F_ovly(2) - 45
Stelle(3) = F_ovly(3) - 45
Stelle(4) = F_ovly(4) - 45
Stelle(5) = F_ovly(5) - 45

Timer_routine:
Portd = X(stelle(a))
Incr A
If A = 5 Then A = 1
Portb = E
E = E / 2
If E < 1 Then E = 8
Return


Muss jetzt noch versuchen die Anzuzeigenden Stelle an die richtige stelle
zu bekommen, weil jetze im moment wierd die Einerstelle
linksbündig ausgegeben und beim erreichen von 10 die Einer dann nach rechts
verschoben usw.
Schön währe es wenn die Einerstellen rechtsbündig bleiben würden, und
was noch fehlt ist auch die Auswertung der Kommastelle.
Das ganze soll mal den Zweck haben einen Industrieellen Drehgeber mit
3600 Impulsen pro Umdrehung auszuwerten und das ganze als Grad-
anzeige Darzustelle.
Wenn das soweit Funktioniert soll dann mal ein Motor Positioniert werden,
bei 3600 kann man ja auf 0,5 Grad genau Positionieren, demnach auch
nur eine Kommastelle.
Habe das ganze auch schon mal mit LCD Versucht, nur ist die
Verarbeitung dann zu langsam :mad: erhoffe mir mit LED mehr Erfolg.
Vielleicht hat noch jemand einen Vorschlag wie man das mit den Stellen
machen kann wenn möglich mit nicht ganz so viel Code in Interuptrotine
der Geschwiendigkeit wegen !!:stupido3:
 
Hallo Uwe,
wie viele Stellen hast du jetzt, 4 oder 5?
Wenn es 5 sind, dann müsste es eigentlich so heißen:
If A = 6 Then A = 1

Kann man bei 3600 pro Umdrehung nicht auf 0,1° angeben?
Bin mir nicht sicher ob ich das richtig verstanden habe, aber wenn der Drehgeber eine Zahl zwischen 0 und 3599 ausgibt, dann kannst du die doch direkt benutzen und ganz auf die Strings verzichten.
Dann ist auch das Thema rechtsbündig ganz einfach zu lösen. Und dein Dezimalpunkt steht dann fest auf der zweiten Stelle von rechts, daneben ist nur noch die 1/10° Stelle.
 
Ist leider kein Drehgeber mit BCD-Ausgang :( , (Heidenhain ERN 1070 3600)
ich habe bei dem Geber folgende Ausgänge :

A
A/Inv.
B
B/Inv.
Z
Z/Inv.

A un B Ausgang liefern mir um 90Grad versetzt 3600 Impulse Pro Umdrehung
und Z einen Impuls Pro Umdrehung, kann man als Nullposition verwenden.

Zur Zeit habe ich 4 Stellen solten reichen, XXX,X Grad also max. 360Grad
bzw. 359,9 dann wieder 0 .
Hast auch recht mit 0,1 Grad, fehler meinerseits.
Wenn ich feste Positionen für die Ausgabe hätte dan kann das Komma fest
auf der vorletzten Stelle ausgegeben werden.
 

Anhänge

  • Impulse.jpg
    Impulse.jpg
    7,3 KB · Aufrufe: 11
Bekommst du bei einer vollen Umdrehung auch tatsächlich 3600 Impulse oder gehen da welche verloren?
Besonders bei schnelleren Bewegungen würde ich denken, dass die Encoder Funktion da nicht mitkommt. Dann könnte man noch überlegen, die ext. Interrupts INT0 und INT1 zu benutzen.
Da du ja selber rauf und runter zählst, hast du eine Variable, die von 0 - 3599 geht. Mit ganz wenig Befehlen, aber nicht wirklich schnell, kannst du es so machen:
F = Str(c)
F = Format(F, " 0.0") 'mit 2 führenden Leerzeichen, dann muss du den Dummy Code aus der Segment Tabelle nehmen oder
F = Format(F, "000.0") 'mit führenden Nullen

Stelle(1) = F_ovly(1) - 45
...

HBA
 
:rolleyes: Hallo HinterBlauenAugen

Der Entcoder gibt tatsächlich 3600 Imp. raus, zur zeit habe ich zum Test erstmal
einen Entcoder der Identisch ist mit den Panasonic von Pollin, also nur einen
der zur Eingabe gedacht ist.
Den Heidenhain Entcoder habe ich wie schon gesagt am ATMEGA8 mit 16Mhz
und LCD-Anzeige gehabt mit Int. nur die Auswertung ist dort einfach zu langsam :mad: .
Bei langsamen Drehungen ist alles O.K. nur wenn es in meinem Arbeitsbereich geht, werden zuviel Impulse Verschluckt :)mad: ).
Ich vermute das daß mit der Anzeige zu tun hat, Funktioniert hat das soweit
nur die Auswertung ist halt viel zu langsam :cool: .
Bin im Programieren halt noch blutiger Anfänger, habe halt versucht mit den
Büchern (BASCOM) von Claus Kühnel und Roland Walter etwas vorannzukommen
sowie Programmteilen aus dem Netz. Wie man aber sieht fehlt mir nach 2 - 3 Monaten
mit dem Tehma leider noch zuviel Grundwiessen :confused: .
Die Bücher geben aber auch zum Thema 7-Segment keine brauchbare Infos.
 
Kannst du deinen ursprünglichen Code mit Interrupt mal posten?
Vielleicht kann man noch was dran machen, dass der schneller wird.
Bei 3600 Interrupts pro Umdrehung und etwa 150 Takte pro Interrupt sollten ewa 30 Umdrehungen pro Sekunde drin sein. Dann macht der µC aber auch nichts anderes mehr.
Mit der Nosave Option kann man die Anzahl Takte vielleicht noch auf die Hälfte runterbekommen.

HBA
 
Danke Dir HinterBlauenAugen :flowers:
Leider leider Funktioniert das noch nicht so wie es soll :( .
Fogende Änderungen habe ich jetzt noch gemacht:

Do
Incr C
If C > 3599 Then C = 0
F = Str(c) 'Zähler Umwandeln in einen String
F = Format(f , "0") 'mit 2 führenden Leerzeichen
D(1) = Mid(f , 1 , 1) 'Erstes Element von D 1.Zeichen
D(2) = Mid(f , 2 , 1) 'Zweites Element von D 2.Zeichen
D(3) = Mid(f , 3 , 1) 'Drietes Element von D 3.Zeichen
D(4) = Mid(f , 4 , 1) 'Viertes Element von D 4.Zeichen
D(5) = Mid(f , 5 , 1) 'Fünftes Element von D 5.Zeichen
' B = Encoder(pinc.5 , Pinc.4 , Links , Rechts , 0)
' If Pinc.3 = 0 Then Goto Taste

Stelle(5) = F_ovly(1) - 45
Stelle(4) = F_ovly(2) - 45
Stelle(3) = F_ovly(3) - 45
Stelle(2) = F_ovly(4) - 45
Stelle(1) = F_ovly(5) - 45
Waitms 50

Loop

Bei F = Format(f , "0") und Stelle(5) = F_ovly(1) - 45 ,zu Anfang Einerstellen linksbündig
bis Hunderter erreicht dann Einerstellen auf zweiter Stelle von links und Zehner auf erster
Stelle von links danach erst bei erreichen der Tausender Stelle die Einer eine Stelle weiter
rechts.Man beachte bitte auch das Vertauschen Stelle(5) = F_ovly(1) - 45.

Erst bei vertauschten Stelle(5) = F_ovly(1) - 45 und F = Format(f , "0000") (hier 4Nullen)
läuft alles soweit ohne unterdrückung vorangestellter Nullen.
Bei Einfügen des Kommas belegt dieses ja auch die ganze Stelle und es wierd hier dann ja auch
keine Zahl mehr ausgegeben.
Es giebt noch die Möglichkeit F = Format(f , " 0") hier 4 Leerstellen aber dann läuft
das ganze extrem langsam, angegebene Verzögerung 50mS und er zählt
max. Zenerstellen im Sekundentackt :confused: .
 
Habe hier mal mein x-ten Versuch mit LCD, das Orginal ist von MCS (#AN115) :rolleyes: .


Code:
'-------------------------------------------------------------------------------
' Filename : QuadrDec_1.0.bas
' Purpose  : Quadrature Decoder/Counter and Display
' Author   : Ger langezaal
' Date     : 5 April 2002
' Compiler : BASCOM-AVR   Rev. 1.11.6.5
'
'-------------------------------------------------------------------------------
'
' Algorithm:
' Interrupt on both edges of phase A
' Test phase B in ISR
' When phase B <> phase A then decrement counter
' When phase B = phase A then increment counter
' Convert counter value to displacment units
' Format value in string and display
'
'-------------------------------------------------------------------------------
'
' Setup for AT90S2313-10
'
' INT0 edge is set to rising edge
' INT1 edge is set to falling edge
' Encoder phase A to INT0 and INT1  (PD2 and PD3)
' Encoder phase B to PD4
' Pushbutton between Portd.5 and GND  (display zero)
' LCD at PortB
'
' Example for PROXXON KT150 XY table:
' Displacement/rev = 2 mm
' Encoder resolution = 20 pulses/rev
' Interrupt on both pulse edges = 40 interrupts/rev
' Dial resolution: 2 mm / 40 = 0.05 mm
' The optical encoder came from a used mouse (two available)
'
'-------------------------------------------------------------------------------
'
' Options/Compiler/Chip:
' Hw Stack 48
' Soft Stack 8
' Framesize 16
'
$hwstack = 48                                               ' default use 32 for the hardware stack
$swstack = 10                                               ' default use 10 for the SW stack
$framesize = 40

'-------------------------------------------------------------------------------
'
$regfile = "m8def.dat"
$crystal = 16000000

'Dim X_axis As String * 16                                   'LCD format string
Dim Axis_raw As Long                                        'optical pulse counter
Dim Axis_mm As Word                                         'counter value converted to mm
Dim Axis_tt As Word
Dim Axis_tu As Word

'Const Enc_res = 20 * 2                                      'encoder resolution * 2
'Const Conv_mm = 200 / Enc_res                               'dial resolution = 0.05 mm

Config Portb = Output
Config Portd = Input
Portd = &B11101111                                          'enable Portd pullup's

Config Lcdbus = 4
Config Lcd = 24 * 2
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
Cls
Cursor Off

Phase_a Alias Pind.2                                        'INT0 also connected to Pind.3 = INT1
Phase_b Alias Pind.3
Axis_rst Alias Pind.5                                       'reset counter if low

'---[ Set Interrupt logic ]-----------------------------------------------------

Mcucr = &B00001010                                          'set interrupt edges
On Int0 Phase_a_edge                                        'ISR on rising edge
On Int1 Phase_b_edge                                        'ISR on falling edge
Enable Int0
Enable Int1
Enable Interrupts

'---[ Initialization ]----------------------------------------------------------

Lcd "X-Axis   Rev.1.3"
Waitms 2000
Cls
Axis_raw = 0

'---[ Main program loop ]-------------------------------------------------------

Do
'  If Axis_rst = 0 Then Axis_raw = 0                         'reset counter if low
  Axis_tt = Axis_raw / 100
  Axis_mm = Axis_raw                                        ' / 10
'  Axis_mm = Axis_raw * Conv_mm                              'convert to mm
'  Axis_tu = Str(axis_mm)                                    '
'  Axis_mm = Format(x_axis , " +0.00")                       'format without leading zero's
'  X_axis = Format(x_axis , "+000.00")                       'format with leading zero's


  Locate 1 , 1
  Lcd "X " ; Axis_tt ; " Grad  "                            'display
  Locate 2 , 1
'  Axis_tu = Axis_raw
  Lcd Axis_mm ; "     "
'  Waitms 50
Loop

'-------------------------------------------------------------------------------
End

'---[ Interrupt Service Routine ]-----------------------------------------------

Phase_a_edge:                                               'Interrupt on rising and falling edge


  If Phase_b <> Phase_a Then                                'test phase B
    Decr Axis_raw                                           'CCW
'  Else
  End If
  If Axis_raw = 3600 Then Axis_raw = 0
  If Axis_raw = -1 Then Axis_raw = 3599
  Return

Phase_b_edge:                                               'Interrupt on rising and falling edge


  If Phase_a <> Phase_b Then                                'test phase B
    Incr Axis_raw                                           'CCW
'  Else
  End If
  If Axis_raw = 3600 Then Axis_raw = 0
  If Axis_raw = -1 Then Axis_raw = 3599
  Return


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

Ich muss später ja sowieso auf Interrupts zurückgreifen geht ja leider nicht anders.
Meine bisherigen Bemühungen siend ja nur zum Verständniss der 7-Segment
Anzeigen. Währe auch sehr schlecht wenn das mit der Anzeige nicht geht
da ich Blauäugig sehr viel 7-Segment Anzeigen gekauft habe ( 250 Stck.).
Ist nicht nur ein Projekt das mit 7-Segment Anzeigen laufen soll, sondern
da soll noch einiges dazukommen allerdings nur Privat für mich
(Drehzahlanzeige für Drehbank Bohrmaschiene Werkzeugschleifer sowie
Wegmeßsysteme für Portalfräse, Drehbank und Anreißlehre.)
Ich muss also mal schauen wie ich jetzt damit klarkomme :rolleyes: .
Die 7-Segment Anzeigen wahren zwar günstig bei der Anzahl, ist aber auch
Geld was dann nur Tot in der Ecke liegt.
Alles mit Beleuchteten LCDs ausstatten währe zu Teuer geworden und die
Lesbarkeit von 7-Segment Anzeigen ist bei Werkzeugmaschienen einfach besser :D .
Habe hier ja auch noch einige LCDs liegen nur alle ohne Beleuchtung und
Leuchtfolie die man mal Kaufen konnte habe ich auch nicht mehr auftreiben
können, also blieb mir ja nichts anderes .
Habe mal das Prg. angehängt und zwei Bilder IMG-2 momentane Anzeige
für den Testbetreib, IMG-3 momentaner Testaufbau mit Mega8 und OLIMEX
Bord :rolleyes: .
 

Anhänge

  • AN115.zip
    90,5 KB · Aufrufe: 17
  • IMG-2.jpg
    IMG-2.jpg
    91 KB · Aufrufe: 22
  • IMG-3.jpg
    IMG-3.jpg
    142 KB · Aufrufe: 24
Hi Uwe,

Der Entcoder gibt tatsächlich 3600 Imp. raus, zur zeit habe ich zum Test erstmal
einen Entcoder der Identisch ist mit den Panasonic von Pollin, also nur einen
der zur Eingabe gedacht ist.
Den Heidenhain Entcoder habe ich wie schon gesagt am ATMEGA8 mit 16Mhz
und LCD-Anzeige gehabt mit Int. nur die Auswertung ist dort einfach zu langsam :mad: .
Ich würde mal sagen das der Panasonic ein normaler Encoder mit mechanischen
Impulserfassung ist. Der Heidenhain wird mit Sicherheit ein optischer Encoder
sein da man sonst wohl nicht diese Anzahl an Impulse pro Umdrehung schafft.

Die Routine in Bascom wird bestimmt für die mechanischen entwickelt worden
sein. Also mit Entprellung usw. Das könnte man sich ja beim Heidenhain
sparen. Das gibt dann schon mal Geschwindigkeit im Programm. Außerdem
könnte man die Impulserkennung über INT0/INT1 für die beiden Phasensignale
machen damit einem keine Impulse verlorengehen. Für den Fall der Fälle kann
man ja zusätzlich über die Null-Impulse des Encoders aufsynchronisieren.

Wenn du mehr Geschwindigkeit benötigst würde ich dir den Mega168
empfehlen. Der ist Pinkompatibel mit dem Mega8 und schafft 20MHz.
Außerdem hat er noch PinChangeInterrupts.

Wenn das auch noch nicht reicht würde ich den Mega168 als Subsystem
laufen lassen was sich intern nur um einen Impulszähler kümmert und die
Daten über einen Bus dem Rest des Systems bereitstellt und über Kommandos
die Zähler auf bestimmte Werte oder auf Null setzen kann.

Bei langsamen Drehungen ist alles O.K. nur wenn es in meinem Arbeitsbereich geht, werden zuviel Impulse Verschluckt :)mad: ).
Ich vermute das daß mit der Anzeige zu tun hat, Funktioniert hat das soweit
nur die Auswertung ist halt viel zu langsam :cool: .
Das kann daran liegen das dir die Timer-Interrupts für das Multiplexing die
Signalerkennung zerschreddern. Laß doch das Multiplexing ohne Timer einfach
in der Hauptschleife laufen. Das muß doch nicht mit gleichmäßiger Frequenz
laufen. Die muß nur hoch genug sein.

Bin im Programieren halt noch blutiger Anfänger, habe halt versucht mit den
Büchern (BASCOM) von Claus Kühnel und Roland Walter etwas vorannzukommen
sowie Programmteilen aus dem Netz. Wie man aber sieht fehlt mir nach 2 - 3 Monaten
mit dem Tehma leider noch zuviel Grundwiessen :confused: .
Die Bücher geben aber auch zum Thema 7-Segment keine brauchbare Infos.
2-3 Monate sind zwar schon ein guter Grundstock aber das mit dem Lernen
wird auch nach ein paar Jahren noch nicht zu Ende sein. ;)

Gruß
Dino
 
Hi
Nun muß ich auch mal etwas Senf dazugeben.. also, ein Drehencoder mit 3000 Imp/Umdr. hat schon eine ordentliche Frequenz. Man kann das grob überfliegen 1 Umdr/sek ergibt eine Signalzeit von ca. 0, 3 ms...
Basic wird in der Regel schon einiges an Zeit durch "aufgeblähte" Funktionen verbraten, daher glaube ich, du hast ein echtes Zeitproblem...
Immer dran deken, Signal erfassen ist das eine, das geht ja noch ohne Probleme in einer ISR. Aber es soll ja auch eine Auswertung un Anzeige da sein. Vielleicht lohnt sich die Mühe, einige Routinen in Assembler einzubinden, um etwas mehr Durchsatz zu bekommen. Auf jeden Fall aber mußt du die Impulse im Interrupt einlesen. Wie schon gesagt, es sind von Elektronik aufbereitete Signale, da bedarf es keiner Entprellung. Außerdem ist der Zeitpunkt eines Signales kritisch, daher geht es auch nur ohne Signalverluste in einer ISR. Außerdem ist es möglich, das dein Encoder keinen stabilen Wert liefert.( zittert) das bedeutet ebenfalls eine hohe Anforderung an den Eingang, denn du möchtest ja einen Winkel bestimmen. Wenn du aber Impulse verlierst, wird dir der Wert wegdriften.
Gruß oldmax
 
Vielen DANK an dino03 und oldmax für eure Atnworten :flowers: .

von dino03
Ich würde mal sagen das der Panasonic ein normaler Encoder mit mechanischen
Impulserfassung ist. Der Heidenhain wird mit Sicherheit ein optischer Encoder
sein da man sonst wohl nicht diese Anzahl an Impulse pro Umdrehung schafft.

Der Entcoder ist von Grayhill, ist mit Optischen ausgang und könnte man auch
ohne Entprellen abfragen ist hier aber nicht so wichtig da es hier ja hauptsächlich
um den Heidenhain geht, das war ja nur zum Testen gedacht.

Die Routine in Bascom wird bestimmt für die mechanischen entwickelt worden
sein.

Mit sicherheit hast Du da Recht !!

Außerdem
könnte man die Impulserkennung über INT0/INT1 für die beiden Phasensignale
machen damit einem keine Impulse verlorengehen.

Habe ich ja schon im Posting #13 geschrieben das daß ein muss ist mit
Interupts zu Arbeiten.

Wenn du mehr Geschwindigkeit benötigst würde ich dir den Mega168
empfehlen. Der ist Pinkompatibel mit dem Mega8 und schafft 20MHz.
Außerdem hat er noch PinChangeInterrupts.

Werde ich auch auf jedenfall versuchen, ist ein sehr guter Tip ;) .

Wenn das auch noch nicht reicht würde ich den Mega168 als Subsystem
laufen lassen was sich intern nur um einen Impulszähler kümmert und die
Daten über einen Bus dem Rest des Systems bereitstellt und über Kommandos
die Zähler auf bestimmte Werte oder auf Null setzen kann.

Hatte ich auch schon mal im Hienterkopf nur ist da auch die Frage der Datenübermittlung, welche möglichkeit ist dort die Beste !!
SPI, TWI oder UART ?

Ich gehe mal davon aus das SPI hier am besten Infage kommt, Hardware
SPI solte dafür gehen nur wie sieht es dann mit der Programierung aus :confused: ?
Doco bei Claus Kühnel 2 Seiten, etwas besser sieht es da bei Roland Walter
aus da siend es schon mal 11 Seiten, Bascom-Hilfe leider alles Englisch :mad: .

Bei langsamen Drehungen ist alles O.K. nur wenn es in meinem Arbeitsbereich geht, werden zuviel Impulse Verschluckt ( ).
Ich vermute das daß mit der Anzeige zu tun hat, Funktioniert hat das soweit
nur die Auswertung ist halt viel zu langsam .

Die Aussage habe ich gemacht über einen Aufbau mit ATMEGA8 16Mhz, LCD
und Abfrage über Interupts.


von oldmax

Basic wird in der Regel schon einiges an Zeit durch "aufgeblähte" Funktionen verbraten, daher glaube ich, du hast ein echtes Zeitproblem...

Das habe ich auf jedenfall !!!

ISR ist mir aufjedenfall klar, ist nunmal nicht anders möglich !

Routinen in Assembler einzubinden

Da Stellt sich die Frage wie man soetwas Lösen könnte, ich wolte ja mal in
Absehbarer Zeit eine Lösung für das Problem, diesen Tip werde ich aber auf jeden
fall weiter im Auge behalten.

Es wierd wahrscheinlich darauf hinauslaufen wie dino03 schon Sagte
Wenn das auch noch nicht reicht würde ich den Mega168 als Subsystem
laufen lassen was sich intern nur um einen Impulszähler kümmert und die
Daten über einen Bus dem Rest des Systems bereitstellt und über Kommandos
die Zähler auf bestimmte Werte oder auf Null setzen kann.
Den 168er als Zähler und etw. ATMEGA 32 zum Anzeigen und zur Ansteuerung
des Motors, sowie Eingabe eines Vorgabewertes für die Gradzahl.
Vieleicht dann doch für diese Lösung ein LCD mit grosser Anzeige und guter
Beleuchtung !!!

Werde jetzt auf jedenfall mal so schnell wie mölich ein oder zwei 168er Bestellen und dann mal Versuchen wie es damiet geht.
Ich habe auch schon gehört das jemand einen ATMEGA höher Taktet als
Angegeben, so 2-4 Mht höher als angegeben ist wobei man hier dan mal
mehrere Cntroller Versuchen solte mit den Meisten sollte das aber gehen ??
Wenn man einen 168er mal mit etwas mehr Mhz Taktet solte das doch mal
ein Versuch wert sein ;) !
:pleasantry: :pleasantry:
Ich möchte mich hier noch einmal bei allen Bedanken die mir Geholfen haben
und mir noch Helfen möchten, ich finde das hier ECHT SUPER
:flowers: :flowers: :
:pleasantry: :pleasantry:
:eek: :adore: Ich währe hier auch echt Sehr Dankbar für wietere Tips die zur Lösung Meines Propblems beitragen :adore:
 

Anhänge

  • Grayhill62A.jpg
    Grayhill62A.jpg
    57,4 KB · Aufrufe: 25
  • Grayhill-1.jpg
    Grayhill-1.jpg
    15,3 KB · Aufrufe: 12
  • Grayhill-2.jpg
    Grayhill-2.jpg
    13,5 KB · Aufrufe: 13
  • Grayhill-3.jpg
    Grayhill-3.jpg
    14,8 KB · Aufrufe: 7
Hallo zusammen!

Ich habe mich bis jetzt aus dem Thema heraus gehalten, weil ich es zum Einen nicht vollständig verfolgt habe und zum Anderen zu viele Köche auch den Brei verderben können. ;)

Kurz aber eine Anmerkung von mir zu den PCInts des 168er....
Ich bin mir nicht sicher, ob das funktionieren würde. :hmmmm:
Der PCINT wird zwar funktionieren, aber wenn eine Flanke am "niederwertigen" PCINT noch ansteht, wird der nächst höhere Pin des PCINT nicht erfasst.
Dies wäre aber doch beim Drehencoder zwingend erforderlich. Schließlich steht eine Flanke immer noch an, wenn das zweite Signal vom anderen Eingang kommt..... Je nach Drehrichtung halt.


Was ich mich auch immer noch frage....
In welcher Zeit müssen die 3600 Impulse/Umdrehung denn nun erfasst werden? In einer Sekunde, in einer Minute, oder..... ? :hmmmm:


So, nun halte ich mich aber erst mal wieder raus.... damit ich hier nichts durcheinander bringe. ;)

Grüße,
Cassio
 
Danke für Deine Beteiligung :flowers:

Wie gesagt bin ich für jeden Tip Dankbar, da ja scheinbar meiner erster Ansatz nicht so gut ist ist ja hier alles Offen !

Wenn da also Irgenwelche Ideen vorhanden siend währe ich auch dafür sehr
Dankbar :) !!!

Um einmal auf denMotor zu kommen ich weiss es jetzt nicht ganz genau aber
Umdrehung Max. 20 - 50 Pro Min. Drehgeber also da 1:1 Übersetzt ist gleiche Drehzahl.
Motor mit Schneckenrad einmal Angefahrene Positionn hält er dann auch.
:rolleyes:
 
Hi,

Bascom-Hilfe leider alles Englisch :mad: .
bei nem Arbeitskollegen ist das Russisch auch besser als das Englisch ;)
Ich sag jetzt aber nicht wo er her kommt :D

Ich habe auch schon gehört das jemand einen ATMEGA höher Taktet als
Angegeben, so 2-4 Mht höher als angegeben ist wobei man hier dan mal
mehrere Cntroller Versuchen solte mit den Meisten sollte das aber gehen ??
Wenn man einen 168er mal mit etwas mehr Mhz Taktet solte das doch mal
ein Versuch wert sein ;) !
Ich hab den Mega168 mit 25MHz betrieben. Lief soweit ich das übersehen
konnte. Über 25MHz würde ich aber nicht gehen. Oder man probiert mal
mit nem Quarzoszillator. Muß ich mal sehen. Nen 60MHz Oszillator und dann
ein FlipFlop um sauberen 30MHz-Takt zu bekommen :rolleyes:
Wichtig ist wohl die richtige Kopplung an den Oszillator-Eingang des Atmels.

Gruß
Dino
 
Danke dino03 !!:pleasantry:

Habe jetzt erstmal 3 * Mega168 bestellt werde mal versuchen was möglich ist
mit ein wenig Mhz mehr.Kann den mir mal jemand auf die schnelle Erklären
wo der Unterschied zwischen einem Interupt und einem PinChangeInterrupt
ist ??:stupido3: ?????
Kann in meinen Büchern so auf die schnelle keine Info darüber finden :confused: .

Habe hier auch noch einige Mega164P-15AZ liegen die haben Einige Interups
mehr unteranderem auch PinChangeInterrupts.
Ich weiss nur nicht ob sich die Bezeichnung (15AZ) auf 15Mhz bezieht bzw. wie hoch ich den Takten könnte ???
Ich habe noch keinen ATMEGA gesehen der mit 15Mhz laufen soll, kann aber auch eine andere Bedeutung haben :stupido3: ???
Mit dem Anschluss eines Quarzoszillator solte das doch keine Probleme geben wenn die Fuses richtig siend.
 

Anhänge

  • ATMEGA164-Testbord.jpg
    ATMEGA164-Testbord.jpg
    63,5 KB · Aufrufe: 4

Ü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)