3 Servos über ein INT Port abfragen?

OP #2450429
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
#2450436
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.
#2450438
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.
#2450446
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.
Gast #2450452
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren