RobG 1,892 Posted February 21, 2011 Author Share Posted February 21, 2011 With all the pins we are saving, using one as input would not be that bad. Even if we use 4 lower bits to drive switch columns and then 3 or 4 inputs to read rows, we still have 4 or 3 pins available to do things like serial comm and more. Quote Link to post Share on other sites
bluehash 1,581 Posted February 21, 2011 Share Posted February 21, 2011 Mac.. how do you make those schematics. Quote Link to post Share on other sites
Mac 67 Posted February 21, 2011 Share Posted February 21, 2011 Mac.. how do you make those schematics. The drawings are Excel 2007 spreadsheets (made using the drawing tools)... bluehash 1 Quote Link to post Share on other sites
RobG 1,892 Posted February 21, 2011 Author Share Posted February 21, 2011 Since we started talking about connecting a keypad and we have another thread talking about building a calculator, I decided to expand this post and... add a keypad. I bought mine from futurlec for <$5 when I was thinking of building DTMF generator and now it will make a perfect calculator pad. Here's my backpack with new keypad header: And the complete setup showing 4 wires from LP to keypad, 4 wires from keypad to backpack, and 5 wires from backpack to LP. We still have 3 pins unused on our LP! Code to follow. Quote Link to post Share on other sites
zeke 693 Posted February 21, 2011 Share Posted February 21, 2011 Mac.. how do you make those schematics. The drawings are Excel 2007 spreadsheets (made using the drawing tools)... Sorry for hijacking the topic... Mac, you're going to have to do a screencast of you making a drawing. I have to see this with my own eyes. gatesphere 1 Quote Link to post Share on other sites
RobG 1,892 Posted February 22, 2011 Author Share Posted February 22, 2011 Here's the code to read the keypad and then display 2 characters. Each key represents a bit, 1 is bit0, A bit4, D bit15, and by pressing multiple keys, you can display appropriate characters. More to come, maybe RPN calculator? Programmable power supply (I still have 3 inputs to measure voltage and current and I didn't get to ADC yet.) #include "msp430g2231.h" #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) #define DATAPIN BIT6 #define CLOCKPIN BIT5 #define ENABLEPIN BIT4 #define BIT0_3 0x0F void send(char data, char registerSelect); void sendDataArray(char data[], char length); char charIndex = 0; char bitCounter = 0; char charsToSend[2] = {0,0}; int keypadPrevState = 0; int keypadCurrState = 0; int keypadPress = 0; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; _delay_cycles(100000); P1OUT &= ~(CLOCKPIN + DATAPIN); P1OUT |= ENABLEPIN; P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN; initDisplay(); P1REN |= BIT0_3; P1OUT |= BIT0_3; CCTL0 = CCIE; CCR0 = 6250; TACTL = TASSEL_2 + MC_1 + ID_3; _bis_SR_register(LPM0_bits + GIE); } // Timer A0 interrupt service routine #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A (void) { keypadCurrState = 0; bitCounter = 0; P1OUT |= DATAPIN; while(bitCounter < 4) { P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; } bitCounter = 0; while(bitCounter < 4) { (bitCounter == 0) ? (P1OUT &= ~DATAPIN) : (P1OUT |= DATAPIN); P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; keypadCurrState <<= 4; keypadCurrState |= (0x000F & P1IN); } if(keypadCurrState != keypadPrevState) { clearDisplay(); charsToSend[0] = keypadCurrState & 0x00FF; charsToSend[1] = (keypadCurrState >> 8) & 0x00FF; sendDataArray(charsToSend, 2); } keypadPrevState = keypadCurrState; } void sendDataArray(char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } void send(char data, char registerSelect) { //TODO may need to disable interrupt bitCounter = 0; while(bitCounter < 8) { (data & BIT7) ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); data <<= 1; P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; } registerSelect ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); P1OUT &= ~ENABLEPIN; P1OUT |= ENABLEPIN; //TODO may need to enable interrupt } bluehash and zeke 2 Quote Link to post Share on other sites
zeke 693 Posted February 22, 2011 Share Posted February 22, 2011 Dude! You are on a roll! Good job!! Quote Link to post Share on other sites
RobG 1,892 Posted February 22, 2011 Author Share Posted February 22, 2011 Dude! You are on a roll! Good job!! It's either that or watching Bachelor with my wife just kidding. I just can't sleep when some idea is planted in my head. Quote Link to post Share on other sites
RobG 1,892 Posted February 23, 2011 Author Share Posted February 23, 2011 I was going to do write a little program to convert decimal/hex/bin to dec/hex/bin, but then I realized my keypad doesn't have E or F. I guess I could allow just dec and bin input and hex as output only, but for now, here's a code to input numbers and A-D. * clears display, # switches between rows. #include "msp430g2231.h" #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) #define DATAPIN BIT6 #define CLOCKPIN BIT5 #define ENABLEPIN BIT4 #define BIT0_3 0x0F const char charMap[16] = { 0x31,0x32,0x33,0x41,0x34,0x35,0x36,0x42,0x37,0x38,0x39,0x43,0x00,0x30,0x00,0x44 }; void send(char data, char registerSelect); void sendDataArray(char data[], char length); char charIndex = 0; char bitCounter = 0; char line = 0; int keypadPrevState = 0; int keypadCurrState = 0; int keypadPress = 0; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; _delay_cycles(100000); P1OUT &= ~(CLOCKPIN + DATAPIN); P1OUT |= ENABLEPIN; P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN; initDisplay(); P1REN |= BIT0_3; P1OUT |= BIT0_3; CCTL0 = CCIE; CCR0 = 6250; TACTL = TASSEL_2 + MC_1 + ID_3; _bis_SR_register(LPM0_bits + GIE); } // Timer A0 interrupt service routine #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A (void) { keypadCurrState = 0; bitCounter = 0; P1OUT |= DATAPIN; while(bitCounter < 4) { P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; } bitCounter = 0; while(bitCounter < 4) { (bitCounter == 0) ? (P1OUT &= ~DATAPIN) : (P1OUT |= DATAPIN); P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; keypadCurrState <<= 4; keypadCurrState |= (0x000F & P1IN); } keypadPress = keypadCurrState ^ keypadPrevState; keypadPress &= ~keypadCurrState; keypadPrevState = keypadCurrState; if(keypadPress) { if(keypadPress & BITC) { clearDisplay(); line = 0; } else if(keypadPress & BITE) { sendInstruction(line ? 0x80 : 0xC0); line ^= 1; } else { char bit = 0; while(bit < 16) { if(keypadPress & BIT0) { sendData(charMap[bit]); } keypadPress >>= 1; bit++; } } } } void sendDataArray(char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } void send(char data, char registerSelect) { bitCounter = 0; while(bitCounter < 8) { (data & BIT7) ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); data <<= 1; P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; } registerSelect ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); P1OUT &= ~ENABLEPIN; P1OUT |= ENABLEPIN; } jim940 1 Quote Link to post Share on other sites
Mac 67 Posted February 23, 2011 Share Posted February 23, 2011 Looks great! Way to go, Rob... Quote Link to post Share on other sites
timotet 44 Posted February 27, 2011 Share Posted February 27, 2011 great work! Quote Link to post Share on other sites
RobG 1,892 Posted February 27, 2011 Author Share Posted February 27, 2011 Just FYI, if anybody needs to read from LCD, I am currently working on expanding my serial backpack to be bi-directional. It will require 5 or 4 wires. bluehash 1 Quote Link to post Share on other sites
timotet 44 Posted March 4, 2011 Share Posted March 4, 2011 So Ive managed to get RobG's code to work on the Wintek 1 x 24 Character LCD Display Module that I got awhile ago from Electronic Goldmine for $1.99. Here's the link: http://www.goldmine-elec-products.com/p ... ber=G15318 There are only 2 cons so far: 1 It takes 5v to power the display. 2 It takes 4 wires instead of 3. ( you have to toggle the reset pin on the display.) logic seems to work fine at the 3.6v the msp430 puts out. here's the code: /* hex instructions for display setup 0x1C == LCD power control PW 0x14 == Display on/off DO 0x28 == Display Control sets lines ect. DC 0x4F == Contrast Set CN 0xE0 == DDRAM address set DA */ #include "msp430g2452.h" #define sendData(data) send(data, 1) #define sendInstruction(data) send(data, 0) #define clearDisplay() sendInstruction(0x01); _delay_cycles(2000) #define DATAPIN BIT6 #define CLOCKPIN BIT5 #define ENABLEPIN BIT4 #define RESETPIN BIT7 void send(char data, char registerSelect); void sendDataArray(char data[], char length); //void resetPin(unsigned int bit); void initDisplay(void); char charIndex = 0; char bitCounter = 0; const char message1[8] = {0x34,0x33,0x6F,0x68,0x2E,0x63,0x6F,0x6D}; char message2[11] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0xA4}; const char message3[16] = {0x34,0x2D,0x70,0x69,0x6E,0x20,0x73,0x65,0x72,0x69,0x61,0x6C,0x20,0x4C,0x43,0x44}; char message4[12] = {0x54,0x68,0x61,0x6E,0x6B,0x73,0x20,0xAE,0x6F,0x62,0x47,0x21}; void main(void) { WDTCTL = WDTPW + WDTHOLD; _delay_cycles(100000); P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN + RESETPIN; // sets ENABLEPIN,CLOCKPIN,DATAPIN and RESETPIN to outputs P1OUT &= ~(CLOCKPIN + DATAPIN + RESETPIN); // sets CLOCKPIN,RESETPIN and DATAPIN low P1OUT |= ENABLEPIN; // sets ENABLEPIN high initDisplay(); // initiate display while(1) { // send const message using sendDataArray clearDisplay(); sendDataArray((char *)message1, 8); _delay_cycles(3000000); // send message using sendDataArray clearDisplay(); sendDataArray(message2, 11); _delay_cycles(3000000); // send message one char at the time clearDisplay(); charIndex = 0; while(charIndex < 16) { sendData(message3[charIndex]); charIndex++; } _delay_cycles(3000000); // send message using sendDataArray clearDisplay(); sendDataArray(message4, 12); _delay_cycles(3000000); } } void sendDataArray(char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } void send(char data, char registerSelect) { bitCounter = 0; while(bitCounter < 8) { (data & BIT7) ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); data <<= 1; P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; } registerSelect ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); P1OUT &= ~ENABLEPIN; _delay_cycles(3000); P1OUT |= ENABLEPIN; _delay_cycles(10000); P1OUT &= ~ENABLEPIN; } void initDisplay(void) { P1OUT &= ~RESETPIN; // RESETPIN low _delay_cycles(10000); P1OUT |= RESETPIN; //RESETPIN high sendInstruction(0x1C); //PW sendInstruction(0x14); //DO 0x14 sendInstruction(0x28); //DC 0x28 sendInstruction(0x4F); //CN 0x4F sendInstruction(0xE0); //DA //sendInstruction(0x72); //SC //sendInstruction(0xC); //CR } roger430, RobG and bluehash 3 Quote Link to post Share on other sites
bluehash 1,581 Posted March 4, 2011 Share Posted March 4, 2011 Pretty neat timotet! Thanks for sharing your code. Quote Link to post Share on other sites
Mac 67 Posted March 4, 2011 Share Posted March 4, 2011 So Ive managed to get RobG's code to work on the Wintek 1 x 24 Character LCD Display Module that I got awhile ago from Electronic Goldmine for $1.99. Nicely done Tim. That looks like a very nice display. If anyone is interested, I found some additional info' on it, including a link to a data sheet for it, here. Cheerful regards, Mike 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.