ATtiny85 RC PWM Signal decodieren So machbar?

Hallo,

über den RPI und Arduino bin ich jetzt beim ATtiny angekommen.

Also absoluter Neuling und warte noch auf die ATtiny's.

Folgendes möchte ich machen:

Auswertung eines PWM Signals von einem Kanal eines RC Empfängers.

Damit sollen 3 Lichter eines Copters gesteuert werden. Z. B.

Aus

Rücklicht Pin 5 = high

Rücklicht + Positionslicht Pin 5 + 6 high

Rücklicht + Positionslicht + Landescheinwerfer Pin 5 + 6 + 3 high

Bitte um Hinweise ob der Code so funktionieren könnte oder Hinweise auf Verbesserungen.

Vor allem was die Klammern und Einrückungen betrifft.

Vielen Dank

Code:

int RXin = 2;             // Input PWM Pin 7
int AUXout0 = 0;      // Output 1 Pin 5
int AUXout1 = 1;      // Output 2 Pin 6
int AUXout2 = 3;      // Output 3 pin 3

unsigned long number;
int signal = 0;

void setup()
{
  pinMode(RXin, INPUT);
  pinMode(AUXout0, OUTPUT);
  pinMode(AUXout1, OUTPUT);
  pinMode(AUXout2, OUTPUT);
}

void loop()
{
  number = pulseIn(RXin, HIGH);
  
  if (number > 500)
   {
     digitalWrite(AUXout0, HIGH);
   }

  if (number > 1000)
   {
     digitalWrite(AUXout1, HIGH);
   }

   if (number > 1500)
   {
     digitalWrite(AUXout2, HIGH);
   }
   
  else
   {
     digitalWrite(AUXout, LOW);
   }
   
} 
/code]

Hallo!

Mir fällt folgendes auf:

Output (oder Input) 3 ist nicht Pin 3 sondern Pin 2

ATtiny 13/25/45/85 Pinout
                ------
         Reset |1    8| Vcc
     ADC3, PB3 |2    7| PB2, SCL, ADC1
     ADC2, PB4 |3    6| PB1, MISO, PWM
           GND |4    5| PB0, MOSI, PWM
                ------

Der Code kompiliert nicht, weil in

else
   {
     digitalWrite(AUXout, LOW);
   }

AUXout nicht deklariert ist.

Vielleicht meinst du:

else
   {
     digitalWrite(AUXout0, LOW);
     digitalWrite(AUXout1, LOW);
     digitalWrite(AUXout2, LOW);
   }

Das würde kompilieren, allerdings würde dieser Code wahrscheinlich nicht das bewirken was du vielleicht willst.

Ob die Auswertung eines Signals von einem Kanal eines RC Empfängers so einfach mit pulseIn funktioniert glaube ich eher nicht, denn es ist ja eigentlich kein PWM-Signal, sondern ein PPM-Signal (Puls-Pausen-Modulation), da sind also wahrscheinlich ziemlich lange Pausen zwischen den Pulsen, die du auswerten möchtest. Das braucht wohl etwas komplexeren Code (sonst werden die Lampen zwar eingeschaltet, aber danach sofort wieder ausgeschaltet und bleiben das für die meiste Zeit).

Schau mal hier, da ging es um eine sehr ähnliche Fragestellung:

Und hier geht es um das Auslesen von Kanälen einer RC-Fernbedienung:
http://playground.arduino.cc/Code/ReadReceiver

Ob das alles auch am ATTiny machbar ist, wäre zu überprüfen. Ich würde das also zuerst mal am “normalen” Arduino testen.

Vielen Dank uxomm für die ausführliche Erklärung warum und wieso.

Zu 1: Das war ein Flüchtigkeitsfehler, wo ich dann u.U. lange danach gesucht hätte.

Zu 2 : Das war mir so nicht bewusst, macht aber Dank deines Hinweises absolut Sinn für mich.

Ob das dann funktioniert, muss ich noch testen.

Die Links habe ich mir angeschaut. Der Kollege hat im Gegensatz zu mir aber eine viel Umfangreichere Problemstellung.

Ich möchte mit dem m.E. PWM “Servo” Signals vom Empfänger lediglich

Alle Lichter aus

1 Licht an

2 Lichter an

3 Lichter an

Mein Gedankengang ist so:

Wenn vom Empfänger z.B. 700 kommen, ist nur die erste Bedingung if (number > 500) erfüllt. LED 1 an.

mit z. B. 1100 wäre Bedingung if (number > 500) und if (number > 1000) erfüllt Also LED 1 und 2 an usw.

Die Idee dazu kam mir nach Stundenlangen Recherchen im Internet hierzu.

Das zählen der Pulse sollte prinzipiell so funktionieren, zumindest behauptet das jemand, der sich so die Pulse auf dem seriellen Monitor hat ausgeben lassen.

Wenn das so nicht geht, dazu kenne ich mich zuwenig damit aus, wäre das noch eine Idee.

Der Code für die Bedingung würde dann so beginnen:

if (number > 1500) Output a+b+c high
if (number < 1100) Output b+c high
if (number < 900) Output c high
if (number < 400) Output a+b+c low

Um die entsprechenden Werte im Sender zu erzeugen, könnte man a einen Regler nutzen, oder b mit 2 Schaltern die das ganze entsprechend mixen.

