Forum: Mikrocontroller und Digitale Elektronik Servoausgänge verUNDen


von Axel R. (Gast)


Lesenswert?

Hallo zusammen,
habe meinen alten Robbe Rodeo 6X6 wieder ausgekramt und ihm einen 
Fahrregler(besser: Steller) im Eigenbau verpasst.
Basierend auf einem Mega48, Fets für die beiden Brücken usw. Wie man 
eben so ein Ding baut. Sind 2Motore zu steuern.
Die PPM Erkennung und die Kanaltrennung laufen im ICP-Interrupt. Alles 
kein Problem. funktioniert soweit auf dem Basteltisch.

Das einzige was nicht geht:

ich bekomme die beiden Servokanäle aus meinem Empfänger nicht über ein 
Kabel auf den ICP-Eingang geschaltet.
Beim Empf. handelt es sich um einen Futaba FP-R112JE AM40. War damals 
mit dabei. Die beiden Servokanäle liegen einzeln an den Ausgängen vor, 
klar. Wenn ich beide Ausgänge über Dioden zusammenschalte, habe ich 
keine zwei Kanäle mit einer kleinen Pause dazwischen, sondern einen 
"langen" High-Impuls, welcher sich über beide Kanalzeiten erstreckt.

Ich habe jetzt hier eigentlich deswegen keinen Thread aufmachen wollen, 
da ich die SuFu benutzt habe und folgende Aussage vom Peter gefunden 
hatte:
Beitrag "Re: 6 PWM eingänge, wie?"

daraus:
[Quote]
Die Impulse werden ja alle hintereinander übertragen, also solltest Du
sie einfach über eine UND-Schaltung (Dioden) wieder zusammenführen
können.
[/Quote]

kann man also bei DEM Empfänger vergessen.

Was kann ich tun?
Wenn jemand schon mal in dieser Klemme steckte, kann er ja mal verraten, 
was er getan hat.
Ich suche unabhängig nach einer Lösung und melde mich bei Gelegenheit.
Evtl. interessiert es ja jemanden ;-)))


Viele Grüße
AxelR.

von Rahul D. (rahul)


Lesenswert?

Pinchange-Interrupt...
Oder den Empfänger "aufbasteln" und den ICP-Eingang direkt an den 
Ausgang des Modulators (oder wie sich das Ding schimpft, das vor dem 
Kanaldecoder sitzt) anschliessen; da kommt nämlich das komplette 
Telegramm "vorbei".

von Axel R. (Gast)


Lesenswert?

PinChangeInt. liefert die Summe beider Kanäle, da die Pause zwischen 
beiden nicht zu erkennen ist...
bin jetzt mit 47K vom PIN15 des verbauten FP8196R abgegangen. Dort liegt 
das Impulstelegramm an.
Die Signalamplitude beträgt hier 1.2V. von da auf einen NPN und mit 1K 
vom Kollektor auf die 3.3V vom AVR. Am Kollektor kann ich jetzt das 
Summensignal      auf den ICP-Pin geben.

Muss ich allerdings meine Auswerteroutine umändern und nur die 
steigenden Flanken zählen.

Jetzt nehme ich ja die steigende und die fallende Flanke und bilde die 
Diiferenz.

AxelR.

von Axel R. (Gast)


Lesenswert?

sieht übrigens iM noch so aus:
1
SIGNAL(SIG_INPUT_CAPTURE1)
2
{
3
#define ICP_POS_FLANKE    TCCR1B |= (1<<ICES1) // aus Main.h der Uebersicht
4
#define ICP_NEG_FLANKE    TCCR1B &= ~(1<<ICES1) // wegen herkopiert
5
 static unsigned int tim_low;
6
 static unsigned int ppm;
7
  if(TCCR1B & (1<<ICES1))   // Positive Flanke
8
    {
9
    Timer1Overflow = 0;    // Timerüberlauf löschen
10
    tim_low = ICR1;       // Zaehlerstand einlesen
11
    if(tim_low > 5000) kanal=0; else kanal=1; //lange Pause?
12
    ICP_NEG_FLANKE;
13
    }
14
  else                      // Negative Flanke
15
    {
16
    ICP_POS_FLANKE;    // schonmal wieder auf positive Flanke stellen
17
    ppm = (ICR1 - tim_low) / 4;
18
    TCNT1 = 0;      // Timer1 auf NULL
19
  
20
      if( ppm>280 && ppm < 510) {
21
        PPM_Signal[kanal] = ppm;
22
        if(kanal) PPM_ok = 1; // wenn beide Kanaele fertig sind, der 
23
      }              // Mainloop bescheid geben
24
  } 
25
}
26
27
SIGNAL(SIG_OVERFLOW1)
28
29
{
30
 Timer1Overflow++; // wenn kein PPM-Signal kommt, gibt es einen Fehler,
31
          // der in der Mainloop abgefangen wird
32
          // if(Timer1Overflow>2) motor_aus(); usw.
33
};

