Question

I am having trouble transmitting a float across a simple 2 node Xbee Network.

I am aware that the Xbee system transmits packages via bytes, so I can send a char, but I am having trouble sending anything more than that, and I can't seem to find any documentation anywhere.

Here is my current (basic) code.

Sender:

(... appropriate setup...)
void loop()
{
  sensorValue = analogRead(analogInPin);
  sensorValueTemp = sensorValue / 9.31; //LM35 measurement into Centigrade
  Serial.print(sensorValueTemp);
  delay(1000);
}

Receiver:

(...appropriate setup...)
void loop() { 
  lcd.setCursor(0, 0);
    if (Serial.available() > 0) {
    lcd.print(incomingByte);
  }
  delay(1000);
}

Any hint as to get the float to be transmitted successfully would be great? Or if it is already being transmitted properly, how to read it properly?

Thanks

Était-ce utile?

La solution

You can send the float in bytes and reconstruct the float at the receiver.

The following example may help you:

Sender side:

float x = 1128.476;

char b[sizeof(x)];
memcpy(b, &x, sizeof(x));

// Iterate over b and send bytes
// [...]

Receiver side:

float y = 0;

char b[sizeof(x)];

// Store 4 bytes representing the float into b
// [...]

// Rebuild the float
memcpy(&y, b, sizeof(y));

At the end, you have float y on the receiver side, which has the same representation of float x on the sender side.

Autres conseils

You can send all the binary data you want between two machines of an identical architecture, memory layout, byte-endianness, etc. by simply taking a byte-sized pointer (char *) on the "sending" side, and iterating over the referenced object for the number of bytes in that object. On the "receiving" side, you allocate an object of the same size (float, long, struct foo), and receiving the bytes, one by one, into a byte-sized pointer which is post-incremented after each byte is received.

On the sending side --

void sendObject(const void *object, size_t size) {
  char *outputCursor = (char *) object;

  for (;size > 0;size--)
    yourSendAByteFunction(*outputCursor++);
}

On the receiving side, assuming yourReceiveAByteFunction() return 0..255 for a valid byte and -1 for a "receiving error", you can do this --

int receiveObject(void *object, size_t size) {
  char *inputCursor = (char *) object;

  for (;size > 0;size--) {
    int nextByte = yourReceiveAByteFunction();
    if (nextByte < 0)
      return FALSE;

    *inputCursor++ = nextByte;
  }
  return TRUE;
}

You can do the same I/O error checking in the sendObject() function by declaring yourSendAByteFunction() so it returns TRUE or FALSE depending on whether or not an error occurred in the output. It all depends on how much complexity you can stand, and whether or not you have a reliable transmission link.

You can also do a bit of data encapsulation if you have bytes you can't transmit by having a "shift" byte and set of byte values that are prefixed by the "shift" byte to represent some other byte.

Your original sender is sending an ASCII string that represents the float value.

In order to receive and display the value you need to modify the lines as shown below:

(...appropriate setup...)
void loop() { 
  lcd.setCursor(0, 0);
  while (Serial.available() > 0) {       //Changed Line
      incomingByte = Serial.read();      //Added Line
      lcd.print(incomingByte);
  }
  delay(1000);
}

Note: If would be better to terminate the serial output with a CR to synchronize the devices instead of the delay(1000);

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top