Spot welder project gone wrong

Hi,
For last couple of days I've been making my own spot welder, building was pretty easy, but I've encoutered some problem while building my own code.
Components used:
20x4 LCD with I2C, Fotek 40Amps relay, rotary encoder, 3 pushbuttons, and a Arduino Nano. I have no idea what to do to make it work. First of all, relay keeps switching with base values continuously until I release welding button. Also I can't make any changes in the menu. My idea was to switch between single pulse and double pulse mode with encoder button. I wanted also to change the times with rotary encoder after pressing suitable pushbuton.
I will be grateful for any help :slight_smile: I've put simplified scheme in attachments.

Code:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const int relayPin = 11;
bool two_pulses_mode = false;
bool pulse_time_change = false;
bool delay_time_change = false;
const int time_changing_button = 4;
const int delay_changing_button = 5;
const int welding_button = 13;
int pulse_duration = 20;
int delay_duration = 50;
const int clkPin = 8; // A
const int dataPin = 9; // B
const int swPin = 10; // Button
int encoder_movement();

void menu();
void mode_change();
void time_change();
void delay_time_changeA();

void setup()

{
  pinMode(relayPin, OUTPUT);
  pinMode(clkPin, INPUT);
  pinMode(dataPin, INPUT);
  pinMode(swPin, INPUT);
  pinMode(time_changing_button, INPUT);
  pinMode(delay_changing_button, INPUT);
  pinMode(welding_button, INPUT);
  lcd.begin(20, 4);
  menu();
}

void menu() {
  lcd.clear();
  if (two_pulses_mode = false) {
    lcd.clear();
    lcd.setCursor(2,0);
    lcd.print("One pulse");
    lcd.setCursor(2,1);
    lcd.print("Time: ");
    lcd.print(pulse_duration);
    lcd.print("ms");
    lcd.setCursor(2,2);
    lcd.print("N/A");
    } else {
      lcd.setCursor(2,0);
      lcd.print("Two pulses");
      lcd.setCursor(2,1);
      lcd.print("Time: ");
      lcd.print(pulse_duration);
      lcd.print("ms");
      lcd.setCursor(2,2);
      lcd.print("Delay: ");
      lcd.print(delay_duration);
      lcd.print("ms");
    }
}

void mode_change() {
  if (digitalRead(swPin) == LOW){
    if (two_pulses_mode = false){
      two_pulses_mode = true;
      menu();
    }
    } else {
      two_pulses_mode=false;
    
  }
}

int encoder_movement() {
  static int aLastState = HIGH;
  static int bLastState = HIGH; 
  int mov = 0;

  int aState = digitalRead(clkPin);
  int bState = digitalRead(dataPin);
  if ((aState != aLastState) || (bState != bLastState)) {
    if (aLastState == HIGH && aState == LOW) {
      ruch = (bLastState * 2 - 1);
    }
  }
  aLastState = aState;
  bLastState = bState;
  return mov;
}

void time_change() {
  if (digitalRead(time_changing_button) == HIGH) {
    pulse_time_change = true;
    }
  if (pulse_time_change = true) {
  int enc_position = 0;
  int enc_LastPosition = 0;
  int enc_movement = 0;

  enc_movement = encoder_movement();
  enc_position += enc_movement;

  if (enc_position > enc_LastPosition) {
    if (pulse_duration == 9995) {
      pulse_duration = 1;
    } else {
      if (pulse_duration < 10) {
        pulse_duration++;
      } else {
        pulse_duration += 5;
      }
    }
  } else if (enc_position < enc_LastPosition) {
    if (pulse_duration == 1) {
      pulse_duration = 9995;
    } else {
      if (pulse_duration <= 10) {
        pulse_duration--;
      } else {
        pulse_duration -= 5;
      }
    }
  }
} else if (digitalRead(time_changing_button) == HIGH) {
  pulse_time_change = false;  
}
}

