0
votes

I am trying to configure my arduino mega with PID functionality. The arduino example initiateS a Relay that turns on and off that is based off the 'millis' function. However, I would like to know if it is possible to have the PID on a timer call so after lets say 6 minutes it checks the sensor reading. Based off the sensor reading and how aggressive the parameters are; this will turn on or off a relay. My question is, can this be done with timers instead of 'millis'? Below is the example arduino provided. Below that, is something i concocted. Please give advice. Thanks.

#include <PID_v1.h>
#define RelayPin 6

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

int WindowSize = 5000;
unsigned long windowStartTime;
void setup()
{
  windowStartTime = millis();

  //initialize the variables we're linked to
  Setpoint = 100;

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  Input = analogRead(0);
  myPID.Compute();

  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  if(millis() - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output < millis() - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);

}

Here is my code:

#include "Wire.h"
#include "DS1307RTC.h"
#include "PID_v1.h"
#include "SPI.h"
#include "Time.h"
#include "TimeAlarms.h"

#define RELAY_ON 1
#define RELAY_OFF 0
#define Relay1  2 

int analogChannel0 = 0;
double Setpoint, Input, Output;
double Kp=1, Ki=0.5, Kd=0.25;  //PID Tuning Parameters
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); //PID Tuning Parameters


void setup() {



     digitalWrite(Relay1, RELAY_ON);

     pinMode(Relay1, OUTPUT);   

Serial.begin(9600);

     Alarm.timerRepeat(360, Pid); 

     Input = analogRead(analogChannel0);
     myPID.SetMode(AUTOMATIC);     //turn the PID on
     Setpoint = 7.0;

     }

void loop() {                           
            Alarm.delay(0); 
            } 


void Pid()
             {
             Input =  analogRead(analogChannel0);              
             myPID.SetTunings(Kp, Ki, Kd);   
             myPID.Compute(); 
             ////FROM HERE I DONT KNOW WHAT TO DO
             } 
1

1 Answers

1
votes

absolutely. TimerOne or SimpleTime libraries.

Where TimerOne uses an interrupt from a timer to do the action in the background, and the later SimpleTime polls the time from a call in the main loop. It does not consume the TimerOne.

One of these will fit your need.