PWM-Signal auswerten

Hallo,
zuerst mal meine "Ausgangslage": Ich möchte für den Modellbau einen Multiswitch bauen, dh. über einen Proportional-kanal einer Funkfernsteuerung viele Schaltfunktionen (digitales An/Aus, zB. für Licht) schalten. Statt mit einem Potentiometer einen Servo anzusteuern untergliedere ich in der Fernsteuerung den Kanal per Widerstände und Schalter in viele kleine Abschnitte (zb. 16). Im Modell gibt der Empfänger ja ein PWM-Signal aus. Mittels des Arduinos möchte ich jetzt dieses PWM-Signal auswerten, um passend zum "Schalterzustand" in der Fernsteuerung im Modell eine Funktion zu schalten.
Meine Frage ist, wie mach ich das XD .
Also, meine bescheidenen Kenntnisse reichen bis jetzt soweit: Ich brauche eine if/while-Schaltung: Wenn das Eingangssignal so und so lang ist (woher weiß ich das?, ausprobieren, oder?) soll der Pin auf high geschaltet werden. Doch was muss ich da jetzt schreiben? Die meisten Tutorials hören schon eher auf, bzw. beschreiben ist nicht, da es ja eher ein Nischen-thema ist. Also, bitte köpft mich nicht gleich, ich bin totaler Anfänger :. und die SuFu hat auch nicht viel genützt.
Achja, ich benutze das "micro", aber ich glaube, das dürfte keine besonderen Auswirkungen haben

Nur dass ich richtig verstehe: Du willst je nach Schalterstellung EINE Funktion steuern? Das Signal ist übrigens kein PWM Signal, sonden PPP. Also Puls Position Pointer.

hi,

ich bin da kein spezialist, aber ich lese brav im forum mit. ist im modellbau nicht eher PPM, Puls-Pausen-Modulation verbreitet?

gruß stefan

Wir beide bekommen's hin. Richtig ist Puls Position Modulation. Jetzt passt's.

Hallo
die Signalleitung des Empfängerausgangs an einen beliebigen Pin.
a=pulseIn(5,HIGH,24000)
Die ehaltenen Wete in a liegen so bei 1000 bis 2000 als maxWerte.
Mit "case a" kannst Du jeden Zwischenwert auswerten.
Grüsse

Zu deiner Fragestellung: Ja, wenn ich den einen Schalter drücke/schließe, soll die eine Funktion angehen (zB. Licht), bei einem andern Schalter zB. der Blinker. Bei einem Funktionsmodell kommt man da halt auf einiges.

@Klaus und Eisbaer: Und nein, es handelt sich wirklich um ein PWM-Signal: Servo – Wikipedia

@swordfish: Danke. Nur verstehe ich hier halben Bahnhof. XD Ich bin mir nicht ganz über die Einbindung sicher.

@uwefed: Gut, das bringt mich jetzt schon ein bisschen weiter.

Ist der dritte Parameter der "Abstand" zwischen den einzelnen Impulsen? Aber was ist dann "a"?
Und "case a" versteh ich nicht.

Müsste ich das dann so einbauen:

