Delay in sensor reading update

Hi people,

I have a control unit on my car which sends a number of sensor readings to an Arduino Mega’s Serial port 1. I have a XBee Pro 60mW Wire Antenna - Series 1 , on the Mega which sends the data to an Arduino Uno with another XBee Pro 60mW Wire Antenna - Series 1 on it’s top which is connected via USB to my laptop. Moreover, the control unit has a software which allows me to connect it to my laptop via USB and monitor a variety of sensor readings on that as well.
The control unit provides me with the vehicle’s throttle position as a percentage. When I monitor the throttle position on the control unit’s software, as I gently press the pedal, the percentage value almost immediately increases. But, there is a delay associated with refreshing of the throttle position when I am receiving the data wireless.
I am not sure whether this is mainly because of the limitations of xbees or because of my code. I am thinking that it is because of my code, but I can not see how or why?
Here is my code:

/*
In "Working_wireless_on_the_car_with_Processing_V2" , it is intended to increase performance speed of the 
 Microcontroller by improving the coding structure
 */
#include <stdlib> // Standard library

/*
The data bytes are defined below as constants
 */

const int THROT_POS1 = 6;
const int THROT_POS2 = 7;
const int ENG_TMP1 = 12;
const int ENG_TMP2 = 13;
const int AIR_TMP1 = 18;
const int AIR_TMP2 = 19;
const int BAT_VOL1 = 10;
const int BAT_VOL2 = 11;
const int OIL_PRS1 = 34;
const int OIL_PRS2 = 35;

/*
End of data byte definition
 */

const unsigned int MAX_INPUT = 104; // The maximum number of bytes to be received over the Serial connection from ECU

void setup ()
{
  Serial.begin (19200);
  // Serial1.begin(19200);  // If using a Mega
} // end of setup

/*
The block of code that calculates the CRC-32 starts here
 */

static PROGMEM prog_uint32_t crc_table[16] = {
  0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
  0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
  0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
  0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};

unsigned long crc_update(unsigned long crc, byte data)
{
  byte tbl_idx;
  tbl_idx = crc ^ (data >> (0 * 4));
  crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f)) ^ (crc >> 4);
  tbl_idx = crc ^ (data >> (1 * 4));
  crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f)) ^ (crc >> 4);
  return crc;
}

unsigned long crc_string( unsigned char *s, unsigned int length)
{
  unsigned long crc = ~0L;
  unsigned int i;
  //while (*s)
  for(i = 0; i<length;i++){
    crc = crc_update(crc, *s++);
  }
  crc = ~crc;
  return crc;
}

/*
The end of CRC-32 block
 */


// Here to process incoming serial data after a terminator received

void process_data (unsigned char *data)
{
  static unsigned long whole_four = 0; // This variable holds the last four bytes of the received bytes which are the CRC bytes


  if (*data == 0x82 && *(data+1) == 0x81 && *(data+2) == 0x80)  //Checking for the starting 3 header bytes
  {

    whole_four = ((unsigned long)(*(data+(MAX_INPUT-4)))<< 24)  | ((unsigned long)(*(data+(MAX_INPUT-3)))<< 16) | ((unsigned long)(*(data+(MAX_INPUT-2)))<< 8) | ((unsigned long)(*(data+(MAX_INPUT-1)))); // Forming a Hexadecimal value from the four CRC bytes
    if (crc_string(data,(MAX_INPUT-4))==whole_four) // Checking if the calculated CRC bytes match the received CRC bytes
    {
      //Calculating and formatting air temperature for dispalying
      float l = (((*(data+AIR_TMP1)) << 8)+ (*(data+AIR_TMP2)))/10; 
      Serial.print("Air Temp ");
      Serial.print(l);
      Serial.print("C[ ");

      //Calculating and formatting Throttle position for dispalying
      float a = (((*(data+THROT_POS1)) << 8)+ (*(data+THROT_POS2)))/10; 
      Serial.print("Throttle position ");
      Serial.print(a);
      Serial.print("%? ");


      //Calculating and formatting Engine temperature for dispalying
      float o = (((*(data+ENG_TMP1)) << 8)+ (*(data+ENG_TMP2)))/10;
      Serial.print("Engine Temp ");
      Serial.print(o);
      Serial.print("C, ");

      //Calculating and formatting Battery voltage for dispalying
      float y = (((*(data+BAT_VOL1)) << 8)+ (*(data+BAT_VOL2)))/100;
      Serial.print("Battery voltage ");
      Serial.print(y);
      Serial.print("V; ");

      //Calculating and formatting Oil pressure for dispalying
      float k = (((*(data+OIL_PRS1)) << 8)+(*(data+OIL_PRS2)))/10;
      Serial.print("Oil pressure ");
      Serial.print(k);
      Serial.print("Kpa: ");
    }


  }

}  // end of process_data

