View previous topic :: View next topic |
Author |
Message |
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
Hexadecimal Keypad |
Posted: Fri Aug 10, 2012 2:46 am |
|
|
Hi All,
I need your advice, which is primarily about code conversion between different number systems (Hexadecimal (base 16) and decimal (base 10).
I have a keypad (and other hardware), that is fully working. It uses a keypad decoder IC - and easily outputs a 5-bit word into the pic.
I read the word - and the read value corresponds to button with a particular value. Now this is where it gets fun.
The keypad is a hexadecimal representation.
So if the user pressed AAA - then this would correspond to 2730 decimal.
I need a quick way to 'build' and convert the data read from hex to decimal (up to FFFFFF (24-BIT = 16777214).
An array could store the values like:
Code: |
long int HEX[16][1] = {
{0x0}, //row0
{0x1},
{0x2},
{0x3},
{0x4},
{0x5},
{0x6},
{0x7},
{0x8},
{0x9},
{0xA},
{0xB},
{0xD},
{0xE},
{0xF},
};
|
So for instance if the user presses three buttons - and the 5-bit value was read three times (say 5, 10 and 15), then the array above would read out the values in the array for [5], [10] and [15] =
0x0, 0x5 and 0xf.
Now what is the best way of converting the above individual' values into the 'complete' decimal value??
Do I have to convert each digit separately, and then right/left shift to make up the complete word?? if so in base 16. I do not know how to do this.
Any help appreciated.
Carl |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Fri Aug 10, 2012 5:31 am |
|
|
OK tried it and it works well.
I can easily convert a 'hex string' of information.
However how would I stuff this string with the required information from the array (and in the right order).
INT8 X,Y,Z
so read1 (x) = [5] [0x5]
so read2 (y) = [10] [0xA]
so read3 (Z) = [15] [0xF]
......
......
so read6.......
How would I put all the hex digits into the string to get:
"00000FA5"
And once fully in I can then convert it using the below:
char toConvert[9];
strcpy(toConvert,"00000FA5"); // fill out the sample string
lResult = gethex(toConvert); // convert the string |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Fri Aug 10, 2012 7:56 am |
|
|
tried doing this Code: |
char const hex_numbers[8][2] =
{
{"5"},
{"a"},
{"f"},
{"0"},
{"0"},
{"0"},
{"0"},
{"0"}
};
//================================
void main()
{
unsigned int32 fullbyte_read;
setup_spi(SPI_SLAVE | SPI_MODE_1); //set up SPI hardware as a slave in mode 0
SETUP_ADC_PORTS(NO_ANALOGS);
setup_comparator(NC_NC_NC_NC);
clear_interrupt(INT_SSP);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
UTRDIS = 1; // Disable USB transceiver
lcd_init();
while(true) {
level = input_state(pin_C5);
if(true) // Char available from SPI slave ?
{
char keypad_array[2];
int8 i;
int32 lResult;
for(i=0; i < 8; i++)
{
strcpy(keypad_array, hex_numbers[i]); // fill out the sample string
lResult = gethex(keypad_array); // convert the string
printf(LCD_PUTC,"\f %lu",lResult); // write it as decimal
delay_ms(5000);
}
}
}
}
|
but no luck. I dont know how to define the constants correectly into the array.
anyone? |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Fri Aug 10, 2012 1:12 pm |
|
|
Still can't do it:(
Please can anyone help |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Fri Aug 10, 2012 3:16 pm |
|
|
You seem to be doing a lot of fiddling that is not necessary.
Store the hex values directly:
Code: |
char const hex_numbers[8]= {
0x5,0xa,0xf,0x0,0x0,0x0,0x0
};
//and just access these directly.
lResult=hex_numbers[i];
|
Generically _avoid declaring variables mid code_. 'C', only technically allows variables to be declared at the start of a function, or code block.
Mid block declarations are a C++ feature, which CCS 'partially' supports, but I have yet to see a large program work faultlessly doing this. The memory allocation seems to get confused, and works _much better_, if you stick to traditional C declarations.
Best Wishes |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sat Aug 11, 2012 2:58 am |
|
|
Which is your real problem?
Converting hex to decimal
OR
Converting to ASCII strings
What are you wanting to do with the strings of digits/characters?
Mike |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Sat Aug 11, 2012 3:02 am |
|
|
Thanks for your help again Ttelmah
I dont think that will work, because the function requires a string to be passed to the gethex function.
so i need to use Code: | //int32 lResult;
char toConvert[9];
strcpy(toConvert,"00ffffff"); // fill out the sample string -
lResult = gethex(toConvert); // convert the string
|
I NEED TO GET THIS INTO THE GETHEX ROUTINE
I do not know though exactly what these digits represent - obvoiusly they represent a complete hex number - but are the individual digits just numeric constants (so "f" = 0xf)? or character constants ( so 'a' = a) or ASCII?? I need to understand this because how do I stuff the string with the correct data.
I have tried making an array as you said with representative hex numbers 0xf. I Have also tried using just the character 'f' or even "f".
But nothing seems to work.
However if i use the full exact example from below then it works well.
http://www.ccsinfo.com/forum/viewtopic.php?t=535&highlight=hex+integer
I need to load the string "00ffffff" from an array with the correct format - but how???
[/b] |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Sat Aug 11, 2012 3:27 am |
|
|
Hi Mike,
My goal is to convert from a hex representative value to decimal.
I can do this though with the gethex routine - it is really good - you pass a hex value in a string - and it returns the decimal value.
But I need to 'load' the string in the correct format - and I cannot do this.
this loading needs to be done from an array (because different keypad presses = different values = use an array to get the values) - but I dont' know what format in the array is required to stuff the individual digits (be it hex, ASCII, decimal ??? I don't know) into the gethex routine that reads a value like: "00ffffff" |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Sat Aug 11, 2012 3:48 am |
|
|
I think you are making this unnecessarily complicated.
All you need is something like:
Code: |
//convert a single hex digit to decimal.
int ASCIIHexToDec(char chr) {
if (chr<='9')
return(chr-'0');
else
return((toupper(chr)-'A')+10);
}
|
Then you just take your digits from the keypad, and use:
Code: |
int16 ival=0;
char dig_from_keypad;
//Loop while the character fetched from the keypad is a hex digit
//assuming routine to get character is called 'get_char_from_keypad'
while (isxdigit(dig_from_keypad=get_char_from_keypad())) {
ival*=10;
ival+=ASCIIHexToDec(dig_from_keypad);
}
|
Then the routine will exit, as soon as a non hex character is pressed, returning the int16 value corresponding to the hex value types in.
You never need store the 'string', you convert on the fly, digit by digit as the number is typed in.
Best Wishes |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Sat Aug 11, 2012 4:14 am |
|
|
OK Ttelmah thanks - I'll try it.
The value will be int32 though so i will just change ival to int32.
Also can you explain what these are:
thanks
Carl |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Sat Aug 11, 2012 6:55 am |
|
|
1) Read the CCS manual.....
isxdigit, is one of the 'standard' character checking functions. Returns 'true' if the character is a hexadecimal digit (0...9, a..f or A..F).
2) Standard C. Equivalent to ival=ival*10, except can (depends on the compiler) be slightly more optimised. Should be ival*=16. I'm so used to doing decimal input, rather than hex.....
Best Wishes |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Sat Aug 11, 2012 7:07 am |
|
|
I tried, but cannot understand how it is supposed to work.
I understand the code below - every time it is called and passed a hex charater it returns a decimal value in the hex range - so 1,2,3...15.
Code: |
//convert a single hex digit to decimal.
int ASCIIHexToDec(char chr) {
if (chr<='9')
return(chr-'0');
else
return((toupper(chr)-'A')+10);
}
|
And the code below is called to get the value. This value is a hexadecimal number. I have done those successfully - every time a key is pressed, a value from 0-15 is returned.
Code: | 'get_char_from_keypad'
|
And this checks if the code is a 'hex valid digit' and also 'loads' the value of 'get_char_from_keypad' into dig_from_keypad.
Code: |
while (isxdigit(dig_from_keypad=get_char_from_keypad())) {
|
and this is where I don't understand. Why ival x 10?
Code: |
ival*=10;
ival+=ASCIIHexToDec(dig_from_keypad);
|
Assuming an examople of two digits coming into this code so f and f. This should return a value of 255.
But going through the code above:
1) Key is pressed
2) 1st f is retrieved from get_char_from_keypad
3) 1st f is stored in dig_from_keypad
4) On the 'first pass' ival = 0x10 = 0
5) ival = get decimal value for 1st f = 15
6) Key is pressed
7) 2nd f is retrived from get_char_from_keypad
8) 1st f is stored in dig_from_keypad
9) ival already = 15. so 15 x 10 =150
10 ival = 150 + (get decimal value for 2nd f = 15) = 165??
11) return 165??
I was expecting 255 = FF hex
I am going wrong somewhere. |
|
|
carl
Joined: 06 Feb 2008 Posts: 240 Location: Chester
|
|
Posted: Sat Aug 11, 2012 7:18 am |
|
|
Done it
Thanks Ttelmah - it was the *16
Very much appreciated!! |
|
|
|