Arduino RF link ... sending a 10-bit value

Hello everyone. This is my 1st post on the forums. I've been tinkering around with Arduino programming for the last few months. I'm kinda stumped right now.

I'm trying to send a 10-bit integer to a second arduino via wireless serial communication. So far I am only able to send an 8-bit integer.

I know the problem is that I'm only sending one BYTE at a time ... and would really need to chop up the 10-bit number into 2 BYTES and then transmit ... but I can't seem to find/think of a way to do it.

...The 10-bit # is from a pressure sensor that is hooked up to the TX arduino via analog input. I'm using the Parallax 900MHz transceiver modules RFD21131 ... quite happy with them. Very easy to use & stable.

Here is my TX Code:

#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3

int potPin = 2; //Goes to the pressure sensor
int val = 0; // variable to store the value coming from the sensor
int valone = 0; //using this to create an average of values...
int valtwo = 0;
int valthree = 0;
int valfour = 0;
int valfive = 0;
int valsum = 0;
int valaverage = 0; // ... keep the output from fluctuating
int PreVal = 0;

SoftwareSerial rfSerial = SoftwareSerial(rxPin, txPin); //using softwareserial

void setup() {

rfSerial.begin(9600); //initialize softwareserial
Serial.begin(9600); // begin serial communication over USB to the computer for debugging purposes
}
void loop(){
val = analogRead(potPin); // read the value from the sensor
valone = val; //Taking average of 5 reading from analog in
val = analogRead(potPin);
valtwo = val;
val = analogRead(potPin);
valthree = val;
val = analogRead(potPin);
valfour = val;
val = analogRead(potPin);
valfive = val;
valsum = valone + valtwo + valthree + valfour + valfive;
valaverage = valsum/5; // Average
val = valaverage/4; //********Change from 10-Bit # to 8-Bit # ***********

if(val != PreVal){ // Prevents TX from constantly transmitting .. only want to TX when value changes
Serial.print(val); // send data to computer
rfSerial.print(val, BYTE); // send data out tx
PreVal = val;
delay(500);
}
}

------------END OF TX CODE-------------------

RX CODE:

#include <SoftwareSerial.h>
#undef int() //required for version 11 Arduino
#include <Stdio.h>
#include <LCD4Bit_mod.h> //Bought a nifty LCD Sheild on Ebay .. uses a modified LCD 4-Bit library
#define rxPin 2
#define txPin 3
SoftwareSerial rfSerial = SoftwareSerial(rxPin, txPin);
int val = 0;
char buf[6]; //Using this to properly display on LCD
char string1[] = " "; // White space on LCD

LCD4Bit_mod lcd = LCD4Bit_mod(2); //Using a 16X2 LCD

void setup() {
lcd.init();
lcd.clear();
pinMode(rxPin, INPUT); // set up pin for serial comm. with RF receiver
rfSerial.begin(9600); // begin serial connection with RF Link unit
Serial.begin(9600); // begin serial communication over USB to the computer
}
void loop(){

val = rfSerial.read(); //Read a Byte?? from the RX
Serial.print(val, DEC); // send data to computer in Decimal
lcd.printIn(string1); //White space on LCD
lcd.cursorTo(1, 0); //Moves cursor on LCD to line 1, position zero
lcd.printIn(itoa(val, buf, 10)); //converts val into a string i think?
delay(100);
lcd.cursorTo(1, 0);

}

---------END OF RX CODE---------------------------------------------

This all works great ... except I'm not able to send a 10-Bit value.

I would greatly appreciate it if you guys & gals could give me some insight on the problem. I can see there are a lot of very bright people here.

thanks,
Phil

Since you control both ends of the communication, the possibilities are wide & varied to solving a problem of this type. Here's one way to do it (pseudo code):

Sending side:

# data10bits is at least 16 bits wide.
byte1 = (data10bits >> 8) & 0x03;
byte2 = (data10bits & 0xff);
rfSend(byte1, BYTE);
rfSend(byte2, BYTE);

Receiving side:
# Again, data10bits is at least 16 bits.
byte1 = rfRecv(); # get a single byte
byte2 = rfRecv(); # get second byte
data10bits = (byte1 << 8) | byte2;

Adjust the endianness to taste.

Thanks a lot simond. I posted the same question on Ladyada's forums. Someone replied with a similar solution:

int val; // This is a 16 bit value
byte msb; // 8 bit variable to hold the most significant byte
byte lsb; // 8 bit variable to hold the least significant byte

loop() {
// some code
// goes
// here

val = somedata;

lsb = (byte)(val & 0xff);
msb = (byte)(val >> 8);

Serial.print(msb);
Serial.print(lsb);
// more code
// goes
// here
}

This all looks like it should work. I'm still trying to decipher it thought .... not sure what all the signs are actually doing ... >> , << , & , 0xff , 0x03 , |

thanks a lot,
Phil

Heh, a C reference will help, but just to get you started:

>>, <<   bit-shift operators. Consider a number represented in binary as a 10001000. Applying  >> 1 results in 01000100. Applying <<2 to that result will itself result in 00010000 - the shifted-off bits are not saved, and the 'new' bits are initialised to zero.

& - bitwise AND. The result of 0110 & 0010  is 0010 - only those bits that are set in both inputs result in an output 1 in that position.

| - bitwise OR. The result of 0110 | 1010 is 1110 - anywhere a 1 appears in any of the inputs, a 1 will be output in that position.

Obviously, you can use any numeric representation, not just binary. Binary is the clearest way to visualise it, IMO.

Awesome. Thank you so much. I got it to work. It works great! I'm now seeing 0-1023 at the receiving end.

I will definitely have to do some reading on C. Thanks for the snippet of info.

Thanks again!
Phil

Can you share your final code, please? Can it be used to transmit analog reading ( 0 to 255 ) as a binary number with 2KM RF Link Kit from Seeed Studio ( http://www.seeedstudio.com/depot/2km-long-range-rf-link-kits-w-encoder-and-decoder-p-321.html ) ? Thank you very much for your help.

Iwan Suryo

A value in the range 0 to 255 is a single byte (8 bits). There is no need to do any bit shifting to send and receive a single byte.