This is not a super elaborate code that controls the universe and everything.
Instead it's just a very simple piece of code that allows driving a display, debouncing a switch, reading two potentiometers, and drive a relay. That's it.
I use busy waiting to execute the read potentiometer values and I use very simple line drawing to visualize the pulse pattern.
I divided the welding process into two steps:
- Pre-welding the material to heat it up, make it soft and establish excellent conductivity between all materials to be welded
- Welding the material together with a potentially longer pulse.
During my initial tests and from what I have read online in several articles, the typical pre weld time is around 50 ms and the typical weld time is around 100 ms. I used this as a base line since most people don't seem to weld with 1750 Watts. I wanted to be able to adjust my welding times between 25 ms and 275 ms by adjusting two potentiometers. I also added a cooldown time in between the two weld actions of 250 ms. That's a pure guess and should have been adjustable with another potentiometer as well but I didn't see the immediate need for it. If you need it, please add a third pot to the code and to your welder. I don't think it's necessary for making battery packs.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
// For the breakout, you can use any 2 or 3 pins
// These pins will also work for the 1.8" TFT shield
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
#define TFT_SCLK 13
#define TFT_MOSI 11
#define MINWELDTIME 25
#define MAXWELDTIME 250
#define COOLDOWNTIME 250
#define ADCRESOLUTION 1023
#define GRAPHDIVIDER 7 // devides the values for displaying the graph to something that can be displayed
// use the hardware SPI pins (for UNO thats sclk = 13 and sid = 11) and pin 10 must be an output.
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 5; // the number of the pushbutton pin
const int ledPin = 12; // the number of the LED pin
const int relayPin = 2; // the number of the relay pin
const int preWeldSensorPin = A0; // the number of the potentiometer ADC pin
const int weldSensorPin = A1; // the number of the potentiometer ADC pin
// Variables will change:
int ledState = LOW; // the current state of the output pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
int preWeldSensorValue = 0; // variable to store the value coming from the potentiometer
int weldSensorValue = 0; // variable to store the value coming from the potentiometer
bool redrawGraph = true; // Did we change the times and need to redraw the graphs?
int lastPreWeldTime = 0; // Storage for the previously set weld times
int lastWeldTime = 0; // So that we don't run into flickering numbers on the display
// the following variables are unsigned long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode(relayPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
digitalWrite(relayPin, HIGH);
Serial.begin(115200); // opens serial port, sets data rate to 115200 bps
Serial.println("Spot Welder Version 0.1 - Timo Birnschein - MicroForge 2018");
Serial.println("email: timo.birnschein@microforge.de");
displayInitScreen();
}
void loop() {
// read the value from the sensor:
preWeldSensorValue = analogRead(preWeldSensorPin);
weldSensorValue = analogRead(weldSensorPin);
// Read analog signal to determine time to weld
int preWeldTime = (int)((float)MINWELDTIME + (((float)MAXWELDTIME / (float)ADCRESOLUTION) * (float)preWeldSensorValue)); // Scale 10 bit value to something with an offset
int weldTime = (int)((float)MINWELDTIME + (((float)MAXWELDTIME / (float)ADCRESOLUTION) * (float)weldSensorValue)); // Scale 10 bit value to something with an offset
// Check for errors
if (preWeldTime <= 0) preWeldTime = (float)MINWELDTIME;
if (weldTime <= 0) weldTime = (float)MINWELDTIME;
if ((preWeldTime > (lastPreWeldTime + 1)) || (preWeldTime < (lastPreWeldTime - 1)))
{
redrawGraph = true;
}
if ((weldTime > (lastWeldTime + 1)) || (weldTime < (lastWeldTime - 1)))
{
redrawGraph = true;
}
if (redrawGraph == true)
{
redrawGraph = false;
String strBuffer = String(" " + String(lastPreWeldTime) + " ms");
tftPrintText(strBuffer, 0, 50, 1, ST7735_BLACK);
strBuffer = String("Pre weld time: " + String(preWeldTime) + " ms");
tftPrintText(strBuffer, 0, 50, 1, ST7735_RED);
strBuffer = String(" " + String(lastWeldTime) + " ms");
tftPrintText(strBuffer, 0, 60, 1, ST7735_BLACK);
strBuffer = String("Weld time: " + String(weldTime) + " ms");
tftPrintText(strBuffer, 0, 60, 1, ST7735_RED);
tft.drawFastHLine(0, 100, 6, ST7735_BLACK);
tft.drawFastVLine(5, 80, 20, ST7735_BLACK);
tft.drawFastHLine(5, 80, (lastPreWeldTime / GRAPHDIVIDER), ST7735_BLACK);
tft.drawFastVLine(5 + (lastPreWeldTime / GRAPHDIVIDER), 80, 20, ST7735_BLACK);
tft.drawFastHLine(5 + (lastPreWeldTime / GRAPHDIVIDER), 100, (COOLDOWNTIME / GRAPHDIVIDER) + 1, ST7735_BLACK);
tft.drawFastVLine(5 + (lastPreWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER), 80, 20, ST7735_BLACK);
tft.drawFastHLine(5 + (lastPreWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER), 80, (lastWeldTime / GRAPHDIVIDER), ST7735_BLACK);
tft.drawFastVLine(5 + (lastPreWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER) + (lastWeldTime / GRAPHDIVIDER), 80, 20, ST7735_BLACK);
tft.drawFastHLine(5 + (lastPreWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER) + (lastWeldTime / GRAPHDIVIDER), 100, COOLDOWNTIME, ST7735_BLACK);
tft.drawFastHLine(0, 100, 6, ST7735_WHITE);
tft.drawFastVLine(5, 80, 20, ST7735_WHITE);
tft.drawFastHLine(5, 80, (preWeldTime / GRAPHDIVIDER), ST7735_WHITE);
tft.drawFastVLine(5 + (preWeldTime / GRAPHDIVIDER), 80, 20, ST7735_WHITE);
tft.drawFastHLine(5 + (preWeldTime / GRAPHDIVIDER), 100, (COOLDOWNTIME / GRAPHDIVIDER) + 1, ST7735_WHITE);
tft.drawFastVLine(5 + (preWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER), 80, 20, ST7735_WHITE);
tft.drawFastHLine(5 + (preWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER), 80, (weldTime / GRAPHDIVIDER), ST7735_WHITE);
tft.drawFastVLine(5 + (preWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER) + (weldTime / GRAPHDIVIDER), 80, 20, ST7735_WHITE);
tft.drawFastHLine(5 + (preWeldTime / GRAPHDIVIDER) + (COOLDOWNTIME / GRAPHDIVIDER) + (weldTime / GRAPHDIVIDER), 100, COOLDOWNTIME, ST7735_WHITE);
lastPreWeldTime = preWeldTime;
lastWeldTime = weldTime;
}
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
ledState = !ledState;
//**************************************************************************************************
Serial.print("Pre weld time set to: ");
Serial.print(preWeldTime);
Serial.print(" ms\n\r");
Serial.print("Weld time set to: ");
Serial.print(weldTime);
Serial.print(" ms\n\r");
String strBuffer = String("!WELDING!");
tftPrintText(strBuffer, 10, 125, 2, ST7735_RED);
// Do pre heating sequence based on predefined fraction of the total welding time
digitalWrite(relayPin, LOW); // Relay is active low
digitalWrite(ledPin, HIGH); // LED is active high
delay(preWeldTime);
digitalWrite(relayPin, HIGH);
digitalWrite(ledPin, LOW);
delay(COOLDOWNTIME);
// Do welding
digitalWrite(relayPin, LOW);
digitalWrite(ledPin, HIGH);
delay(weldTime);
// Reset all ports
digitalWrite(relayPin, HIGH);
digitalWrite(ledPin, LOW);
tftPrintText(strBuffer, 10, 125, 2, ST7735_BLACK);
// Restart loop
//**************************************************************************************************/
}
}
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState = reading;
}
void displayInitScreen(void)
{
tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
tft.setRotation(0);
tft.fillScreen(ST7735_BLACK);
char display_buffer [20];
memset(display_buffer, 0, 20);
sprintf(display_buffer, "Spot Welder v0.1");
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(1);
tft.setCursor(0, 0);
tft.print(display_buffer);
memset(display_buffer, 0, 20);
sprintf(display_buffer, " MicroForge - 2018");
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(1);
tft.setCursor(0, 10);
tft.print(display_buffer);
//delay(1000);
//tft.fillScreen(ST7735_BLACK);
String strBuffer = String("Spot weld timing:");
tftPrintText(strBuffer, 0, 35, 1, ST7735_YELLOW);
}
void tftPrintText(String textBuffer, int x, int y, int textSize, int color)
{
if (textSize == 0) textSize = 1;
tft.setTextColor(color);
tft.setTextSize(textSize);
tft.setCursor(x, y);
tft.print(textBuffer.c_str());
}
Here is the resulting visualization for both peeks as well as the exact times of both weld actions.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.