Pourquoi mon code dinterruption ne fonctionne-t-il pas?

Contexte

Jessaie décrire du code pour lire les signaux dun récepteur RC à six canaux sur un Arduino Mega 2560 . Actuellement, je garde le code pour ne lire quun seul canal afin de faciliter le dépannage. Le problème est que ma variable partagée ne se met pas à jour, ce qui me porte à croire que mon interruption La routine de service ne détecte aucun front montant.

Je pensais que mon récepteur était cassé, je lai donc testé en utilisant la fonction dinterruption de connexion Arduino standard . Cela a parfaitement fonctionné, donc mon récepteur va bien.

Jai utilisé Serial.print () pour voir si ma variable de canal volatile était mise à jour (autrement dit, remplacez sa valeur par la valeur de lindicateur du canal 1). Il ne sest pas mis à jour, donc mon ISR doit être erroné. Vous pouvez trouver le code dorigine dans larticle du blog.

Quel est le problème? Je suis à court d’idées.

 #include <PinChangeInt.h> //Pin assignment #define channel1PIN 10 //Bit flags #define Channel1FLAG 1 //Flag holder volatile uint8_t bFLAGUPDATESHARED; //Shared variables: Accessed by the interrupt service routine and read in "void loop". volatile uint16_t unCHANNEL1SHARED; //Start time variables: These are used to set the start time of the rising edge of //a pulse. They are only accessed by the ISR, and thus they are unsigned integers and //not volatiles. uint32_t ulCHANNEL1START; void setup() { Serial.begin(9600); Serial.print("RC Channel PWM Read Interrupt Test"); //PinChangInt library function. Used to set attach interrupts. PCintPort::attachInterrupt(channel1PIN, calcCHANNEL1, CHANGE); } void loop() { //In-loop variables to hold local copies of channel inputs. //This is static so it retains values between call loops. static uint16_t unCHANNEL1IN; //The in-loop copy of the bSHAREDFLAGUPDATE volatile flag holder static uint8_t bFLAGUPDATELOCAL; //Check to see if any channels have received signals. If so, copy //shared variables to local in loop variables. if (bFLAGUPDATESHARED) { //Switch off interrupts when I copy shared variables to local variables noInterrupts(); bFLAGUPDATELOCAL = bFLAGUPDATESHARED; if (bFLAGUPDATELOCAL & Channel1FLAG) { unCHANNEL1IN = unCHANNEL1SHARED; } bFLAGUPDATESHARED = 0; interrupts(); } Serial.println(unCHANNEL1IN); //Clear local update flags copy as all values have been copied to local variables bFLAGUPDATELOCAL = 0; } void calcCHANNEL1() { if (digitalRead(channel1PIN) == HIGH) { //If pin goes high, start timer and set ulCHANNEL1START to timer start ulCHANNEL1START = micros(); } else { //If it is not rising, it must be falling so set shared //variable to current time-start time unCHANNEL1SHARED = (uint16_t)(micros() - ulCHANNEL1START); //Tell that channel 1 has received a signal bFLAGUPDATESHARED |= Channel1FLAG; } }  

Commentaires

  • Essayez de simplifier votre code. Demandez à lISR dallumer une LED, par exemple. Je ne vois ‘ rien de fondamentalement faux.
  • Jai compris. Pour une raison quelconque, cela ne fonctionne que sur les broches 10, 11 et 12. Je ne sais ‘ pas pourquoi. PinchangeInt devrait fonctionner sur nimporte quelle broche numérique
  • Mais vous utilisez la broche 10? Quoi quil en soit, heureux que cela fonctionne.

Réponse

Seuls certains ports sur lAtmega2560 prennent en charge les interruptions de changement de broche, en particulier les ports B, E (bit 0), J (bits 0 à 6) et K.

En regardant le schéma de référence qui signifie que ces broches sur la carte sont supportées:

 Chip Name Pin Pin on board ----------------------- Port B PB0 - 19 - D53 (SS) PB1 - 20 - D52 (SCK) PB2 - 21 - D51 (MOSI) PB3 - 22 - D50 (MISO) PB4 - 23 - D10 PB5 - 24 - D11 PB6 - 25 - D12 PB7 - 26 - D13 Port E PE0 - 2 - D0 (RXD0) Port J PJ0 - 63 - D15 (RXD3) PJ1 - 64 - D14 (TXD3) PJ2 to PJ6 - not connected on board Port K PK0 - PK7 - (89 - 82) - A8 - A15 

Ainsi vous pouvez voir que D10 à D12, qui, selon vous, fonctionne, sont dans cette liste. Les autres aléatoires ne le seraient pas.


SoftwareSerial

Vous pouvez voir la confirmation sur la page de SoftwareSerial où il est dit:

Toutes les broches des Mega et Mega 2560 ne prennent pas en charge les interruptions de changement, donc seuls les éléments suivants peuvent être utilisés pour RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

Ceci est dû au fait que SoftwareSerial utilise des interruptions de changement de broches pour détecter les données série entrantes, et donc la clause de non-responsabilité sur cette page concernant les broches avec lesquelles il fonctionnera.


Brochage Atmega2560

Brochage Atmega2560


PinchangeInt devrait fonctionner sur nimporte quelle broche numérique

Notez que lAtmega328P (tel quutilisé dans lUno) a moins de ports, et tous sont disponibles pour les interruptions de changement de broches sur cette carte.

Commentaires

  • Cela peut ‘ t être correct. La première page liée par OP revendique que les broches 2, 3, 18, 19, 20 et 21 peuvent être utilisées pour les interruptions. Celles-ci correspondent à PE4, PE5, PD3, PD2, PD1 et PD0, selon goo.gl/DvHEUA et goo.gl/xAwBGM Pour ma part, je ‘ je me préoccupe davantage de savoir si PORTC peut être utilisé, comme dans ros_arduino_bridge: goo.gl/rq6yQO
  • La page liée fait référence aux interruptions externes mais lOP utilise les interruptions de changement de broche comme vous pouvez le voir à partir de #include <PinChangeInt.h>. Les broches dinterruption de changement de broche sont celles que jai répertoriées.
  • Je vois. Javais une idée qui pourrait être la distinction, mais jai supposé que toutes les broches capables dinterruptions externes seraient également capables de changer de broches, mais pas linverse.

Réponse

Sur lATmega1280 / 2560, seuls les ports B, J, F et K ont une capacité dinterruption de changement de broche. Celles-ci correspondent approximativement aux broches 10 à 15, 50 à 53 et A6 à A15 (bien quune partie du port J ne soit pas mappée aux broches Arduino, par conséquent PCINT11 à PCINT15 ne sont pas disponibles sur lArduino Mega / Mega 2560).

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *