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

Table search algorithm
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
wgalaugher



Joined: 10 Jan 2011
Posts: 18

View user's profile Send private message

PostPosted: Thu Jun 16, 2011 9:50 am     Reply with quote

I see the logic of the new code. It compiles without error but returns a position of 0 for any value. I played with the variables to make them int16 but it seems to be stuck with the original problem.


Code:

#include <18F2620.h>

//#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP

#use delay(clock = 4000000)

#include <flex_lcd.c>

#define NR_ELEMENTS(x) (sizeof(x)/sizeof(x[0])) 

int16 table_search(int16 *pointer, int8 size, char value)     //   <<---  note the int16 *
{
   int8 count=0;
   while((value>*pointer)&&(--size)) { count++; pointer++; }
   return count;
}

 
void main()
{
lcd_init();  // Always call this first.

 
  int16 Array[] = {1800,2001,3500,4001,7000,7351,10100,10201,14000,14351,18068,18169,21000,21451,24890,24991,28000,29701};
  int8 Position;

  Position = table_search(Array,NR_ELEMENTS(Array), 7001);    //   changed the automatic array calculation to be more flexible for other data types

 // for(;;);
               
lcd_putc("\fHello World\n");
printf(lcd_putc,"      %u "Position);


while(1);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Thu Jun 16, 2011 10:04 am     Reply with quote

Obvious problem.
How large is a character?.
How large is 7001?.

Best Wishes
wgalaugher



Joined: 10 Jan 2011
Posts: 18

View user's profile Send private message

PostPosted: Thu Jun 16, 2011 2:02 pm     Reply with quote

I guess I'm a bit thick; hate to admit it. I think a character is a byte and 7001 is 2 bytes. It may seem obvious but I don't know how to fix it. But I want to learn.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 16, 2011 2:41 pm     Reply with quote

He's talking about your function declaration. You have the size of 'value'
set as a char (0 to 255), but you're giving it 7001. You need to change
the function declaration so that 'value' is specified as a data type that's
large enough to hold 7001.
Quote:

int16 table_search(int16 *pointer, int8 size, char value) // Function Declaration

Position = table_search(Array,NR_ELEMENTS(Array), 7001);

Download the CCS manual.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look in this section:
Quote:
Basic and Special types

It's on page 43 of the manual (or page 55 in the Acrobat reader).
It lists all CCS data types and the size of numbers that they can hold.
From that table, you should be able to select the next larger data type
above a char, that will hold 7001.
Note that it says: All types, except float, by default are unsigned.
wgalaugher



Joined: 10 Jan 2011
Posts: 18

View user's profile Send private message

PostPosted: Thu Jun 16, 2011 3:08 pm     Reply with quote

Thanks guys. Its too bad I need a 2x4 across the forehead. I think age is creeping; no one in his right mind should be learning C at 70.

All is working and I learned alot along the way
wgalaugher



Joined: 10 Jan 2011
Posts: 18

View user's profile Send private message

PostPosted: Thu Aug 18, 2011 5:28 pm     Reply with quote

I got the above code working as advertised but I need a modification to make the project work.
Below is a snippet from pbasic that does the job but I'm having a hard time to convert the code to CCS

LOOKDOWN freq,<[1800,2001,3500,4001,7000,7351,10100,10201,14000,14351,18068,18169,21000,21451,24890,24991,28000,29701],x

For example If the measured freq=14300 the x=9. If freq=13500 then x=0 which is out of amateur bands; the value of freq must fall inside the band intervals.
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Aug 19, 2011 9:06 am     Reply with quote

Heck, I'm impressed you want to learn C at 70 and a Ham at that !!

Try reading about the 'Switch' function. It might be a LOT easier to understand and code up AND get working.

ie...
Code:

switch (cmd) {

    case 0:printf("cmd 0");

           break;

    case 1:printf("cmd 1");

           break;

    default:printf("bad cmd");

            break;
}

for you.. ??
Code:

switch(freq ) {
 case 1800:x=0;
 case 2000:x=1;

more of the same...

 case 14351:x=0;

more as required...


It's another way to get what I think you want and easier for me to understand.

BTW pressing F11 will open the CCS compiler's onscreen help file...mine's always open....
73 J
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 19, 2011 1:50 pm     Reply with quote

Quote:
LOOKDOWN freq,<[1800,2001,3500,4001,7000,7351,10100,10201,14000,14351,18068,18169,21000,21451,24890,24991,28000,29701],x

For example If the measured freq=14300 the x=9. If freq=13500 then x=0 which is out of amateur bands; the value of freq must fall inside the band intervals.

I'm trying to understand what you are trying to do. In the your first
example of a number, 14300, it's clearly between two of the values in
the table, 14000 and 14351. Then you're assigning the index (9)of the
larger number in the table (14351) as the result. OK, I understand that.

But then in your 2nd example number, 13500, you don't want it to give
a result of 8, even though 13500 is between 10201 and 14000.

OK, so I'm starting to guess that maybe you view the tables as Pairs of
numbers. In other words, 1800 and 2001 are a pair. Then 3500 and 4001
are the next pair, and so on. You actually want to know if the "freq" is
within any of these pairs. If not, then return 0. If so, then return the
index (0 based) of the higher number in the pair.


See if this works:
Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

int16 const freq_table[18]= { 1800,2001,   3500,4001,   7000,7351,
                             10100,10201, 14000,14351, 18068,18169,
                             21000,21451, 24890,24991, 28000,29701};

int8 lookdown(int16 freq)
{
int i;
int8 retval;
int16 lower;
int16 upper;

retval = 0;

for(i = 0; i < sizeof(freq_table)/2; i+=2)  // Test each pair
   {
    lower = freq_table[i];   // Get lower value of current pair
    upper = freq_table[i+1]; // Get upper value of current pair
 
    if(freq >= lower  &&  freq <= upper) // Check if freq is in range
      {
       retval = i+1;  // If so, return index of upper pair
       break;
      }
   }

return(retval);
}


//==========================================
void main()
{
int8 result;


result = lookdown(1800);
printf("1800 gives result of: %u \r", result);
result = lookdown(2000);
printf("2000 gives result of: %u \r", result);
result = lookdown(2001);
printf("2001 gives result of: %u \r", result);


result = lookdown(29000);
printf("29000 gives result of: %u \r", result);

result = lookdown(30000);
printf("30000 gives result of: %u \r", result);


while(1);
}
wgalaugher



Joined: 10 Jan 2011
Posts: 18

View user's profile Send private message

PostPosted: Fri Aug 19, 2011 8:29 pm     Reply with quote

Your interpretation of the problem works perfectlly. I have wrestled with this for some time. It's nice to see the logic work. Basically, this is a universal band switch determined by frequency.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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