-
Notifications
You must be signed in to change notification settings - Fork 0
/
iteration2.ino
256 lines (211 loc) · 7.92 KB
/
iteration2.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#include <Stepper.h>
// Constants
const int voltagePin = A0; // Voltage feedback
const int currentPin = A1; // Current feedback
const int feedRatePin = A2; // Target wire feed rate
const int burnFudgePin = A3; // Wire burn pulse fudge factor
const int pwmPin = 9; // PWM output for buck converter
const int stepPin = 2; // Stepper motor step pin
const int dirPin = 3; // Stepper motor direction pin
const int buttonPin = 7; // Button for initiating weld
const int photoSensorPin = A4; // Photoelectric sensor feedback
const int fineTunePin = A5; // Fine-tuning knob
// Parameters
int targetFeedRate = 0;
int burnFudgeFactor = 0;
int pwmDutyCycle = 0;
int stepperPosition = 0;
int stepperMaxPosition = 200; // Adjust as per actual requirements
// Frequency search parameters
float minFrequency = 500.0; // Minimum PWM frequency in Hz
float maxFrequency = 2000.0; // Maximum PWM frequency in Hz
float tolerance = 0.1; // Tolerance for frequency search
// Moving average filter parameters
const int numSamples = 10; // Number of samples for moving average
float voltageSamples[numSamples]; // Voltage samples for moving average
float currentSamples[numSamples]; // Current samples for moving average
float photoSensorSamples[numSamples]; // Photoelectric sensor samples
int sampleIndex = 0;
// Stepper motor configuration
Stepper stepper(200, stepPin, dirPin); // 200 steps per revolution
void setup() {
pinMode(voltagePin, INPUT);
pinMode(currentPin, INPUT);
pinMode(feedRatePin, INPUT);
pinMode(burnFudgePin, INPUT);
pinMode(pwmPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(photoSensorPin, INPUT);
pinMode(fineTunePin, INPUT);
stepper.setSpeed(60); // Initial speed setting
initializeSamples();
}
void loop() {
// Read inputs
targetFeedRate = analogRead(feedRatePin);
burnFudgeFactor = analogRead(burnFudgePin);
// Wait for button press to start the process
if (digitalRead(buttonPin) == LOW) {
// Pre-contact feed
feedWireForward();
// Oscillate to detect contact
while (!detectContact()) {
oscillateWireFeed();
}
// Arc initiation with binary search for resonant frequency
initiateArc();
// Enter welding loop
while (weldingInProgress()) {
burnWirePulse();
adjustWireFeed();
}
}
}
// Functions for various stages of the welding process
void feedWireForward() {
// Feed forward a few mm
moveStepper(stepperMaxPosition / 10, true); // Example: feed forward 10% of max range
}
bool detectContact() {
int voltage = analogRead(voltagePin);
return (voltage < 10); // Example threshold for contact detection
}
void oscillateWireFeed() {
// Oscillate the stepper back and forth
moveStepper(-20, false);
moveStepper(20, true);
}
void initiateArc() {
// Use binary search to find the resonant frequency
float resonantFrequency = findResonantFrequency(minFrequency, maxFrequency, tolerance);
// Set PWM to the resonant frequency
adjustPwmFrequency(resonantFrequency);
// Start arc with the resonant frequency
pwmDutyCycle = 50; // Start with a low duty cycle
analogWrite(pwmPin, pwmDutyCycle);
while (!arcStable()) {
// Adjust PWM duty cycle if necessary during arc initiation
pwmDutyCycle++;
analogWrite(pwmPin, pwmDutyCycle);
}
}
bool arcStable() {
// Update the moving average samples
updateSamples();
// Calculate the moving averages
float avgVoltage = calculateMovingAverage(voltageSamples);
float avgCurrent = calculateMovingAverage(currentSamples);
float avgPhotoSensor = calculateMovingAverage(photoSensorSamples);
// Fine-tuning knob input
float fineTune = analogRead(fineTunePin) / 1023.0; // Normalize to 0-1
// Scoring system for arc quality (weights can be fine-tuned)
float voltageWeight = 0.4 + 0.3 * fineTune; // Adjust weight based on fine-tuning knob
float currentWeight = 0.4 - 0.3 * fineTune;
float photoSensorWeight = 0.2;
// Calculate the weighted score
float score = voltageWeight * avgVoltage + currentWeight * (100 - avgCurrent) + photoSensorWeight * avgPhotoSensor;
// Threshold for determining arc stability
return (score > 50); // Example threshold (adjust as needed)
}
void burnWirePulse() {
// Short burst of high current to burn wire
pwmDutyCycle += burnFudgeFactor;
analogWrite(pwmPin, pwmDutyCycle);
delay(100); // Pulse duration
pwmDutyCycle -= burnFudgeFactor;
analogWrite(pwmPin, pwmDutyCycle);
}
void adjustWireFeed() {
// Adjust the wire feed based on the length of the wire burnt
int burnCorrection = burnFudgeFactor / 2; // Example correction factor
moveStepper(burnCorrection, true);
}
void adjustPwmFrequency(float frequency) {
// Adjust PWM frequency by modifying timer settings
// Implementation will depend on the specific microcontroller and PWM configuration
}
bool weldingInProgress() {
// Condition to check if welding is still in progress
return digitalRead(buttonPin) == LOW;
}
// Function to find the resonant frequency using binary search
float findResonantFrequency(float minFreq, float maxFreq, float tol) {
float midFreq;
while ((maxFreq - minFreq) > tol) {
midFreq = (minFreq + maxFreq) / 2.0;
adjustPwmFrequency(midFreq);
if (arcQuality(midFreq)) {
maxFreq = midFreq; // Narrow down to the lower half
} else {
minFreq = midFreq; // Narrow down to the upper half
}
}
return midFreq;
}
// Function to assess arc quality at a given frequency (improved with advanced evaluation)
bool arcQuality(float frequency) {
return arcStable();
}
// Initialize the sample arrays for moving average
void initializeSamples() {
for (int i = 0; i < numSamples; i++) {
voltageSamples[i] = analogRead(voltagePin);
currentSamples[i] = analogRead(currentPin);
photoSensorSamples[i] = analogRead(photoSensorPin);
}
}
// Update the samples with new readings for moving average
void updateSamples() {
voltageSamples[sampleIndex] = analogRead(voltagePin);
currentSamples[sampleIndex] = analogRead(currentPin);
photoSensorSamples[sampleIndex] = analogRead(photoSensorPin);
sampleIndex = (sampleIndex + 1) % numSamples;
}
// Calculate the moving average of an array of samples
float calculateMovingAverage(float samples[]) {
float sum = 0.0;
for (int i = 0; i < numSamples; i++) {
sum += samples[i];
}
return sum / numSamples;
}
// Function to move the stepper motor with acceleration and jerk control
void moveStepper(int steps, bool accelerate) {
int direction = (steps > 0) ? 1 : -1;
steps = abs(steps);
static int currentStepperSpeed = minStepperSpeed;
static long lastStepTime = 0;
static int currentAccel = 0;
static int currentJerk = 0;
for (int i = 0; i < steps; i++) {
long currentTime = micros();
long timeDiff = currentTime - lastStepTime;
// Calculate speed based on acceleration and jerk
if (accelerate) {
currentAccel += maxJerk * timeDiff / 1000000; // Change acceleration with jerk
currentAccel = constrain(currentAccel, -maxAccel, maxAccel);
currentStepperSpeed += currentAccel * timeDiff / 1000000; // Change speed with acceleration
currentStepperSpeed = constrain(currentStepperSpeed, minStepperSpeed, maxStepperSpeed);
} else {
// Decelerate smoothly
currentStepperSpeed -= maxAccel * timeDiff / 1000000;
currentStepperSpeed = max(currentStepperSpeed, minStepperSpeed);
}
// Set stepper direction
digitalWrite(dirPin, direction > 0 ? HIGH : LOW);
// Step the motor
digitalWrite(stepPin, HIGH);
delayMicroseconds(1); // Minimum step pulse width
digitalWrite(stepPin, LOW);
// Wait before next step based on current speed
delayMicroseconds(1000000 / currentStepperSpeed);
lastStepTime = currentTime;
}
// Reset acceleration and jerk if decelerating
if (!accelerate) {
currentAccel = 0;
currentJerk = 0;
}
}