2016-02-15 2 views
0

J'ai essayé de mesurer le temps que la ligne est haute sur l'Arduino. Il va haut, puis reste élevé pendant quelques millisecondes. Ensuite, il est tiré bas pour 1us puis remonte à la hauteur. Mon code ne semble pas reconnaître la ligne tirée bas. Est-ce que 1us est trop rapide pour l'interruption? Comment puis-je le ralentir?Interruptions externes Arduino pas assez rapide

Merci

EDIT Mes pensées sont à utiliser un filtre RC en conjonction avec une diode pour ralentir suffisamment le temps de montée de l'Arduino de reconnaître le changement, mais seulement quand le changement se produit à partir de la réception ligne. Est-ce viable? Ou puis-je utiliser une puce d'extension d'impulsion avec une diode de la même manière?

#define ESC 2 //the digital pin the esc signal line is attached to 

int throttlePos = 0; 

volatile unsigned long timer_start; 
volatile int last_interrupt_time; 
volatile int pulse_time; 

void setup() { 
// put your setup code here, to run once: 
pinMode(ESC, OUTPUT); //originally set the ESC's line to output to keep line high ready for throttle armature 
digitalWrite(ESC, HIGH); //keep the pulse high due to inverted throttle pulse 
Serial.begin(115200); //opens the serial port for use when testing 
timer_start = 0; 
    attachInterrupt(digitalPinToInterrupt(ESC), calcSignal, CHANGE); 
for(throttlePos = 0; throttlePos <= 1000; throttlePos += 1) //these for loops arm the ESC by emulating an inverted PWM pulse, process takes two seconds 
{ 
    digitalWrite(ESC, LOW); 
    delayMicroseconds(1500); 
    digitalWrite(ESC, HIGH); 
    delayMicroseconds(100); 
} 
for(throttlePos = 1000; throttlePos <= 2000; throttlePos += 1) 
{ 
    digitalWrite(ESC, LOW); 
    delayMicroseconds(1000); 
    digitalWrite(ESC, HIGH); 
    delayMicroseconds(100); 
} 
} 

void loop() { 
digitalWrite(ESC, LOW); 
delayMicroseconds(1200); 
digitalWrite(ESC, HIGH); 
delayMicroseconds(100); 
delay(19); 
Serial.println(pulse_time); 
} 
void calcSignal() 
{ 
    //record the interrupt time so that we can tell if the receiver has a signal from the transmitter 
    last_interrupt_time = micros(); 
    //if the pin has gone HIGH, record the microseconds since the Arduino started up 
    if(digitalRead(ESC) == HIGH) 
    { 
     timer_start = micros(); 
    } 
    //otherwise, the pin has gone LOW 
    else 
    { 
     //only worry about this if the timer has actually started 
     if(timer_start != 0) 
     { 
      //record the pulse time 
      pulse_time = ((volatile int)micros() - timer_start); 
      //restart the timer 
      timer_start = 0; 
     } 
    } 
} 

oscilloscope

Répondre

0

1/1US est 1MHz. Étant donné que votre Arduino exécute des instructions à 16 MHz (au mieux, certaines instructions prennent plus de temps), votre gestionnaire d'interruption pourrait facilement manquer des choses. Cependant, l'interruption doit toujours s'exécuter, même si la condition d'interruption est effacée avant la fin de l'interruption. Utilisez-vous les bibliothèques Arduino pour les interruptions ou la configuration des interruptions de changement de broche directement au niveau du registre? Avez-vous vérifié que l'impulsion dans l'Arduino est électriquement saine? Sans en savoir plus sur votre circuit, il est difficile de proposer une solution.

+0

J'ai ajouté une photo à ma réponse dans le montage. J'envoie un signal PWM inversé. La tique est retournée par le récepteur tirant la ligne à la terre pendant 1us. – Peter

+0

Hmm. Il semble que l'Arduino devrait capturer ce pouls. Est-ce qu'il échoue toujours, ou seulement une partie du temps? –

+0

Il tombe 11 sur 12 impulsions PWM .. Cela permet l'étalonnage. J'ai ajouté mon code dans l'édition pour voir si vous trouvez des erreurs. En ce moment, il imprime juste le temps que le signal était élevé entre les impulsions de gaz. – Peter