Reputation: 11
I am making this project for my school: a whole fridge using Arduino. I used a ds18b20 temperature sensor, tm1637 to display the current temperature inside and a solid state relay to start the motor at certain temperature I choose.
THE PROBLEM is that I used an ec11 rotary encoder to change the temperature at which the ssr activates but when I turn the knob at any direction it only increases the value and never decreases. I tested the encoder alone many times and it works fine but when I add it to the code it doesn't work at all. When I remove the (printTemperature
) function it works again.
note : when I tested the display and the encoder alone it kept producing zeros without touching it.
#include <TM1637Display.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWireBus = 2;
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);
const int CLK = 3;
const int DIO = 4;
TM1637Display display = TM1637Display(CLK, DIO);
const uint8_t celsiusSymbol[] = {
SEG_A | SEG_B | SEG_F | SEG_G,
SEG_A | SEG_D | SEG_E | SEG_F
};
#define ContactA 10
#define ContactB 11
// ----- Logic
boolean LastStateA;
boolean CurrentStateA;
boolean CurrentStateB;
const int SSR_PIN = 9;
// Threshold temperature
int motorThreshold = 20.0;
int newmotorThreshold = motorThreshold;
bool thresholdAdjusted = false;
void setup() {
// ----- Configure Serial port
Serial.begin(9600);
Serial.println("Initializing...");
display.clear();
display.setBrightness(7);
sensors.begin();
// Set SSR pin as output
pinMode(SSR_PIN, OUTPUT);
Serial.println("Initialization complete.");
// ----- Display initial count
// ----- Configure encoder
pinMode(ContactA, INPUT_PULLUP);
pinMode(ContactB, INPUT_PULLUP);
LastStateA = stateContactA();
}
void adjustThresholdTemperature() {
/*
The encoder output comprises two 90 degree offset squarewaves.
The direction of rotation is:
- clockwise if the state of output A is opposite to output B
- counterclockwise if the state of output A is the same as output B
*/
// ----- Check encoder output
CurrentStateA = stateContactA();
// ----- Record changes
if (CurrentStateA != LastStateA) {
// Check state of ContactB
CurrentStateB = digitalRead(ContactB);
if (CurrentStateA == CurrentStateB) {
// Clockwise rotation, increase threshold temperature
motorThreshold += 2; // Example adjustment, change as needed
thresholdAdjusted = true; // Set flag to indicate threshold adjustment
if (motorThreshold % 2 == 0) {
Serial.print("motorThreshold: ");
Serial.println(motorThreshold / 1);
};
}
if (CurrentStateA != CurrentStateB) {
// Counterclockwise rotation, decrease threshold temperature
motorThreshold -= 2; // Example adjustment, change as needed
thresholdAdjusted = true; // Set flag to indicate threshold adjustment
if (motorThreshold % 2 == 0) {
Serial.print("motorThreshold: ");
Serial.println(motorThreshold / 1);
};
}
// Counterclockwise rotation
LastStateA = CurrentStateA;
}
/*if (digitalRead(SW_PIN) == LOW)
{
// Button is pressed
// Reset threshold temperature to default value
motorThreshold = 20.0; // Example default value, change as needed
Serial.println("Threshold temperature reset to default.");
thresholdAdjusted = true; // Set flag to indicate threshold adjustment
delay(200); // Debouncing delay
} */
}
void printTemperature() {
sensors.requestTemperatures();
float measuredTemperature = sensors.getTempCByIndex(0);
Serial.print("Current temperature: ");
Serial.print(measuredTemperature);
Serial.println("°C");
//Display current temperature
display.showNumberDec(measuredTemperature, false, 2, 0);
display.setSegments(celsiusSymbol, 2, 2);
// Check if temperature exceeds threshold
if (measuredTemperature >= motorThreshold) {
// Activate SSR
digitalWrite(SSR_PIN, HIGH);
} else {
// Deactivate SSR
digitalWrite(SSR_PIN, LOW);
}
if (thresholdAdjusted) {
unsigned long startTime = millis();
while (millis() - startTime < 3000) {
// Flash the display by toggling brightness every 500 milliseconds
if ((millis() - startTime) % 500 < 250) {
display.showNumberDec(motorThreshold, false, 2, 0);
display.setSegments(celsiusSymbol, 2, 2);
} else {
display.clear();
}
}
thresholdAdjusted = false; // Reset threshold adjustment flag after 3 seconds
}
}
boolean stateContactA() {
/*
Two integrators are used to suppress contact bounce.
The first integrator to reach MaxCount wins
*/
// ----- Locals
int Closed = 0; // Integrator
int Open = 0; // Integrator
int MaxCount = 250; // Increase this value if you see contact bounce
// ----- Debounce Contact A
while (1) {
// ----- Check ContactA
if (digitalRead(ContactA)) {
// ----- ContactA is Open
Closed = 0; // Empty opposite integrator
Open++; // Integrate
if (Open > MaxCount) return HIGH;
} else {
// ----- ContactA is Closed
Open = 0; // Empty opposite integrator
Closed++; // Integrate
if (Closed > MaxCount) return LOW;
}
}
}
void loop() {
adjustThresholdTemperature();
printTemperature();
}
Upvotes: 1
Views: 63
Reputation: 26
Your printTemperature()
blocks for 3 seconds, while in order to catch the direction of the knob, you have to test ContactA
and ContactB
at least once in 50ms or so, or less, to be responsive. And you have to measure ContactB
only when ContactA
is caught changing state. So this is not guaranteed if the testing is done only a few times in each 3 seconds.
Additionally, ContactB
is not debounced in your case. You might want to use the same procedure you use for ContactA
If you would try removing the flashing display part, please update again how it goes, probably we can see more clearly what happens there that prevents the threshold from decreasing when the knob is turned CCW
Upvotes: 0