I'm building a small project to maintain a copper plating tank's temperature and filter pump duty cycle. I'm using the Adafruit Feather platform to hold an 8 segment matrix coupled with a Teensy 3.2 (on a Feather shield) to calculate and display temp. There is a 10K Pot on A0 and an 8 segment NeoPixel Strip to set and display pump duty cycle from 1 to 8 corresponding to .125*hour and 100% on. There is also a push and hold set switch to operate temperature target point setting using the same pot.
Things that work: Almost Everything! Thing that doesn't work:
Changing the Duty Cycle knob (which changes the duty cycle global variable) after turning the unit on doesn't seem to change the on/off times other than to successfully change the NeoPixel display. If the unit is turned on at a particular duty cycle, the program will run that duty cycle successfully. While running, if I change the duty Cycle to 8, I don't get a "100% On". In other words the change in the duty cycle variable doesn't seem to change the on time and off time variables in the code while running.
Q: What do I need to do to make the duty cycle setting work on the fly?
Oh... That Volatile Float declaration was my last desperate attempt, Please ignore / forgive. ;-)
Hopefully the fix is as simple as the code. ;-) I just don't see it and my (perhaps flawed) understanding of global variables is hit a wall.
Any help will be much appreciated. Thanks.
Jeff
Code:
/***************************************************
Copper Plating Tank Control - v1.1
by Jeff W. Parisse - July 7st, 2021
www.coppercholla.com
This program runs a programmable interval timer for chemical pump
duty cycle and a programmable temperature setting and heating control
for maintaining plating solution temperature.
Processor: PJRC Teensy 3.2
Additional Libraries: Adafruit Industries LLC
Temperature Sensor: Adafruit MAX31865 w/P1000 Platinum Wire Probe
Pin Outs:
Setting Knob: Pin A0
Matrix Display: Feather Matrix I2C 0x70
Neopixels: Pin 5
MAX31865: CLK Blue
MAX31865: SDO Yellow
MAX31865: SDI White
MAX31865: CS Pin 6 Green
Temp Set Switch: Pin 8
Chemical Pump: Pin 9
Tank Heater: Pin 10
****************************************************/
#include <Adafruit_MAX31865.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include <Adafruit_NeoPixel.h>
#define knobPin A0
#define ledPin 5
#define csPin 6
#define switchPin 8
#define pumpPin 9
#define heaterPin 10
#define ledCount 8
#define sampleNum 4
#define RREF 4296.0
#define RNOMINAL 1000.0
Adafruit_MAX31865 thermo = Adafruit_MAX31865(csPin);
Adafruit_7segment matrix = Adafruit_7segment();
Adafruit_NeoPixel strip(ledCount, ledPin, NEO_GRB + NEO_KHZ800);
float targetTemp = 77.0; // Starting Value
float readTemp = 0;
float toleranceTemp = 0.25;
float tempSum = 0;
float cTemp = 0;
float fTemp = 0;
volatile float dutyCycle = 4;
unsigned long previousTime = 0;
unsigned long oneHour = 3600000; // 1 Hour in Milliseconds
unsigned long timeOn = 450000; // 7.5 Minutes in Milliseconds
unsigned long pumpInterval = timeOn;
boolean pumpState = true;
void setup() {
thermo.begin(MAX31865_3WIRE);;
matrix.begin(0x70);
strip.begin();
strip.show();
pinMode(csPin, OUTPUT);
pinMode(heaterPin, OUTPUT);
pinMode(pumpPin, OUTPUT);
pinMode(switchPin, INPUT_PULLUP);
digitalWrite(csPin, LOW);
digitalWrite(heaterPin, LOW);
digitalWrite(pumpPin, LOW);
}
void loop() {
// Read Set Switch
int setSwitch = (digitalRead(switchPin));
while (setSwitch == LOW) {
int readKnob = analogRead(knobPin);
targetTemp = map(readKnob, 1, 1023, 67, 87);
matrix.print(targetTemp, 1);
matrix.writeDisplay();
setSwitch = (digitalRead(switchPin));
}
// Read, Convert, and Display Temp
tempSum = 0;
for (int i = 1; i <= sampleNum; i++) {
readTemp = thermo.temperature(RNOMINAL, RREF);
tempSum = tempSum + readTemp;
}
cTemp = tempSum / sampleNum;
fTemp = (cTemp * 1.8) + 32;
matrix.print(fTemp, 1);
matrix.writeDisplay();
// Heater Logic
if (fTemp < targetTemp - toleranceTemp) {
digitalWrite(heaterPin, HIGH);
}
else if (fTemp > targetTemp + toleranceTemp) {
digitalWrite(heaterPin, LOW);
}
// Read and Display Duty Cycle
int readKnob = analogRead(knobPin);
dutyCycle = map(readKnob, 1, 1023, 1, 8);
for (int i = 0; i <= ledCount; i++) {
strip.setPixelColor(i, 0, 0, 0);
}
strip.show();
for (int i = 0; i <= dutyCycle - 1; i++) {
strip.setPixelColor(i, 0, 0, 20);
}
strip.show();
// Pump Timer
digitalWrite(pumpPin, pumpState);
unsigned long timeOn = ((dutyCycle / 8UL) * oneHour);
unsigned long timeOff = (oneHour - timeOn);
unsigned long currentTime = millis();
if (currentTime - previousTime >= pumpInterval) {
if (pumpState) {
pumpInterval = timeOff;
}
else {
pumpInterval = timeOn;
}
pumpState = !(pumpState);
previousTime = currentTime;
}
}