Guten Abend zusammen,
auf dem Dachboden lag nach eine Fernsteuerung 2Kanal 2.4Ghz, welche nun umfunktioniert werden soll, als Funksender für kleine Daten.
Bisher habe ich mit dem DSO112A herausgefunden, dass die Impulsdauer von ~0,95ms bis ~2.10ms variiert. Das ganze wiederholt sich alle ~20ms (50Hz).
Nun wollte ich mit dem Arduino die Impulsdauer auswerten, ohne grosse Auswirkungen auf die Zykluszeit.
Versuch 1: mit pulseIn() (Problem wenn kein Signal anliegt sehr hohe Wartezeit in pulseIn())
const uint8_t signal_PPM = 2; //Interrupt faehiger Pin (UNO)
const uint8_t status_LED = 13;
const uint16_t low_PPM = 1200;
const uint16_t high_PPM = 1800;
uint16_t dauer_PPM, max_us;
void setup()
{
Serial.begin(19200);
while (!Serial) {}
pinMode(signal_PPM, INPUT);
pinMode(status_LED, LED_BUILTIN);
}
void loop()
{
uint32_t start_us = micros();
noInterrupts();
dauer_PPM = pulseIn(signal_PPM, HIGH); //timeout moeglich
interrupts();
if (dauer_PPM >= high_PPM)
{
digitalWrite(status_LED, HIGH);
}
else
{
digitalWrite(status_LED, LOW);
}
uint32_t ende_us = micros();
uint16_t dauer_loop = ende_us - start_us;
if (dauer_loop > max_us)
{
max_us = dauer_loop;
}
Serial.print("PPM = "); //test ohne F()
Serial.print(dauer_PPM);
Serial.print("\tmax_us = ");
Serial.println(max_us);
}
//AUSGABE: PPM = 1322 max_us = 1988
Frage zwischendurch: Macht die Zykluszeiterfassung mit micros() ueberhaupt Sinn? Wird waehrend eines Interrupts der micros-Zaehler hochgezaehlt?
Versuch 2: attacheInterrupt(...,...,CHANGE)
const uint8_t signal_PPM = 2; //Interrupt faehiger Pin (UNO)
const uint8_t status_LED = 13;
const uint16_t low_PPM = 1200;
const uint16_t high_PPM = 1800;
volatile uint32_t PPM_start = 0;
volatile uint32_t PPM_stopp = 0;
uint16_t dauer_PPM, max_us;
void get_PPM()
{
if (digitalRead(signal_PPM)) //Beidseitige Verzoegerung (unrelevant?)
{
PPM_start = micros();
}
else
{
PPM_stopp = micros();
}
}
void setup()
{
Serial.begin(19200);
while (!Serial) {}
pinMode(signal_PPM, INPUT);
pinMode(status_LED, LED_BUILTIN);
attachInterrupt(digitalPinToInterrupt(signal_PPM), get_PPM, CHANGE);
}
void loop()
{
uint32_t start_us = micros();
if (PPM_start < PPM_stopp)
{
dauer_PPM = PPM_stopp - PPM_start;
}
if (dauer_PPM >= high_PPM)
{
digitalWrite(status_LED, HIGH);
}
else
{
digitalWrite(status_LED, LOW);
}
uint32_t ende_us = micros();
uint16_t dauer_loop = ende_us - start_us;
if (dauer_loop > max_us)
{
max_us = dauer_loop;
}
Serial.print("PPM = "); //test ohne F()
Serial.print(dauer_PPM);
Serial.print("\tmax_us = ");
Serial.println(max_us);
}
//AUSGABE: PPM = 1321 max_us = 24
Versuch 3: attacheInterrupt(...) verschieben
(Problem dauer_PPM instabil)
const uint8_t signal_PPM = 2; //Interrupt faehiger Pin (UNO)
const uint8_t status_LED = 13;
const uint16_t low_PPM = 1200;
const uint16_t high_PPM = 1800;
volatile uint32_t PPM_start = 0;
volatile uint32_t PPM_stopp = 0;
uint16_t max_us;
uint32_t dauer_PPM;
void get_start()
{
PPM_start = micros();
detachInterrupt(digitalPinToInterrupt(signal_PPM));
attachInterrupt(digitalPinToInterrupt(signal_PPM), get_stopp, FALLING);
}
void get_stopp()
{
PPM_stopp = micros();
detachInterrupt(digitalPinToInterrupt(signal_PPM));
attachInterrupt(digitalPinToInterrupt(signal_PPM), get_start, RISING);
}
void setup()
{
Serial.begin(19200);
while (!Serial) {}
pinMode(signal_PPM, INPUT);
pinMode(status_LED, LED_BUILTIN);
attachInterrupt(digitalPinToInterrupt(signal_PPM), get_start, RISING);
}
void loop()
{
uint32_t start_us = micros();
dauer_PPM = PPM_stopp - PPM_start;
if (dauer_PPM >= high_PPM)
{
digitalWrite(status_LED, HIGH);
}
else
{
digitalWrite(status_LED, LOW);
}
uint32_t ende_us = micros();
uint16_t dauer_loop = ende_us - start_us;
if (dauer_loop > max_us)
{
max_us = dauer_loop;
}
Serial.print("PPM = "); //test ohne F()
Serial.print(dauer_PPM);
Serial.print("\tmax_us = ");
Serial.println(max_us);
}
//AUSGABE: PPM = 1321 max_us = 20
FEHLERFALL: PPM = 4294948472 max_us = 20
Versuch 2 scheint fuer mich am "besten" zu sein. Wie ist Euere Erfahrung?
Vielen Dank
Grillgemuese