Programming XBee to transmit and receive data

I am working on transmitting remote temperature data using MLX90614 to my PC. For this, I have two XBee tranceivers, with their shields connected to an Arduino Uno on each side.

On the transmitting side, I have temperature data being sent to the Arduino its connected to using I2C. I want to wirelessly transmit this data using the XBee as transmitter, to the XBee as receiver. The receiver XBee, shield and Arduino are connected to my laptop.

I have already configured both the XBees in PuTTY using commands :

+++
ATMY1000
ATDL1001
ATID1111
WR

and also for the other one using ATMY1001 and ATDL1000. I got OK for both.

But what code do I burn into each Arduino for placing the temperature data into a variable, wirelessly transmitting it to the other Arduino (connected to my laptop) and displaying it in Serial monitor?

Thanks,

But what code do I burn into each Arduino for placing the temperature data into a variable

Surely, you jest.

I have temperature data being sent to the Arduino its connected to using I2C.

Where is the code?

wirelessly transmitting it to the other Arduino

Nowhere near enough information provided.

with their shields

There are at least 5 different XBee shields. Which ones do you have?

and displaying it in Serial monitor?

The same code you's use if the Arduino on the PC end was making up data.

Surely, you jest.

Surely I jest? xD lol

Instead of quoting me line for line, I hope you could help me sir because I haven't worked with the XBee before. I have the XBee S1 (Series 1) and the XBee Pro Shields.

For now, I have a MLX90614 sensing temperature data and sending it to my laptop.

I saw a tutorial on YouTube by Jeremy Blum which explained how to configure the XBee using PuTTY. I have done that, and received the acknowledgement messages. I am not sure, what I need to do further.

###---###---###

Since I am remote sensing the temperature, I assume I should have two arduinos with separate codes in each of them, and each connected to their respective shield and transceiver.

So this is what I am thinking : Receiver side and Transmitter side.

Transmitter side:

  • Connected to temperature sensor
  • Sends the temperature data wirelessly to receiver side.
  • Code burned into microcontroller of Arduino functions to :

1. receive MLX90614 data via I2C --> 2. use that temperature data to be transmitted wirelessly to the receiver side (Zigbee).

Receiver side:

  • Receives temperature data
  • Connected to my laptop, displays on serial monitor.
  • Code burned into microcontroller of Arduino functions to :

3. receive the temperature data from transmitter side --> 4. display in serial monitor


What I have now goes directly from 1. to 4. because it is a wired system.

But I need to use the XBees to make it wireless. I would like to know what commands I need to put for the wireless transmitting and receiving. I hope its clearer now. Thank you.

This is the present code I have :

#include <i2cmaster.h>


void setup(){
	Serial.begin(9600);
	Serial.println("Setup...");
	
	i2c_init(); //Initialise the i2c bus
	PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}

void loop(){
    int dev = 0x5A<<1;
    int data_low = 0;
    int data_high = 0;
    int pec = 0;
    
    i2c_start_wait(dev+I2C_WRITE);
    i2c_write(0x07);
    
    // read
    i2c_rep_start(dev+I2C_READ);
    data_low = i2c_readAck(); //Read 1 byte and then send ack
    data_high = i2c_readAck(); //Read 1 byte and then send ack
    pec = i2c_readNak();
    i2c_stop();
    
    //This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
    double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90614)
    double tempData = 0x0000; // zero out the data
    int frac; // data past the decimal point
    
    // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
    tempData = (double)(((data_high & 0x007F) << 8) + data_low);
    tempData = (tempData * tempFactor)-0.01;
    
    float celcius = tempData - 273.15;
    float fahrenheit = (celcius*1.8) + 32;
    float rankine = fahrenheit + 459.67;

    Serial.print("Rankine: ");
    Serial.println(rankine);

    delay(3000); // wait 3 seconds before printing again
}

You are reading two bytes from the device., There are 4 bytes in a float or a double. This tells me that you are getting an int, not a float. Why are you pretending that the data represents a float?

What do you think the = operator is doing? If you don't know, hit the reference section until you do KNOW.

