Go Down

Topic: Fahrtenregler mit Arduino bauen (Read 2216 times) previous topic - next topic

ArduStemmi

Ich habe ein ca. 15 Jahre altes ferngesteuertes Modellauto. Dieses wird über eine 27 MHz Funkfernsteuerung betrieben. Da das Ding so gut funktioniert, möchte ich es auf eine 2.4 GHz Pistolenfernsteuerung umbauen.
Da es aber Probleme mit den verschiedenen Spannungsebenen gibt, muss ich einen Fahrtenregler selber bauen. Die eigentliche Technik, H-Brücke und deren Ansteuerung mit Arduino ist klar.

Meine Frage ist, wie kann ich die Signale aus dem Empfänger mit dem Arduino verarbeiten und auswerten? Gibt es da Beispiele?

Herzlichen Dank für Eure Antworten.

derRobert

Der Empfänger gibt ja ein Gepulstes Signal aus welches sich jeh nach gebelstellung am Sender ändert.

Dieses Signal kannst du mit pulsIn(pin,zustand) Abfragen und dann evtl. mit map() verarbeiten.

http://www.arduino.cc/en/Reference/PulseIn
http://www.arduino.cc/es/Reference/Map


mit pulseIn habe ich mir einen Tiny programmiert der eine Kamera ein und ausschaltet.

evtl hilft dir das weiter

Code: [Select]
#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 4
SoftwareSerial serial(rxPin, txPin);

unsigned long timestamp2 = 0;
int timestamp3 = 0;



void setup(){

  pinMode(2,INPUT);
  pinMode(0,OUTPUT);
  digitalWrite (0, LOW);
   serial.begin(4800);
}


void loop(){

timestamp3= pulseIn(2,LOW);
timestamp2= timestamp3 / 100;
serial.println(timestamp2);




  switch (timestamp2){
  case 193:
  rc1();
    break;
  case 185:
    rc2();
    break;
  }


}
void rc1()
{
  digitalWrite(0, HIGH);
  delay(300);
  digitalWrite(0, LOW);

}

void rc2()
{
  digitalWrite(0, HIGH);
  delay(3000);
  digitalWrite(0, LOW);
 
}

ArduStemmi

Herzlichen Dank, das ist ja einfacher als gedacht. Mich hätte aber jetzt noch interessiert, wie dieses geheimnisvolle Signal denn aussieht? Ich habe gehört, es wäre ein 5 Volt Puls, der alle 20 ms ausgesendet wird. Die Pulslänge würde in Nullstellung 2,5 ms betragen, die Abweichung von dieser Pulslänge repräsentiert den Wert des Signal, respektive die Stellung des Gashebels.

Kennt das jemand genauer?

derRobert

Ja es ist ein Rechtecksignal

Code: [Select]
timestamp= pulseIn(2,LOW);

serial.println(timestamp);


zeigt dir kontinuierlich die Dauer zwischen Low und Low an. diese Dauer verändert sich jeh nach Hebelstellung.

Gruß
derRobert


ArduStemmi

Inzwischen habe die genaue Beschreibung des Signals rausgefunden.

Es ist ein Rechtecksignal von 1 bis 2 ms Breite:
Minimum: 1ms
Mittelstellung: 1,5ms
Maximum: 2ms
Natürlich sind alle anderen Werte dazwischen auch möglich.
Nach 20 ms muss ein neuer Impuls kommen.

Das Gänze kann man mit Pulsin einlesen.

uwefed


Inzwischen habe die genaue Beschreibung des Signals rausgefunden.

Es ist ein Rechtecksignal von 1 bis 2 ms Breite:
Minimum: 1ms
Mittelstellung: 1,5ms
Maximum: 2ms
Natürlich sind alle anderen Werte dazwischen auch möglich.
Nach 20 ms muss ein neuer Impuls kommen.

Das Gänze kann man mit Pulsin einlesen.

Es ist ein Puls Pause Modulation. Sehr ähnich einer PW-Modulation aber, wie Du geschrieben hast, mit Impulsen zwischen 1 und 2 mS.
Manche Servo nehmen auch längere bzw kürzere Impulse entgegen und haben dann einen größeren Drehwinkel (0,5 bis 2,5mS). Für Spezialanwendungen wo eine schnelle Reaktion notwendig ist wird statt des 50Hz Signals ein 400Hz Singnal verwendet ( zB Helikopter). Frag mich aber nicht ob bei einem 400Hz signal noc 1-2 mS impulse verwendet werden oder dementsprechend kürzere. Ich tippe auf normal lange.

Ich würd aber die HIGH Zeit des Signals messen und nicht die LOW Zeit:

Code: [Select]
timestamp= pulseIn(PIN,HIGH,20000);
if (timestamp==0) Serial.print("Kein Impuls festgestellt");


Grüße Uwe

ArduStemmi

Das mit der High-Zeit hätte ich sowieso gemacht. Denn die Spezifikation ist da eindeutig. Aber ich werde mal beispielhaft die Löw-Zeit messen. Diese liegt ja zwischen zwischen 18 und 19 ms. Vielleicht läßt die sich besser messen. Allerdings muss dann natürlich die Zeit zwischen zwei Pulsen konstant 20ms betragen.

