Глобальная переменная не обновляется…
Я разрабатываю небольшой проект по поддержанию температуры резервуара для меднения и рабочего цикла фильтрующего насоса. Я использую платформу Adafruit Feather для хранения 8-сегментной матрицы в сочетании с Teensy 3.2 (на щите из перьев) для расчета и отображения температуры. На A0 имеется емкость 10K и полоска неопикселя 8 сегментов для установки и отображения рабочего цикла насоса от 1 до 8, соответствующего .125*часу и 100% вкл. Существует также переключатель push и hold set для управления настройкой целевой точки температуры с помощью той же кастрюли.
Вещи, которые работают: Почти все! Вещь, которая не работает:
Изменение ручки рабочего цикла (которая изменяет глобальную переменную рабочего цикла) после включения устройства, по-видимому, не изменяет время включения/выключения, кроме как для успешной смены дисплея NeoPixel. Если устройство включено в определенный рабочий цикл, программа успешно выполнит этот рабочий цикл. Во время работы, если я изменю рабочий цикл на 8, я не получу "100% включено". Другими словами, изменение переменной рабочего цикла, по-видимому, не изменяет переменные времени включения и выключения в коде во время выполнения.
Вопрос: Что мне нужно сделать, чтобы настройка рабочего цикла работала на лету?
О... Это изменчивое объявление с плавающей точкой было моей последней отчаянной попыткой, пожалуйста, проигнорируйте / простите. ;-)
Надеюсь, исправление так же просто, как и код. ;-) Я просто этого не вижу, и мое (возможно, ошибочное) понимание глобальных переменных упирается в стену.
Любая помощь будет очень признательна. Спасибо.
Джефф
Код:
/***************************************************
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;
}
}
@Jeff Parisse, 👍2
Обсуждение1 ответ
Я действительно не понимаю, в чем может быть причина вашей проблемы, но я определил две проблемы, которые потенциально могут быть связаны.
У вас есть:
dutyCycle = map(readKnob, 1, 1023, 1, 8);
Из-за некоторых проблем с округлением в функции Arduino map()
это
может работать не так, как вы ожидаете: выход будет равен 8, только если вход
достигнет 1023. Если readKnob
равен 1022, то DutyCycle
будет равен 7. Это может
объяснить, почему вы никогда не видите, что насос постоянно включен.
Способ работы map()
имеет наибольший смысл, если вы мыслите в терминах
полуоткрытых интервалов, открытых справа. Если вы напишете:
dutyCycle = map(readKnob, 0, 1024, 1, 9);
вы получите идеальное отображение от [0, 1024) до [1, 9). Идеально в том смысле, что каждому выходному значению будет сопоставлено ровно 128 входных значений:
[ 0, 128) → 1
[128, 256) → 2
[256, 384) → 3
...
И позже:
for (int i = 0; i <= ledCount; i++) { strip.setPixelColor(i, 0, 0, 0); }
Полоса имеет количество
пикселей светодиодов, пронумерованных от 0 до 1
. Этот цикл
установит цвет пикселей от 0 до ledCount
включительно. Последняя
итерация выходит за пределы конца полосы, и это, скорее
всего, приводит к повреждению памяти, т. Е. перезаписи любых данных, которые находятся сразу
после области памяти, используемой для полосы. Если это перезапись какой
-то переменной, связанной с рабочим циклом, это может объяснить странное поведение
, которое вы испытываете.
Спасибо, Эдгар… Я перепишу это после обеда и обратной связи…, @Jeff Parisse
Фабиан... сначала я так и сделал, когда работал с маршрутизацией светодиодов. Затем я перестал следить за этой функцией… вероятно, поэтому я, возможно, пропустил это., @Jeff Parisse
Дейв, потому что я хватался за соломинку, а не делал то, что делаю сейчас, просил о помощи, что гораздо более рационально… Я исправлю этот код как можно скорее. :-), @Jeff Parisse
- Как объявить массив переменного размера (глобально)
- Как получить тип данных переменной?
- Преобразование long в массив символов и обратно
- контент» не захватывается
- Получение имени перечисления из экземпляра перечисления
- Некоторые переменные не сохраняют свои значения при выходе из цикла while?
- Как отобразить переменные с плавающей запятой на OLED-дисплее (0,96 дюйма)
- Сохранение файла .txt на SD-карту и чтение данных каждого содержимого в файл txt, а затем сохранение его в переменной
Вы пробовали распечатать и протестировать для вывода функции карты?, @fabiuz7
И почему это значение с плавающей точкой, если его значение может быть только целым числом от 1 до 8?, @Dave Newton