Arduino PID Update

I wrote a post a few months back detailing my Arduino PID controller approach.  Based on some feedback, I realized the code in that post was overly complicated as well as had some errors in it.  I am now going to detail a much simpler approach.

Previously, I used a PID controller to schedule temperature over a fixed amount of time, such as to have precise ramp up time, hold time, and cool down time.  It is worth noting that a PID controller is also useful for indefinite time control, like a thermostat.  By varying the coefficients, you can customize how fast the system reacts and not damage any equipment (this is a consideration when using mechanical relays that don’t like fast switching).

Below is my Arduino C code for maintaining a set temperature like a thermostat with a PID controller.  The MAX31855 and the PID_v1 libraries can be found on my Github page.

#include "SPI.h"
#include "MAX31855.h"
#include "PID_v1.h"

//
//Arduino Pins
//
//CSB of MAX31855 thermocouple. By using separate CSBs, multiple devices can use the same SPI bus.
byte thermo1_csb = 7;
//Pin to control relay that switches the heating element
byte temp_relay0_Pin = 0;

//
//PID calculation parameters
//
//Value read by thermocouple sensor
double temp_read1;
//Temperature that system is currently maintaining
double temp_set1 = 95;
//Control value resulting from PID calculation
double Output_T1;

//
//Library Objects
//
MAX31855 thermo;
PID PID_temp1(&temp_read1, &Output_T1, &temp_set1, 1, 5, 0.5, DIRECT);

void setup()
{
   //Initiate thermocouple
   SPI.begin();
   thermo.setup(thermo1_csb);

   //Initiate heating element relay
   pinMode(temp_relay0_Pin, OUTPUT);
   digitalWrite(temp_relay0_Pin, LOW);
}

//This function reads the thermocouple sensor and translates the value into temp_read1
void read_sensors()
{
   thermo.read_temp();
   temp_read1 = thermo.thermocouple_temp*1.8+32;
}

//This function computes the output control value from the thermocouple reading and current set point
//and then turns the heating element on and off accordingly
void run_PID()
{
   uint16_t low_WindowSize = 0;
   uint16_t high_WindowSize = 1000;
   uint32_t windowStartTime = millis();

   //Specify the links and initial tuning parameters
   PID_temp1.SetOutputLimits(low_WindowSize, high_WindowSize);
   //PID_temp1.SetTunings(Kp, Ki, Kd);
   PID_temp1.SetMode(AUTOMATIC);

   PID_temp1.Compute();

   //This section controls the heating element
   while(millis() < (high_WindowSize-low_WindowSize) + windowStartTime) 
   {
       if(Output_T1 > (millis() - windowStartTime))
       {
          digitalWrite(temp_relay0_Pin, HIGH);
       }
       else
       {
         digitalWrite(temp_relay0_Pin, LOW);
       }
   }
}

void loop()
{
   read_sensors();
   run_PID();
}

Advertisements

USB Power Supply Arduino Shield

I want to start making some battery powered gadgets, but I really want to know how much power my circuits require before hooking up the battery and releasing them into the world.  After a bit of searching, I couldn’t find anything that would let me set my own voltage (sometimes 5V, sometimes 3.7V for batteries, sometimes something else), tell me how much current I’m using, and be cheap enough for a hobbyist like myself.  So I started drawing up a schematic.  This is what I think I can do:

– Switching regulator for good efficiency and up and down DC voltage conversion.  Highly considering LTC3112 to get a 3 to 12V range.

– Arduino shield.  This will give me lots of analog and digital I/Os.

– Can run off of the Arduino power or from an external power input.  Going to use an FDC6324 to switch between them.

– Current Sensing Circuit.

– Current Limit Circuit.  I don’t want to blow anything up with an accidental short.  I couldn’t find any integrated chips to handle the voltage range I want, to I’m going to use a power pFET.

– Programmable potentiometers so that everything can be set digitally.

I started drawing up a project in Kicad.  Here is the schematic so far usb_power.  Here is the project on Github.

Programming with Adafruit Trinket

I’m very excited about using the Adafruit Trinkets, which are essentially small breakout boards for the Atmel ATtiny85 microcontroller.  It is intended to be used with the Arduino IDE (and I hoped this would be easy), and I found this to work well for compiling source code into a HEX file.  However, I was never successful getting the upload to work directly with Arduino IDE.  At this point, I learned to use avrdude from the command line (I’ve been working in Windows XP up to this point, but I’m switching to Ubuntu since MS doesn’t support XP anymore).

I followed the instructions from Adafruit given here.  These are well written and got me a long way.  I only had trouble uploading with avrdude.

I found this to be a two step process:

1.  I used this command to clear the on-chip flash:  avrdude -c usbtiny -p attiny85 -U flash:w:<hexfile.hex>

This would flag tons of errors that would require a CTRL-C to stop.

Inline image 1

 

2.  Then run this similar command:  avrdude -c usbtiny -p attiny85 -D -U flash:w:<hexfile.hex>

This will actually write to the flash.  If you don’t do step 1, you will get a verification error.

Inline image 1

 

Once the chip was programmed, everything worked well.  Many of the Arduino commands work with the ATtiny85.

Arduino Garage Door Opener

As the first sensor in a long line of future home automation contraptions, I put together a small board that can sense the current state of the garage door (up or down), toggle the garage door motor, and wirelessly send and receive commands.  Here’s what I’ve got so far.  It’s built around the Arduino Nano that controls a NRF24L01 breakout for wireless, a Parallax PING proximity sensor for determining if the door is up or down, and a 5V relay for toggling the door motor.  The hardware is mostly finished, now I’ve got to get to coding.  I’m planning on developing several more sensors around ATMEGA and NRF24 chips.

IMG_20130626_201740_824 IMG_20130626_201827_172

Garage Door Opener

The theme of this blog is taking stuff apart with the goal of adding some awesome features.  Today I am going to start with the mission of taking my regular garage door opener and adding smart phone control to it.  I want to see if it is up or down and be able to open or close it from anywhere.

To start with, I have a Liftmaster 1/2 HP Security Plus motor and it has a button that I am taking apart.  The button has 2 wires going to it and it has 3 buttons on it: 1 large button for opening/closing the garage door, 1 small button for the light on the motor, and one for locking the door.  When I got the button open, the basic circuit looks like this:

Image

I’m going to guess the white wire is a GND and the red wire is either straight 24V or 24V through a pull-up resistor inside the motor.  Anyway, with the button disconnected, touching the red and white wires together will open and close the door.  That part is easy.  As for the light and the lock, my guess is there is a circuit that measures the charge up time of these capacitors and this tells the motor to activate either the light or lock.  However, what I am not seeing is a easy way to tell the current state of the garage door electronically (i.e. not just looking at it).  These controls can toggle the state, but not tell me what state I am currently in.  The nice part about these switches being in parallel is I can create my own set of switches to be controlled via Arduino, put them in parallel to this button, and then I can use either this button or Arduino to open/close the door.  I’ll likely use either a proximity or light sensor to tell me the current state of the door.