/*
This function processes data as they come to the serial buffer
 */

void processIncomingByte (unsigned char inByte)
{
  static unsigned char input_line [MAX_INPUT]; //Self-defined buffer for data
  static unsigned int input_pos = 0; //To determine the index of data in self-defined buffer



  switch (input_pos)
  {

  case MAX_INPUT:   // When arrive to the end of self-defined buffer, process and format data

    process_data (input_line);

    // reset buffer for next time
    input_pos = 0;  
    break;

    //case '\r':   // discard carriage return
    // break;

  default:
    // keep adding if not full 
    if (input_pos < (MAX_INPUT))
      input_line [input_pos++] = inByte;

    break;

  }  // end of switch

} // end of processIncomingByte  


void loop()
{
  // if serial data available, process it
  if (Serial.available () > 0)
    processIncomingByte (Serial.read ());

  // do other stuff here like testing digital input (button presses) ...

}  // end of loop

Do you have any ideas or hints?

Do you have any ideas or hints?

Yes.

  Serial.begin (19200);

Pick up the pace. 115200 is 6 times as fast.

What baud rate are the XBees using?

  if (*data == 0x82 && *(data+1) == 0x81 && *(data+2) == 0x80)  //Checking for the starting 3 header bytes

Ugh!

if(data[0] == 0x82 && data[1] == 0x81 && data[2] == 0x80)

would be a lot more readable.

Do you really need to send so much useless text? “A,xx.xxx; T,xx.xxx; E,xx.xxx; B,xx.xxx; O,xx.xxx!” would convey the same information in a lot fewer byte. And, the receiver would KNOW when the end of a packet had arrived.

Hi PaulS,

Pick up the pace. 115200 is 6 times as fast.

The control unit that I am using recommended me that I "should" use 19200 bps for serial communication. However, the next highest transmission rate that it offers is 38400 bps. I tried that as well and I started getting a lot of corrupted data coming in( i.e. a lot of data bytes repetition and zeros in between the data bytes). The interesting thing is that when I set it back to 19200 bps again it worked fine. I also like to mention that I did not forget to update the baud rate on my code and Xbees when I switched the baud rates, so corrupted data would not have anything to do with that.

What baud rate are the XBees using?

19200 bps

Ugh!

Code:

if(data[0] == 0x82 && data[1] == 0x81 && data[2] == 0x80)

would be a lot more readable.

Sorry about the readability :sweat_smile:. I was very excited with pointers and thinking about them when I was writing that code, even though I am aware of their connection with arrays. Nonetheless, I really appreciate it that you pointed that out. :slight_smile:

Do you really need to send so much useless text? "A,xx.xxx; T,xx.xxx; E,xx.xxx; B,xx.xxx; O,xx.xxx!" would convey the same information in a lot fewer byte. And, the receiver would KNOW when the end of a packet had arrived.

I am using those text to display the data on a window that I created using Processing. May I ask for example, how would you have it?
Also if you think it helps, I can post the code I am using on Processing as well. :smiley:

The control unit that I am using recommended me that I "should" use 19200 bps for serial communication.

The "control unit" you are talking to is Processing. I don't understand this statement.

May I ask for example, how would you have it?

I showed you. One letter is sufficient to define each of the different types of data you are sending.

The "control unit" you are talking to is Processing. I don't understand this statement.

The control unit I am talking to is not "Processing". By Processing I meant the software from www.processing.org.
The control unit is fixed on a car. A variety of the sensors on the car send data to the control unit, which can do a variety of things to the data. One of the things that the control unit can do, is to send out serial data regarding the sensor readings from it's serial output. I am receiving these data using an Arduino Mega's Serial port 1 and sending it out using an Xbee module.
I have an Arduino Uno with another Xbee module on it, which receives the data and does things to it as you have seen in my code. I have also written a code using the Processing software that I mentioned previously, which allows me to display things nicely on my laptop. So the control unit on the car is currently sending data to the Mega at 19200 bps, and in it's manual, this is the recommended baud rate.

I showed you. One letter is sufficient to define each of the different types of data you are sending.

I see. So I will be better off writing the full text like "Air temp" inside my Processing code rather than prompting Uno to print it and then use Processing to show that.

The control unit I am talking to is not "Processing".By Processing I meant the software from www.processing.org.

That's what I said.

The control unit is fixed on a car.

So, I'll take this to mean that you are trying to use the ONE serial port on the Arduino to talk to some device in the car AND to Processing. That will NOT work.

So, I'll take this to mean that you are trying to use the ONE serial port on the Arduino to talk to some device in the car AND to Processing. That will NOT work.

Hi PaulS,
I would like to mention that there are two arduino boards, one Mega and one Uno. Why this will not work, considering that it seems to be working now with 19200 bps ???
The only problem is that it has some delay as I mentioned previously . Because I would like to make sure that I have not misguided you with my descriptions, I have added a simple diagram of my apparatus.
Please have a look at the diagram and tell me whether that is what you thought of my descriptions or not. Also if your answer is that my apparatus is not going to work, would you be able tell me why not and how I can go about fixing it?

