Concatenate bytes and convert to a float.

I receive 6 bytes from processor that represent a floating point number (i.e. 10.78367), so, I've coded serial.read and gotten the bytes, but, I can't figure out how to convert those 6 bytes to a floating point number. Here is my code:

/* FA; Frequency query command AD9954 sends frequecy to PC /
if (inByte=='01000110'&'001000001') //FA, What is frequency VFO A?
{
mySerialA.write(0110010); //write to Register 2 AD9854
}
inByte = mySerialA.read(); //returns byte 5 tuning word VFO A
byte5 = inByte;
inByte = mySerialA.read(); //byte 4
byte4 = inByte;
inByte = mySerialA.read(); //byte 3
byte3 = inByte;
inByte = mySerialA.read(); //byte 2
byte2 = inByte;
inByte = mySerialA.read(); //byte 1
byte1 = inByte;
inByte = mySerialA.read(); // byte 0
byte0 = inByte;
total =
tuneWord = total
convTuningWord(tuneWord);
Serial.write(freq); //write freq FA to pc
mySerialA.print(AresetDDS, '0');
/
End of FA: Frequency query command and response VFO A */

total is defined as a float variable. convTuningWord is a separate function that does the calculation. I also need to figure out how to convert it back for the Serial.write(freq);

What processor?
How do the 6 bytes represent a float?

You need to post your full code.

Also, you cant represent a binary number as: '01000001'. That is actually 12952, not 65. Binary can be represented in two ways in arduino, either:
B01000001
or
0b01000001

So this:

if (inByte=='01000110'&'001000001')

would be:

if (inByte==0b01000110&0b01000001)

but that simplifies to:

if (inByte==0b01000000)

The processor I am communicating with is an Analog Devices AD9854.

I receive 6 bytes from the AD9854 and they represent a number that is a tuning word. (i.e. 4.376 or 20.9874)

Okay, I'm a noob and don't understand what I receive in a serial.read. If I receive the letters F and A from a program on
my computer pc. SDR-Radio.exe, it is requesting the frequency of VFO A. So,:

if inByte=FA {        //"here I don't know  how many bytes, but assume, two.
}   
mySerialA.write(2);         //this goes to the AD9854 and tells it to send me 6 bytes of info (tuning word) from register 2.

So, the BIG picture question is, does the Arduino know that I received an "FA"
                                           does the AD9854 understand "2" or does it need "0b0110010"
                                           will the Arduino convert the 6 bytes I receive to a float number????

or do I need to concatenate the 6 bytes and somehow convert????

By the way, Thanks for being there and helping!!

You still haven't posted your full code, and until you do, I cant help.

From the code you have posted, the answer to all 3 of your questions is No,Maybe,No.
The arduino won't undersant "FA" because you haven't programmed it to.
I am not sure if it will understand "2" or "0b0110010" because you haven't posted the code which communicates with the AD9854
The arduino won't convert the 6 bytes to a float, because again, your program doesn't tell it how.

/* Started Transceiver Program over after making some serial

  • mistakes.
  • Need to be more careful with external memory.
  • Need to better organize code. Started again on 7/25/12
  • Decided to use SDR-Radio on my PC and now I'll only
  • need to program for the communication link between the
  • Ardudino Mega_AD9954_SDR-Radio on PC
  • FREQ MUST BE 11 BYTES?
  • NEED TO DETERMINE WHICH VFO IS CURRENT
  • FIGURE OUT HOW TO CONNECT !!
    */

// include the library code:
#include <EEPROM.h>
#include <SoftwareSerial.h>

/* Global Constants */
const int FA(), FB(), FAS(), FBS(), FC(), FR0(); //VFO commands
const int IF(), IF1(), IF0(); // Transmit
const int SMO(), MD(), PS(), GT(), SH(), SL(); //
const int AG(), MU(), VS(); //
String NA("Ron's Homebrew SDR"); //name of radio
#define CLK 1.0e8 //clock frequency of AD9854
#define TUW 2.81e14 //tuning word mulitplier = 2_48

// Global Variables
long tuneWord(0);
long byte6(0);
char byte5(0), byte4(0), byte3(0), byte2(0), byte1(0), byte0(0);
float freq(0);
long buffer1(0);
char inByte(0), outByte(0);
float total;

// Construct LED Pin
const int ledPin(13);