mal sehn, was ich daraus mache, um mich an die neue Situation anzupassen 
- bin ja nicht soo der C-Kenner :-( fehlt mir etwas die Erfahrung...

AxeR.

von Axel R. (Gast)


Lesenswert?

so sollte es gehen ;-))
1
SIGNAL(SIG_INPUT_CAPTURE1)
2
{
3
 static unsigned int tim_icp[3],ICP_mirror;
4
 static unsigned char icp_flanke;
5
6
    Timer1Overflow = 0;    // Timerüberlauf löschen
7
    ICP_mirror = ICR1;       // Zaehlerstand einlesen
8
    if(ICP_mirror > 5000) icp_flanke = 1; //lange Pause?
9
    
10
      switch (icp_flanke)
11
        {
12
        case (1):
13
          tim_icp[0] = ICP_mirror;
14
          icp_flanke = 2;
15
          break;
16
      
17
        case (2):
18
          tim_icp[1] = ICP_mirror;
19
          PPM_Signal[0] = (tim_icp[1]-tim_icp[0]) / 4;
20
          icp_flanke = 3;
21
          break;
22
      
23
        case (3):
24
          tim_icp[2] = ICP_mirror;
25
          PPM_Signal[1] = (tim_icp[2]-tim_icp[1]) / 4;
26
          PPM_ok = 1;
27
          TCNT1 = 0;
28
          tim_icp[0]=tim_icp[1]=tim_icp[2] = 0;
29
          break;
30
      
31
        default:
32
          icp_flanke = 1;
33
          break;
34
        }
35
}

bin ich ja mal gespannt...

AxelR.

von Hannes L. (hannes)


Lesenswert?

Axel, wenn die Signalamplitude des Telegramms nur 1,2V hat, dann kannst 
Du sie direkt auf den Analog-Comparator legen und mittels 
Spannungsteiler (oder Diode und internem PullUp) die Referenz von 0,6V 
erzeugen. Der Analog-Comparator kann auch den ICP triggern. War 
zumindest bei den älteren AVRs so, müsste der Mega48 auch können.

Ansonsten ist PCI schon richtig, beide Kanalimpulse an zwei Pins eines 
Ports, nur die benutzten Bits maskieren (PCI-Maske), jeder Pegelwechsel 
an einem der Pins löst den PCI aus. Bitmuster einlesen, um zu erkennen 
in welcher Phase man sich befindet, und dann Differenz zum letzten Int 
bilden und verarbeiten.

Da Du in C werkelst halte ich mich mit Code zurück.

'73

...

von Axel R. (Gast)


Lesenswert?

fertig! so gehts prima
1
SIGNAL(SIG_INPUT_CAPTURE1)
2
{
3
#define ICP_POS_FLANKE    TCCR1B |= (1<<ICES1) // aus Main.h der Uebersicht
4
#define ICP_NEG_FLANKE    TCCR1B &= ~(1<<ICES1)// wegen herkopiert
5
6
 static unsigned int tim_2;
7
 static unsigned char icp_flanke;
8
9
    Timer1Overflow = 0;    // Timerüberlauf löschen
10
    if(ICR1 > 5000) icp_flanke = 1; //lange Pause?
11
    
12
      switch (icp_flanke)
13
        {
14
        case (1):
15
        PPM_Signal[2] = ICR1;
16
        TCNT1 = 1;
17
        icp_flanke = 2;
18
          break;
19
      
20
        case (2):
21
        tim_2 = ICR1;
22
        PPM_Signal[0] = ICR1 / 4;
23
        icp_flanke = 3;
24
        break;
25
      
26
        case (3):
27
          PPM_Signal[1] = (ICR1-tim_2) / 4;
28
          PPM_ok = 1;
29
          break;
30
      
31
        default:
32
          icp_flanke = 1;
33
          break;
34
        }
35
}

PPM_Signal[2] verwende ich nur zum debuggen. Hier wird in der 
Hauptschleife die Gesamtdauer des Paketes augegeben.

Zur Hardware:
Ich hatte noch einen BC817 da. Den habe ich im Empfänger auf ein 
unbenutztes Pad nahe am Ausgang KANAL2 gelötet und einen 56Kohm an den 
Basisanschluss angelötet . Einen CuL-Draht zum PIN15. Den Leiterzug von 
KANAL2 habe ich entsprechend aufgetrennt und den Kollektor dorthin 
verdrahtet (Emitter an Masse - hat gut gepasst, war gleich daneben).

Funktioniert sehr gut. freu

Gruß
AxelR.

von Axel R. (Gast)


Lesenswert?

Hannes Lux wrote:
> Axel, wenn die Signalamplitude des Telegramms nur 1,2V hat, dann kannst
> Du sie direkt auf den Analog-Comparator legen und mittels
> Spannungsteiler (oder Diode und internem PullUp) die Referenz von 0,6V
> erzeugen. Der Analog-Comparator kann auch den ICP triggern. War
> zumindest bei den älteren AVRs so, müsste der Mega48 auch können.
>
> Ansonsten ist PCI schon richtig, beide Kanalimpulse an zwei Pins eines
> Ports, nur die benutzten Bits maskieren (PCI-Maske), jeder Pegelwechsel
> an einem der Pins löst den PCI aus. Bitmuster einlesen, um zu erkennen
> in welcher Phase man sich befindet, und dann Differenz zum letzten Int
> bilden und verarbeiten.
>
> Da Du in C werkelst halte ich mich mit Code zurück.
>
> '73
>
> ...

Sorry Hannes, hatte deinen Post übersehen...
wo ich sooo stolz bin, das meine Routine nu läuft, habe ich ohne 
hinzusehen gepostet.

Jetzt kann ich mit dem - sagen wir - Einwurf "PinChangeInt" von rahul 
auch was anfangen.
Klar hätte man auf zwei PINs verteilen können. Hatte ich nicht in 
Verbindung gebracht.

Sorry rahul. Nächstes mal denke ich etwas länger nach.

Mit dem PCINT konnte ich schon erfolgreiche Tests starten. Das geht 
erstaunlicherweise sehr gut. Besonders vorteilhaft ist die Tatsache, das 
der Controller auch aus dem tiefsten Tiefschlaf geweckt werden kann.

Nun gut. Als alter Hardwarerer habe ich nun den Empfänger "aufgebastelt" 
die Sache so gelöst.
Jetzt muss ich nur noch einen IRF4905 irgentwo auftreiben. War zu 
geizig, bei Reichelt gleich 10x oder 20x zu kaufen. Nu ist einer kaputt. 
:-((
Wegen einem solch Teil bestell ich nicht bei Reichelt.

Gruß

AxelR.

von Hannes L. (hannes)


Lesenswert?

Axel, kein Problem, Hauptsache es funktioniert. Viele Wege führen nach 
Rom.

"Einwurf"... ;-)
Ja, das ist Rahuls Art. Ich find's gut so, ein kleiner Denkanstoß reicht 
meist völlig aus.

Mit dem IRF kann ich Dir nicht helfen, solche starken P-Kanal-FETs habe 
ich nicht vorrätig... ;-)

Gruß nach P.
Hannes

von Axel R. (Gast)


Lesenswert?

Hallo, ihr lieben...

Der Thread ist noch nicht so lang, als dass es sich lohnt, einen neuen 
aufzumachen
Folgendes Problem ist aufgetaucht:

Fährt das Modell aus dem Sendebereich heraus, so bleibt es stehen. Das 
habe ich über den Int1 Overflow gelöst, der ja sonst in der ICR 
zurückgesetzt wird. Bleiben die Impulse aus, läuft Timer1 über und der 
Motor/die Motoren werden abgeschaltet. Funktioniert also erstmal,

ABER:

Wenn der Sendebereich gerade noch nicht verlassen wurde, ist das 
Emfangssignal stark "verrauscht". Wie lege ich denn eine "Maske" über 
mein Impulsdiagramm, um eine Prüfung auf Plasibilität stattfinden zu 
lassen?

Oder anders gefragt, hat schon mal jemand versucht, so einen 
Summenimpuls softwaretechnisch zu "breinigen"?

Ich habe schon beim DCF77 Thread, der mir ja noch gut in Erinnerung ist, 
beim Korrelationsverfahren nachgeschlagen, aber soo viel Speicher habe 
ich ja nicht, um alle möglichen Knüppelstellungen der zwei Kanale als 
Muster zu hinterlegen.

Vielen Dank für hilfreiche Infos eurerseits.

AxelR.

von Klaus L. (kllei)


Lesenswert?

Hallo Axel,

nachdem Du mich aus diesem thread 
Beitrag "Servo Summensignal auswerten"
hergelockt hast ;-)

Prüfst Du die Impulse auf "zu kurze" Flanken?

Ich finde, das das einlesen von 2 Servosignalen mit 2 Interrupts 
einfacher geht und sicherer ist. (INT0=Sig1, INT1=Sig2) Bei meinem 
Kettenfahrtregler (auch 2 Motoren wie bei Dir) triggere ich den INT auf 
einen Flankenwechsel und messe die Zeit dazwischen. Du brauchst auch nur 
einen Timer, da die Signale ja nacheinander kommen.

War der impuls zu kurz oder zu lange-> Signal verwerfen, Fehlerzähler 
runterzählen.
Fehlerzähler auf 0 -> Motor Aus

Bei Reichweitenproblemen wirst Du i.d.R. sehr kurze Impulse haben, die 
Dir möglicherweise in der INT-Capture Routine "durchflutschen". Kann das 
sein?

My2Cent,
Klaus

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.