Looks like the diagram didn't make it for some reason.

Wow. :cold_sweat: My apologies.
Here’s the image.

Setup image.tif (31.2 KB)

The code we have been looking at is running on which Arduino?

Arduino Uno.

So, when I said to increase the serial baud rate, why do you think that the baud rate between the Uno and Processing has ANYTHING to do with the baud rate between the Mega and the control unit?

So, when I said to increase the serial baud rate, why do you think that the baud rate between the Uno and Processing has ANYTHING to do with the baud rate between the Mega and the control unit?

I am so sorry, because it seems that I misunderstood you. So just to clarify things, you are saying that if I change the baud rate on the Uno, I will not get a lot of junk data? What I mean is, I was under the impression that whenever two devices (say an Uno and a Mega) try to serially communicate with each other with mismatched baud rates, I would get a lot of nonsense displayed on the serial monitor. For example in this case because the Mega is wirelessly sending the data at 19200 bps, I thought I need to have the Uno's Serial also running at 19200 bps.

So just to clarify things, you are saying that if I change the baud rate on the Uno, I will not get a lot of junk data? What I mean is, I was under the impression that whenever two devices (say an Uno and a Mega) try to serially communicate with each other with mismatched baud rates, I would get a lot of nonsense displayed on the serial monitor.

The Mega and the car thing talk to each other at some baud rate.
The Mega and the XBee talk to each other at some baud rate.
The XBee on the Mega and the XBee on the UNO talk to each other at some baud rate.
The XBee on the Uno and the Uno talk to each other at some baud rate.
The Uno and the PC talk to each other at some baud rate.

None of the 5 baud rates needs to be the same. But, the baud rate for each end must be the same.

It still seems like you are using one serial port on the Uno to talk to two devices - the XBee and the PC. That won't work. If the Uno is doing nothing more than attempting to relay information from the XBee to the PC, then it needs to be running this sketch:

void setup() {}
void loop() {}

If the Uno is to be doing more than acting as a relay, the XBee can not be connected to the RX and TX pins. They are for communication with the PC.

Since the Uno only has one hardware serial port, you need to use SoftwareSerial to communicate with the XBee.

Thank you very much. That clears a lot of things. :slight_smile:

It still seems like you are using one serial port on the Uno to talk to two devices - the XBee and the PC. That won't work.

I have been told that such thing won't work before. The reason that I attempted it is that one of my friends mentioned to me at one point that it works and it is some sort of hardware serial hack. To be honest, it seems to be working not taking into account the delays. However, do you think that the reason behind the delays is using the same serial port for two things and also would you be able to tell me (or refer me to some article or website) the reason why such thing shouldn't work based on certain principles?
All that said, I really appreciate that you have been patiently following up this post. :smiley:

I've hinted before that you need to tell us what kind of shield you are using. No more hints. What kind of XBee shield are you using?

It has yet to be established where the apparent delay is coming from.
Is it that the Mega is taking a while to get data from the device?
Is it that the Mega is taking time to get the data to the XBee (unlikely)?
Is it that the XBees are taking time to communicate with each other? What kind of XBees are they? How are they configured?
Is it that the XBee is taking time to get the data to the Uno (unlikely)?
Is it that Processing is taking time to display the data?

Firstly I apologize for coming back to you a bit late.

Is it that the XBees are taking time to communicate with each other? What kind of XBees are they? How are they configured?

The Xbees are :
XBee Pro 60mW Wire Antenna - Series 1
Bothe Xbees are configured using XTC-U.
The Xbee on the car is configured as a Coordinator, set to broadcast the information(i.e. the Destination address low byte is “FFFF” and the high byte is zero). It is configured to have a Packatization timeout of 0xFF. It has the baud rate 19200 bps.
The Xbee connected to my laptop is configured as an End Device, and it’s PAN ID and baud rate match the Coordinator.
Let me know if you need to know any other specific parameter as there are quite a few.

tell us what kind of shield you are using

On my shields it is written:
“Arduinoxbee v1.1”
Underneath that it is written “M.Yerze”.

I apologize again for coming back to you late and certainly appreciate your guidance. I am not sure about the answer to the rest of the questions that you have asked and I have not had the chance to test what happens when I increase the baud rate on the Uno and Processing, as we discussed previously. I will let you about that as well as soon as possible.

On my shields it is written:
"Arduinoxbee v1.1"
Underneath that it is written "M.Yerze".

I apologize for my crudeness, I have to clarify that the shield that I am using is based on "Libelium Xbee Shield" design with those particular writings on it.

When you get around to posting a link, and explaining how the jumpers are set, I'll respond again.