RC Quadrotor helikopter (17 / 37 steg)
Steg 12: Arduino Demo: PWM Input
Jag har även bifogat en logik analyzer skärmdump för att visa dig hur signalerna från min RC radiomottagare ser ut. Var och en av dessa pulser har en puls bredd mellan 1000 och 2000 mikrosekunder, perioden är cirka 20 millisekunder.
För mer information, forskning:
- PWM
- Servo signaler
- ISRs i AVR (avbrottstjänstens rutin)
- PCINT, Pin förändring avbryta
- 16-bitars timers i AVR
Här är koden:
void setup(){
DDRC = 0; stift som indata
Aktivera PCINT 18 – 23
PCICR | = (1 << PCIE2);
PCMSK2 = 0XFC;
Serial.BEGIN(115200);
}
TypeDef struct {
byte bakkant.
osignerade långa riseTime;
osignerade långa fallTime;
unsigned int lastGoodWidth;
} tPinTimingData;
flyktiga statisk tPinTimingData pinData [6 + 1];
flyktiga statisk uint8_t PCintLast;
ISR(PCINT2_vect)
{
uint8_t bit;
uint8_t curr;
uint8_t mask;
uint32_t currentTime;
uint32_t tid.
få pin staterna för den angivna porten.
curr = PINC & 0xFC;
mask = curr ^ PCintLast;
PCintLast = curr;
currentTime = micros();
mask är pcint stift som har ändrats.
för (uint8_t jag = 0; jag < 6; i ++) {
bit = 0x04 << i.
om (bit och mask) {
för varje stift ändras, rekordtid av förändring
om (bit och PCintLast) {
tid = currentTime - pinData [i] .fallTime;
pinData [i] .riseTime = currentTime;
om ((tid > = 10000) & & (tid < = 26000))
pinData [i] .edge = 1;
annat
pinData [i] .edge = 0; Ogiltig stigande kant upptäckt
}
annat {
tid = currentTime - pinData [i] .riseTime;
pinData [i] .fallTime = currentTime;
om ((tid > = 800) & & (tid < = 2200) & & (pinData [i] .edge == 1)) {
pinData [i] .lastGoodWidth = tid;
pinData [i] .edge = 0;
}
}
}
}
}
void loop()
{
Serial.println();
för (byte jag = 0; jag < 6; i ++) {
Serial.Print("C");
Serial.Print ((int) i + 1);
Serial.Print(":");
Serial.Print(pinData[i].lastGoodWidth);
Serial.Print (",");
}
Delay(500);
}