How to work with 4 sets of data and 2 variables?

Hey folks!

I am working on a project dealing with OBD2. In a nutshell, I have to light up an LED if certain parameters dealing with RPM and Speed are met.

Now, the problem is that I need 4 sets of data of RPM and speed; and compare them.

For example:

At t=0, the first RPM and speed data recorded are set as R1 & S1 respectively.
Now the next set of data received is set as R2 & S2, and same with 3 and 4.

If the parameters are met for these 4 sets, then light up the led; or if not met, the next set of data received is used instead of the first one.

In other words, the latest 4 sets of data are to be used.

Now, I don't have a bit of idea how to get with it. Any suggestion/guidance regarding this is truly appreciated.

Thanks!

struct

Array of struct:

struct speedRpm {
  uint32_t speed;
  uint32_t rpm;
};

speedRpm dataSamples[4];

Sounds like a "circular buffer" to me.

struct {int _RPM; int _MPH;} Entries[4];
byte BufferPointer;

void addEntry(int RPM, int MPH) {
    Entries[BufferPointer].RPM = _RPM;
    Entries[BufferPointer].MPH = _MPH;
    BufferPointer = (BufferPointer+1) % 4;  // Modulo operator to give a 0..3 answer
}

   //  Entries[BufferPointer] is the oldest entry
   //  Entries[(BufferPointer+1) %4] is the second-oldest entry
   //  Entries[(BufferPointer+2) %4] is the third-oldest entry
   //  Entries[(BufferPointer+3) %4] is the newest entry

gfvalvo:
Array of struct:

Right. To be specific.

At t=0, the first RPM and speed data recorded are set as R1 & S1 respectively

Read the data into the variables. If the parameters are met by the data received then set a boolean to true else set it to false.

Read the data again into the same variables. If the parameters are met by the data received then set the boolean to true else set it to false.

Read the data again into the same variables. If the parameters are met by the data received then set the boolean to true else set it to false.

Read the data again into the same variables. If the parameters are met by the data received then set the boolean to true else set it to false.

If the boolean is still true after 4 reads then the conditions have been met.

My first choice would be struct and pointers because storing new data and dropping the oldest is just an exercise in using pointers.

My second choice would be an array of structs.

My third choice would be an array of RPM values and an array of speeds.

The array approaches need a loop to move data to get rid of the oldest.

My fourth choice would be a big bunch of variables and would need a big bunch of code to get rid of the oldest. It also would not be easy to change from saving the last four readings to some other number.

If the parameters are met for these 4 sets, then light up the led; or if not met, the next set of data received is used instead of the first one.

In other words, the latest 4 sets of data are to be used.

It seems to me that these 2 statements are contradictory

vaj4088:
The array approaches need a loop to move data to get rid of the oldest.

no - just an index that you move to the current start in the array and doing math with modulo the size of the array.

This would work also. I usually avoid division - which is what the modulo operation may entail for values that are not a power of two - but division is likely to be quicker than moving a bunch of data. Good one!

vaj4088:
This would work also. I usually avoid division - which is what the modulo operation may entail for values that are not a power of two - but division is likely to be quicker than moving a bunch of data. Good one!

well also in that case since it's a simple circular buffer you can do it with no division at all since it's just moving one position by one position

you need

  • a boolean stating if the array has been fully populated, starts at false
  • an index going through the array

when the boolean is false, data captured are in 0..index
when the boolean is true, you have historical valid data in the array and you can iterate through the array from most recent to oldest with just two for loops (index-1 to 0 whilst >=0) and (max size - 1 to index)

Sincerest gratitude to everyone for helping me out! Though, the biggest problem is that I'm a novice(can blink and fade an LED).

For this reason, though I was able to understand the replies, I'm unable to put this in code.

I'm using Kokoras' RPM Indicator project (Arduino Bluetooth OBDII RPM Shift Light) as a base and modifying it according to my needs.

So, where do I need to incorporate this in my code?

johnwasser:
Sounds like a "circular buffer" to me.

struct {int _RPM; int _MPH;} Entries[4];

byte BufferPointer;

void addEntry(int RPM, int MPH) {
    Entries[BufferPointer].RPM = _RPM;
    Entries[BufferPointer].MPH = _MPH;
    BufferPointer = (BufferPointer+1) % 4;  // Modulo operator to give a 0..3 answer
}

//  Entries[BufferPointer] is the oldest entry
  //  Entries[(BufferPointer+1) %4] is the second-oldest entry
  //  Entries[(BufferPointer+2) %4] is the third-oldest entry
  //  Entries[(BufferPointer+3) %4] is the newest entry

UKHeliBob:
It seems to me that these 2 statements are contradictory

I'm sorry if I messed it up, but I need the last 4 data set received from the OBD for the job.

Regards

torquefreak:
For this reason, though I was able to understand the replies, I'm unable to put this in code.

Only in the short period of time that elapsed since the replies... programming takes time. It would be better for you to study the replies than to sail off with a cut and paste job from another program.

torquefreak:
So, where do I need to incorporate this in my code?

You mean that other person's code? Probably in 'rpm_calc()' if you want to store that latest four values for RPM.

Hey!

So after a long time, I figured it out (with some help!). I have the code ready, just unable to connect it to the car.

For testing purpose, I switched the loop part to light up an led when rpm>1000. But it doesn't work.

I believe it's most probably due to the IAC error (How to set Inquire Access Code (IAC) via AT commands on HC-05 - Programming Questions - Arduino Forum) which I had posted in a different thread.

I'm uploading the code and the circuit diagram. In the circuit, I've tried interchanging 'State' & 'Key' but to no avail.

Would be very thankful if someone could point out what's cooking. At best, the HC05 is blinking twice per 5 seconds.

Regards

Arduino_ODB2_Circular_Buffer.ino (16.2 KB)