Displaying multiple serial data items using processing

Hi everyone,

I have an Arduino Mega which is sending some predefined data to an Arduino Uno. Namely "Air temperature", "Oil temperature" and "Battery voltage". Consider also that I have checked the incoming serial data into the Uno and confirmed that the correct data is received. Now my problem is that I can not get these data displayed properly using processing. I am trying to display each of the three data items in a separate line. "Air temperature" should read a value of "2266". "Oil temperature" should read a value of "2159" and "Battery voltage" should read a value "531". So I am looking for an output on the screen that looks something like:

Air temp is: 2266 Oil temp is: 2159 Battey voltage is: 531

I would appreciate it if you have a look at my code and let me know where I am going wrong.

Here's my Code on Arduino IDE which is being compiled on Uno:

unsigned char buff[14];
void setup() 
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600); //talk to laptop
}
 
void loop() // run over and over
{ 
  if (Serial.available() == 14) // I'm sending 14 bytes and want to check that some bytes are read, before filling the buff
 
  {
    if (Serial.read() == 0x82)
    {
      if (Serial.read() == 0x81)
      {
        if (Serial.read() == 0x80)
        {
          buff[0] = 0x82;
          buff[1] = 0x81;
          buff[2] = 0x80;
          for (int i = 3; i<14; i++)
          {
            buff[i] = Serial.read();
          }
 
          /*for(int k = 0; k<14;k++)  // supposed to empty the buffer or reset it
           {
           Serial.read();
           }*/
        }
      }
    }
  }
  if (buff[0] == 0x82 && buff[1] == 0x81 && buff[2] == 0x80)
  {
 
    int c = ((buff[4] << 8) + buff[5])/10;
 
    Serial.print("Air temp is: ");
    Serial.println(c);
    Serial.print('F');
 
    int d = ((buff[6] << 8) + buff[7])/10;
    Serial.print("Oil temp is: ");
    Serial.println(d);
    Serial.print('J');
 
    int e = ((buff[8] << 8) + buff[9])/10;
    Serial.print("Battey voltage is: ");
    Serial.println(e);
    Serial.print('N');
    //Serial.println(freeRam());
  }
}

Here's the code that I run on processing for Uno:

import processing.serial.*;
Serial myPort;
String Air_temp="";
String Oil_temp="";
String Battey_voltage="";
PFont font;
int lf = 10;
 
 
void setup() {
  size(500, 500);
  myPort = new Serial(this, "COM24", 9600);
  myPort.bufferUntil('N');
  font = createFont(PFont.list()[2], 32);
  textFont(font);
}
 
void draw() {
  //The serialEvent controls the display
} 
 
void serialEvent (Serial myPort) {
 
  Air_temp = myPort.readStringUntil('F');
  //Oil_temp = myPort.readStringUntil('J');
  //Battey_voltage = myPort.readStringUntil('N');
  /*  if(Air_temp != null){
   Air_temp=trim(Air_temp);
   }*/
 
  text(Air_temp, 1, 60);
  //text(Oil_temp,width/10,height/20);
  // text(Battey_voltage,10,40);
}
 
 
void writeText(String textToWrite) {
 
  background(255);
  fill(0);
  text(textToWrite, width/20, height/2);
}

Here's the result that I get from processing:

I have an Arduino Mega which is sending some predefined data to an Arduino Uno. Namely "Air temperature", "Oil temperature" and "Battery voltage".

Why does the Uno need these strings?

How is the Mega sending these strings? How is the Uno reading them?

  if (Serial.available() == 14) // I'm sending 14 bytes and want to check that some bytes are read, before filling the buff

I hope you never miss a byte, or take so long getting back to this loop, so that there are 15 bytes or more in the buffer. Typically, you would use >=, not ==.

    int c = ((buff[4] << 8) + buff[5])/10;

What happens to your 8 bit value when you shift it 8 bits to the left? You should be casting buff[4] (and the other MSBs) to int before shifting.

Here's the code that I run on processing for Uno:

I don't know what "processing for Uno" means, because Processing doesn't run on a Uno or any other Arduino. That code does NOT create the posted image.

It isn't clear what your problem is.

Hi PaulS,

I understand that I made some mistakes in my explanation and failed to clarify my aims. Thanks for pointing them out. I'm going to try to fix them:

Why does the Uno need these strings?

I am trying to simulate the serial function of a device called an Engine Control Unit (ECU). The ECU that I'm using, uses RS-232 to send out data, while I am aware that Arduinos use TTL. However, in this case the pure purpose of my simulation was just to be able to send some data using Mega (using a piece of wire from it's TX) to Uno's RX. Then write a piece of code which stores the incoming data and does some conversions and prints the results to the serial port. The ECU always sends three header bytes (0x82, 0x81, 0x80) and then the rest of the data. This can be seen in my code. Most of the parameters are sent as 2 bytes hence the left shifting and the rest of the process in conversion section.
So this is what I'm compiling on the Mega:

unsigned char sample[14] = {0x82,0x81,0x80,0x21,0x58,0x89,0x54,0x56,0x14,0xC5,0xDA,0x55,0xA6,0xBC};

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial1.begin(9600); // talk to car
          
}

void loop() // run over and over
{  
  for(int i = 0; i<14; i++)
  {
  Serial1.write(sample[i]);
  }
}

As you can see, I am sending :

unsigned char sample[14] = {0x82,0x81,0x80,0x21,0x58,0x89,0x54,0x56,0x14,0xC5,0xDA,0x55,0xA6,0xBC};

Where element 4 and 5 of sample represent the Air temperature.

How is the Mega sending these strings? How is the Uno reading them?

You can look at the code I compiled on the Mega and see that the "Serial1.write" is sending the data from Mega's serial port number 1.
If you look at the code for Uno, I first check for the header bytes to be present, then write them and the rest of the 14 elements to the "buff" array.

I hope you never miss a byte, or take so long getting back to this loop, so that there are 15 bytes or more in the buffer. Typically, you would use >=, not ==.

Very good point. I will certainly fix that.

What happens to your 8 bit value when you shift it 8 bits to the left? You should be casting buff[4] (and the other MSBs) to int before shifting.

I believe I already answered this question while answering your first question. The ECU I'm using sends most of the data ( or at least the ones I have in mind) in 2 bytes. I have attached a file that shows in a table, how the ECU sends data. Have a look at the Air temperature, or the Engine temperature and see if my conversion makes sense.

I don't know what "processing for Uno" means, because Processing doesn't run on a Uno or any other Arduino. That code does NOT create the posted image.

I am very very sorry for this. I made a big mistake putting that part into words. What I meant to say was that I wrote a piece of code to display the serial data transmitted from the Mega to the Uno on my computer screen using processing. I was thinking of creating a user interface which allows the people to run it and see the incoming serial data in a nice way.

So as I mentioned before, I connect TX 1 of the Mega to RX of the Uno using a copper wire. Eventually I intend to transmit the data using wireless Xbee modules.

PSAU0015 MoTeC M800 Set 3 Data Protocol.zip (941 KB)

I believe I already answered this question while answering your first question. The ECU I'm using sends most of the data ( or at least the ones I have in mind) in 2 bytes.

Suppose the MSB byte contains 255 (0xFF or 0b11111111). What will the byte contain after being left shifted once? Show us what you understand the bit pattern will be. Hint: it will be 0b11111110 (the high bit is lost).

Now what will the bit pattern be after being left shifted 7 more times? Show us what you understand the bit pattern will be.

Then, consider what the differences would be if the value being shifted was 0x00FF, instead. This is why the MSB needs to be cast to an int (so that it becomes 16 bits) before the shifting happens.

The real problem, though, is that you have the roles of the Mega and the Uno reversed. The Mega has 4 hardware serial ports, of which you are using one to talk to the UNO. The UNO has one hardware serial port. It can use that port to talk to the Mega OR it can use that port to talk to the PC.

If the UNO was sending the data to the Mega, the Mega could receive the data on Serial1 pins, and send it to the PC using Serial.

The Processing application doesn't create the screen shot you posted. It might, if some of the commented out code was uncommented.

I'm not sure that I understand how the screen shot differs from what you want. If you want all the data displayed on one line, you need to collect all the data in one string and make one call to text().

I apologize for coming back to this post this late.

I appreciate your thorough and step by step analysis of my problem. You make very valid points and I am sorry to make things confusing. I will revise my work and let everyone know of my progress.

Hi Jimbojon, did you have any luck getting the rs232 tx from the M800? I would like to try to do.something similar with an SDL.

Kind of. Follow my other posts and if you still bump into issues certainly ask. :slight_smile: