The main Logic is :
1.Calculate PWM Starting Value during Raising Edge
2.When Falling Edge Detected Calculate Width
1.Calculate PWM Starting Value during Raising Edge
2.When Falling Edge Detected Calculate Width
/* Author : Kunchala Anil Email : anilkunchlaece@gmail.com Date : 6 Mar 2018 Pin Change Interrupts - Single Rx Channel i.e Single PWM Wave PCMSKx - Pin Change Mask Register PCMSK0 - portB (D8-D13) (PCINT0 - PCINT6) PCMSK1 - portC (A0-A5) (PCINT8 - PCINT14) PCMSK2 - portD (D0-D7) (PCINT16 - PCINT23) PCICR - Pin Change Interrupt Control Register PCIE0 - Pin Change Interrupt Enable 0 - Port B (D8-D13) PCIE1 - Pin Change Interrupt Enable 1 - Port C (A0-A5) PCIE2 - Pin Change Interrupt Enable 2 - Port D (D0-D7) */ /*############################# Rx Connections Ch1 = D8 PCINT0 Ch2 = D9 PCINT1 Ch3 = D10 PCINT2 Ch4 = D11 PCINT3 */ #define DEBUG // comment it out to disable the debug mode volatile boolean recvPCInt = false; //to know interrupt status volatile int portValue; //used to store the pwm duration volatile unsigned long pwmDuration[4]; volatile unsigned long pwmStart[4]; unsigned long pwmEnd[4]; //pinDeclaration for Rx const byte rxCh[] = {8, 9, 10, 11}; const byte noOfChannels = sizeof(rxCh); //portStatus volatile int prevPortState[] = {0, 0, 0, 0}; volatile int presentPortState[4]; //Interrupt Service Routine will fire when for PinChange in PortB ISR(PCINT0_vect) { recvPCInt = true; for (int ch = 0; ch < noOfChannels ; ch++) { presentPortState[ch] = digitalRead(rxCh[ch]); }//end of for loop for (int c = 0; c < noOfChannels ; c++) { if (prevPortState[c] == 0 & presentPortState[c] == 1) { //if previous state is 0 and present state is 1 (Raising Edge) then take the time stamp pwmStart[c] = micros(); prevPortState[c] = 1; //update the prevPort State } else if (prevPortState[c] == 1 & presentPortState[c] == 0) { //if previous state is 1 and present state is 0 (Falling Edge) then calculate the width based on the change pwmDuration[c] = micros() - pwmStart[c]; prevPortState[c] = 0; //update Present PortState } }//end of for loop //portValue = PINB & 0x0f;//we are only intrested in first four bits } void setup() { cli(); //Clear all interrupts PCICR |= 1 << PCIE0; //Enable port B Registers i.e D8-D13 PCMSK0 |= (1 << PCINT0) | (1 << PCINT1) | (1 << PCINT2) | (1 << PCINT3);// Pin8,9,10,11 sei(); //enable all interrupts #ifdef DEBUG Serial.begin(9600); Serial.println("DEBUG mode Enabled"); #endif for (int ch = 0 ; ch < noOfChannels; ch++) { pinMode(rxCh[ch], INPUT_PULLUP); //make pin input with pullup enabled }//end of for loop }//end of setup void checkForRxPulseWidths() { for (int i = 0; i < noOfChannels ; i++ ) { #ifdef DEBUG Serial.print("ch => "); Serial.print(i); Serial.print(" pulseWidth "); Serial.println(pwmDuration[i]); #endif } } void loop() { if (recvPCInt == true) { checkForRxPulseWidths(); recvPCInt = false; }//end of if }//end of loop
No comments:
Post a Comment