CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Hexadecimal Keypad

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
carl



Joined: 06 Feb 2008
Posts: 240
Location: Chester

View user's profile Send private message

Hexadecimal Keypad
PostPosted: Fri Aug 10, 2012 2:46 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 10, 2012 3:44 am     Reply with quote

Hmmm...

I think I can use this.

http://www.ccsinfo.com/forum/viewtopic.php?t=535&highlight=hex+integer

I will try
carl



Joined: 06 Feb 2008
Posts: 240
Location: Chester

View user's profile Send private message

PostPosted: Fri Aug 10, 2012 5:31 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 10, 2012 7:56 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 10, 2012 1:12 pm     Reply with quote

Still can't do it:(

Please can anyone help
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Aug 10, 2012 3:16 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 2:58 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 3:02 am     Reply with quote

Thanks for your help again Ttelmah Very Happy

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
Code:
"00ffffff"


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

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 3:27 am     Reply with quote

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: 19504

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 3:48 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 4:14 am     Reply with quote

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:
Code:
isxdigit


Code:
ival*=10;


thanks
Carl
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 6:55 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 7:07 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 11, 2012 7:18 am     Reply with quote

Done it Very Happy

Thanks Ttelmah - it was the *16

Very much appreciated!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group