/* Serial to PC */
#define pcrxPin 0
#define pctxPin 1

/* Serial to AD9954 VFO A*/
#define ArxPin 51
#define AtxPin 50
#define AClock 52
#define AresetDDS 53

/* Serial to AD9954 VFO B*/
#define BrxPin 19
#define BtxPin 18
#define BClock 21
#define BresetDDS 20
SoftwareSerial mySerialA(ArxPin, AtxPin); // RX, TX
SoftwareSerial mySerialB(BrxPin, BtxPin); // RX, TX

//Eeprom Reader
// start reading from the first byte (address 0) of the EEPROM
int address = 0;
volatile byte value;
// End of Eeprom Reader

void setup() {

pinMode(ArxPin, INPUT);
pinMode(AtxPin, OUTPUT);
pinMode(AClock, OUTPUT);
pinMode(AresetDDS, OUTPUT);
pinMode(pcrxPin, INPUT);
pinMode(pctxPin, OUTPUT);
pinMode(BrxPin, INPUT);
pinMode(BtxPin, OUTPUT);
pinMode(BClock, OUTPUT);
pinMode(BresetDDS, OUTPUT);

//set data rate to computer
Serial.begin(57600);
establishContact();

//set data rate for AD9954 VFO A
mySerialA.begin(57600);
mySerialA.print(AresetDDS, '0');

//set data rate for AD9954 VFO B
mySerialB.begin(57600);
mySerialB.print(BresetDDS, '0');

}
/* Eeprom Read Setup Routine /
void eepromReadsetup()
{
}
/
End of Eeprom Read Setup Routine */

void loop()
{
if (Serial.available()>0)
{
inByte = Serial.read();
}

/* FA; Frequency query command AD9954 sends frequecy to PC /
if (inByte=='FA') //FA, What is frequency VFO A?
{
mySerialA.write(2); //write to Register 2 AD9854
}
inByte = mySerialA.read(); //returns byte 5 tuning word VFO A
byte5 = inByte;
inByte = mySerialA.read(); //byte 4
byte4 = inByte;
inByte = mySerialA.read(); //byte 3
byte3 = inByte;
inByte = mySerialA.read(); //byte 2
byte2 = inByte;
inByte = mySerialA.read(); //byte 1
byte1 = inByte;
inByte = mySerialA.read(); // byte 0
byte0 = inByte;
total = float('byte5','byte4','byte3','byte2','byte1','byte0');
convTuningWord(total);
Serial.write(freq); //write freq FA to pc 11 BYTES
mySerialA.print(AresetDDS, '0');
/
End of FA: Frequency query command and response VFO A */

/* Set Frequency FAS for VFO A /
if (inByte=='FAS')
{
// write FAS to AD9954
mySerialA.write(130); //write to Register 2 VFO A
}
Serial.read(buffer1);
freqConv(float(buffer1));
mySerialA.write(tuneWord);
mySerialA.print(BresetDDS, '0');
/
End of FAS write frequency to VFO A */

}
/* Establish contact subroutine /
int establishContact() {
while ((Serial.available() <= 0) {
Serial.print('65'); // send a 65
delay(300);
if Serial.read = '65' {
Serial.print('66')
return;
}
}
/
End of Establish Contact Routine */

/* Eeprom Read Loop */
void eepromReadloop()
{

}

/* End of Eeprom Read Loop */

/* Tuning Word Calculation from Frequency provided /
float freqConv()
{
tuneWord = ((freq
TUW)/CLK) //converts freq
// to tuning word
}
return(tuneWord);
/* End of Tuning Word Routine */

/* Frequency Calculation from Tuning Word provided by AD9854 /
float convTuningWord()
{
freq = ((CLK
tuneWord)/TUW); //converts tuning
//word to frequency
}
return(freq);
/* End of Frequency Calculation Routine */

/* EOF */

KE5QDA:
I receive 6 bytes from processor that represent a floating point number (i.e. 10.78367), so, I've coded serial.read and gotten the bytes, but, I can't figure out how to convert those 6 bytes to a floating point number.

