Forum: Mikrocontroller und Digitale Elektronik 3 Servos über ein INT Port abfragen?


von Stefan B. (blueberlin)


Lesenswert?

Hallo,

ich habe ein kleines Programm mit hilfe dieses Forums Geschrieben. Mit 
diesen Code ist es möglich die Position eines Servos abzufragen. Das 
klappt auch, aber ich muss leider die Position von 3 Servos und nicht 
nur von einen abfragen, nur habe ich keine Idee wie ich das anstellen 
könnte.

1) Versuch
Alle Drei Servo Leitungen an den INT0 Port anschließen ( es war kein 
Sinvolles Signal auszumachen )

2) Idee
Jeden Servo an einen extra INT Port, Problem dabei ist das man dann auch 
3 Timer benötigen würde, ich brauche die anderen beiden aber leider für 
den restlichen Programmablauf und kann sie deswegen nicht dafür 
benutzen.

Aktuell würde ich das ganze nur Lösen indem ich 3 Atmegas benutze, das 
ist aber leider sehr unwirtschaftlich und benötigt leider auch zuviel 
Platz :(

habt ihr vielleicht noch eine idee?

1
'Konfiguration für Atmega8 mit 1 Mhz
2
$regfile "m8def.dat"
3
$crystal = 1000000
4
5
'Konfiguration für Das Empfangen des Servo Signal's, Angeschlossen an Port D2 abgefragt mit Timer1
6
Config Portd.2 = Input
7
Config Timer1 = Timer , Prescale = 1
8
Config Int0 = Change
9
Dim Reading As Bit
10
Dim Servogeschw As Word
11
Dim Error As Bit
12
On Int0 Rc_read
13
On Timer1 Rc_error
14
Enable Timer1
15
Stop Timer1
16
Enable Int0
17
Enable Interrupts
18
19
Do
20
21
If Reading = 0 Then
22
Print "Servo: " ; Servogeschw
23
End If
24
25
Loop
26
27
28
29
30
Rc_read:
31
If Reading = 0 Then
32
Start Timer1
33
Reading = 1
34
Else
35
Stop Timer1
36
Servogeschw = Timer1
37
Timer1 = 0
38
Reading = 0
39
End If
40
Error = 0
41
Return
42
Rc_error:
43
Error = 1
44
Reading = 0
45
Stop Timer1
46
Servogeschw = 6300
47
Return

von Karl H. (kbuchegg)


Lesenswert?

Die 3. Möglichkeit wäre das Messprinzip umzustellen. Zb sagt kein 
Mensch, dass man den einzigen Timer immer wieder starten und stoppen 
muss.

Du kannst ja auch mit einer normalen Uhr mit Sekundenzeiger bei der 
Leichtathletik-WM mitstoppen, wenn du keine Stoppuhr hast.
Einfach die Startzeit von der Endzeit abziehen und du weißt, wie lange 
der Läufer gelaufen ist.
Mit einer Stoppuhr gehts natürlich einfacher, weil dann am Display 
direkt die Laufzeit in Sekunden steht, aber so eine Subtraktion ist für 
einen Computer nun wirklich nicht das große Problem.

von Volkmar D. (volkmar)


Lesenswert?

Stefan B. schrieb:
> 1) Versuch
> Alle Drei Servo Leitungen an den INT0 Port anschließen ( es war kein
> Sinvolles Signal auszumachen )

Das kann nicht funktionieren, da Du hier alle Signale kurzschließt.

Stefan B. schrieb:
> 2) Idee
> Jeden Servo an einen INT Port, Problem dabei ist das man dann auch 3
> Timer benötigen würde,

Nein, es geht auch mit einem Timer. Diesen Timer startest Du im 
Hauptprogramm und läßt ihn immer durchlaufen. In den 3 getrennten 
Interrupt-Routinen liest Du den Wert des Timers aus und speicherst diese 
Werte ab (jeweils bei positiver und negativer Flanke). Anschließend 
kannst Du durch Differenzbildung die Stellung für jedes Servo unabhängig 
berechnen.

von Stefan B. (blueberlin)


Lesenswert?

auf die idee bin ich noch garnicht gekommen ;)

jetzt sehe ich aber das es ein weiteres problem gibt^^

der atmega8 hat nur zwei int ports :(

ein größeren chip kann ich leider nicht nehmen, habt ihr dafür 
vielleicht auch noch ne idee?

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> auf die idee bin ich noch garnicht gekommen ;)
>
> jetzt sehe ich aber das es ein weiteres problem gibt^^
>
> der atmega8 hat nur zwei int ports :(

keine Interrupts verwenden.
Servosignale bewegen sich im Bereich 1 bis 2 Millisekunden.
Dein Mega wird mindestens um einen Faktor 1000 schneller betrieben. Da 
braucht man keine Interrupts. Wenn man mit einem anderen Timer einfach 
alle paar µS am Port nachsieht ob die Flanke da war, dann ist das 
ausreichend genau.

von Oli (Gast)


Lesenswert?

Zu dem Interruptproblem ganz allgemein: du kannt per OR/AND alle 
interruptbenötigenden Signale an ein Interrupt legen und parallel jedes 
Signal an einen IO Port und dann in deiner Interruptroutine 
herausfinden, welches Signal denn nun gefeuert hat.
Ist natürlich mit Fehlern behaftet aber machbar.

von Stefan B. (blueberlin)


Lesenswert?

danke für eure schnellen antworten und vor allem die guten ideen ;)

werde mal sehen wie weit ich komme ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.