Arduino im Modellbau

helifan10
Beiträge: 102
Registriert: 11.11.2009 07:59:27

#121 Re: Arduino im Modellbau

Beitrag von helifan10 »

Asche auf mein Haupt! :oops:
Hatte ich vergessen anzupassen als ich GND und Vin getauscht habe.
Ist natürlich richtig, die LEDs müssen natürlich gedreht werden.
Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#122 Re: Arduino im Modellbau

Beitrag von Husi »

helifan10 hat geschrieben:also geplant sind mal drei Eingänge. Ich möchte eigentlich die Standardbibliothek nutzen.
Mittlerweile habe ich das Einlesen der Empfängerkanäle ohne externe Bibliothek versucht. Siehe da, es ist einfacher als gedacht. Allerdings habe ich gelesen, das bei gleichzeitiger Ausgabe mittels der Servo-Bibliothek ungleiche Zyklen entstehen könen. Schuld sollen die Interrupts sein, die die Abarbeitungszeit der Schleifen durcheinander wirbeln können.

Code: Alles auswählen

 // Empf�nger Kan�le auslesen und via Serial wieder ausgeben.

const int BAUD_RATE       = 9600;
const int PIN_RC_KANAL_01 = 3;  // Ausgangs Kanal am Empf�nger 01 wird an die PWM Leitung 3 angeschlossen.
const int PIN_RC_KANAL_02 = 4;  // Ausgangs Kanal am Empf�nger 02 wird an die PWM Leitung 4 angeschlossen.
const int PIN_RC_KANAL_03 = 5;  // Ausgangs Kanal am Empf�nger 03 wird an die PWM Leitung 5 angeschlossen.
const int DELTA           = 7;  // Rauschunterdr�ckung bei der Ausgabe auf Serial.

int Kanal_01;        // Variablen erzeugen, in denen der jeweilige Empf�nger-Kanal gespeichert wird.
int Kanal_02;
int Kanal_03;
int Kanal_01_alt;    // hier liegen dann die alten Werte, die zur Rauschunterdr�ckung auf Serial gebraucht werden.
int Kanal_02_alt;
int Kanal_03_alt;


void setup() {
  pinMode(PIN_RC_KANAL_01, INPUT);
  pinMode(PIN_RC_KANAL_02, INPUT);
  pinMode(PIN_RC_KANAL_03, INPUT);
  
  Serial.begin(BAUD_RATE);
  Serial.println("Mirkos Empfaenger Test 01");
}


void Werte_auf_Serial_ausgeben() {
  int diff;            // Differenz des neuen und alten Wertes zur Rauschunterdr�ckung bei der Serial Ausgabe
  int neu_schreiben;   // steuert, ob die Textausgabe erfolgen mu�, oder eben nicht
  
  neu_schreiben = 0;   // Null hei�t, die Werte sind noch gleich => keine neue Ausgabe
  
  diff = abs(Kanal_01 - Kanal_01_alt);      // Absolut Wert von der Differenz der alt und neu-Werte bilden.
  if (diff > DELTA) { neu_schreiben = 1; }  // Wenn Differenz gr��er als Raussperre, dann Text neu ausgeben.
  
  diff = abs(Kanal_02 - Kanal_02_alt);
  if (diff > DELTA) { neu_schreiben = 1; }
  
  diff = abs(Kanal_03 - Kanal_03_alt);
  if (diff > DELTA) { neu_schreiben = 1; }
  
  if (neu_schreiben == 1) {
    Serial.print("Kanal 01: ");
    Serial.println(Kanal_01);
    Serial.print("Kanal 02: ");
    Serial.println(Kanal_02);
    Serial.print("Kanal 03: ");
    Serial.println(Kanal_03);
    Serial.println();
  }
  
  Kanal_01_alt = Kanal_01;  // den aktuellen Wert in den alt Speicher schreiben, weil jetzt wieder neu eingelesen wird.
  Kanal_02_alt = Kanal_02;
  Kanal_03_alt = Kanal_03;
}

void loop() {
  Kanal_01 = pulseIn(PIN_RC_KANAL_01, HIGH, 25000);  // Empf�nger Kanal 01 einlesen.
  Kanal_02 = pulseIn(PIN_RC_KANAL_02, HIGH, 25000);  // Empf�nger Kanal 02 einlesen.
  Kanal_03 = pulseIn(PIN_RC_KANAL_03, HIGH, 25000);  // Empf�nger Kanal 03 einlesen.
  
  Werte_auf_Serial_ausgeben();
} 
Viele Grüße
Mirko
Bild Bild Bild Bild
Benutzeravatar
Crizz
Beiträge: 27061
Registriert: 12.04.2007 17:44:22
Wohnort: Haiger
Kontaktdaten:

#123 Re: Arduino im Modellbau

Beitrag von Crizz »