if (pulseIn(5,HIGH,>1450 && Signal < 1550)
{
digitalWrite (13, High);
}

??? Irgendwas ist bestimmt falsch XD

PS: Während ich diesen Beitrag geschrieben habe, haben schon 3 wieder einen neuen verfasst :0 :slight_smile:

swordfish:
Hallo
die Signalleitung des Empfängerausgangs an einen beliebigen Pin.
Signal=pulseIn(Pin,HIGH,24000)
Die ehaltenen Wete in a liegen so bei 1000 bis 2000 als maxWerte.
Mit "case a" kannst Du jeden Zwischenwert auswerten.
Grüsse

Das Servosignal an eine Kanal des RC-Empfängers ist ein impuls von 1mS bis 2mS der alle 20mS (50Hz) wiederholt wird.
Du kannst die Dauer des Impulses messen und in bestimmten Intervallen etwas aktivieren, wobei Du 2 Werte brauchst, einmal zum einschalten und einmal zum ausschalten.

Das wie hat Dir swordfish schon oben gezeigt.

Ich würde das aber nicht mit switch case realisieren sondern mit if

if (Signal >1450 && Signal < 1550) {Tue etwas;}
ecc

Mit dem Spannungsteiler an der Fernsteuerung kannst Du nicht so genaue Werte eingeben daß Du

if (Signal == 1500) {Tue etwas;}

schreiben kannst.

Grüße Uwe

ps: PWM- und PPM-Signale sind in bestimmten Bereichen das gleiche Signal.
pps: Bluetruck : Nicht alles was Wikipedia scheibt ist richtig.

Ihr schreibt zu schnell und ich zu langsam :wink:

Nochmal das vom Editieren meines Vorhergehenden Beitrages:

Ist der dritte Parameter der "Abstand" zwischen den einzelnen Impulsen? Aber was ist dann "a"? Und "case a" versteh ich auch nicht.

Müsste ich das dann so einbauen:

if (pulseIn(5,HIGH,>1450 && Signal < 1550) 
{
digitalWrite (10, High);
}

??? Irgendwas ist bestimmt falsch

Achja, als "if" hatte ich es sowieso vor. Was ist "switch case" dann? Ich hab nur "Mehrfachabfrage usw." gefunden.

Nö,
ich probiere mal ausfühlicher.
pulseIn erwartet drei Parameter.
pulseIn(Pin an dem Dein Empfängersignal anliegt,HIGH ist der Wert auf den Pulse wartet,24000 ist das Timout bei unserem Problem exakt 20000. Ich gebe etwas Zeit zu.
a ist nur eine Variable zum Speichern.
In a befindet sich nun ein Zeitwert der exakt deiner Knüppelposition an Deiner fernsteuerung entspricht.
er liegt in einem Bereich von 1000=Knuppel minimum und 2000 Knüppel max.
a=pulseIn(5,HIGH,24000);
Serial.println(a);
Einfach auf dem seriellen Monitor ausprobieren.

Bluetruck:
Ihr schreibt zu schnell und ich zu langsam :wink:

Die Welt ist nunmal ungerecht. :wink: :wink: :wink:

Bluetruck:
Nochmal das vom Editieren meines Vorhergehenden Beitrages:

Ist der dritte Parameter der "Abstand" zwischen den einzelnen Impulsen? Aber was ist dann "a"? Und "case a" versteh ich auch nicht.

Der dritte Parameter ist der Timeaut. Es wird max 24000µS gewartet, ob ein Impuls kommt und dann auf alle Fälle zurüchgesprungen. Dies ist notwendig da pulseIn() den Arduino wie delay() blockiert und erst nach gemessener Impulszeit zurückspringt.

Bluetruck:
Müsste ich das dann so einbauen:

if (pulseIn(5,HIGH,>1450 && Signal < 1550) 

{
digitalWrite (10, High);
}



??? Irgendwas ist bestimmt falsch 

Achja, als "if" hatte ich es sowieso vor. Was ist "switch case" dann? Ich hab nur "Mehrfachabfrage usw." gefunden.

Nein. Bei if kannst Du nicht 2 Bedingungen auf die gleiche Variable anwenden.
Es fehlt auch eine Klammer.

also
if (a>5 &&<10) ist falsch
if (a>5 && a<10) ist richtig.

auf Arduino - Home findest Du Erklärungen bezüglich der Funktionen und Kontrollstrukturen.

Grüße Uwe

Danke euch!
auch für den Link :astonished:

Wäre das dann so richtig?

void setup ()
{
pinMode (2, OUTPUT);
pinMode (5, INPUT);
}

void loop ()
{
int a = pulseIn(5,HIGH,24000);
if (a>1450 && a<1500)
digitalWrite (2,HIGH);
}

ja prima.

Nee, stimmt eigentlich nicht. Ich muss die LED ja an- und ausschalten können.

So müsste das funktionieren:

int LED2 = 2;
void setup ()
{
pinMode (2, OUTPUT);
pinMode (5, INPUT);
ditigalWrite (2,LOW)
}

void loop ()
{
int a = pulseIn(5,HIGH,24000)
if (a>1450 && a<1500 && LED2=LOW)
digitalWrite (2,HIGH);
if (a>1450 && a<1500 && LED2=HIGH)
digitalWrite (2,LOW);
}

so funktioniert das nicht.
Dein Sketch schaltet das led ein und sofort wieder aus weil di 2. Bedingung sofort wahr ist.

void loop ()             //Wiederholt das Ein-Ausschalten solange das Signal anliegt
{
int a = pulseIn(5,HIGH,24000)
if (a>1450 && a<1500 && LED2=LOW)  // schaltet LED ein
digitalWrite (2,HIGH);
if (a>1450 && a<1500 && LED2=HIGH)  // schaltet LEd wieder aus
digitalWrite (2,LOW);
}

Um mit dem gleichen Signal das LED ein und dann wieder auszuschalten müßtest Du kontrollieren ob das signal entweder lange genug HIGH ist oder zuvor LOW wurde. Auf alle Fälle hast Du keine Kontrolle ob der Ausgang nun HIGH oder LOW ist. Wen Du 2 verschiedene Signale für ein- und ausschalten nimmst ist das eindeutig.

Grüß Uwe

Also das Board weiß nicht, ob der Ausgang LOW oder HIGH ist? Ansonsten würde ich dazwischen einfach delay(1000) schreiben, dann wärs kein Problem.

Nein, für ein und Ausschalten möchte ich in der Fernbedienung den gleichen Schalter/Taster verwenden.

Bluetruck:
Nein, für ein und Ausschalten möchte ich in der Fernbedienung den gleichen Schalter/Taster verwenden.

Du brauchst ja eine Logik zum Ein- und auch wieder ausschalten.

Mit Deiner Stückelung in 16 Bereiche kannst Du es beispielsweise so schalten, daß bei "null" alle Pins/Geräte ausgeschaltet werden, und bei jedem anderen Wert wird genau ein einzelner Pin mit einem Gerät aktiviert (und alle anderen sind aus). So daß immer nur "kein" oder "ein" Gerät eingeschaltet ist.

Ist das die Logik, die die vorschwebt?
Die ließe sich nämlich realisieren.

Wenn jedes Gerät unabhängig ein- und ausschaltbar sein soll, z.B. erstes Gerät ein, zweites Gerät aus, drittes Gerät ein, viertes Gerät aus, dann kannst Du mit Deinen 16 Zuständen nur viel weniger als 15 Geräte unabhängig schalten.

Also wie soll es sein:

  • Immer nur ein Gerät zur Zeit eingeschaltet?
    oder:
  • Jedes Gerät unabhängig ein- und ausschaltbar, auch mehrere zur selben Zeit ein?

Ist denn die Hardware im Sender vorhanden?
Am einfachsten wäre es mit 3Stufenschaltern und 2 oder 3 Kanälen zu bewerkstelligen.

Nein, dein Irrtum liegt in

LED2=LOW

Das prüft nicht, welchen Zustand deine LED hat, sondern setzt die Variable int LED2; auf den Wert 0.

Das stört zwar nicht, weil LED2 nicht weiter gebraucht wird, ist aber sicher nicht das was du willst.

Einen Irrtum hab ich behoben.

void setup ()
{
pinMode (2, OUTPUT);
pinMode (5, INPUT);
ditigalWrite (2,LOW)
}

void loop ()
{
int a = pulseIn(5,HIGH,24000);
int LED2v = digitalRead (2);
if (a>1450 && a<1500 && LED2v=LOW)
digitalWrite (2,HIGH)
delay(1000);
if (a>1450 && a<1500 && LED2v=HIGH)
digitalWrite (2,LOW)
delay(1000);
}

Hab gelesen, dass man über digitalRead auch den Ausgang messen kann Arduino Forum
Wenn also der Impuls stimmt, und die LED aus ist, wird sie angeschalten. Dann wird eine sec. gewartet: In dieser Zeit sollte ich meinen Finger wieder vom Taster nehmen. In der zweiten Gleichung stimmt dann zwar, dass die LED an ist, aber nicht mehr der Impuls.
Mal schaun, wo der Fehler liegt, dass was so schnell funktioniert ist ja eher unwarscheinlich XD

Zu euren Fragen: Ich möchte einen Multiswitch bauen. Für die, die sich im Modellbau jetzt nicht so weit auskennen: Einen "Proportionalkanal", der mittels PWM übertragen wird, aufsplitten auf mehrere "An/Aus-Kanäle". In der Fernsteuerung wird die Stellung des Kreuzknüppels als erstes über ein Poti (veränderbarer Widerstand) erfasst und dann elektronisch auf ein PWM-Signal "konvertiert". Wenn man statt dem Poti ein paar Widerstände mit (An-/Aus-)Schaltern ansteuert, kann man somit gezielt eine bestimmte Impulslänge erzielen.
Achja, zur selben Zeit drücke ich immer nur einen Schalter! Aber es sollen mehrere LEDs and unterschiedlichen Ausgängen gleichzeitig an sein können.

Bluetruck:
Achja, zur selben Zeit drücke ich immer nur einen Schalter! Aber es sollen mehrere LEDs and unterschiedlichen Ausgängen gleichzeitig an sein können.

Also 16 Taster zum Schalten von 8 Kanälen (Pins) mit insgesamt 17 Schaltzuständen (alles aus = es wird gerade nichts geschaltet, 8 Einschalt-Taster = Kanal einschalten, 8 Ausschalt-Taster = Kanal ausschalten)

Also teilst Du die Bandbreite von 1000 bis 2000 Microsekunden in 17 Pulsbreiten-Bereiche ein, und machst je nach empfangenem Pulsbreitenbereich entweder nichts (kein Taster gerdückt) oder einen Ein- oder Ausschaltvorgang (bei Emfpang einer bestimmten Pulsbreite).

Bei nur wenigen Prozent erlaubtem Unterschied in der Pulsbreite und bei teils recht deftigen Toleranzen handelsüblicher Widerstände wirst Du aber vermutlich schon etwas suchen und messen müssen, um geeignete Widerstände für Dein Vorhaben zu finden, die diese zahlreichen und exakten Impulsbreiten tatsächlich erzeugen, die Du unterscheiden möchtest.