youssef samy
youssef samy

Reputation: 11

controlling solid state relay by rotary encoder error

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

Answers (1)

Robert Wilingakar
Robert Wilingakar

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

Related Questions