Schau dir mal den Quellcode von MultiWii an, vielleicht hilft dir das weiter. Damit läßt sich auch ein PPM-Summensignal auf PWM-Einzelkanäle ausgeben ohne das du wirkliche Probleme zu erwarten hast, ist ne Grundfunktion die wegen der Gimbal-Ansteuerung mit drin ist.
_________________________________________________________________________________
"Leben ist das, was passiert, während du etwas ganz anderes planst" ... ( John Lennon )

! REVOLECTRIX-Distributor ! -> Ladeequipment / Akkus : -> HaDi-RC.de

Alle Projektberichte für den VTH-Verlag als PDF zum Download unter http://www.CrizzD.de !
Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#124 Re: Arduino im Modellbau

Beitrag von Husi »

Crizz hat geschrieben:Schau dir mal den Quellcode von MultiWii an, vielleicht hilft dir das weiter.
Das werde ich auch, wenn es so weit ist. Zuerst möchte ich (zumindest) alle Grundlagen von der Basis her einmal selbst im Texteditor geschrieben haben. Mir geht es zumindest so, das ich es dann wirklich verstanden habe.
Natürlich gibt es dabei (wie immer) verschiedene Herangehensweisen.
Mirko
Bild Bild Bild Bild
Benutzeravatar
the-fallen
Beiträge: 1976
Registriert: 07.03.2011 14:20:47
Wohnort: zwischen Augsburg und Landsberg a.L.

#125 Re: Arduino im Modellbau

Beitrag von the-fallen »

Wenn die Servobibliothek Interrupts benutzt, dann vermute ich, dass sie selbst (per Software "BitBanging") ein PWM Signal erzeugt. Dabei könnte der Atmega328P auf 6 Pins ein PWM per Hardware erzeugen (die PWM Pins).

Die analogWrite() Funktion macht genau das. Will man die Frequenz verändern muss man allerdings ein paar Register einstellen (weg von den Default-Werten). Dann kann man übrigends auch unter gewissen Umständen feinere Abstufungen als 0-255 erzeugen wenn man muss.

Hier gibt es die ersten Infos dazu:
http://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM

Da das PWM Signal auf den PWM Pins im Chip und nicht in der Software erzeugt wird stört es nicht den Ablauf deines Programm es und wird andersherum natürlich auch nicht durch dein Programm gestört. Es liegt immer ein sauberes PWM an selbst wenn du in deinem Code selber ein Interrupt benutzt.
  • Prôtos FBL -stretched- a un motor 5+4D 1.13mm 14P de torro [V-Stabi]|[V-Gov] | [YGE90LV] | [UweG-Taumelscheibe] | [ZyclicMod]
  • SuziJanis 700 UltraLight 3570g Abfluggewicht
  • Besessen: T-Rex 250SE, T-Rex 450L, T-Rex600EFL, TDR, Blade mSRX
  • nur Gebaut und eingeflogen: Blade700, Goblin500, TRex150 RKH, Blade 130X RKH, Vibe90
  • Heizkoffersteuerung "HeatBox"

[" 99 little bugs in the code | 99 little bugs in the code | Take one down, patch it around | 117 little bugs in the code "] - Alex Shchepetilnikov
helifan10
Beiträge: 102
Registriert: 11.11.2009 07:59:27

#126 Re: Arduino im Modellbau

Beitrag von helifan10 »

Hallo zusammen,

habe nun endlich meine Schaltung von Post 110 in den Rumpf eingebaut.
Habe aber die Belegung der Pins was Funktionen und Beleuchtung betrifft noch einmal angepasst.
Habe jetzt ca. 3 Stunden probiert und Fehlersuche betrieben.
Bis ich darauf gekommen bin, das bei Ausgabe im seriellen Monitor die ersten beiden Pins belegt werden.
Die Auswertung der beiden Sendersignale wollte überhaupt nicht klappen. Im Monitor wurde nur Müll angezeigt.
Jetzt funzt es aber einwandfrei. Manchmal sind es kleine Dinge auf die man erst mal kommen muss :shock:

- Positionsbeleuchtung und Landescheinwerfer über normalen Schalter am Heli einschalten ( onkl. Servo fahren )
- Doppelblitz ACLs
- Wechsellicht Scheinwerfer am Bug
- Taster an Sender wählt auf MP3 Player nächsten Titel an
- Schalter an Sender (drei Stellungen) schaltet später Zusatzfunktionen Winde oder Wasserpumpe für Löschtank

Hier mal mein aktueller Scatch. Eventuell kann sich ja noch jemand was abkupfern.
Wobei Ihr beim Thema Arduino kompetenter seit als ich.

Programm Bell UH-1H RAVEN 3

#include <Servo.h>

Servo SERVO1;
Servo SERVO2;
Servo SERVO3;
int Kanal7;
int Kanal8;