Then, you'll understand why I think you are jesting when you ask how to put temperature data into a variable.

I would like to know what commands I need to put for the wireless transmitting and receiving.

I would like to know what tonight's winning lottery numbers are going to be, so I can buy a ticket with those numbers on it. I have about the same chance of getting answers as you do.

There are at least 5 different XBee shields. Which ones do you have?

No answer == no help.

The shield is Xbeeshield V1.1.

This above code works well. I get temperature readings on the Serial monitor.

The shield is Xbeeshield V1.1.

Your link doesn't work. I'm done.

I didn't send you a link. I just typed the name of it.

It looks like this :

But its V1.1. If someone could

All of this abuse at the OP is unnecessary.

The actual question should be how the XBees are configured. There seem to be two modes, API mode and AT (transparent) mode. Most of the time AT mode is used for simplicity sake. Here is a page explaining the benefits of each mode.

If you have configured the XBees properly for AT mode, you just need to treat them as a virtual serial cable. All you need to do is write to the serial port on one and read from the serial port on the other. The XBees should act just like you have a 3 wire cable connecting RX1 to TX2, RX2 to TX 1, and GND1 to GND2. (The "1" and "2" of the name I just used just reference Arduino1 and Arduino2.) There are no special commands that you need to send to the XBees from the Arduinos in AT mode.

If you really want to use API mode (probably overkill for your project as you have described it), see the xbee-arduino library.

I hope this clears up your questions.

The actual question should be how the XBees are configured.

It doesn't matter how they are configured if the Arduino is not talking to them. Without knowing how the XBee is connected to the Arduino, we can't tell if the Arduino is talking to the XBee or not.

All of this abuse at the OP is unnecessary.

I do not accept that asking OP to post a link to, not a hand-waving description of, or a picture of, the shield the he/she is using is abuse.

BUt, feel free to try to help someone who apparently doesn't really want help.

Hey Sembazuru

I configured the XBees in AT mode by these commands :
+++
ATMY1000
ATDL1001
ATID1111
WR

and also for the other one using ATMY1001 and ATDL1000. I got OK for both.

I have connected my XBee shields (with the transceivers) to the Arduinos. My first Arduino-Xbee shield-transceiver is connected to the temperature sensor.

My other one ("receiver") is connected only to the laptop. I am treating the gap between them like a virtual cable.

I burned the following codes into them.

RECEIVER SIDE:

void setup()
{
	Serial.begin(9600);
	Serial.println("Setup...");
        
}

void loop()
{
    float rankine;
    Serial.print("Rankine: ");
    Serial.println(rankine);
    delay(3000);
}

TRANSMITTER SIDE :

#include <i2cmaster.h>

void setup()
{
	Serial.begin(9600);	
	i2c_init(); //Initialise the i2c bus
	PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}

void loop()
{
    int dev = 0x5A<<1;
    int data_low = 0;
    int data_high = 0;
    int pec = 0;
    
    i2c_start_wait(dev+I2C_WRITE);
    i2c_write(0x07);
    
    // read
    i2c_rep_start(dev+I2C_READ);
    data_low = i2c_readAck(); //Read 1 byte and then send ack
    data_high = i2c_readAck(); //Read 1 byte and then send ack
    pec = i2c_readNak();
    i2c_stop();
    
    //This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
    double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90614)
    double tempData = 0x0000; // zero out the data
    int frac; // data past the decimal point
    
    // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
    tempData = (double)(((data_high & 0x007F) << 8) + data_low);
    tempData = (tempData * tempFactor)-0.01;
    
    float celcius = tempData - 273.15;
    float fahrenheit = (celcius*1.8) + 32;
    float rankine = fahrenheit + 459.67;
}

The only thing that is displayed is 0.00, which means nothing is being sent from from transmitter side wirelessly. I put the code for sensing the temperature in the transmitter basically, and the one for displaying it in the computer at the receiver.

Neither of your sketches actually attempt to transmit or receive anything over the pins that are connected to the XBees.

