RobG 1,892 Posted July 27, 2011 Share Posted July 27, 2011 So here is my final (for now) encoder implementation, most reliable 2 pin so far. 1. Increased capacitors to 1uF electrolytic (did try to debounce in software with WDT, but results were not so good.) 2. Encoder A is P1.6, B is P1.7 3. No other pins will use interrupts on P1 4. Only one switch can interrupt at any time, this eliminates most of the problems with rocking and bouncing 5. I really need to get something better than PEC11, about 90-120 deg of the turn produces horrible results. #include "msp430g2553.h" //required funct.asm #define APIN BIT6 #define BPIN BIT7 #define DPINT P1IE = 0; #define CLRPFG P1IFG = 0; #define LOWERNIBBLE BIT0 + BIT1 + BIT2 + BIT3 #define UPPERNIBBLE BIT4 + BIT5 + BIT6 + BIT7 #define ENABLEPIN BIT4 #define REGISTERSELECTPIN BIT5 #define sendData(data) send(data, 1) #define sendInstruction(data) send(data, 0) #define initDisplay() sendInstruction(0x3C); sendInstruction(0x0C); clearDisplay(); sendInstruction(0x06) #define clearDisplay() sendInstruction(0x01); _delay_cycles(2000) void binaryToASCIIScale(unsigned int n, unsigned char * digits, unsigned int scale); // asm prototype unsigned char d[5] = {0,0,0,0,0}; void sendDataArray(unsigned char data[], char length); void send(unsigned char data, unsigned char registerSelect); char charIndex = 0; char valueIndex = 0; int counter = 500; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = ENABLEPIN; P1DIR = ENABLEPIN + REGISTERSELECTPIN + LOWERNIBBLE; P2SEL &= ~(BIT6|BIT7); P2DIR = UPPERNIBBLE; P1IES = BPIN; CLRPFG; _delay_cycles(10000); // delay to allow display to settle down, might not be needed initDisplay(); _bis_SR_register(GIE); P1IE = BPIN; while(1) { sendInstruction(0x80); binaryToASCIIScale(counter>>1, d, 0); sendDataArray(d, 5); _bis_SR_register(LPM0_bits); } } void sendDataArray(unsigned char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } void send(unsigned char data, unsigned char registerSelect) { P1OUT &= 0xF0; P1OUT |= data & 0x0F; P2OUT &= 0x0F; P2OUT |= data & 0xF0; registerSelect ? (P1OUT |= REGISTERSELECTPIN) : (P1OUT &= ~REGISTERSELECTPIN); P1OUT &= ~ENABLEPIN; P1OUT |= ENABLEPIN; } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { DPINT; // disable interrupts on port 1 if(P1IFG & APIN) { // interrupt came from switch A CLRPFG; // clear interrupt flags if((P1IES & APIN) ^ (P1IN & BPIN)) { // XOR IES of A with level of B to determine dir counter--; } else { counter++; } (P1IN & BPIN) ? (P1IES |= BPIN) : (P1IES &= ~BPIN); // set IES of B based on it's current level, safer than toggling P1IE = BPIN; // enable interrupts for switch B } else { // interrupt came from switch A CLRPFG; // clear interrupt flags if((P1IES & BPIN) ^ (P1IN & APIN)) { // XOR IES of B with level of A to determine dir counter++; } else { counter--; } (P1IN & APIN) ? (P1IES |= APIN) : (P1IES &= ~APIN); // set IES of A based on it's current level P1IE = APIN; // enable interrupts for switch A } _bic_SR_register_on_exit(LPM0_bits); } bluehash and kenemon 2 Quote Link to post Share on other sites
kenemon 29 Posted July 29, 2011 Author Share Posted July 29, 2011 did you guys see this one? http://cgi.ebay.com/ws/eBayISAPI.dll?Vi ... K:MEWNX:IT hell of a deal, but no push switch Quote Link to post Share on other sites
kenemon 29 Posted August 4, 2011 Author Share Posted August 4, 2011 Hey Rob, please help me find funct.asm Quote Link to post Share on other sites
RobG 1,892 Posted August 4, 2011 Share Posted August 4, 2011 Here it is funct.rar kenemon 1 Quote Link to post Share on other sites
Mac 67 Posted August 10, 2011 Share Posted August 10, 2011 ... you've come up with simplest and most elegant solution I've seen. @Mac: Please don't heap praise on me. I stand on the shoulders of others on this topic. In this case, I located the sample code on this blog entry. I only adapted it to CSS from mspgcc. Then thank you (Zeke) for passing along a good idea. I implemented it (on the circuit below) by adding a few lines of code to my parallel switch state logic and it's working surprisingly well. Since the switch state logic is designed to filter out all but a "new press" switch state, it works extremely well for filtering out all but a single A or B encoder transition between detents. Check out this excerpt from my test program (a small eight line mux' routine fills the 'swnew' sample variable); /* * * Mike McLaren's parallel switch state logic (plus encoder) * * * * swnew ___---___---___---___ inverted active lo sample * * swold ____---___---___---__ switch state latch * * swnew ___-__-__-__-__-__-__ changes, press or release * * swnew ___-_____-_____-_____ filter out 'release' bits * * flags ____------______----- toggle flag bits for main * * */ swnew ^= swold; // changes, press or release swold ^= swnew; // update switch state latch swnew &= swold & 0xEF; // filter out 'release' bits if(swnew & 0x20) // if encoder B "new press" { if(swold & 0x10) // if opposite direction swnew ^= 0x30; // toggle up/dn switch flags } // /* * * test for encoder "new press" and bump "count" accordingly * * */ if(swnew & 0x20) // increment 'count' count = _bcd_add_short(count,0x01); if(swnew & 0x10) // decrement 'count' count = _bcd_add_short(count,0x99); I'll post a demo' program in a new thread. That is, if anyone is interested. Cheerful regards, Mike oPossum and zeke 2 Quote Link to post Share on other sites
zeke 693 Posted August 11, 2011 Share Posted August 11, 2011 I'll post a demo' program in a new thread. That is, if anyone is interested. Don't think like that. Of course we're interested! :thumbup: Quote Link to post Share on other sites
gwdeveloper 275 Posted October 7, 2011 Share Posted October 7, 2011 Good work to everyone on all of this. I have a question about simplifying the debouncing of a rotary encoder... Could a hardware debouncer such as the Maxim MAX6817 be used to get a pure, clean digital signal from a rotary encoder? http://www.maxim-ic.com/datasheet/index.mvp/id/1896 I got a few of the 6817s as samples for a device I'm working on after seeing this post http://dangerousprototypes.com/2011/09/25/debounced-breadboard-keypad/ on dangerousprototypes' blog. Tonight, I was thinking it might work on a rotary as well. Quote Link to post Share on other sites
bluehash 1,581 Posted October 7, 2011 Share Posted October 7, 2011 I would go for a hardware debouncer if it weren't too expensive. You should whip out a booster pack. Quote Link to post Share on other sites
zeke 693 Posted October 7, 2011 Share Posted October 7, 2011 I believe RobG already implemented a hardware debounce circuit. I wonder which post that's hiding in? Oh! It's this one. Back on page 2 there are a couple hardware debounce circuits. gwdeveloper 1 Quote Link to post Share on other sites
gwdeveloper 275 Posted October 7, 2011 Share Posted October 7, 2011 @zeke thanks, man. It should probably work with the MAX6817 then with no issues and less parts count. @bluehash That's a great idea. I have a few of the MAX6818 octal debouncers as well. Maybe a shield that has a the 6818, one or two rotary encoders and a few buttons all hardware debounced? ---- Honestly, I'm still struggling through making my own schematics and boards in Eagle. Is there a file or post somewhere that contains a blank shield template to start with? I've already created the part and footprint for the 6817 if anyone wants it. RobG 1 Quote Link to post Share on other sites
gordon 229 Posted October 7, 2011 Share Posted October 7, 2011 Unless someone beats me to it (do! please do! pretty please with sugar on top!), I'll try to glue together a LaunchPad device in the coming days. Quote Link to post Share on other sites
gordon 229 Posted October 7, 2011 Share Posted October 7, 2011 Here's a quick one. Haven't even made a printout to compare to the device, so quick one . Should be more or less OK, though. Includes the main LaunchPad obstacles on tDocu, might come handy if you plan populating the bottom as well. I'll eventually add a reduced 5cm x 5cm package as well, as it is a popular cheap option. (BH: .lbr is still not allowed) Edit: the current version can be found at viewtopic.php?f=10&t=1684#p11477 gwdeveloper 1 Quote Link to post Share on other sites
SugarAddict 227 Posted October 7, 2011 Share Posted October 7, 2011 Fixed some misalignment and increased pad sizes to be comparable to the LP pads. TI_launchpad.zip gordon, gwdeveloper and bluehash 3 Quote Link to post Share on other sites
gwdeveloper 275 Posted October 7, 2011 Share Posted October 7, 2011 Thanks guys! I'm going to finish off the MAX681x library with a single and octal and design a booster 'shield'. (or Sword as I read it in another thread ) Quote Link to post Share on other sites
gordon 229 Posted October 7, 2011 Share Posted October 7, 2011 design a booster 'shield'. (or Sword as I read it in another thread ) I thought we called them Payloads :shh: There are tiny bits of enhancements still to come. I did them already, now waiting for SugarAddict to come around, check them then post the updated lib (I'll probably be fast asleep the whole weekend); you may want to wait for that . Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.