plastikboot
08.06.2013, 13:04
Hallo AVRler,
ich habe ein mittlerweile sehr nerviges Problem und komme nicht weiter: ich will mittels zweier Hallsensoren TLE4905L (Unipolar) eine Seilrolle abfragen nach Richtung und Länge, d.h. über die Rolle läuft ein Kabel und ich will immer sehen wieviel Kabel ist gerade draußen.
Die Schaltung an sich funktioniert sehr gut - die Hallsensoren sind nach Datenblatt mit Widerständen und Kondensatoren abgefedert und das Oszi, sowie die angeschlossenen LEDs zeigen mir sauber an, wie die Zustände wechseln. Mit dem angehängten Code soll nun bei jedem CHANGE je ein Interrupt für den einen Sensor und ein Interrupt für den anderen Sensor ausgelöst werden. Damit kann ich dann die Richtung und die Länge bestimmen - der Magnet spricht zuerst den ersten, dann beide und zum Schluss des Durchgangs nur den zweiten an. Die LEDs zeigen das auch. Ein Durchgang wäre also 00 - 10 - 11 - 01 - 00 - in die andere Richtung dann eben umgekehrt.
Das Problem ist nun, das das mit den Interrupts schon klappt, aber leider in keiner Weise kalkulierbar - einmal löst er zweimal aus, dann wieder nur einmal, dann nur steigend und nicht fallend. Beim Durchmessen mittels Oszi siehen die Signaleingänge aber perfekt aus - beide Hallsensoren wechseln brav von 0 auf 4,94V und wieder zurück.
Die beiden Printbefehle machen den Interrupt natürlich langsamer (sind auch nur fürs debugging drin). Ich kann auch ganz langsam drehen und es klappt irgendwie nicht. Ich habe auch schon mal die typischen Changeinterrupts PCINT ausprobiert - gleiches Phänomen.
Ich habe auch schon überlegt das ganze über Timer zu machen und einfach den Zustand der beiden Sensoren abzufragen. Die Trommel sollte nachher jedoch auch noch per PWM angesteuert werden und mit einem Display über RS485 kommunizieren - irgendwie wären mir die Interrupts aber lieber, da so weit weniger Last anfällt - die Rolle dreht mit maximal 180 Umdrehungen pro Minute.
Hoffe jemand kann helfen. Der Code ist auch als Datei angehängt.
Gruss
Plastikboot
CODE:
'################################################# ##
'Modul Drehgeber Starfishsidescanwinde
'mit Modul RN-Mega2560
'für
'RoboterNetz Board RN-Mega2560 ab Version 1.0
'
'################################################# #############
'###################### Standards ##############################################
'Diese Anweisung setzt die Fusebits automatisch korrekt für Atmega 2560
' Syntax $PROG LB, FB , FBH , FBX
$prog , 255 , &B11011001 , 'Quarz an / Teiler aus / Jtag aus
$regfile = "m2560def.dat" 'Atmega 2560 einstellen
$loadersize = 512
$hwstack = 128
$framesize = 128
$swstack = 128
$crystal = 16000000 'Quarzfrequenz
$baud = 57600
Config Single = Scientific , Digits = 2
'######################ENDE STANDARDS ##########################################
'-------------------------------------------------------------------------------
'###################### Variablendefinitionen ##################################
Dim Zustandhallsensor1 As Bit ' Erfasst den Zustand 0/1 des Hallsensors1
Dim Zustandhallsensor2 As Bit ' Erfasst den Zustand 0/1 des Hallsensors2
Dim Hallsensordurchlauf As String * 2 ' Gibt Auskunft über den aktuellen Stand der Hallsensoren
'Diese Variablen dienen zur Erkennung eines vollen Durchlaufs
Dim Durchgang1 As Bit ' Wenn Hallsensor 1 auslöst, wird hier vermerkt mit 1
Dim Durchgang2 As Bit ' Wenn Hallsensor 2 auslöst, wird hier vermerkt mit 1
Dim Umdrehungen As Integer ' Anzahl der Drehungen (geteilt durch 3 sind die Volldrehungen)
Dim Umlenkrollenumfang As Word ' Rollenumfang in mm!
Dim Kabelmeter As Single ' Ausgegebene Kabelmeter gerundet
'##################### ENDE Variabelndefinitionen ##############################
'-------------------------------------------------------------------------------
'###################### DEBUG-Variablen ########################################
Dim Vorher As Integer ' Um RS232 im Debug zu entlasten
Vorher = 0
'##################### ENDE DEBUGVariablen####### ##############################
'-------------------------------------------------------------------------------
'##################### DEBUGGING einschalten ###################################
' dieser Bereich kann bei funktionierendem Programm auskommentiert werden
' nicht löschen, dann man weiß ja nie
'Debuggervariablen
Dim Hallsensor1interrupts As Word
Dim Hallsensor2interrupts As Word
' LED auf Platine definieren
Config Pind.5 = Output ' Schaltet die LED auf der Atmega Platine ein!
Led Alias Portd.5 ' Gibt dem Port D5 den Aliasnamen LED
' Die LED kann mit Led = 1 eingeschaltet werden und mit Led = 0 aus
'USB anschluss auf Platine als COM4 definieren für DEBUGGING
Config Com4 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Open "com4:" For Binary As #4 'USB Buchse
'##################### ENDE DEBUGGING einschalten ##############################
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'##################### CONFIG Interrupts für Hallsensoren ######################
Hallsensor1 Alias Porte.4 ' Hallsensor 1 definieren an PortE4 JP1Pin6 Int4
Config Hallsensor1 = Input
On Int4 Hallsensor1change ' Bei Change auf Routine Hallsensor1change springen
Hallsensor1 = 1
Config Int4 = Change ' Change um beide Flanken zu erkennen!!!!
Enable Int4
Hallsensor2 Alias Porte.6 ' Hallsensor 2 definieren an PortE6 JP1Pin8 Int6
Config Hallsensor2 = Input ' Bei Change auf Routine Hallsensor1change springen
On Int6 Hallsensor2change
Hallsensor2 = 1
Config Int6 = Change
Enable Int6
'Interrupts einschalten
Enable Interrupts
'##################### ENDE Config Interrupts für Hallsensoren #################
'-------------------------------------------------------------------------------
'##################### Preprogramm Parameter einstellen ########################
Print #4 , "Programmstart"
Print #4 , ""
Print #4 , ""
Gosub Checkhallsensorstate
Umdrehungen = 0 ' Anzahl der Umdrehungen auf 0 setzen
Umlenkrollenumfang = 546 'ACHTUNG WERT in mm ohne Komma
'##################### ENDE Preprogramm Parameter einstellen ###################
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'##################### PROGRAMMSTART ###########################################
Do
If Umdrehungen <> Vorher Then
Kabelmeter = Umlenkrollenumfang * Umdrehungen
Kabelmeter = Kabelmeter / 1000
Vorher = Umdrehungen
End If
Loop
End
'#################### PROGRAMMENDE #############################################
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'#################### Hallsensoren Interruptbehandlung #########################
Hallsensor1change: ' Hallsensor 1 Auswertung
Select Case Hallsensordurchlauf
'Drehung nach rechts anfang
Case "00" :
Hallsensordurchlauf = "10"
Durchgang1 = 1
'Drehung nach links
Case "10" :
Hallsensordurchlauf = "00"
Durchgang1 = 0
If Durchgang2 = 1 Then
Umdrehungen = Umdrehungen - 1
Durchgang2 = 0
End If
'Drehung über die Mitte hinaus
Case "11" :
Hallsensordurchlauf = "01"
'Drehung auf Mitte
Case "01" :
Hallsensordurchlauf = "11"
End Select
Print #4 , "1 - " ; Pine.4 ; " " ; Pine.6 ; " " ; Hallsensordurchlauf
Return
Hallsensor2change: ' Hallsensor 2 Auswertung
Select Case Hallsensordurchlauf
'Drehung nach links anfang
Case "00" :
Hallsensordurchlauf = "01"
Durchgang2 = 1
'Drehung nach rechts
Case "01" :
Hallsensordurchlauf = "00"
Durchgang2 = 0
If Durchgang1 = 1 Then
Umdrehungen = Umdrehungen + 1
Durchgang1 = 0
End If
'Drehung über die Mitte hinaus
Case "11" :
Hallsensordurchlauf = "10"
'Drehung auf Mitte
Case "10" :
Hallsensordurchlauf = "11"
End Select
Print #4 , "2 - " ; Pine.4 ; " " ; Pine.6 ; " " ; Hallsensordurchlauf
Return
'################################################# ##############################
'Checkhallsensorstate um Ungenauigkeiten wieder auszubügeln
'################################################# ##############################
Checkhallsensorstate:
' Abfrage des aktuellen Zustandes der Hallsensoren
' und setzen der Hallsensordurchlauf Variable auf den aktuellen Zustand
Zustandhallsensor1 = Pine.4
Zustandhallsensor2 = Pine.6
Print #4 , Pine.4 ; " " ; Pine.6
Print #4 , ""
If Zustandhallsensor1 = 1 And Zustandhallsensor1 = 1 Then
Hallsensordurchlauf = "00"
End If
If Zustandhallsensor1 = 0 And Zustandhallsensor2 = 1 Then
Hallsensordurchlauf = "10"
End If
If Zustandhallsensor1 = 1 And Zustandhallsensor2 = 0 Then
Hallsensordurchlauf = "01"
End If
If Zustandhallsensor1 = 0 And Zustandhallsensor2 = 0 Then
Hallsensordurchlauf = "11"
End If
Return
ich habe ein mittlerweile sehr nerviges Problem und komme nicht weiter: ich will mittels zweier Hallsensoren TLE4905L (Unipolar) eine Seilrolle abfragen nach Richtung und Länge, d.h. über die Rolle läuft ein Kabel und ich will immer sehen wieviel Kabel ist gerade draußen.
Die Schaltung an sich funktioniert sehr gut - die Hallsensoren sind nach Datenblatt mit Widerständen und Kondensatoren abgefedert und das Oszi, sowie die angeschlossenen LEDs zeigen mir sauber an, wie die Zustände wechseln. Mit dem angehängten Code soll nun bei jedem CHANGE je ein Interrupt für den einen Sensor und ein Interrupt für den anderen Sensor ausgelöst werden. Damit kann ich dann die Richtung und die Länge bestimmen - der Magnet spricht zuerst den ersten, dann beide und zum Schluss des Durchgangs nur den zweiten an. Die LEDs zeigen das auch. Ein Durchgang wäre also 00 - 10 - 11 - 01 - 00 - in die andere Richtung dann eben umgekehrt.
Das Problem ist nun, das das mit den Interrupts schon klappt, aber leider in keiner Weise kalkulierbar - einmal löst er zweimal aus, dann wieder nur einmal, dann nur steigend und nicht fallend. Beim Durchmessen mittels Oszi siehen die Signaleingänge aber perfekt aus - beide Hallsensoren wechseln brav von 0 auf 4,94V und wieder zurück.
Die beiden Printbefehle machen den Interrupt natürlich langsamer (sind auch nur fürs debugging drin). Ich kann auch ganz langsam drehen und es klappt irgendwie nicht. Ich habe auch schon mal die typischen Changeinterrupts PCINT ausprobiert - gleiches Phänomen.
Ich habe auch schon überlegt das ganze über Timer zu machen und einfach den Zustand der beiden Sensoren abzufragen. Die Trommel sollte nachher jedoch auch noch per PWM angesteuert werden und mit einem Display über RS485 kommunizieren - irgendwie wären mir die Interrupts aber lieber, da so weit weniger Last anfällt - die Rolle dreht mit maximal 180 Umdrehungen pro Minute.
Hoffe jemand kann helfen. Der Code ist auch als Datei angehängt.
Gruss
Plastikboot
CODE:
'################################################# ##
'Modul Drehgeber Starfishsidescanwinde
'mit Modul RN-Mega2560
'für
'RoboterNetz Board RN-Mega2560 ab Version 1.0
'
'################################################# #############
'###################### Standards ##############################################
'Diese Anweisung setzt die Fusebits automatisch korrekt für Atmega 2560
' Syntax $PROG LB, FB , FBH , FBX
$prog , 255 , &B11011001 , 'Quarz an / Teiler aus / Jtag aus
$regfile = "m2560def.dat" 'Atmega 2560 einstellen
$loadersize = 512
$hwstack = 128
$framesize = 128
$swstack = 128
$crystal = 16000000 'Quarzfrequenz
$baud = 57600
Config Single = Scientific , Digits = 2
'######################ENDE STANDARDS ##########################################
'-------------------------------------------------------------------------------
'###################### Variablendefinitionen ##################################
Dim Zustandhallsensor1 As Bit ' Erfasst den Zustand 0/1 des Hallsensors1
Dim Zustandhallsensor2 As Bit ' Erfasst den Zustand 0/1 des Hallsensors2
Dim Hallsensordurchlauf As String * 2 ' Gibt Auskunft über den aktuellen Stand der Hallsensoren
'Diese Variablen dienen zur Erkennung eines vollen Durchlaufs
Dim Durchgang1 As Bit ' Wenn Hallsensor 1 auslöst, wird hier vermerkt mit 1
Dim Durchgang2 As Bit ' Wenn Hallsensor 2 auslöst, wird hier vermerkt mit 1
Dim Umdrehungen As Integer ' Anzahl der Drehungen (geteilt durch 3 sind die Volldrehungen)
Dim Umlenkrollenumfang As Word ' Rollenumfang in mm!
Dim Kabelmeter As Single ' Ausgegebene Kabelmeter gerundet
'##################### ENDE Variabelndefinitionen ##############################
'-------------------------------------------------------------------------------
'###################### DEBUG-Variablen ########################################
Dim Vorher As Integer ' Um RS232 im Debug zu entlasten
Vorher = 0
'##################### ENDE DEBUGVariablen####### ##############################
'-------------------------------------------------------------------------------
'##################### DEBUGGING einschalten ###################################
' dieser Bereich kann bei funktionierendem Programm auskommentiert werden
' nicht löschen, dann man weiß ja nie
'Debuggervariablen
Dim Hallsensor1interrupts As Word
Dim Hallsensor2interrupts As Word
' LED auf Platine definieren
Config Pind.5 = Output ' Schaltet die LED auf der Atmega Platine ein!
Led Alias Portd.5 ' Gibt dem Port D5 den Aliasnamen LED
' Die LED kann mit Led = 1 eingeschaltet werden und mit Led = 0 aus
'USB anschluss auf Platine als COM4 definieren für DEBUGGING
Config Com4 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Open "com4:" For Binary As #4 'USB Buchse
'##################### ENDE DEBUGGING einschalten ##############################
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'##################### CONFIG Interrupts für Hallsensoren ######################
Hallsensor1 Alias Porte.4 ' Hallsensor 1 definieren an PortE4 JP1Pin6 Int4
Config Hallsensor1 = Input
On Int4 Hallsensor1change ' Bei Change auf Routine Hallsensor1change springen
Hallsensor1 = 1
Config Int4 = Change ' Change um beide Flanken zu erkennen!!!!
Enable Int4
Hallsensor2 Alias Porte.6 ' Hallsensor 2 definieren an PortE6 JP1Pin8 Int6
Config Hallsensor2 = Input ' Bei Change auf Routine Hallsensor1change springen
On Int6 Hallsensor2change
Hallsensor2 = 1
Config Int6 = Change
Enable Int6
'Interrupts einschalten
Enable Interrupts
'##################### ENDE Config Interrupts für Hallsensoren #################
'-------------------------------------------------------------------------------
'##################### Preprogramm Parameter einstellen ########################
Print #4 , "Programmstart"
Print #4 , ""
Print #4 , ""
Gosub Checkhallsensorstate
Umdrehungen = 0 ' Anzahl der Umdrehungen auf 0 setzen
Umlenkrollenumfang = 546 'ACHTUNG WERT in mm ohne Komma
'##################### ENDE Preprogramm Parameter einstellen ###################
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'##################### PROGRAMMSTART ###########################################
Do
If Umdrehungen <> Vorher Then
Kabelmeter = Umlenkrollenumfang * Umdrehungen
Kabelmeter = Kabelmeter / 1000
Vorher = Umdrehungen
End If
Loop
End
'#################### PROGRAMMENDE #############################################
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'#################### Hallsensoren Interruptbehandlung #########################
Hallsensor1change: ' Hallsensor 1 Auswertung
Select Case Hallsensordurchlauf
'Drehung nach rechts anfang
Case "00" :
Hallsensordurchlauf = "10"
Durchgang1 = 1
'Drehung nach links
Case "10" :
Hallsensordurchlauf = "00"
Durchgang1 = 0
If Durchgang2 = 1 Then
Umdrehungen = Umdrehungen - 1
Durchgang2 = 0
End If
'Drehung über die Mitte hinaus
Case "11" :
Hallsensordurchlauf = "01"
'Drehung auf Mitte
Case "01" :
Hallsensordurchlauf = "11"
End Select
Print #4 , "1 - " ; Pine.4 ; " " ; Pine.6 ; " " ; Hallsensordurchlauf
Return
Hallsensor2change: ' Hallsensor 2 Auswertung
Select Case Hallsensordurchlauf
'Drehung nach links anfang
Case "00" :
Hallsensordurchlauf = "01"
Durchgang2 = 1
'Drehung nach rechts
Case "01" :
Hallsensordurchlauf = "00"
Durchgang2 = 0
If Durchgang1 = 1 Then
Umdrehungen = Umdrehungen + 1
Durchgang1 = 0
End If
'Drehung über die Mitte hinaus
Case "11" :
Hallsensordurchlauf = "10"
'Drehung auf Mitte
Case "10" :
Hallsensordurchlauf = "11"
End Select
Print #4 , "2 - " ; Pine.4 ; " " ; Pine.6 ; " " ; Hallsensordurchlauf
Return
'################################################# ##############################
'Checkhallsensorstate um Ungenauigkeiten wieder auszubügeln
'################################################# ##############################
Checkhallsensorstate:
' Abfrage des aktuellen Zustandes der Hallsensoren
' und setzen der Hallsensordurchlauf Variable auf den aktuellen Zustand
Zustandhallsensor1 = Pine.4
Zustandhallsensor2 = Pine.6
Print #4 , Pine.4 ; " " ; Pine.6
Print #4 , ""
If Zustandhallsensor1 = 1 And Zustandhallsensor1 = 1 Then
Hallsensordurchlauf = "00"
End If
If Zustandhallsensor1 = 0 And Zustandhallsensor2 = 1 Then
Hallsensordurchlauf = "10"
End If
If Zustandhallsensor1 = 1 And Zustandhallsensor2 = 0 Then
Hallsensordurchlauf = "01"
End If
If Zustandhallsensor1 = 0 And Zustandhallsensor2 = 0 Then
Hallsensordurchlauf = "11"
End If
Return