How do you have the serial communication jumpers (indicated by the datasheet for the shield as zone 3) set? I have a suggestion, but I want to first see how you have them currently configured.

When I had the same thing setup with one Arduino connected to my laptop, I merely Serial printed the values to my laptop.

Now when I have the two Arduinos each with a transceiver and Xbee shield, I really don't know what command to use to transmit or receive. I merely broke the early code into two parts:

  1. In the transmitter Arduino connected to the Xbee, I placed the commands that obtain the data from the temperature sensor.
  2. In the receiver Arduino connected to the Xbee, I placed the commands that display it in the serial monitor.

Jumpers

This is the datasheet https://www.sparkfun.com/datasheets/Wireless/Zigbee/XBee-Datasheet.pdf

I have the jumpers in the right side position now. I shifted them to the left and also short the reset and ground pins at the time I configured them. I configured it using PuTTY and got OK too. Was I supposed to leave the jumpers in the left position even during the actual operation?

V_88:
When I had the same thing setup with one Arduino connected to my laptop, I merely Serial printed the values to my laptop.

Now when I have the two Arduinos each with a transceiver and Xbee shield, I really don't know what command to use to transmit or receive. I merely broke the early code into two parts:

The commands that you will be using will be some sort of serial write or print to send and a serial read to receive. You said in your original post you are using UNOs. Because the UNO only has one hardware serial port, on at least the receiver that needs to talk to the computer over USB using the hardware serial that XBee will need to use software serial. To make things a little simpler, I would suggest both XBees use software serial on the same pins.

V_88:

  1. In the transmitter Arduino connected to the Xbee, I placed the commands that obtain the data from the temperature sensor.
  2. In the receiver Arduino connected to the Xbee, I placed the commands that display it in the serial monitor.

Jumpers

This is the datasheet https://www.sparkfun.com/datasheets/Wireless/Zigbee/XBee-Datasheet.pdf

Yep, that was not the datasheet I was referring to because it has nothing about the shield. The shield datasheet can be found at iteadstudio.com's web page for their shield.

V_88:
I have the jumpers in the right side position now. I shifted them to the left and also short the reset and ground pins at the time I configured them. I configured it using PuTTY and got OK too. Was I supposed to leave the jumpers in the left position even during the actual operation?

Your terminology is confusing. The terms "right side" and "left side" don't mean much to me because I don't know what the reference for left and right are. My best guess is by "right side" DOUT is shorted to the center row at D0 and DIN is shorted to the center row at D1 as shown in the first diagram on page 3 of the shield's datasheet.

I would suggest shifting both jumpers (on both shields) two places so DOUT is shorted to the center row at D2 and DIN is shorted to the center row at D3. Look at the examples for SoftwareSerial library. There are several examples distributed with the IDE to look at, and also read the reference page on this site for SoftwareSerial. When setting up SoftwareSerial in sketches with the jumper configuration that I'm suggesting here, RX will be pin 2 and TX will be pin 3.

See if you can start to get things working with what I've pointed you towards now. I already see one stumbling block, but I want to see if you can get to it before I start confusing you by getting too far ahead. I guess I could foreshadow it, serial data is only read in one byte at a time and a float is 4 bytes. But lets get something (even if it isn't the eventual intended thing) to transmit from one XBee to the other. Small steps.

I will change my code and try it again using serial commands. But coming to the jumpers first, consider the picture attached.

My jumpers were in that position while I was trying to transmit and receive. I didn't change the jumpers on D0 and D1 at any point.

I did change the the other jumpers with the "3.3V" and "JMP" label, I shorted A-B and D-E ("left" position), during configuring the XBees using PuTTY. I changed them back to the B-C and E-F ("right" positions) after that.

Does the position of the jumpers at DIN and DOUT imply that Pin1 is the RX and Pin0 is the TX? If this is true then would I keep the corresponding jumpers in vice-versa in the other XBee?

Like in one XBee, I have the DIN of Pin1 shorted to the center and the DOUT of Pin2 shorted to the center. Would that mean in the other one I would have DOUT of Pin1 shorted to the center and the DIN of Pin 2 shorted to the center?

