Beginners: please read this post and this post before posting to the forum.
0 Members and 1 Guest are viewing this topic.
#define rcVer 1#define rcRev 0#define rcMaxChannels 6 // Maximum R/C channels#define RC_NO_SIGNAL -127 // Value to use if no signal is present#define rcSignals2BeValid 8 // Must see at least this many pulses to consider radio to be on#define rcMaxDroppedSignals 3 // Must lose this many pulses to consider radio off// The following min/max are used to filter out noise and interference.#define rcBasePeriodMin 21800 // Min base period in uS#define rcBasePeriodMax 22200 // Max base period in uS#define rcPulseTimeMin 950 // Min pulse period in uS#define rcPulseTimeMax 2050 // Max base period in uS#define rcPinMask 0x3F // Mask to turn on all R/C pins.// Connect R/C inputs to Bank K 0-7 (input pins 8-15)// R/C channel 1 -> K0// R/C channel 2 -> K1// R/C channel 3 -> K2// R/C channel 4 -> K3// R/C channel 5 -> K4// R/C channel 6 -> K5// R/C channel 7 -> K6// R/C channel 8 -> K7// Build a structure to hold the data for each pinstruct { unsigned long int startTime; unsigned long int pulseTime; unsigned long int basePeriod; signed int signalsUntilValid; signed int pct; // Value range from -100 to 100 } rcPin[rcMaxChannels];// Global variable that can be used to determine if the radio is on or off.// #define of OFF and ON in main.h// #define ON 1// #define OFF 0int rcState=OFF;signed int rcGetChannel(unsigned int channel) { /***************************************************/ /* Get the current value of the requested channel. */ /* Returns percent as -100 to 100 */ /***************************************************/ return(rcPin[channel-1].pct);}int rcIsOn(void) { /******************************/ /* Returns state of R/C radio */ /******************************/ return rcState;}unsigned long int rcGetDiff(unsigned long int now, unsigned long int last) { /*************************************************/ /* Get the time difference between now and last */ /* Must divide by 2 since prescale only /8 and */ /* CPU is 16Mz. getTimeDiff defined elsewhere... */ /* #define getTimeDiff(now,last) ((last>now)?(65535-last+now):(now-last)) */ /*************************************************/ return (getTimeDiff(now,last)/2);}ISR (PCINT2_vect){ /********************************/ /* Handle pin changes on PORT K */ /* via interrupts. */ /********************************/ u08 pulseDefRise,pulseDefFall; static u08 prevState; // Holds the previous state of K7-0 u08 currState=PINK; // Get current state of K7-0 u08 mask; unsigned long int now=TCNT5; // Timer5. Rolls over at 65535 pulseDefRise = (~prevState) & ( currState); // Rising edges pulseDefFall = ( prevState) & (~currState); // Falling edges for (int pin=0;pin<rcMaxChannels;pin++) { mask=0x01<<pin; if(pulseDefRise & mask){ // Rising edge /* Rising edge to rising edge = base period */ rcPin[pin].basePeriod=rcGetDiff(now,rcPin[pin].startTime); // Calculate base period rcPin[pin].startTime=now; } else if(pulseDefFall & mask){ // Falling edge /* Rising edge to falling edge = pulse time */ rcPin[pin].pulseTime=rcGetDiff(now,rcPin[pin].startTime); // Calculate pulse time /* Determine if the pulse is good */ if (rcPin[pin].basePeriod > rcBasePeriodMin && rcPin[pin].basePeriod < rcBasePeriodMax && rcPin[pin].pulseTime > rcPulseTimeMin && rcPin[pin].pulseTime < rcPulseTimeMax) { // Possible good signal if (rcPin[pin].signalsUntilValid > -rcMaxDroppedSignals) { rcPin[pin].signalsUntilValid--; if (rcPin[pin].signalsUntilValid==0) { // Saw enough to be good rcPin[pin].signalsUntilValid=-rcMaxDroppedSignals; } } } else { // Possible lost signal if (rcPin[pin].signalsUntilValid < rcSignals2BeValid) { rcPin[pin].signalsUntilValid++; if (rcPin[pin].signalsUntilValid==0) { // Lost too many in a row rcPin[pin].signalsUntilValid=rcSignals2BeValid; } } } } } prevState=currState;}void rcDoUpdate(void) { /***************************************************/ /* Sanity check and convert R/C inputs. */ /* This process should be run on a regular basis */ /* based on the update freqency required for */ /* reading the R/C values. */ /***************************************************/ int tmpState=OFF; for (int pin=0;pin<rcMaxChannels;pin++) { if (rcPin[pin].signalsUntilValid<0) { tmpState=ON; } if (rcPin[pin].signalsUntilValid==-rcMaxDroppedSignals) { // Last pulse was valid so convert it to a percentage rcPin[pin].pct=rcReceiverConvert(rcPin[pin].pulseTime); } else { // Last pulse may not be valid so don't use rcPin[pin].pct=RC_NO_SIGNAL; } } if (tmpState) { LED_on(); } else { LED_off(); } rcState=tmpState;}void rcInit(void) { /*****************************/ /* Set up interrupts for R/C */ /*****************************/ rprintf(" R/C: \t%d",rcVer); rprintf(".%d\t",rcRev); // Clear all channel info for (int pin=0;pin<rcMaxChannels;pin++) { rcPin[pin].pct=RC_NO_SIGNAL; rcPin[pin].signalsUntilValid=rcSignals2BeValid; } // Enable PCINT2 PCICR=0x04; // Turn on for 6 channels PCMSK2=rcPinMask; // 00 A off, toggle on compare // 00 B on, toggle on compare // 00 C on, toggle on compare // 00 Low part of WGM: None TCCR5A=0x00; // 0 No input noise cancelling // 0 Input edge select does not matter // 0 Not used // 00 High part of WGM: None // 010 Prescale 8 TCCR5B=0x02; // Clear TCNT TCNT5H=0x00; TCNT5L=0x00; // Enable timer5 overflow interrupt // TIMSK5=0x01; // Schedule update schedAdd(rcDoUpdate,timerRcDoUpdate); // Done rprintf("done\r\n");}
a slight misalignment causing a left turn when told to go straight. I was able to correct the alignment with shims.
What's a shim?
Detect stairs - I have yet to find a good way to determine when it is about to plummet down the stairs or any other abrupt edge like that