void delay_time_changeA() {
  if (two_pulses_mode = true && digitalRead(delay_changing_button) == HIGH) {
    delay_time_change = true;
  }
  if (delay_time_change = true) { 
    int enc_position = 0;
  int enc_LastPosition = 0;
  int enc_movement = 0;

  enc_movement = encoder_movement();
  enc_position += enc_movement;

  if (enc_position > enc_LastPosition) {
    if (delay_duration == 9995) {
      delay_duration = 1;
    } else {
      if (delay_duration < 10) {
        delay_duration++;
      } else {
        delay_duration += 5;
      }
    }
  } else if (enc_position < enc_LastPosition) {
    if (delay_duration == 1) {
      delay_duration = 9995;
    } else {
      if (delay_duration <= 10) {
        delay_duration--;
      } else {
        delay_duration -= 5;
      }
    }
  }
  } else if (digitalRead(delay_changing_button) == HIGH) {
    delay_time_change = false;
  }
  
}

void loop() {
if (digitalRead(welding_button) == HIGH) {
    if (two_pulses_mode = true) {
      digitalWrite(relayPin, HIGH);
      delay(pulse_duration);

      digitalWrite(relayPin, LOW);
      delay(delay_duration);

      digitalWrite(relayPin, HIGH);
      delay(pulse_duration);
      digitalWrite(relayPin, LOW);

      menu();
    } else
    digitalWrite(relayPin, HIGH);
    delay(pulse_duration);
    digitalWrite(relayPin, LOW);
    menu ();
  } else {
    digitalWrite(relayPin, LOW);
  }
}

For last couple of days I've been making my own spot welder,

And your experience of digital circuits in high noise environments is . . ?

You make this mistake several times throughout the code:

  if (two_pulses_mode = false) {

You schematic also appears to have a wire connected to RST which should probably be connected to GND. Also, you don't have any pull-up resistors on your switches. Should you be using INPUT_PULLUP instead?

  1. You will not able to read buttons when you have delay() calls in your code. What if you press a button during a delay()?
  2. Assignment uses '='. Compare uses '=='
  3. To detect a button press you need to detect a CHANGE in the state of the button not the state of the button
  4. I recommend using the INPUT_PULLUP pin mode and wire your buttons accordingly
  5. You will need to refactor your code to eliminate delays() and perform all of your timing using millis(). You will also benefit from a state machine. The following tutorials will be helpful:

State Machine

StateChangeDetection

Arduino Multiple Things

Several Things at a Time

TheMemberFormerlyKnownAsAWOL:
And your experience of digital circuits in high noise environments is . . ?

My experience is not that good probably, but whole arduino circuit is shielded from the electromagnetic influence of high power transformer inside. Besides, 3KW transformer is not that powerful to cause any side affects to the circuit.

ToddL1962:
You make this mistake several times throughout the code:

  if (two_pulses_mode = false) {

Would you please explain it to me? I'm newbie in arduino staff, not gonna lie. I thought that the if function checks the condition in it?

ToddL1962:
You schematic also appears to have a wire connected to RST which should probably be connected to GND. Also, you don't have any pull-up resistors on your switches. Should you be using INPUT_PULLUP instead?

There's an error on scheme, it's connected porperly :slight_smile: I totally forgot about pullups :open_mouth:
Thanks for the replies.

= for assignment, == for comparison.

Or, more simply

 if (!two_pulses_mode ) {

wilqsensei:
Besides, 3KW transformer is not that powerful to cause any side affects to the circuit.

I think you may take that statement back at some point :slight_smile: Switching high current loads is
fraught with problems of EMI, and it would be good to have a photo of the layout of the
whole thing, to see where there are any obvious problems (good layout can really help
reduce interference).

Welders of all sorts are notorious for extreme levels of EMI...

Update:
Changed INPUT to INPUT_PULLUP on pushbuttons,
Solved relay switching problem by modifying void loop()

if (digitalRead(welding_button) == HIGH) { 
      delay(100);
      while (digitalRead(welding_button) == HIGH) {
        if (!welding_button_down) {
         if (two_pulses_mode == true) {
            
              digitalWrite(relayPin, HIGH);
              delay(pulse_duration);
              digitalWrite(relayPin, LOW);
              delay(delay_duration);
              digitalWrite(relayPin, HIGH);
              delay(pulse_duration);
              digitalWrite(relayPin, LOW);
              
              
            
          }
          else {
            digitalWrite(relayPin, HIGH);
            delay(pulse_duration);
            digitalWrite(relayPin, LOW);
            
          }
          welding_button_down = true;
        }
       
      }
    }
    welding_button_down = false;

   
  }

and adding one bool welding_button_down = false
Working on millis() right now.
Still can't make the encoder button work. It's not switching modes. Any ideas?

Thanks for the replies :slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.