Thank you for your efforts of helping.

V_88:
I will change my code and try it again using serial commands. But coming to the jumpers first, consider the picture attached.

My jumpers were in that position while I was trying to transmit and receive. I didn't change the jumpers on D0 and D1 at any point.

I did change the the other jumpers with the "3.3V" and "JMP" label, I shorted A-B and D-E ("left" position), during configuring the XBees using PuTTY. I changed them back to the B-C and E-F ("right" positions) after that.

Why would you change those? Those are zone 5 jumpers and the datasheet seems to indicate they have to do with operating voltage. I tried to look at the shield's schematic to figure out what that does, and I can't seem to figure out how changing those jumpers effects operation for 3.3V versus 5V. Not a very good schematic... I would actually use it as a teaching tool of some things not to do in schematics.

But none of that matters for the task at hand. For what we are doing, leave the zone 5 jumpers the way you have them in your picture.

Does the position of the jumpers at DIN and DOUT imply that Pin1 is the RX and Pin0 is the TX? If this is true then would I keep the corresponding jumpers in vice-versa in the other XBee?

Well, this can get a bit confusing. The DIN and DOUT on the shield are from the point of view of the XBee module.

  • DIN is data in, also could be called receive or RX, metaphorically the XBee's ear.
  • DOUT is data out, also could be called transmit or RX, metaphorically the XBee's mouth.
    So, yes the way they are configured right now, Pin1 of the shield is the XBee's RX and Pin0 of the shield is the XBee's TX. It is done this way so the XBee's mouth is connected to the Arduino's ear (Arduino Pin0) and the XBee's ear is connected to the Arduino's mouth (Arduino Pin1).

Like in one XBee, I have the DIN of Pin1 shorted to the center and the DOUT of Pin2 shorted to the center. Would that mean in the other one I would have DOUT of Pin1 shorted to the center and the DIN of Pin 2 shorted to the center?

Not quite. Those pins are only for communication from an XBee to it's physically connected Arduino. I want you to connect them up the same way on both shields: DIN on pin3 and DOUT on pin2. We will then use software serial (with RX set to 2 and TX set to 3) to communicate from each Arduino to their attached XBees. (Because of the way the XBees are configured they should already communicate with each other.)

This way you can use the hardware serial to communicate back to the computer so you can monitor debugging and diagnostics with serial monitor. (Where ever I can on my designs, I avoid using Arduino pins 0 and 1 for anything so I can look at debugging information on my computer when the Arduino is connected via USB.)

