背景
Arduino Mega 2560 。現在、トラブルシューティングを簡単にするために、1つのチャネルを読み取るだけのコードを保持しています。問題は、共有変数が更新されていないため、割り込みが発生したと思われることです。サービスルーチンが立ち上がりエッジを検出していません。
レシーバーが壊れていると思ったので、標準のArduino接続割り込み機能を使用してテストしました。 。完全に機能したので、受信機は問題ありません。
Serial.print()を使用して、揮発性チャネル変数が更新されているかどうかを確認しました(つまり、その値をチャネル1フラグ値に変更します)。更新されていなかったため、 ISR が間違っている必要があります。元のコードは次の場所にあります。ブログ投稿。
何が問題なのですか?アイデアが足りません。
#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; } }
コメント
- コードを単純化してみてください。たとえば、ISRにLEDを点灯させます。'本質的に問題はありません。
- わかりました。何らかの理由で、ピン10、11、12でのみ機能します。'理由はわかりません。PinchangeIntはどのデジタルピンでも機能するはずです
- しかし、ピン10を使用していますか?とにかく、機能してよかったです。
回答
Atmega2560の一部のポートのみがピン変更割り込みをサポートします。具体的には、ポートB、E(ビット0)、J(ビット0〜6)およびK。
ボード上のこれらのピンがサポートされていることを意味する参照回路図を見てください:
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
したがって、動作すると言うD10からD12がそのリストに含まれていることがわかります。他のランダムなものは、含まれていません。
SoftwareSerial
SoftwareSerial のページに確認が表示されます。
MegaおよびMega2560のすべてのピンが変更割り込みをサポートしているわけではないため、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)。
これは、SoftwareSerialがピン変更割り込みを使用して着信シリアルデータを検出するためです。したがって、そのページのどのピンで動作するかについての免責事項があります。
Atmega2560ピン配列
PinchangeIntはすべてのデジタルピンで機能するはずです
Atmega328P(Unoで使用されている)のポートは少なく、すべてがそのボードのピン変更割り込みに使用できることに注意してください。
コメント
- これは'正しくありません。 OPクレームピン2、3、18、19、20、および21によって最初にリンクされたページは、割り込みに使用できます。 goo.gl/DvHEUA と goo.gl/xAwBGM 私としては、' ros_arduino_bridgeのようにPORTCを使用できるかどうかについてもっと心配しています: goo.gl/rq6yQO
- リンクされたページは外部割り込みを参照していますが、OPはピン変更割り込みを次のように使用しています
#include <PinChangeInt.h>
から確認できます。ピン交換割り込みピンは私がリストしたものです。 - なるほど。区別できるかもしれないインクリングがありましたが、外部割り込みが可能なすべてのピンがピン変更も可能であると想定しましたが、その逆ではありませんでした。
回答
ATmega1280 / 2560では、ポートB、J、F、およびKのみがピン変更割り込み機能を備えています。これらはおおよそピン10から15、50から53、およびA6からA15にマップされます(ただし、ポートJの一部はArduinoピンにマップされていないため、PCINT11からPCINT15はArduino Mega / Mega 2560では使用できません)。