I'm working on a project that uses 6 PID controllers, and I want to have them update every 30ms. There are other devices besides the PID's in this project, so I have to keep that in mind as well. I have added some code to use millis, but I'm trying to figure out if I need to time the PID's individually, or as one in the loop. I'm also not sure how to code that. I'll add the 1st part of my code that includes all the way through the 1st PID controller. I have read, and watched, a couple "tutorials" on milli timing, but can't figure out how to cross those over to my needs. Do I need the SetSampleTime lines at all?
#include <Wire.h> //for I2C
#include <ADS1X15.h>
#include <PID_v2.h>
// #define TCA9548 0x70
#define Motor1aPin 52
#define Motor2aPin 50
#define Motor3aPin 48
#define Motor4aPin 46
#define Motor5aPin 44
#define Motor6aPin 42
#define Motor1bPin 51
#define Motor2bPin 49
#define Motor3bPin 47
#define Motor4bPin 45
#define Motor5bPin 43
#define Motor6bPin 41
int actual1;
int demand1;
int actual2;
int demand2;
int actual3;
int demand3;
int actual4;
int demand4;
int actual5;
int demand5;
int actual6;
int demand6;
double Pk = 10; //speed it gets there
double Ik = 1;
double Dk = 1;
double Setpoint1, Input1, Output1;
double Setpoint2, Input2, Output2;
double Setpoint3, Input3, Output3;
double Setpoint4, Input4, Output4;
double Setpoint5, Input5, Output5;
double Setpoint6, Input6, Output6;
PID PID1(&Input1, &Output1, &Setpoint1, Pk, Ik, Dk, DIRECT);
PID PID2(&Input2, &Output2, &Setpoint2, Pk, Ik, Dk, DIRECT);
PID PID3(&Input3, &Output3, &Setpoint3, Pk, Ik, Dk, DIRECT);
PID PID4(&Input4, &Output4, &Setpoint4, Pk, Ik, Dk, DIRECT);
PID PID5(&Input5, &Output5, &Setpoint5, Pk, Ik, Dk, DIRECT);
PID PID6(&Input6, &Output6, &Setpoint6, Pk, Ik, Dk, DIRECT);
unsigned long startMillis;
unsigned long currentMillis;
unsigned long prevMillis = 0;
const unsigned long period = 10; //the value is a number of milliseconds
void setup() {
startMillis = millis(); //initial start time
pinMode (A0, INPUT);
pinMode (A1, INPUT);
pinMode (A2, INPUT);
pinMode (A3, INPUT);
pinMode (A4, INPUT);
pinMode (A5, INPUT);
pinMode (A6, INPUT);
pinMode (A7, INPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
pinMode (6, OUTPUT);
pinMode (7, OUTPUT);
pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
pinMode (10, OUTPUT);
Serial.begin(115200);
PID1.SetMode(AUTOMATIC);
PID1.SetOutputLimits(-255,255);
PID1.SetSampleTime(10);
PID2.SetMode(AUTOMATIC);
PID2.SetOutputLimits(-255,255);
PID2.SetSampleTime(10);
PID3.SetMode(AUTOMATIC);
PID3.SetOutputLimits(-255,255);
PID3.SetSampleTime(10);
PID4.SetMode(AUTOMATIC);
PID4.SetOutputLimits(-255,255);
PID4.SetSampleTime(10);
PID5.SetMode(AUTOMATIC);
PID5.SetOutputLimits(-255,255);
PID5.SetSampleTime(10);
PID6.SetMode(AUTOMATIC);
PID6.SetOutputLimits(-255,255);
PID6.SetSampleTime(10);
}
void TCA9548(uint8_t bus)
{
Wire.beginTransmission(0x70);
Wire.write(1 << bus);
Wire.endTransmission();
}
void loop() {
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
// ** start PID 1 **
actual1 = analogRead(A0);
demand1 = analogRead(A1);
actual1 = map(actual1,0,1023,341,682);
actual1 = map(actual1,341,682,-255,255);
demand1 = map(demand1,0,1023,-255,255);
Input1 = actual1;
Setpoint1 = demand1;
PID1.Compute();
if (Output1 < 0) {
Output1 = abs(Output1);
analogWrite(52,Output1);
analogWrite(51,0);
}
else if (Output1 >= 0) {
Output1 = abs(Output1);
analogWrite(51,Output1);
analogWrite(52,0);
}
else {
analogWrite(51,0);
analogWrite(52,0);
}```