websterling 12 Posted September 8, 2011 Share Posted September 8, 2011 I'm working on a project requiring a calculated 3-digit number to be updated periodically on a LCD display and came up with a simple solution to convert the number to characters. I'm posting it here on the chance that others might find it useful. I first thought of sprintf, but it's way too big for a msp430g2452. I found and tried tfp_sprintf, but it was also too big. I tried sstream (apparently the preferred method) but it caused 100+ errors in CCS, somewhere in the TI include files. I found this to convert a single digit to a character character = (char)(((int)'0') + digit_to_convert); I had a 3 digit number to convert; after a bit of thought I came up with this- // All number variables are type int // joules is the calculated 3-digit number- it is displayed with leading joules = total_seconds/3.2; joules100 = joules/100; // joules100 is the 100's place digit joules10 = (joules/10)%10; // joules10 is the 10's place digit joules1 = joules%10; // joules1 is the 1's place digit // The complete message is in a 32 element array- these 3 digits are elements 22-24 message[22] = (char)(((int)'0')+joules100); message[23] = (char)(((int)'0')+joules10); message[24] = (char)(((int)'0')+joules1); nuetron and bluehash 2 Quote Link to post Share on other sites
nuetron 64 Posted September 9, 2011 Share Posted September 9, 2011 Hi webster, I've also found a useful int-to-char converter: void tostr(int i,char *s) { // Convert Integer to String char *p; p=s; p[2]=i%10; i-=p[2]; i/=10; p[1]=i%10; i-=p[1]; i/=10; p[0]=i%10; i-=p[0]; p[3] = 0; // mark end of string p[2]+=0x30; p[1]+=0x30; p[0]+=0x30; } I hope you don't mind me going into microscopic detail for others' benefit; This will take an integer and a string[4], and perform modulo, division, and subtraction on the int, generating the answers in the string, and adds 0x30 to each element in the string to convert it to ASCII for an LCD to read. So, when calling this, if we set the arguments to nVar and blah[4], it should look like this: int nVar = 0x7F; // give nVar a set value tostr(nVar, blah[4]); The values of the elements in blah[4] would be as follows: blah[0] = 0x31 blah[1] = 0x32 blah[2] = 0x37 blah[3] = 0x00 And, if printed on an HD44780 character display, it would appear as: 127 Quote Link to post Share on other sites
gordon 229 Posted September 9, 2011 Share Posted September 9, 2011 void tostr(int i,char *s) { // Convert Integer to String This will take an integer and a string[4] Slightly uh, no. This will take a pointer to a char array; you probably mean the right thing, but string[4] is very bad parlance, because So, when calling this, if we set the arguments to nVar and blah[4], it should look like this: int nVar = 0x7F; // give nVar a set value tostr(nVar, blah[4]); Very uh, no . blah[4] is one single char, the last element in something that was presumably declared as char blah[4]; basically, this passes literally one byte worth of storage to the function to work with; to the function that doesn't check its arguments (which might, might be explainable in a constrained environment but also means you have to be very, very, very careful not to make these kinds of mistakes) and will happily overwrite whatever is next to this in memory. nuetron 1 Quote Link to post Share on other sites
nuetron 64 Posted September 9, 2011 Share Posted September 9, 2011 OOPS!!! :oops: Sorry and thanks for pointing that out, as you can see I'm still learning... to type... or post... replies. That should have been: char blah[4]; int nVar = 0x7F; // give nVar a set value tostr(nVar, blah); So, when calling this, if we set the arguments to nVar and blah[4], it should look like this: int nVar = 0x7F; // give nVar a set value tostr(nVar, blah[4]); Very uh, no . blah[4] is one single char, the last element in something that was presumably declared as char blah[4]; basically, this passes literally one byte worth of storage to the function to work with; to the function that doesn't check its arguments (which might, might be explainable in a constrained environment but also means you have to be very, very, very careful not to make these kinds of mistakes) and will happily overwrite whatever is next to this in memory. My logic was right, but it didn't get to the computer intact... In udah woids, dat wuz uh tiepoe! :wave: Quote Link to post Share on other sites
turd 31 Posted December 10, 2011 Share Posted December 10, 2011 I'm trying to use your code with a seven segment display but I'm having trouble getting it to work. #include #include void tostr(int i,char *s) { // Convert Integer to String char *p; p=s; p[2]=i%10; i-=p[2]; i/=10; p[1]=i%10; i-=p[1]; i/=10; p[0]=i%10; i-=p[0]; p[3] = 0; // mark end of string p[2]+=0x30; p[1]+=0x30; p[0]+=0x30; } void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR = 255; P1OUT = 0; const int seven_seg[] = { 64, 121, 36, 48, 25, 18, 2, 120, 0, 16}; //Bit patterns for the seven int int_val = 12; //segment display (common anode) char chr_val[4]; int delay_var = 1; tostr(int_val, chr_val); while(1) { P1OUT = seven_seg[chr_val[0]] | BIT7; //BIT7 is used for the common anode on one segment and for(delay_var = 0; delay_var < 100; delay_var++) //to a transistor for the other segment (toggling between) { } P1OUT = seven_seg[chr_val[1]]; for(delay_var = 0; delay_var < 100; delay_var++) { } } } The program works if I just replace chr_val[1] with a value. #include #include void tostr(int i,char *s) { // Convert Integer to String char *p; p=s; p[2]=i%10; i-=p[2]; i/=10; p[1]=i%10; i-=p[1]; i/=10; p[0]=i%10; i-=p[0]; p[3] = 0; // mark end of string p[2]+=0x30; p[1]+=0x30; p[0]+=0x30; } void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR = 255; P1OUT = 0; const int seven_seg[] = { 64, 121, 36, 48, 25, 18, 2, 120, 0, 16}; //Bit patterns for the seven int int_val = 12; //segment display (common anode) char chr_val[4]; int delay_var = 1; tostr(int_val, chr_val); while(1) { P1OUT = seven_seg[1] | BIT7; //BIT7 is used for the common anode on one segment and for(delay_var = 0; delay_var < 100; delay_var++) //to a transistor for the other segment (toggling between) { } P1OUT = seven_seg[2]; for(delay_var = 0; delay_var < 100; delay_var++) { } } } Thanks for any help nuetron 1 Quote Link to post Share on other sites
nuetron 64 Posted December 10, 2011 Share Posted December 10, 2011 Remove the p[3] = 0; // mark end of string p[2]+=0x30; p[1]+=0x30; p[0]+=0x30; and you should be fine. This section is for conversion to ASCII for the LCD. turd 1 Quote Link to post Share on other sites
turd 31 Posted December 10, 2011 Share Posted December 10, 2011 It works Thank you! #include #include void tostr(int i,char *s) { // Convert Integer to String char *p; p=s; p[2]=i%10; i-=p[2]; i/=10; p[1]=i%10; i-=p[1]; i/=10; p[0]=i%10; i-=p[0]; p[3] = 0; // mark end of string } void main(void) { WDTCTL = WDTPW + WDTHOLD; P1DIR = 255; P1OUT = 0; const int seven_seg[] = { 64, 121, 36, 48, 25, 18, 2, 120, 0, 16}; //Bit patterns for the seven int int_val = 23; //segment display (common anode) char chr_val[4]; int delay_var = 1; tostr(int_val, chr_val); while(1) { P1OUT = seven_seg[chr_val[1]] | BIT7; //BIT7 is used for the common anode on one segment and for(delay_var = 0; delay_var < 100; delay_var++) //to a transistor for the other segment (toggling between) { } P1OUT = seven_seg[chr_val[2]]; for(delay_var = 0; delay_var < 100; delay_var++) { } } } Quote Link to post Share on other sites
nuetron 64 Posted December 11, 2011 Share Posted December 11, 2011 You are quite welcome, and thank YOU! In the process of asking for help, you inadvertently helped me as well, as these programs show: Before looking at your code: #include "MSP430G2252.h" #define NUM0 0x3F #define NUM1 0x06 #define NUM2 0x5B #define NUM3 0x4F #define NUM4 0x66 #define NUM5 0x6D #define NUM6 0x7D #define NUM7 0x07 #define NUM8 0x7F #define NUM9 0x6F #define NUMa 0x77 #define NUMb 0x7C #define NUMc 0x39 #define NUMd 0x5E #define NUMe 0x79 #define NUMf 0x71 #define NUMh 0x76 #define NUMj 0x1E #define NUMl 0x38 #define NUMo 0x5C #define NUMp 0x73 #define NUMu 0x1C #define NUMI 0x30 #define NUMQ 0x53 #define NUMZ 0x00 int NUMBER=0; char DIGI[7] = {NUMc,NUM0,NUMf,NUMf,NUMe,NUMe,NUMQ}; const char BIT[8] = {1,2,4,8,16,32,64,128}; int DIGIT=0; int c = 0; void updateDIGIT(void); void updateNUMBER(void); void main( void ){ // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = 0x7F; P1DIR = 0x7F; P2SEL = 0x00; // allow 2.6-2.7 to output P2OUT = 0x7F; P2DIR = 0x7F; P1IES = BIT7; P1IFG = 0; P1IE = BIT7; P2IES = BIT7; P2IFG = 0; P2IE = BIT7; DIGIT=NUMBER=0; __enable_interrupt(); for(;{ while(c < 7){ P1OUT = DIGI[c]; P2OUT = ~BIT[c]; __delay_cycles(5); P2OUT = 0xFF; c++; } c = 0; } } #pragma vector=PORT1_VECTOR __interrupt void PORT1_ISR(void){ NUMBER++; if(NUMBER > 10) NUMBER = 0; updateNUMBER(); P1IFG &= ~BIT7; } #pragma vector=PORT2_VECTOR __interrupt void PORT2_ISR(void){ DIGIT++; if(DIGIT == 7) DIGIT = 0; P2IFG &= ~BIT7; } void updateNUMBER(void){ switch (NUMBER){ case 0: DIGI[DIGIT] = NUM0; break; case 1: DIGI[DIGIT] = NUM1; break; case 2: DIGI[DIGIT] = NUM2; break; case 3: DIGI[DIGIT] = NUM3; break; case 4: DIGI[DIGIT] = NUM4; break; case 5: DIGI[DIGIT] = NUM5; break; case 6: DIGI[DIGIT] = NUM6; break; case 7: DIGI[DIGIT] = NUM7; break; case 8: DIGI[DIGIT] = NUM8; break; case 9: DIGI[DIGIT] = NUM9; break; case 10: DIGI[DIGIT] = NUMa; break; case 11: DIGI[DIGIT] = NUMb; break; case 12: DIGI[DIGIT] = NUMc; break; case 13: DIGI[DIGIT] = NUMd; break; case 14: DIGI[DIGIT] = NUMe; break; case 15: DIGI[DIGIT] = NUMf; break; case 16: DIGI[DIGIT] = NUMh; break; case 17: DIGI[DIGIT] = NUMj; break; case 18: DIGI[DIGIT] = NUMl; break; case 19: DIGI[DIGIT] = NUMo; break; case 20: DIGI[DIGIT] = NUMp; break; case 21: DIGI[DIGIT] = NUMu; break; case 22: DIGI[DIGIT] = NUMI; break; case 23: DIGI[DIGIT] = NUMQ; break; case 24: DIGI[DIGIT] = NULL; break; } } After looking at your code: #include "MSP430G2252.h" const char CHAR[] = { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x07, // 7 0x7F, // 8 0x6F, // 9 0x77, // a 0x7C, // b 0x39, // c 0x5E, // d 0x79, // E 0x71, // F 0x76, // h 0x1E, // j 0x38, // l 0x5C, // o 0x73, // P 0x1C, // u 0x60, // r 0x30, // I 0x53, // ? 0x00, // BLANK }; const char BIT[8] = {1,2,4,8,16,32,64,128}; char DIGI[7] = {CHAR[12],CHAR[0],CHAR[15],CHAR[15],CHAR[14],CHAR[14],CHAR[24]}; int NUMBER=0; int DIGIT=0; int c = 0; void main( void ){ // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = 0x7F; P1DIR = 0x7F; P2SEL = 0x00; // allow 2.6-2.7 to output P2OUT = 0x7F; P2DIR = 0x7F; P1IES = BIT7; P1IFG = 0; P1IE = BIT7; P2IES = BIT7; P2IFG = 0; P2IE = BIT7; DIGIT=NUMBER=0; __enable_interrupt(); for(;{ while(c < 7){ P1OUT = DIGI[c]; P2OUT = ~BIT[c]; __delay_cycles(5); P2OUT = 0xFF; c++; } c = 0; } } #pragma vector=PORT1_VECTOR __interrupt void PORT1_ISR(void){ NUMBER++; if(NUMBER > 10) NUMBER = 0; DIGI[DIGIT] = CHAR[NUMBER]; P1IFG &= ~BIT7; } #pragma vector=PORT2_VECTOR __interrupt void PORT2_ISR(void){ DIGIT++; if(DIGIT == 7) DIGIT = 0; P2IFG &= ~BIT7; } Here is the common-cathode display: (sorry abt quality, camera wouldn't focus on the flashing...) Quote Link to post Share on other sites
turd 31 Posted December 11, 2011 Share Posted December 11, 2011 I'm glad I could inadvertently help you Cool looking project by the way. How are you drive that display? Quote Link to post Share on other sites
nuetron 64 Posted December 11, 2011 Share Posted December 11, 2011 It's a 7-digit 7-seg display, so it has 14 pins to control all 49 LEDs. (7x7=49) I'm using a 'G2252 (has 16 GPIO) to drive it: lower 7 bits of port 1 for the segments, lower 7 bits of port 2 for the digits. Both of the BIT7 pins have buttons on them: one controls which digit is selected, and the other makes that digit scroll through the available characters. I know it's a bit expensive on I/O, but it works... and I could probably make it better and save six pins by using an HEF4017 for the digits. Quote Link to post Share on other sites
turd 31 Posted December 11, 2011 Share Posted December 11, 2011 Nice! What do you think you'll make with it? Maybe a frequency counter or something? Quote Link to post Share on other sites
nuetron 64 Posted December 11, 2011 Share Posted December 11, 2011 I don't know, I was mostly testing it out/playing around. (The code is currently set up to say "COFFEE?" when first powered up) What would you do if you had it? Quote Link to post Share on other sites
turd 31 Posted December 11, 2011 Share Posted December 11, 2011 Maybe a hex clock that could also display the temperature. Quote Link to post Share on other sites
simpleavr 399 Posted December 11, 2011 Share Posted December 11, 2011 I don't know, I was mostly testing it out/playing around. (The code is currently set up to say "COFFEE?" when first powered up)What would you do if you had it? do u mean "display" COFFEE? it takes quite a bit to make Launchpad "say" things. [EDIT] to fix embed video nuetron, RobG, gordon and 1 other 4 Quote Link to post Share on other sites
timotet 44 Posted December 11, 2011 Share Posted December 11, 2011 that is awesome 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.