Shop OBEX P1 Docs P2 Docs Learn Events
XBEE Transmit and Receive Float on ActivityBoard Using SimpleIDE — Parallax Forums

XBEE Transmit and Receive Float on ActivityBoard Using SimpleIDE

I'm having a lot of trouble transmitting and receiving float data between two XBEEs.

I can get the system to successfully send and receive letters, but I just can't seem to get these things to do Floating Point.

I am trying to send the results of ADC_VOLTS. I know there may be a way to skirt around that issue by trying ADC_IN, but honestly I'd like to just try to find a way to deal with Floats and be done with it.

Has anyone already done this, or do you have suggestions? I've seen some deal with the Float as a String and convert it back to a Float. I'm hoping for a more direct way of doing this.

Comments

  • Please show us your program. What language is it in? The solution depends on the language. A floating point value is represented internally as a 4 byte value and each of these bytes has to be transmitted from one XBee to the other. You can also convert the value to a string equivalent and send that wirelessly (and convert back to float).
  • I have had lots of success sending floats as 4 raw bytes over XBees in packet (API) mode. I haven't tried it in stream (normal) mode, which I assume you're using, but I don't see why it shouldn't work.
  • Current code trying to temporarily trick it using chars. I know it's a mess.

    Transmit:

    /*
    Blank Simple Project.c
    http://learn.parallax.com/propeller-c-tutorials
    */
    #include "simpletools.h" // Include simple tools
    #include "fdserial.h"
    #include "abdrive.h"
    #include "adcDCpropab.h"

    fdserial *xbee;

    int main() // Main function
    {
    xbee = fdserial_open(9, 8, 0, 9600);
    adc_init(21, 20, 19, 18);

    writeChar(xbee, CLS);
    dprint(xbee, "Click this terminal, \n");
    dprint(xbee, "and type on keybaord...\n\n");

    char c;
    float lrV, udV;

    while(1)
    {
    udV = adc_volts(0);
    lrV = adc_volts(1);


    c = 19.7*udV-32;
    c = 0;
    if( udV < 1.5 ) c = -21.3 * udV + 32;
    if( udV > 2 ) c = 25.6 * udV + 12.8;
    //c = fdserial_rxChar(xbee);
    //dprint(xbee, "%c", c );
    //dprint(xbee, "%d %c %3.2f \n", udV, udV, (float)udV);
    dprint(xbee, "%d", c );
    pause(250);
    /*
    if(c != -1)
    {
    dprint(xbee, "%f", udV);
    pause(10);
    }
    */
    }
    }

    Receive:

    /*
    Joystick.c

    Simple Propeller P8X32A Propeller C demo with the Parallax 2-axis Joystick

    http://learn.parallax.com/propeller-c-simple-devices/joystick
    */

    #include "adcDCpropab.h" // Include adcDCpropab
    #include "simpletools.h" // Include simpletools
    #include "abdrive.h"
    #include "fdserial.h"

    fdserial *xbee;

    int main() // Main function
    {
    xbee = fdserial_open(9, 8, 0, 9600);
    //adc_init(21, 20, 19, 18); // CS=21, SCL=20, DO=19, DI=18


    float lrV, udV; // Voltage variables
    char c;
    int mv;

    while(1) // Loop repeats indefinitely
    {
    //udV = adc_volts(0); // Check A/D 2
    //lrV = adc_volts(1); // Check A/D 3
    fdserial_rxFlush(xbee);
    c = fdserial_rxChar(xbee);
    dprint(xbee, " \n RECEIVED %d\n", c );

    if( c < 40 ) mv = c * -1;
    if( c > 40 ) mv = c - 64;
    dprint(xbee, " \n mv=%d\n", mv );
    drive_speed( mv, mv );
    //if( c == 'f' ) drive_goto( 32, 32 );
    //if( c == 'b' ) drive_goto( -32, -32 );
    //if( lrV > 2.5) drive_goto( 12, -12 );
    //if( lrV < 0.1) drive_goto( -12, 12 );

    pause(100); // Wait 1/10 s
    }
    }
  • I have had lots of success sending floats as 4 raw bytes over XBees in packet (API) mode. I haven't tried it in stream (normal) mode, which I assume you're using, but I don't see why it shouldn't work.

    I'm fine with changing modes etc.

    Can you post your code and how you did it?
  • Essentially you have to coerce a float to a char[4], then go through the chars, one at a time sending them with writeChar. On the receiving end, just do the opposite. Use fdserial_rxChar to get the 4 characters and store them in the char[4] variable in the same order you sent them, then coerce the char[4] to a float to use the value.

    You can do the same sort of thing using a union of a float and a char[4].
  • Do you know the coercion process?
  • Mike GreenMike Green Posts: 23,101
    edited 2015-09-24 14:32
    To use union, declare

    union { float floatIt; char charIt[4]; } fixIt; /* 4 bytes as float or char array */

    Then do something like:

    fixIt.floatIt = 3.14159; /* store float value */

    for (i=0;i<4;i++) writeChar(fixIt.charIt[ i ]); /* break it up into sequence of 4 bytes */
  • ElectrodudeElectrodude Posts: 1,658
    edited 2015-09-24 16:26
    I did all my API stuff in Spin. I generally avoid PropGCC whenever I can. Here's the Spin object I used: obex.parallax.com/object/763. That version is modified by me to use 4 port FDS, but there's a link on that page to the original single port FDS (written by Martin Hebel).

    Outputting the floats was as trivial as just adding the variables containing the floats to the array of stuff to be sent, as Spin doesn't know anything about floats.

    About C float-int coercion, I usually use the somewhat hackish *((float*)&myint) or *((int*)&myfloat) . However, it would probably be better to do what Mike Green said in an inline function.
Sign In or Register to comment.