void setup() {

pinMode(0, OUTPUT); // Legt OUT 0 als Ausgang Leiste Pin7 ACL Unten fest > Blinkfrequenz
pinMode(1, INPUT); // Eingang Kanal7 von Sender
pinMode(2, INPUT); // Eingang Kanal8 von Sender
pinMode(3, INPUT_PULLUP); // Legt IN 3 als Eingang Schalter Beleuchtung fest
pinMode(4, OUTPUT); // Legt OUT 4 als Ausgang Leiste Pin 6 ACL Oben fest > Blinkfrequenz
pinMode(5, OUTPUT); // Legt OUT 5 als Ausgang Leiste Pin 5 Scheinwerfer Unten rechts fest
pinMode(6, OUTPUT); // Legt OUT 6 als Ausgang Leiste Pin 4 Scheinwerfer Unten links fest
pinMode(7, OUTPUT); // Legt OUT 7 als Ausgang Leiste Pin 3 Landescheinwerfer und Positionslampen fest
pinMode(8, OUTPUT); // Legt OUT 8 als Ausgang Relais 1 fest > Motor Wasserpumpe Ein
SERVO1.attach(9); // Legt PWM OUT 9 für das Servo des Landescheinwerfers fest.
SERVO2.attach(10); // Legt PWM OUT 10 für das Servo des Lasthaken fest.
SERVO3.attach(11); // Legt PWM OUT 11 für das Servo des Winde fest.
pinMode(12, OUTPUT); // Legt OUT 12 als Ausgang Relais 2 fest > Vorwärts MP3 Player
pinMode(13, OUTPUT); // Legt OUT 13 als Ausgang Relais 3 fest > Play MP3 Player

//Serial.begin(9600); // Startet die Datenübertragung mit 9600 Baud
}

void loop() { // Loop starten// Positionsbeleuchtungen einschalten,

if (digitalRead(3) == LOW) { // Schalter am Input 3 auf Platine schaltet Beleuchtung ein
digitalWrite(7,HIGH); //Schaltet Landescheinwerfer und Positionslampen ein
}
else {
digitalWrite(7,LOW); //Schaltet Landescheinwerfer und Positionslampen aus
}

// Relais K1 9V Ausgang für Pumpe

if (digitalRead(3) == LOW) {
digitalWrite(8,HIGH); //Schaltet Relais K1 ein.
}
else {
digitalWrite(8,LOW); //Schaltet Relais K1 aus.
}

// MP3 Player vorwärts schalten Relais K2

Kanal7 = pulseIn(1, HIGH, 25000); //Ließt Eingangssignal am Input 1 an Platine ein Taster Ruhestellung ca.1100.
//Serial.print("RX-K7 (ms): ");
//Serial.println(Kanal7);
if (Kanal7 >=1600) { //Wenn Eingangssignal größer 1600 Signal ein Titel weiter
digitalWrite (12,HIGH); //Schaltet Relais K2 am Ausgang 12 Vorwärts am MP3 Player
}
if (Kanal7 <=1500){
digitalWrite (12,LOW);
}

// Schalten Relais K3

Kanal8 = pulseIn(2, HIGH, 25000); //Ließt Eingangssignal am Input 2 ein Stellung 1 ca.1100, Stellung 2 ca.1600, Stellung 3 ca.1900
if (Kanal8 >=1200) { //Wenn Eingangssignal
digitalWrite (13,HIGH); //Schaltet Relais K2 am Ausgang 13
}
if (Kanal8 <=1200){
digitalWrite (13,LOW);
}

// ACL einschalten und blinken lassen

unsigned long time = millis() % 2000; // Zeitachse zum schalten der ACL Beleuchtung

if (time <= 80 || time >=160 && time <=240) { // Schaltet zwischen zu den angegebenen Zeiten ACL Oben ein
digitalWrite(4, HIGH); // Ausgang ACL Oben ein
}
else {
digitalWrite(4, LOW);
}
if (time >= 1000 && time <= 1080 || time >=1160 && time <=1240) { // Schaltet zwischen zu den angegebenen Zeiten ACL Unten ein
digitalWrite(0, HIGH); // Ausgang ACL Unten ein
}
else {
digitalWrite(0, LOW);
}

// Bugscheinwerfer einschalten und blinken lassen
if (time <= 900) { // Schaltet innerhalb der ersten 900ms Bugscheinwerfer Links ein
digitalWrite(6, HIGH); // Ausgang Bugscheinwerfer Links
}
else {
digitalWrite(6, LOW);
}
if (time >= 1000 && time <=1900) { // Schaltet zwischen 1000ms und 1900ms Bugscheinwerfer Rechts ein
digitalWrite(5, HIGH); // Ausgang Bugscheinwerfer Rechts
}
else {
digitalWrite(5, LOW);
}

// Servo Landescheinwerfer ein/ausfahren und Landescheinwerfer ein/ausschalten

if (digitalRead(3) == LOW) { // Abfrage Schalter Input 3 auf Platine
SERVO1.write(140); // Servo fährt auf Position 140 Grad Landescheinwerfer ausfahren
delay(10); // Verzögerungszeit Landescheinwerfer einschalten
digitalWrite(6,HIGH); // Einschalten Landescheinwerfer am Ausgang 6
}
else
{
SERVO1.write(20); // Servo fährt auf Position 10 Grad Landescheinwerfer eingefahren
digitalWrite(6,LOW); // Ausschalten Landescheinwerfer am Ausgang 6
}

} //Programmende
Proto
Beiträge: 19
Registriert: 11.04.2016 15:39:16
Wohnort: Frankenthal

#127 Re: Arduino im Modellbau

Beitrag von Proto »

Ich hab sowas ähnliches auch mal gebaut und dafür das SUMD von Graupner genutzt. Hab grad einen Listener via Optokoppler mit über ein T-Stück ans Datenkabel zum Stabi gehängt. Recht Simpel da es ein Standard UART mit 115200 boud im 8N1 ist. Bietet sich also quasi an einfach den Hardware UART RX zu nutzen. Hier hat es einer Entschlüsselt:


Programmausschnitte wie ich das damals genutzt hab:

Simple Abfrage ob Byte 1 Normal Boot oder Failsave ist und Byte 0 die Graupnerkennung. Somit bestimme ich den Anfang des Array rc_rawdata[]

Code: Alles auswählen

ISR(USART_RX_vect) 
{
	static unsigned char rc_byteposition;
	rc_rawdata[rc_byteposition]=UDR0;

	if((rc_rawdata[rc_byteposition]==0x81)|(rc_rawdata[rc_byteposition]==0x01)&&(rc_rawdata[rc_byteposition-1]==0xA8))
	{
		rc_rawdata[0]=rc_rawdata[rc_byteposition-1];
		rc_rawdata[1]=rc_rawdata[rc_byteposition];
		rc_byteposition=1;
		rc_newdata=1;
	}		
	rc_byteposition++;
}
Auswertung (noch ohne Checksum, die hab ich damals nicht fertig gestellt weil ich mir irgendwann dachte das es für ne LED Steuerung eigentlich egal ist. Hier hab ich die Rohdaten ins Format 0-100% umgerechnet.

Code: Alles auswählen

void uart_interpret(volatile unsigned char *last_channel_count, volatile unsigned char rc_rawdata[],unsigned int *rc_data, volatile unsigned char *rc_newdata)
{
	unsigned char data_ok=0;
	*last_channel_count=rc_rawdata[2];
	if (*last_channel_count<4)
		*last_channel_count=4;
	if(*rc_newdata==1)	
	{														//Nur wenn neue Daten vorhanden sind werden diese auch ausgewertet.
		data_ok=uart_check(rc_rawdata);
		if(data_ok==1)
		{
			for (unsigned char byte = 0; byte < *last_channel_count; byte++ )				//Wird so oft verrechnet wie der Empfänger uns über die Anzahl im letzten Telegram angegeben hat
				rc_data[byte] = (((unsigned long)(rc_rawdata[(byte << 1) + 3]) << 8) + rc_rawdata[(byte << 1) + 4]) / 38.4 - 187.5;		
/*
Zur einfacheren Weiterverarbeitung werden alle Werte vom ursprünglichen Wertebereich Dezimal 7200 (bei -150% in der Funke) über Dezimal 12000 (0% in der Funke) bis Dezimal 16800 (+150% in der Funke) in 0-255 umgerechnet.
Effektiver Wertebereich erstreckt sich von Dezimal 46 (bei -100% in der Funke) über Dezimal 127 (bei 0% in der Funke) bis Dezimal 209 (bei +100% in der Funke). Das ganze ist nicht sehr genau (Rundungsfehler) aber 
völlig ausreichend. Wer erkennt schon mehr als 200 verschiedene Stufen für die jeweilige Farbe. Wir Männer sehen höhstens 5 :-) 
Formel ergibt sich: (16800 - 7200) / 255 (neuer Bereich 0-100%) - 191 (Offset entfernen)			
rc_data Kanalzuordnung ist wie folgt:								
rc_data[0] == Kanal 1
rc_data[1] == Kanal 2
rc_data[n] == Kanal n
*/

			*rc_newdata=0;															//Falls neue Daten da waren wird dieser Indikator wieder abgearbeitet zurückgesetzt
		}
	}
}
Vielleicht kanns ja wer brauchen oder wills verbessern. Potential ist da genug, da ich auch nur Hobbybastler bin :-)

Grüße
Christian
Antworten

Zurück zu „Arduino Tipps & Hilfe“