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 support@ccsinfo.com

Send and 32bit int via Rs232

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



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

Send and 32bit int via Rs232
PostPosted: Tue Jul 11, 2006 3:26 am     Reply with quote

Hi,

I want to send an 32bit int via RS232. I did use the search function but only found howto send floats via RS232.

Code:
unsigned int16 V07, V100, ADC_Reading;
int V_X;

V_X = (int) 1000000000 * (ADC_Reading - V07) / (V100 - V07);


I want to send the 32 bit V_X to the PC so that I can compare.

Is the casting actually correctly? My guess that V_X is only 8 bit..
Ttelmah
Guest







PostPosted: Tue Jul 11, 2006 4:02 am     Reply with quote

There are two basically different ways of sending values. The first is to send the actual 'value', and the second is to send the ASCII representation of the value. The latter has the advantage that what is sent is 'human readable', but the downside that it takes more bytes. This also then splits into different forms of representation (so you can send a value in base 10, or in hex).
Examples of each, are:
Code:

union {
   int8 b[4];
   int32 word;
} val_to_send;
int8 ctr;

   val_to_send.word=123456L;
   for (ctr=0;ctr<4;ctr++) {
      putc(val_to_send.b[ctr]);
      //This sends the four bytes as raw binary values
   }

   printf("%08x",val_to_send.word);
   //This sends the eight hexadecimal digits

   printf("%lu",val_to_send.word);
   //This sends the ASCII characters '123456'


The 'binary' form is the most compact, sending just four bytes over the RS232, no matter what value is in the variable. The hex form has the advantage of only sending text characters (voids potential problems with sending 'control' characters, and as shown, sends 8 characters,again to send any length value. The 'decimal' form, is actually smaller for the six digit value shown, but will be larger is the value is something like 4000000000.
You can use fixed length fields, or automatic variable length (with the leading zeros omitted), for either of the last two forms.

Now there are a series of 'problems'in your arithmetic as shown. With ADC_Reading, and V07, both 'unsigned', the values will overflow (wrap round), if ADC_Reading is less than V07. You need these values to be signed int16, if this is likely to happen. The same applies with V100-V07.
If either of these is negative, you are then going to get a -ve result.
Then the 'cast', is converting the value of 1E9, to an 8bit integer, _not_the result. This will give zero.
Then, V_X, needs to be an int32, if you are meant to be sending an int32 value.

You need:
Code:

signed int16 V07,V100,ADC_Reading;
signed int32 V_X

V_X = (1000000000 * (signed int32)(ADC_Reading-V07)) / (V100-V07);


Best Wishes
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Tue Jul 11, 2006 5:24 am     Reply with quote

thks for the tips, still I do not seem to manage to make it work. I want to cast to 16 bit int because 32 bits is too much actually.

Code:
signed int16 ADC_READING, V07 = 835, V100 = 894, V_X;

V_X = (signed int16) (10000 * ((ADC_Reading - V07)) / (V100 - V07));               
   
         putc (make8 ( V_X , 1));
         putc (make8 ( V_X , 0));
         buzzer ();


I receive 493.
While it needs to be : 10000 * (( 877 - 835 ) / (894 -835)) = 7118,644 casted to int 16 = 7119

Or am I missing something?
Ttelmah
Guest







PostPosted: Tue Jul 11, 2006 6:30 am     Reply with quote

You need to cast to an int32, and only cast the _result_ to an int16.

The maths is always done, in the form of the 'biggest' element of a section. So if you try to evaluate what you have shown:

10000*((877-835)/(894-835)) with the brackets as you have shown them, you will get:

877-835 = 42
894-835 = 59

42/59 = 0 (remember you are working in _integers_).

However with the brackets as they are in the real sum, you get:

10000 * 42 = 26784 (this is being calculated as an _int16_ so will wrap).
26784/59 = 453

You need:

V_X = (signed int16) (10000 * (signed int32)((ADC_Reading - V07)) / (V100 - V07));

This forces the 10000*42 to be evaluated first, and use int32 arithmetic. This then gives 420000, which when divided by 59, gives 7118.

Casting, also, _does not round_, but truncates.

Best Wishes
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Tue Jul 11, 2006 7:29 am     Reply with quote

working now.. thx!
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