Incubator using fotek SSR

Hello guys!

I'm currently working on a simplified incubator using arduino nano(ATmega 328p) for its brain, 2pcs seven segment (tm1637) to display temperature and humidity level, 4pcs fotek ssr to control 50ktyz AC220V motor(cw, ccw), humidifier, heater, and 2pcs buttons to control motor position manually.

My codes are working perfectly fine, but whenever I add the buttons for manual control the fotek ssr suddenly wont work. This is the only problem I facing, I tried all my best but seems not enough.

const int relayleft = A3;
const int relayright = A2;

const int buttonleft = 6;
const int buttonright = 7;

const int limitleft = 11;
const int limitright = 12;

int relayleftstate = LOW;
int relayrightstate = LOW;

unsigned long relay_interval = 30000; //For testing only
unsigned long previousMillis = 0;
   
int control = 0;
int control_state = 0;

void setup() {
  Serial.begin(9600);
  pinMode(relayleft, OUTPUT);
  pinMode(relayright, OUTPUT);
  
  pinMode(buttonleft, INPUT_PULLUP);
  pinMode(buttonright, INPUT_PULLUP);
  
  pinMode(limitleft, INPUT_PULLUP);
  pinMode(limitright, INPUT_PULLUP);
  
  relayleftstate = LOW;               //Keeping the relay off during booting up
  digitalWrite(relayleft, LOW);       //Keeping the relay off during booting up
  relayrightstate = LOW;              //Keeping the relay off during booting up
  digitalWrite(relayright, LOW);      //Keeping the relay off during booting up
}

void loop() {
  int buttonleftstate = digitalRead(buttonleft);
  int buttonrightstate = digitalRead(buttonright);

  if (buttonleftstate == HIGH) {
    relayleftstate = LOW;
    digitalWrite(relayleft, LOW);
  } 
  else if (buttonleftstate == LOW){
    relayleftstate = HIGH;
    digitalWrite(relayleft, HIGH);
    control = 2;
  }
  
  if (buttonrightstate == HIGH) {
    relayrightstate = LOW;
    digitalWrite(relayright, LOW);
  } 
  else if (buttonrightstate == LOW){
    relayrightstate = HIGH;
    digitalWrite(relayright, HIGH);
    control = 4;
  }
  tiltcontrol();
}

void tiltcontrol(){
  control_state = control;
  int limitleftstate = digitalRead(limitleft);
  int limitrightstate = digitalRead(limitright);
  
  unsigned long currentMillis = millis();
  
  switch(control){
    case 0: //Start
    Serial.println("START");
    control = 1;
    break;
    case 1: //left
    if ((relayleftstate==LOW) && (currentMillis-previousMillis>=relay_interval))
      {
      previousMillis = currentMillis;
      relayleftstate = HIGH;
      digitalWrite(relayleft, HIGH);
      Serial.println("TURNING LEFT");
      control = 2;
      }
    break;
    
    case 2://left stop
    if(limitleftstate==LOW) {
      Serial.println("STOP LEFT");
      relayleftstate = LOW;
      digitalWrite(relayleft, LOW);
      control = 3;
      }
    break;
    
    case 3: //right
    if((relayrightstate==LOW) && (currentMillis-previousMillis>=relay_interval))
      {
      previousMillis = currentMillis;
      relayrightstate = HIGH;
      digitalWrite(relayright, HIGH);
      Serial.println("TURNING RIGHT");
      control = 4;
      }
    break;

    case 4: //right stop
    if(limitrightstate == LOW) {
      Serial.println("STOP RIGHT");
      relayrightstate = LOW;
      digitalWrite(relayright, LOW);
      control = 0;
      }
     break;
    }
  }

How can I implement the buttons for manual control without interfering fotek ssr (motor control). The code I uploaded is only the motor control, the other code is working. Any suggestions and answers would be great help, thanks!

without checking for a button "press" instead of simply the button "state" (LOW or HIGH), the code repeatedly sets the value of "relayleftstate" overriding any other logic.

consider the following code that monitors multiple buttons for button presses, return the button pressed

// check multiple buttons and toggle LEDs

enum { Off = HIGH, On = LOW };

byte pinsLed [] = { 10, 11, 12 };
byte pinsBut [] = { A1, A2, A3 };
#define N_BUT   sizeof(pinsBut)

byte butState [N_BUT];

// -----------------------------------------------------------------------------
int
chkButtons ()
{
    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        byte but = digitalRead (pinsBut [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            delay (10);     // debounce

            if (On == but)
                return n;
        }
    }
    return -1;
}

// -----------------------------------------------------------------------------
void
loop ()
{
    switch (chkButtons ())  {
    case 2:
        digitalWrite (pinsLed [2], ! digitalRead (pinsLed [2]));
        break;

    case 1:
        digitalWrite (pinsLed [1], ! digitalRead (pinsLed [1]));
        break;

    case 0:
        digitalWrite (pinsLed [0], ! digitalRead (pinsLed [0]));
        break;
    }
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        pinMode (pinsBut [n], INPUT_PULLUP);
        butState [n] = digitalRead (pinsBut [n]);
    }

    for (unsigned n = 0; n < sizeof(pinsLed); n++)  {
        digitalWrite (pinsLed [n], Off);
        pinMode      (pinsLed [n], OUTPUT);
    }
}

1 Like

EDITED***

It works like a toggle button and seems like it doesn't fit to my need(or im just dumb at programming haha). What I wanted is the buttons works when I pressed the button, the fotek SSR is on and when it reaches the limit switch its automatically off but when I release the button the fotek SSR off even its not reach the limit switches. Also I forget to tell that I have limit switch in both end of motor to prevent over turning. Anyways, I'm literally new at arduino programming, so its still confusing for me to work with it. The attached picture is the rough schematic of my work.

Thank you for your response!

in loop() i see conditional tests that set relayleftstate. these tests always set relayleftstate either HIGH or LOW. while there are separate tests for HIGH and LOW, the code may as well have been written as

    if (buttonleftstate == HIGH) {
        relayleftstate = LOW;
        digitalWrite(relayleft, LOW);
    }
    else {
        relayleftstate = HIGH;
        digitalWrite(relayleft, HIGH);
        control = 2;
    }

tiltcontrol has the following code which also conditionally sets relayleftstate, but regardless what it does, the above code sets relayleftstate solely on the button state

        if ((relayleftstate==LOW) && (currentMillis-previousMillis>=relay_interval))
        {
            previousMillis = currentMillis;
            relayleftstate = HIGH;

the code could detect a button press -- a change in state where the new state is LOW and toggle the relayleftstate

    static byte butLst = HIGH;
    byte but = digitalRead (butPin);
    if (butLst != but)  {
        butLst = but;

        if (LOW == but)
            relayleftstate = ! relayleftstate;
    }

which would allow it's state to be change elsewhere

Sorry for late reply, its finally working! Thank you so much. :slight_smile: