Controlling Multiple PID Loops with One Arduino

My blog post that gets the most attention is by far the Arduino PID Temperature Controller, and I got a great suggestion from a reader about modifying that code to accommodate more than one PID loop in a single Arduino sketch.  While this is slightly more difficult than simply adding a second PID instance, it’s not too hard.  Let me explain.

I’ve started a new file on Github for this here.  It is still a work in progress, but I hope to finish it soon.

If you notice in the previous post, the run_PID function uses while loops to kill time in between switching the SSR_PIN (which is the Solid State Relay digital control switch, in case you’ve forgotten).  I’ve copied the relevant section of the original code below.

void run_PID(double Kp, double Ki, double Kd, uint16_t WindowSize, uint32_t time_interval)
{
   ...

   digitalWrite(SSR_PIN, 1);
   while(millis() - windowStartTime < time_interval * ratio);

   digitalWrite(SSR_PIN, 0);
   while(millis() - windowStartTime < time_interval);
}

This is fine for a single loop, but multiple loops couldn’t work this way.  If you had 2 copies of this running, the first instance would execute and then the second instance would execute, causing one instance to be asleep half the time.  This serial implementation would certainly mess up your loop timing.

The fix is to move the loop outside of this function and use if statements instead.  In this way, this run_PID function simply checks if the time is right to toggle SSR_PIN and doesn’t “block” other instances.  The proposed revision is below.

void run_PID(double Kp, double Ki, double Kd, uint16_t WindowSize, uint32_t time_interval)
{
   ...

   if(millis() - windowStartTime < time_interval * ratio)
   {
       digitalWrite(SSR_PIN, 1);
   }

   if(millis() - windowStartTime < time_interval)
   {
       digitalWrite(SSR_PIN, 0);
   }
}

The run_PID function could also be further split, because now that this function will be called many times, the PID equation does not need to be computed each time.

 

This is just the introduction to the revisions that need to be made to handle multiple loops.  I will add to this post as I update the PID controller in github and actually test out the code.  Thanks for reading!

 

Advertisements

OBDII Controller with Raspberry Pi

It’s been awhile since I last posted, but I have a new idea.  I’m always fascinated with data, and I feel like just a small portion of available data in a car is actually accessible through the dashboard.  Therefore, I am going to start working on a project to collect car sensor data using a Raspberry Pi.

I bought a OBDII reader several years ago, and I’d check out “Check Engine” light codes and other stuff with a laptop.  However with advancing technology, I don’t see any reason why I can’t use that same reader with a Raspberry Pi and send that data to my phone for displaying.  Or even to send that data into my home WiFi network to be saved for later analysis.  I’ll worry about extra add-ons later.

Here’s how I’m breaking this project down (I’ll update as I complete):

  1. Get the reader communicating with the RPi.  I currently have a Elm Scan 5 OBD scan tool, a RPi version B+, and a 2006 Toyota Highlander that I’m planning to use for this.  Ideally, all of these parts will be interchangeable if you are playing along at home, but this is what I have.
  2. Start pulling some data off the OBDII system.
  3. Set up data sharing protocol.  Not sure yet if this will be WiFi or Bluetooth.  WiFi is probably overkill, but I could probably get it to connect directly with my home network for data collection.  Bluetooth would likely be simpler for just a smartphone interface.
  4. Graph the data into something nice to look at.  Hopefully this will be done on my smartphone (Nexus 5x).

If I get all the way through this, I think it will shower me in engine data as I drive along.

UPDATE:  I have started preparing a RPi B+ with a clean Raspbian Jessie Lite image and things are going well.  I did already learn a critical lesson: the Elm Scan 5 has to be plugged into the OBD port to communicate, even though the red power LED turns on with just USB.  I spent an hour wondering why I couldn’t get any serial comms going in my office, only to get some data action when I took the unit outside and plugged it into the car.

My plan is to combine all these tricks I learn along the way into a new, finished post.