#46 Re: Servo Position-Halten - Adruino Nano
Verfasst: 31.07.2018 19:59:42
Mach ich was falsch? Beim Hochladen von Sketch von Tim folgender Fehler:
Ach ja. Meine Nanos sind endlich da...
Ach ja. Meine Nanos sind endlich da...
Ich bin zwar blöd in Sachen Elektronik und programmieren aber net ganz blöd. Konnte soweit deinen Code noch lesen! Und was soll ich sagen! Geiler Scheiß!!! Mit deinem Standard Code viel viel besser als die Kaufmodule!!!telicopter hat geschrieben:Und bitte bedenken, dass ich bei mir im Code die Pins D5-D7 als Eingänge und die Pins D8-D10 als Ausgänge definiert habe. Wenn du das anders haben willst, muss du die Zuweisung oben in den Defines entsprechend ändern.
Grüße Tim
Code: Alles auswählen
#include <Servo.h>
#define LED_RC_PIN 4 //Empfänger LED-Steuerkanal D4
#define RC1_PIN 5 //Empfänger Steuer-Kanal D5
#define RC2_PIN 6 //Empfänger Steuer-Kanal D6
#define RC3_PIN 7 //Empfänger Steuer-Kanal D7
#define SERVO1_PIN 8 //Servosteuerleitung D8
#define SERVO2_PIN 9 //Servosteuerleitung D9
#define SERVO3_PIN 10 //Servosteuerleitung D10
#define LED_OUT_PIN 11 //LED Steuerleidung D11
#define RC_MIN 1000 //Maximale und minimale Pulslänge
#define RC_MAX 2000
#define MAX_SPEED 50 //Maximale Geschwindigkeit bei Knüppelvollausschlag (Microsekunden-Inkrement je Berechnungsschritt)
#define RC_TOTZONE 10 //Totzone um die Knüppelmitte
#define RC_INPUT_TOLERANCE 35 //Toleranzbereich der RC-EIngangssignale in Microsekunden
#define LM_SIZE 2 //Breite des Laufenden Mittelwert-Filters
Servo servo_1;
Servo servo_2;
Servo servo_3;
unsigned int prevPulse [3] = {0, 0, 0}; //letzte berechnete Pulsweite
unsigned int actPulse [3] ={0, 0, 0}; //aktuelle berechnete Pulsweite
unsigned int LM[LM_SIZE][3]; // Letzte Messungen
unsigned int sum [3]= {0, 0, 0}; //Summe aller Messungen
int channelPin[3] = {RC1_PIN, RC2_PIN, RC3_PIN}; //Array mit den Servobelegungen
unsigned int servoPosition[3] = {1500, 1500, 1500}; //aktuelle Servoposition als Pulsweite
byte index = 0; //Position im Array der Messwerte
void setup()
{
servo_1.attach(SERVO1_PIN);
servo_2.attach(SERVO2_PIN);
servo_3.attach(SERVO3_PIN);
InitializeLMArray(); //Initialisierung der Filterfunktion
pinMode (LED_OUT_PIN, OUTPUT);
Serial.begin(115200);
}
void loop()
{
readChannelFiltered();
LEDcontrol();
}
/*****************************************************************************************************************************
// Funktion zum Simulieren der Hydraulik-Eigenschaften
//
*****************************************************************************************************************************/
unsigned int Hydraulik(int pulse, int servoNr )
{
if (abs( pulse - 1500) <= RC_TOTZONE) //Anpassung der RC-Totzone in der Knüppelmitte
{
pulse = 1500;
}
int correction = map(pulse, RC_MIN, RC_MAX, -MAX_SPEED, MAX_SPEED);
servoPosition[servoNr] += correction;
if ( servoPosition[servoNr] <= RC_MIN )
{
servoPosition[servoNr] = RC_MIN;
}
if ( servoPosition[servoNr] >= RC_MAX)
{
servoPosition[servoNr] = RC_MAX;
}
return servoPosition[servoNr];
}
/*****************************************************************************************************************************
// Funktion zum Auslesen und Filtern der RC-Eingangskanäle mithilfe eines laufenden Mittelwertfilters
//
*****************************************************************************************************************************/
void readChannelFiltered()
{
unsigned int currPulse;
for (int i = 0; i <= 2 ; i++)
{
currPulse = pulseIn(channelPin[i], HIGH, 25000); //Aufnahme der RC-Pulsweite
if(currPulse == 0)
{
currPulse = 1500; //Ausgabe des Neutralwertes, wenn kein gültiger Puls vorhanden
}
sum [i] -= LM[index][i]; //Berechnung des gleitenden Mittelwertes
LM[index][i] = currPulse;
sum[i] += LM[index][i];
actPulse[i] = sum [i] / LM_SIZE; //Gleitender Mittelwert wird zur aktuellen Pulsweite
if ( abs (prevPulse[i] - actPulse[i]) <= RC_INPUT_TOLERANCE) //Unterdrückung von Servozittern durch die Einführung eines Toleranzbereiches
{ //Wenn neuer Wert innerhalb der Toleranz liegt, wird der alte Wert weiterverwendet
actPulse[i] = prevPulse[i];
}
prevPulse[i] = actPulse[i];
servo_1.writeMicroseconds(Hydraulik(actPulse[0], 0)); //Möglichst häufige Ansteuerung der Servos für einen flüssigeren Lauf
servo_2.writeMicroseconds(Hydraulik(actPulse[1], 1));
servo_3.writeMicroseconds(Hydraulik(actPulse[2], 2));
}
index++;
index = index % LM_SIZE;
}
/*****************************************************************************************************************************
// Funktion zum Ansteuern einer LED
//
*****************************************************************************************************************************/
void LEDcontrol()
{
unsigned int currPulse = pulseIn(LED_RC_PIN, HIGH, 25000);
if (currPulse >= 1500)
{
digitalWrite (LED_OUT_PIN, HIGH);
}
else
{
digitalWrite (LED_OUT_PIN, LOW);
}
}
/*****************************************************************************************************************************
// Initialisierungsfunktion zum Auffüllen aller Arraywerte
//
*****************************************************************************************************************************/
void InitializeLMArray()
{
while ( index < LM_SIZE)
{
unsigned int currPulse;
for (int i = 0; i <= 2 ; i++)
{
currPulse = pulseIn(channelPin[i], HIGH, 25000); //Aufnahme der RC-Pulsweite
if(currPulse == 0)
{
currPulse = 1500; //Ausgabe des Neutralwertes, wenn kein gültiger Puls vorhanden
}
sum [i] -= LM[index][i]; //Berechnung des gleitenden Mittelwertes
LM[index][i] = currPulse;
sum[i] += LM[index][i];
actPulse[i] = sum [i] / (index + 1 ); //Gleitender Mittelwert wird zur aktuellen Pulsweite
if ( abs (prevPulse[i] - actPulse[i]) <= RC_INPUT_TOLERANCE) //Unterdrückung von Servozittern durch die Einführung eines Toleranzbereiches
{ //Wenn neuer Wert innerhalb der Toleranz liegt, wird der alte Wert weiterverwendet
actPulse[i] = prevPulse[i];
}
prevPulse[i] = actPulse[i];
}
servo_1.writeMicroseconds(1500); //Servoposition in Neutrallage halten bis Initialisierung beendet
servo_2.writeMicroseconds(1500);
servo_3.writeMicroseconds(1500);
index++;
}
index = 0;
}
Code: Alles auswählen
#include <Servo.h>
#define LED_RC_PIN 4 //Empfänger LED-Steuerkanal D4
#define RC1_PIN 5 //Empfänger Steuer-Kanal D5
#define RC2_PIN 6 //Empfänger Steuer-Kanal D6
#define RC3_PIN 7 //Empfänger Steuer-Kanal D7
#define SERVO1_PIN 8 //Servosteuerleitung D8
#define SERVO2_PIN 9 //Servosteuerleitung D9
#define SERVO3_PIN 10 //Servosteuerleitung D10
#define LED_OUT_PIN 11 //LED Steuerleidung D11
#define RC_MIN 1000 //Maximale und minimale Pulslänge
#define RC_MAX 2000
#define MAX_SPEED 50 //Maximale Geschwindigkeit bei Knüppelvollausschlag (Microsekunden-Inkrement je Berechnungsschritt)
#define RC_TOTZONE 10 //Totzone um die Knüppelmitte
#define RC_INPUT_TOLERANCE 35 //Toleranzbereich der RC-EIngangssignale in Microsekunden
#define LM_SIZE 2 //Breite des Laufenden Mittelwert-Filters
Servo servo_1;
Servo servo_2;
Servo servo_3;
unsigned int prevPulse [4] = {0, 0, 0, 0}; //letzte berechnete Pulsweite
unsigned int actPulse [4] ={0, 0, 0, 0}; //aktuelle berechnete Pulsweite
unsigned int LM[LM_SIZE][4]; // Letzte Messungen
unsigned int sum [4]= {0, 0, 0, 0}; //Summe aller Messungen
int channelPin[4] = {RC1_PIN, RC2_PIN, RC3_PIN, LED_RC_PIN}; //Array mit den Servobelegungen
unsigned int servoPosition[4] = {1500, 1500, 1500, 1500}; //aktuelle Servoposition als Pulsweite
byte index = 0; //Position im Array der Messwerte
void setup()
{
servo_1.attach(SERVO1_PIN);
servo_2.attach(SERVO2_PIN);
servo_3.attach(SERVO3_PIN);
InitializeLMArray(); //Initialisierung der Filterfunktion
pinMode (LED_OUT_PIN, OUTPUT);
Serial.begin(115200);
}
void loop()
{
readChannelFiltered();
LEDcontrol(actPulse[3]);
}
/*****************************************************************************************************************************
// Funktion zum Simulieren der Hydraulik-Eigenschaften
//
*****************************************************************************************************************************/
unsigned int Hydraulik(int pulse, int servoNr )
{
if (abs( pulse - 1500) <= RC_TOTZONE) //Anpassung der RC-Totzone in der Knüppelmitte
{
pulse = 1500;
}
int correction = map(pulse, RC_MIN, RC_MAX, -MAX_SPEED, MAX_SPEED);
servoPosition[servoNr] += correction;
if ( servoPosition[servoNr] <= RC_MIN )
{
servoPosition[servoNr] = RC_MIN;
}
if ( servoPosition[servoNr] >= RC_MAX)
{
servoPosition[servoNr] = RC_MAX;
}
return servoPosition[servoNr];
}
/*****************************************************************************************************************************
// Funktion zum Auslesen und Filtern der RC-Eingangskanäle mithilfe eines laufenden Mittelwertfilters
//
*****************************************************************************************************************************/
void readChannelFiltered()
{
unsigned int currPulse;
for (int i = 0; i <= 3 ; i++)
{
currPulse = pulseIn(channelPin[i], HIGH, 35000); //Aufnahme der RC-Pulsweite
if(currPulse == 0)
{
currPulse = 1500; //Ausgabe des Neutralwertes, wenn kein gültiger Puls vorhanden
}
sum [i] -= LM[index][i]; //Berechnung des gleitenden Mittelwertes
LM[index][i] = currPulse;
sum[i] += LM[index][i];
actPulse[i] = sum [i] / LM_SIZE; //Gleitender Mittelwert wird zur aktuellen Pulsweite
if ( abs (prevPulse[i] - actPulse[i]) <= RC_INPUT_TOLERANCE) //Unterdrückung von Servozittern durch die Einführung eines Toleranzbereiches
{ //Wenn neuer Wert innerhalb der Toleranz liegt, wird der alte Wert weiterverwendet
actPulse[i] = prevPulse[i];
}
prevPulse[i] = actPulse[i];
servo_1.writeMicroseconds(Hydraulik(actPulse[0], 0)); //Möglichst häufige Ansteuerung der Servos für einen flüssigeren Lauf
servo_2.writeMicroseconds(Hydraulik(actPulse[1], 1));
servo_3.writeMicroseconds(Hydraulik(actPulse[2], 2));
}
index++;
index = index % LM_SIZE;
}
/*****************************************************************************************************************************
// Funktion zum Ansteuern einer LED
//
*****************************************************************************************************************************/
void LEDcontrol(unsigned int LEDpulse)
{
if (LEDpulse >= 1500)
{
digitalWrite (LED_OUT_PIN, HIGH);
}
else
{
digitalWrite (LED_OUT_PIN, LOW);
}
}
/*****************************************************************************************************************************
// Initialisierungsfunktion zum Auffüllen aller Arraywerte
//
*****************************************************************************************************************************/
void InitializeLMArray()
{
while ( index < LM_SIZE)
{
unsigned int currPulse;
for (int i = 0; i <= 3 ; i++)
{
currPulse = pulseIn(channelPin[i], HIGH, 25000); //Aufnahme der RC-Pulsweite
if(currPulse == 0)
{
currPulse = 1500; //Ausgabe des Neutralwertes, wenn kein gültiger Puls vorhanden
}
sum [i] -= LM[index][i]; //Berechnung des gleitenden Mittelwertes
LM[index][i] = currPulse;
sum[i] += LM[index][i];
actPulse[i] = sum [i] / (index + 1 ); //Gleitender Mittelwert wird zur aktuellen Pulsweite
if ( abs (prevPulse[i] - actPulse[i]) <= RC_INPUT_TOLERANCE) //Unterdrückung von Servozittern durch die Einführung eines Toleranzbereiches
{ //Wenn neuer Wert innerhalb der Toleranz liegt, wird der alte Wert weiterverwendet
actPulse[i] = prevPulse[i];
}
prevPulse[i] = actPulse[i];
}
servo_1.writeMicroseconds(1500); //Servoposition in Neutrallage halten bis Initialisierung beendet
servo_2.writeMicroseconds(1500);
servo_3.writeMicroseconds(1500);
index++;
}
index = 0;
}