Nochmals die Frage: Kann mir jemand die genaue Spezifikation der Ausgangssignale eines Empfängers einer handelsüblichen Modellbaufernsteuerung liefern?

uwefed

pulsein() blockiert den Arduino gleich wie delay(). Darum ist es vorteilhaft die HIGH Zeit zu messen.

Spezifikation:
Da ist ja schon alles gesagt: 1-2mS H alle 20mS und H Signal (wahrscheinlich 4,8V, mit der die Fernsteuerung Empfangsteil versorgt wird) Andernfalls mit einem Vorwiderstand und einer ZDiode die Spannung begrenzen.

Grüße Uwe

ArduStemmi

Jetzt verwirrst Du mich. Ich hatte verstanden, mit PulseIn die HighZeit zu messen. Jetzt verstehe ich, ich soll mit anderen Methoden die HighZeit messen. Meins Du Atmels Timer?

derRobert

Ich denke er meint die High Zeit trotzdem mit pulseIn Messen. Aber ebend die High Zeit da sie kürzer ist als Low.

Bei meiner Anwendung ist es Egal ob der Controller kürzer oder länger Blockiert ist. Daher habe ich mir die Längere Low Zeit genommen und habe diese dan noch durch 100 geteilt. Somit hatte ich einen Sauberen und fest Stehenden Wert. denn wenn du dir mal deinen Empfänger nimmst und den an den Arduino hängst und dir mit pulseIn() und serial.print() die Werte Anschaust dann wirst du sehen das die recht Springen. je nach dem wie sehr es sich auf deinen Fahrtregler ausübt würde ich einen mittelwert berechnen oder ebend auch einen Teiler Einbauen. Beim Teiler könnte es aber sein das dein fahrtregler dann nicht Feinfühlig genug wird.
So habe ich den Empfänger an einen Attiny angeschlossen. Kannst das aber auch an einen Digitalpin vom Arduino hängen


und das ist der Code dazu. 

Code: [Select]
#include <SoftwareSerial.h>
#define rxPin 3
#define txPin 4
SoftwareSerial serial(rxPin, txPin);

unsigned long timestamp1 = 0;
int timestamp2 = 0;



void setup(){

  pinMode(2,INPUT);
  pinMode(0,OUTPUT);
  digitalWrite (0, LOW);
   serial.begin(4800);
}


void loop(){

timestamp2= pulseIn(2,LOW);
timestamp1= timestamp2 / 100;
serial.println(timestamp1);               // Oder timestamp2 für die ungeteilten Werte




  switch (timestamp1){
  case 193:
  rc1();
    break;
  case 185:
    rc2();
    break;
  }


}
void rc1()  //Gopro einschalten
{
  digitalWrite(0, HIGH);
  delay(300);
  digitalWrite(0, LOW);

}

void rc2()  //Gopro ausschalten
{
  digitalWrite(0, HIGH);
  delay(3000);
  digitalWrite(0, LOW);
 
}

derRobert

Um dir das Signal genauer an zu schauen lässt du dir die Serielle Ausgabe nicht in der ArduinoIDE ausgeben sondern mit Hyperterminal unter Windoof.
Da kannste dir die Ausgabe als .csv Datei speichern lassen und die dann mit Excel auswerten. Oder du versuchst http://accrochages.drone.ws/en/node/90


ArduStemmi

Das haben wir jetzt, denke ich, ausreichend beleuchtet. Schon naht eine neue Frage.

Ich kann beim Arduino eine PWM über analogWrite realisieren. Meine Frage: Kann ich auf einfache Weise die Frequenz der PWM beeinflussen?

uwefed


Das haben wir jetzt, denke ich, ausreichend beleuchtet. Schon naht eine neue Frage.

Ich kann beim Arduino eine PWM über analogWrite realisieren. Meine Frage: Kann ich auf einfache Weise die Frequenz der PWM beeinflussen?

Wozu brauchst Du eine Frequenzänderung?
Ja, es sind einige Frequenzen möglich, da mußt Du aber auf die Register zugreifen.
http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
http://arduino.cc/playground/Main/TimerPWMCheatsheet

Grüße Uwe

ArduStemmi

Das ist genau, wonach ich gesucht habe. Danke Uwe.

Ich habe im Netz ganz viele Begründungen für hohe Frequenzen und für niedrige Frequenzen gelesen. Das hängt unter anderem von der Bauart der Motore ab. Da ich so wenig über meine Motoren weiß, werde ich die Taktfrequenz der bisher verbauten H-Brücke messen und diese Frequenz am Arduino (bzw. am Attiny, denn soll's am Ende werden) einstellen.

Bis bald!

uwefed

Ich weiß, daß die PWM-Frequenz des Arduino auf 490Hz gestellt wurde wegen Problemen mit Motoren, aber nichts genaueres.
Grüße Uwe

Go Up