Hallo,

habe meinen Code eben auf einen Arduino nano zum testen geladen.

Generell funktioniert es, aber es gehen dann irgendwann beim erhöhen der Pulse am Sender alle Ausgänge gleichzeitig auf high.

Zum trouble shooting habe ich noch ein paar Befehle zum auslesen auf der Konsole eingebaut, und zum einfacheren testen die Schaltpunkte verändert.
< 1100 alle aus

1150 LED 1 glimmt
1400 LED 1 voll hell LED 2 voll hell LED 3 glimmt
danach bis 1950 Pulse keine Änderung mehr.

Hat hier jemand vielleicht noch eine Idee? Vielen Dank.

int RXin = 3;             // Input PWM
int AUXout0 = 5;      // Output 1
int AUXout1 = 6;      // Output 2
int AUXout2 = 7;      // Output 3

unsigned long number;
int signal = 0;

void setup()
{
  pinMode(RXin, INPUT);
  Serial.begin(9600);
  pinMode(AUXout0, OUTPUT);
  pinMode(AUXout1, OUTPUT);
  pinMode(AUXout2, OUTPUT);
}

void loop()
{
  number = pulseIn(RXin, HIGH);
  Serial.println(number);
  delay(10);
  
  if (number > 1150)
   {
     digitalWrite(AUXout0, HIGH);
   }

  if (number > 1250)
   {
     digitalWrite(AUXout1, HIGH);
   }

   if (number > 1400)
   {
     digitalWrite(AUXout2, HIGH);
   }
   
  else
   {
     digitalWrite(AUXout0, LOW);
     digitalWrite(AUXout1, LOW);
     digitalWrite(AUXout2, LOW);
   }
   
} 
/code]

Hallo,

du wolltest das haben …

Aus

Rücklicht Pin 5 = high

Rücklicht + Positionslicht Pin 5 + 6 high

Rücklicht + Positionslicht + Landescheinwerfer Pin 5 + 6 + 3 high

genau das macht dein Code scheinbar. Schwellwert überschritten > LED an, bei allen Auswertungen.

Ein Problem steckt in der letzten if else.

1400 ein und sofort < 1400 aus. Was bedeutet das. Mindestens die ersten beiden LEDs flackern wenn der Meßwert > 1150 und < 1400 ist. Nur siehst du das nicht, geht zu schnell für das Auge. Nur das es dunkler leuchtet müßte man sehen.

Vorschlag

  if (number > 1150) {
    digitalWrite(AUXout0, HIGH);
  }

  if (number > 1250) {
    digitalWrite(AUXout1, HIGH);
  }

  if (number > 1400) {
    digitalWrite(AUXout2, HIGH);
  }

  if (number < 1150) {
    digitalWrite(AUXout0, LOW);
    digitalWrite(AUXout1, LOW);
    digitalWrite(AUXout2, LOW);
  }

du solltest bei jeder if ein else machen, sonst musst du um z.b. die Landescheinwerfer auszuschalter, zunächst ALLES ausschalten und dann Rück- und Positionslicht wieder einschalten

Richtig, für jedes Licht sollte unabhängig abgefragt werden, ob es ein- oder ausgeschaltet werden soll. Das geht auch ganz ohne if/else:

 digitalWrite(AUXout0, number > 1150);

usw.

Klar, ich persönlich liebe solche Dinge.

Aber am Anfang sollte man es doch besser "lesbar" programmieren.

Falls der Kanal mit Poti angesteuert wird, wäre eine Hysterese auch nicht schlecht :wink:

Super, Danke es funktioniert!!!!!!

Hier ist der Code:

int RXin = 3;             // Input PWM
int AUXout0 = 5;      // Output 1
int AUXout1 = 6;      // Output 2
int AUXout2 = 7;      // Output 3

unsigned long number;
int signal = 0;

void setup()
{
  pinMode(RXin, INPUT);
  Serial.begin(9600);
  pinMode(AUXout0, OUTPUT);
  pinMode(AUXout1, OUTPUT);
  pinMode(AUXout2, OUTPUT);
}

void loop()
{
  number = pulseIn(RXin, HIGH);
  Serial.println(number);
  delay(10);
  
  
  
  
  
  if (number > 1150)
   {
     digitalWrite(AUXout0, HIGH);
   }
   
  else
   {
     digitalWrite(AUXout0, LOW);
   }
  
  if (number > 1250)
   {
     digitalWrite(AUXout1, HIGH);
   }
  else
   {
     digitalWrite(AUXout1, LOW);
   }
    
   if (number > 1400)
   {
     digitalWrite(AUXout2, HIGH);
   }
   
  else
   {
     digitalWrite(AUXout2, LOW);
   }
   
} 
/code]

Getestet habe ich das jetzt mit dem Throttle Kanal also wie ein poti.

Der nächste Schritt ist die Zeiten mit einem 2 position und einem 3 position Schalter zu mischen.

Da sehe ich jetzt keine Schwierigkeiten.

Der Sketch soll dann auf einen ATtiny laufen, aber die sind noch unterwegs. Die Ausgänge steuern dann via Mosfet's 12 Volt LED's.

Vielen Dank noch mal für die Hinweise.