The Arduino makes use of a single precision IEEE format floating point, which is four bytes. So there is no direct mechanism for converting the 6 bytes you are receiving. I just skimmed the data sheet (http://www.analog.com/static/imported-files/data_sheets/AD9854.pdf) for that device and it doesn't seem to make any mention of what the format of the "floating point" it is sending. You will likely need to identify the coding/format that is being used for the floating point. More help will be likely after you can provide that information.

(code tags are useful, if you edit your post, select all the code and click the # button on the toolbar above all the smilies)

First things first, you can't use SoftwareSerial for this. The AD9854 uses SPI. Actually it is not quite SPI as it uses a bidirectional data line. It also doesn't return floating point variables.

You need to read up on the syntax of c programming, as there are many bits of your code which are wrong.

float convTuningWord(){
    freq = ((CLK*tuneWord)/TUW); //converts tuning
                      //word to frequency
}
    return(freq);

A return call goes INSIDE the function it belongs to.

This is not how you declare a variable, it is how you declare a function.

long byte6(0);

It should be:

long byte6 = 0;

This is not how if statements are used:

if Serial.read = '65' {
}

Nor is it how serial.read() is used.
That should be this:

    if (Serial.read() == '65') {

But even that won't do what you want it to.

' ' marks are used to convert from ascii, e.g. 'a' is another way of writing 65.
If you want to declare a string, it would be "This is a string". Notice that it is in " " marks, not ' ' marks.
So if you had the two characters 6 and 5, it would be "65".

Serial.read() is a function which returns one character, not more than one.

End of part 1.

Thanks for all the help, guys!! The C++ site was down and I decided to ask this while I was waiting for it to come back up.
It's quite evident, I need more study!

Ron

This function doesn't make much sense to me:

int establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('65');   // send a 65
    delay(300);
    if (Serial.read() == '65') {
      Serial.print('66');
      return;
    }
  }
}

"While there is nothing available on the serial port, send a nonsense character, then wait 300ms and read the serial port without checking if there is anything available. If the same nonsense characher is returned, print another nonsense character and return nothing from a non-void function (which you cant do)".

I think rather than trying to modify the code just yet, lets start from the beginning.
What are you trying to do? By that i don't mean "Concatenate bytes and convert to a float.", what I mean is:

What do you wan't the whole program to do?
How have you wired up your two AD9854 chips? - I gather that you have two from your code.

Once you have done that, you need to read up on C and C++. There are lots of resources on the web, not just cplusplus.com. I think this may be helpful:
C, C++ Programming Tutorials - Cprogramming.com

This question got my curiosity up. And it appears that you are making a fundamental mistake in trying to interpret the 6 byte number as a floating point. It appears to be a 48-byte integer where the frequency is

AD9854 Frequency Tuning Word (FTW) = DDS Frequency * (2^48 / (Clock frequency))

The Arduino has no built-in support for integers larger than 32 bits, so in order to perform the above calculations you will either need to use something like the BigNumber library or craft you own functions. Whatever method you use will dictate how to convert the raw 48-bit integer into a floating point DDS frequency...

On the contrary, arduino supports the "unsigned long long" 64bit variable type.


The AD9854 is a fairly complex system, and requires some setting up of registers before you can use it.

PAge 33 of the datasheet shows how the registers are laid out, and the following pages explain how to communicate with it.

Page 37 expains the protocol.

In order to make it compatible with arduino, the first thing you need to do at power up is to tell it to use the correct SPI protocol, that is CS, SCLK, MOSI, MISO lines.
This can be done by writing to the control register, which is register 7 for serial communication.

The first byte that needs to be sent is an instruction byte. (see page 37).
To write to register 7, that is: 0b00000111.
Then we need to write the correct register values. As we don't yet talk the correct language, we can't read what the current register value is. However we know from the datasheet that at power up it is: 10,64,1,20. So we will assume this is the value.
To convert to our SPI protocol, we need to set the least significant bit of that 32bit register to be a 1. So that means the LSB of the last byte should be a 1. Thus we are sending: 10,64,1,21.
Once that is done, the two devices can communicate properly.

I guess this wouldn't help?

Really? I couldn't find any information on the Arduino language reference page concerning that. Do you have a pointer to documentation on the subject?

EDIT: Never mind, I found that gcc-avr supports the type. Shame the Arduino reference doesn't mention it.

To give you a helping hand, this is one way you may be able to do it. I have no idea if it will talk properly to the AD9854, but it might :).

I know the Register struct stuff works, so you shouldn't need to worry about that.

It is not complete by any means as I don't know how your PC program communicates with the Arduino, so I ended up making some educated guesses from your code.

AD9854.zip (2.69 KB)