If you have two USB cables (if you don't, I would highly suggest getting a second one), connect both Arduinos to your computer at the same time. Have two ArduinoIDE windows running at the same time with the "SoftwareSerialExample" sketch loaded in both. Set one to the COM port of one of the attached Arduino boards, and the other to the COM port of the other attached Arduino board. In both IDE windows, change line 30 from SoftwareSerial mySerial(10, 11); // RX, TX to SoftwareSerial mySerial(2, 3); // RX, TX. Then change line 44 (mySerial.begin(4800);) to the baud rate that your XBees are configured for. (I use X-CTU to configure my XBees, because I'm running Windows and it is easier to click buttons than to manually use lookup tables to find command and setting codes. I presume you are also running Windows because you used PuTTy which is a Windows application... Why didn't you use X-CTU?) You can also change the header comment to reflect these changes, but for what we are doing this isn't important because you don't need to save the modified sketch. Upload the sketches to both Arduinos, and open the Serial Monitor for both IDE windows. What you type in one serial monitor should show up in the other serial monitor.

Once you are sure that you are able to communicate from one Arduino to the other, you know the hardware is correct. Now it is time to start writing code that will do what you want to do. If you are having hardware problems, ignore the following until we get the hardware sussed out.

When structuring your code, the more I think about it I think the raw 2-byte code plus some unique separator from the temperature sensor is what should be transmitted via XBee, and then do the conversions on the receiver end. Transmitting and receiving a float value isn't quite as straight forward.

Take a look at how you get the data from the temperature sensor. First you send it a command requesting data. Based on the command you sent you know exactly what data to expect so you put the first byte into data_low (this should actually be initialized as byte, not int), then you put the second byte into data_high (again, should be initialized as byte), and finally you put the third byte into pec. You know what format to expect and when the first, second, and third bytes will be transmitted. But with your Arduino to Arduino communication it might be simpler to not request data and just receive the data. Because only 1 byte at a time is transmitted over the XBees, how does the receiver know which byte it received is data_high or data_low? You will need some sort of handshaking to say "the following byte is the start of the data", or "the last byte was the end of the data", or both. And, that handshaking byte needs to be some byte value that will never be part of valid data. Unfortunately, looking at the possible values of both data_high and data_low i see all the possible values that can be contained in 1 byte (0x00 through 0xFF), particularly with the data_low byte. We will need to encode the values some how. The simplest would be to transmit the ASCII characters representing the hex value. I.E for the hex value of 0x2A, you would transmit the two ASCII characters '2' and 'A'. This type of conversion is already built into the print method we will be using to send the data from the Arduino to the transmitting XBee. Based on that, we know that the individual values being transmitted will all fall into the set of values for the ASCII digits and the ASCII capital letters 'A' through 'F'. These are 0x30 inclusively through 0x39 and 0x41 inclusively through 0x46, respectively. (If you don't already have an ASCII table bookmarked, I suggest this one. I don't even have it bookmarked because the url is so easy to remember: "asciitable.com".) You have literally every other one byte hex value to choose for your start and/or stop bytes. But for ease of troubleshooting, I'd probably suggest another printable ASCII character, and would probably avoid any in the two ranges 0x30 inclusively through 0x3F and 0x40 inclusively through 0x4F. This still leaves most of the symbols, all the lowercase letters, and uppercase letters 'P' inclusively through 'Z'. This would allow you to echo all the characters received for troubleshooting/diagnostics, even if you just act on the ones your are interested in.

I would probably suggest going with a start byte only. That way when your receiver sees that start byte it captures the next 4 bytes as data. Checking to see if the 4 bytes represent the only possible valid values, and if so then convert them. If one checks each one while receiving them then you can ignore bad data sooner. (Sort of like buzzing in on Jeopardy before Alex Trebek finishes reading the clue.) Then wait for the next valid start byte while throwing away any received bytes until then. This allows you to send new line characters for your first echo tests. Because the new line characters (CR and LF) will be the 5th and 6th bytes after the start byte, your receiving code would just throw them away along with any other noise.

Receiving the ASCII representations and reconstituting the hex value might be a bit tougher, so for now just write your receiver code to echo everything back to the hardware serial port by leaving the example loaded that we used to test the hardware connection.

You don't need to be constantly transmitting. What happens if you can't receive as fast as you can transmit? It would look like the scene from the old Lucy show when she is working at the candy factory. The conveyor belt speed would be analogous to baud-rate, and the spacing of the chocolates would be how often you transmit the temperature code. Even on a fast baud-rate, spacing the transmits out would allow the receiver time to catch all the packets and do other things (like process the packets, send the result on elsewhere, etc). For now I would suggest a nice even cadence of 1 second between each transmission of temperature. You can adjust this later if needed. You should also send over the hardware serial what you are sending over software serial. That way you can verify that what you are receiving is actually what you sent (just like with the hardware configuration testing I had you do earlier).

I used PuTTY because I looked at this tutorial:

Also, he mentions at 1:26, about configuring the XBee shields and says you have to physically remove the micro-controller and shift "these two jumpers", from the right to left position. Now the shield he had was a bit different from what I have which is XBee shield V1.1. So while configuring the XBees do I move any jumpers at all?

I have made the change of moving the jumpers so that D2 center is short with DOUT and D3 center is short with DIN. Also, I copied the "SoftwareSerialExample" code and made the modifications you said.

When the baud rate was 57600 in the void setup() method, I got some funny looking characters. I changed the baud rate in that to 9600, and also in the other mySerial.begin. I can send and receive text messages well.

Thanks again for helping me through with this.

V_88:
I used PuTTY because I looked at this tutorial:

Tutorial 9 for Arduino: Wireless Communication – JeremyBlum.com

That is one of the few tutorials that I've seen not using X-CTU to configure XBee modules. I think he did it that way to show people who don't use MSWindows how they can do it. But if you are using MSWindows, why do things the hard way and ignore provided tools? (If you have access to the Snap-On tool van, why use a pen-knife blade to turn screws when you can get the proper sized screwdriver?)

V_88:
Also, he mentions at 1:26, about configuring the XBee shields and says you have to physically remove the micro-controller and shift "these two jumpers", from the right to left position. Now the shield he had was a bit different from what I have which is XBee shield V1.1. So while configuring the XBees do I move any jumpers at all?

Actually, the shield he showed in his tutorial is completely different than your shield. Not even the same designer/manufacturer. IMHO, he kinda did his audience a disservice by not better identifying the XBee shields that he was using, and explaining what the jumper change was all about. The jumpers he moved would have the same effect as adjusting the jumpers in the zone 3 area of the XBee shield that you have. If they seemed to program ok for you (i.e. you got the proper responses as you indicated that you did) then there shouldn't be a lasting issue. Especially since you indicated that you were able to get the communication going using the software serial example sketch.
Ideally, in the future you should get (as he did suggest) a USB to XBee adapter (also called XBee Explorers) if you plan on playing with XBee configurations. Several vendors and manufacturers carry their own versions of them, but they are all pretty much identical in operation. Adafruit has one for $20USD with some assembly required, and SparkFun has two (here and here), each $24.95USD as finished units. I'm too lazy to look further, but I'm sure there are plenty more.

V_88:
I have made the change of moving the jumpers so that D2 center is short with DOUT and D3 center is short with DIN. Also, I copied the "SoftwareSerialExample" code and made the modifications you said.

When the baud rate was 57600 in the void setup() method, I got some funny looking characters. I changed the baud rate in that to 9600, and also in the other mySerial.begin. I can send and receive text messages well.

Be careful describing things. If you look carefully in the setup() you should actually see two baud rates, one for the hardware serial with serial.begin(), and one for the software serial with mySerial.begin().
Just to make sure you understand, explain where the name "mySerial" came from. Don't be afraid to get the question wrong, I'll try to help you understand it if you are wrong. I tend to value knowing why to do things slightly higher than knowing how to do things. Because if you know why then you can apply that knowledge to a different situation to come up with the appropriate (and some times unique) how.

Looking at the example and seeing which one defaults at 57600, I see that it was the hardware serial. There were two ways to correct the problem you had. The hardware serial is what is communicating with the serial monitor. You could have changed the baud rate in the code (you did), or you could have changed the baud rate of the serial monitor to 57600. Personally, I use 115200 for my serial monitor and Arduino's hardware serial baud rates so it takes less time to send diagnostic messages.

V_88:
Thanks again for helping me through with this.

Sure, no problem. Helping people is why I come to the Arduino forum.

Now that you have verified that the hardware works, how far have you gotten reading the temperature sensor and sending data_high and data_low to the other Arduino via the XBees?

That is one of the few tutorials that I've seen not using X-CTU to configure XBee modules. I think he did it that way to show people who don't use MSWindows how they can do it. But if you are using MSWindows, why do things the hard way and ignore provided tools? (If you have access to the Snap-On tool van, why use a pen-knife blade to turn screws when you can get the proper sized screwdriver?)

The serial communication that happened wirelessly tells that the XBees are configured correctly right? Do I need to worry about X-CTU now? I will certainly try using it next time though.

I tend to value knowing why to do things slightly higher than knowing how to do things. Because if you know why then you can apply that knowledge to a different situation to come up with the appropriate (and some times unique) how.

I agree.

You could have changed the baud rate in the code (you did), or you could have changed the baud rate of the serial monitor to 57600.

Understood /thumb up/

how far have you gotten reading the temperature sensor and sending data_high and data_low to the other Arduino via the XBees?

I haven't done anything since yesterday. I will be back here if I have questions. You said its better to transmit the 'data_high' and 'data_low' to the receiver side and then do the math conversions there, right?

V_88:

That is one of the few tutorials that I've seen not using X-CTU to configure XBee modules. I think he did it that way to show people who don't use MSWindows how they can do it. But if you are using MSWindows, why do things the hard way and ignore provided tools? (If you have access to the Snap-On tool van, why use a pen-knife blade to turn screws when you can get the proper sized screwdriver?)

The serial communication that happened wirelessly tells that the XBees are configured correctly right? Do I need to worry about X-CTU now? I will certainly try using it next time though.

I agree that the serial communication that you did shows that the XBees are configured correctly. I wouldn't worry about X-CTU unless you need to reconfigure these modules for something else, or to configure new modules. At this point for what you have it's all water under the bridge.

V_88:
[...snip...]

how far have you gotten reading the temperature sensor and sending data_high and data_low to the other Arduino via the XBees?

I haven't done anything since yesterday. I will be back here if I have questions. You said its better to transmit the 'data_high' and 'data_low' to the receiver side and then do the math conversions there, right?

No rush, but please keep me updated with both your successes and failures.

I just think it would be simpler to transmit the encoded two byte value that the temperature sensor transmitted over I2C. Float values are encoded within 4 bytes (so there would be at least twice as much to transmit). It can be done, but would require some more advanced techniques and not lose precision.

Hi Sembazuru,

I set the two arduinos with the codes below, but I got some erroneous data (clearly!). It seems like data was being transmitted, but no new data was being read by the temperature sensor, because bringing my finger close to the sensor didn't change the erroneous values either.

If the erroneous values changed, I would think the problem was only with synchronization of the data.

I know the sensor is working fine, because I put the other code for the "wired" sensing and it worked right - temperature was changing when I brought my finger close to the sensor.

Here are the codes I put, and I have attached the output I received in the image.

TRANSMITTER

#include <SoftwareSerial.h>
#include <i2cmaster.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup()
{
     Serial.begin(9600);
     mySerial.begin(9600);
     i2c_init(); //Initialise the i2c bus
     PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}

void loop()
{
    int dev = 0x5A<<1;
    int data_low = 0;
    int data_high = 0;
    int pec = 0;
    
    i2c_start_wait(dev+I2C_WRITE);
    i2c_write(0x07);
    
    // read
    i2c_rep_start(dev+I2C_READ);
    data_low = i2c_readAck(); //Read 1 byte and then send ack
    data_high = i2c_readAck(); //Read 1 byte and then send ack
    pec = i2c_readNak();
    i2c_stop();

    mySerial.write(data_low);        // send data_low
    Serial.flush();	                                // wait till transmitted (right??)
    mySerial.write(data_high);     // send data_high
    Serial.flush();	
}

RECEIVER

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup()
{
     Serial.begin(9600);
     mySerial.begin(9600);
}

void loop()
{
     int flag = 0;
     int data_low;
     int data_high;  

     if (mySerial.available() && flag<2)
     flag = flag+1;
{
	if ((flag%2)!=0)
	{
	data_low = mySerial.read();
	}

	else if ((flag%2)==0)
	{
	data_high = mySerial.read();
	}
}
    
    
double tempFactor = 0.02;
double tempData = 0x0000;
int frac;
    

tempData = (double)(((data_high & 0x007F) << 8) + data_low);
tempData = (tempData * tempFactor)-0.01;
    
float celcius = tempData - 273.15;

Serial.print("Celcius: ");
Serial.println(celcius); 
delay(2500);
}

The logic of placing the 'flag' variable was to make sure every 'odd' data would come into data_low, and then 'flag' would increment by one and become even, the next data would go into data_high. This was my attempt at some sort of synchronization. I placed the last statement delay(2500); in the transmitter side too, but it showed the same erroneous data. Also, I suspect data is not being read by the sensor, or is perhaps being read just once and the same data is being transmitted again and again.

1_.jpg