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

Sending a float through CANbus

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



Joined: 02 Sep 2008
Posts: 3

View user's profile Send private message

Sending a float through CANbus
PostPosted: Tue Sep 02, 2008 6:46 am     Reply with quote

So ive got two PICs connected via CAN bus using those MCP2551 CAN bus transceiver thingies. Ive got it working 100% no problems everythings fine.... wait for it... BUT .. there it is :P

can-18xxx8.c
... as far as my mind can stretch, it understands that wen u send a message over canbus, u are essentially sending an array of integers (8bits x 8integers) .. yea???

... now how would i go about taking a floating point variable, cutting it up into four bytes, sending it over Canbus and on the other side, make em into a foating point variable again???

i know how to do that when writing floats to eeprom, u gotta like do a for loop thingy and then index address ur float. i would obviously have to do sumthing like that yea???

a point in the right direction would be really really awesomeness and appreciated

chow for now
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Sep 02, 2008 7:02 am     Reply with quote

There are several ways to do this.

With a union

Sending:-
Code:

union myval {
  float fl;
  int8 bytes[4];
}

fl = 0.14;
putc(bytes[0]);
putc(bytes[1]);
putc(bytes[2]);
putc(bytes[3]);


Recieving
Code:

union myval {
  float fl;
  int8 bytes[4];
}

bytes[0] = getc();
bytes[1] = getc();
bytes[2] = getc();
bytes[3] = getc();
printf("%f", fl);


Using a pointer
Code:

int8 *fl_ptr;
float fl;

fl = 0.14;
fl_ptr = &fl;
putc(*fl_ptr++);
putc(*fl_ptr++);
putc(*fl_ptr++);
putc(*fl_ptr);


Code:

int8 *fl_ptr;
float fl;

fl_ptr = &fl;
*fl_ptr++ = getc();
*fl_ptr++ = getc();
*fl_ptr++ = getc();
*fl_ptr = getc();
printf("%f", fl);
SEptic



Joined: 02 Sep 2008
Posts: 3

View user's profile Send private message

PostPosted: Tue Sep 02, 2008 7:08 am     Reply with quote

Shocked wow thanks for such a quick reply

awesome lemme try it out Very Happy
thank you very much wayne
SEptic



Joined: 02 Sep 2008
Posts: 3

View user's profile Send private message

PostPosted: Tue Sep 02, 2008 8:49 am     Reply with quote

Wayne_ .... you're my hero!

awesome got it working using a union thing,
took a few tries and a bit of chop and change
but i got it working nicely Razz

many many thanx mate :D
laters
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Sep 02, 2008 10:08 am     Reply with quote

Glad to be of help.
Enjoy Smile
ratgod



Joined: 27 Jan 2006
Posts: 69
Location: Manchester, England

View user's profile Send private message

PostPosted: Sun Sep 07, 2008 12:35 am     Reply with quote

I've tried several different methods, including your 2 but I cannot seem to get any to work right.

Code:

float float1=123.45f,float2=0;
byte a=0,b=0,c=0,d=0;

void float_to_bytes(byte *a,*b,*c,*d,float data1)
{
  union myval
  {
    float fl;
    int8 bytes[4];
  } x;
  x.fl = data1;
  *a=x.bytes[0];
  *b=x.bytes[1];
  *c=x.bytes[2];
  *d=x.bytes[3];
}

float bytes_to_float(byte a,b,c,d)
{
  union myval
  {
    float fl;
    int8 bytes[4];
  } x;
 
  x.bytes[0] = a;
  x.bytes[1] = b;
  x.bytes[2] = c;
  x.bytes[3] = d;
  return(x.fl);
}


these are called by these lines
Code:
  printf(" %4.4f : %4.4f : %x : %x : %x : %x \r\n",float1,float2,a,b,c,d);
  float_to_bytes(&a,&b,&c,&d,&float1);
  printf(" %4.4f : %4.4f : %x : %x : %x : %x \r\n",float1,float2,a,b,c,d);
  float2=bytes_to_float(a,b,c,d);
  printf(" %4.4f : %4.4f : %x : %x : %x : %x \r\n",float1,float2,a,b,c,d);


but all I seem to get out of from this is this:
Code:

  123.4500 : 0.0000 : 00 : 00 : 00 : 00
  123.4500 : 0.0000 : 86 : 5c : 00 : 00
  123.4500 : 220.0000 : 86 : 5c : 00 : 00

I don't know enough about memory organisation of float to tell if the problem is at the float_to_bytes or bytes_to_float routine.

I get the same result when using both of your examples. same when I use a modified version of these routines http://www.ccsinfo.com/faq.php?page=write_eeprom_not_byte

any idea where I'm going wrong?
Ttelmah
Guest







PostPosted: Sun Sep 07, 2008 2:47 am     Reply with quote

Your pointer handling is screwed up... You have _global_ variables called 'a,b,c,d', and local variables with the same name. Always risky. But then you pass the four integer value _addreses_ (OK), but then pass the _address_ of the float. The routine wants the _value_... Hence what you see, are the two bytes representing the address of the float variable...
The union approach is likely to be slightly quicker (depends how good the optimisation is on the PIC). Why not just use the union locally?. Calling the routine is an extra overhead. So:
Code:

  union conv {
    float f;
    int8 b[4];
  };

union conv val1, val2;

//Pt a float value into the first variable
val1.f=123.45;

printf(" %4.4f : %x : %x : %x : %x \r\n",val1.f,\
    val1.b[0],val1.b[1],val1.b[2],val1.b[3]);
    //The four bytes that make up the float

//Put four bytes into the second
val2.b[0]= 0x86;
val2.b[1]= 0x6A;
val2.b[2]= 0x8F;
val2.b[3]= 0x5C;

printf(" %4.4f : %x : %x : %x : %x \r\n",val2.f,\
    val2.b[0],val2.b[1],val2.b[2],val2.b[3]);
    //The new float value, and the bytes that make it.


Remember you have the Pconvert tool in your PICC directory (if you have the 'W' version compiler), that allows you to see what bytes should make up a number.

Best Wishes
ratgod



Joined: 27 Jan 2006
Posts: 69
Location: Manchester, England

View user's profile Send private message

PostPosted: Sun Sep 07, 2008 7:53 am     Reply with quote

What I'm doing here is simulating the buffer and conversion ready to drop into my CAN code.

The variables a,b,c,d are global as they represent the payload part of my packet buffer. Float1 would represent a voltage or current value read from ADC and float2 would represent the buffer for this value on the target system.

I'm still learning about pointers and haven't got my head around them completely unfortunately, but I understand what you mean.

Ok, just made the alterations (local variables are named uniquely and removed & from passing the float).
It works great,

many thanks for that, I will keep it all in mind from now on.
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