Alright, bringing this thread up again as I havent had the posibility to work on this project for a while.
I'm having some issues with firing the SCRs and I'm not sure whats causing it.
First of all the SCRs dosent start conducting until about 40% duty cycle of the trigger signal from the µC.
Secondly when they fire they seems to be firing three times per cycle.
And when about 60-70% duty cycle is reached there is some jitter appearing.
I tested the system with a purely resistiv three phase load of 9kW with 230V three phase supply.
As you can see on 4-first attached pictures (firing pulse at Chn A, zero-cross signal at Chn B) the firing works as expected except for the jitter at 60-70%-ish.
The next 4 pictures shows the firing pulse and the phase-phase (between L1/L2) output on the SCRs. Clearly something odd happening as one can observe on the output-curve.
Schematics also attached. The parallell-resistors to the 1N400x-diodes at the SCR-circuitry is not solder on (R30 to R35), otherwise the schematic is correct.
Also an image of the actual "thing" is attached. Maybe theres some noise issues due to wiring?
For reference, the arduino code:
/* ------------*/
/* INPUTS PINS */
/* ------------*/
const byte L1_ZC_Pin = 2;
const byte L2_ZC_Pin = 3;
const byte L3_ZC_Pin = 7;
const byte L1_SCR_Pin = 4;
const byte L2_SCR_Pin = 5;
const byte L3_SCR_Pin = 6;
const byte pot_pin = A5;
const byte enable_pin = 12;
const byte lamp_pin = 11;
/* ----------*/
/* CONSTANTS */
/* ----------*/
const long iDelay = 1000; // Sampling delay/interval [µs]
const int SCR_Pulse_Width = 100; // SCR Pulse-width [µs]
const int minimumDelay = 300; // Minimum firing-delay at max power [µs]
const float smoothFactor = 0.95; // Smoothing value for fire delay [0-1].
const long iLamp = 500000; // Blink-intervall for errorlamp
/* ----------*/
/* VARIABLES */
/* ----------*/
int potValue; // Raw value of the potentiometer
int enableState; // State of the enable-switch
int pEnableState; // Previous state of the enable-switch
int enable = 1; // Variable for enabling firing
int errorLampState; // State of error-lamp
int error; // Error-state
volatile byte L1_ZC_Trg; // Variable triggered by ISR for Zero Cross
volatile byte L2_ZC_Trg; // Variable triggered by ISR for Zero Cross
volatile byte L3_ZC_Trg; // Variable triggered by ISR for Zero Cross
float frequency;
float delayValAvg; // Smoothed fire delay from measured samples
int rawFireDelay; // Fire delay mapped from potmeter value and delta time for ZC
volatile unsigned long dT_ZC_INT; // time between zero crosses
unsigned long pDelay; // Previous time a sample happened
volatile unsigned long pL1_ZC; // Previous time zero cross phase L1
volatile unsigned long pL2_ZC; // Previous time zero cross phase L2
volatile unsigned long pL3_ZC; // Previous time zero cross phase L3
unsigned long pL1_SCR; // Previous time L1 SCR was fired
unsigned long pL2_SCR; // Previous time L2 SCR was fired
unsigned long pL3_SCR; // Previous time L3 SCR was fired
unsigned long microsNow; // Time now
unsigned long pErrorLamp; // Previous state change of error-lamp
void setup() {
// Initialize IO-Pins
pinMode(L1_ZC_Pin, INPUT);
pinMode(L2_ZC_Pin, INPUT);
pinMode(L3_ZC_Pin, INPUT);
pinMode(L1_SCR_Pin, OUTPUT);
pinMode(L2_SCR_Pin, OUTPUT);
pinMode(L3_SCR_Pin, OUTPUT);
// Activate interrupt routines
attachInterrupt(digitalPinToInterrupt(L1_ZC_Pin), L1_ZC, RISING);
attachInterrupt(digitalPinToInterrupt(L2_ZC_Pin), L2_ZC, RISING);
attachInterrupt(digitalPinToInterrupt(L3_ZC_Pin), L3_ZC, RISING);
Serial.begin(9600);
}
void loop() {
while(1) {
microsNow = micros(); // Save current time
enableState = digitalRead(enable_pin); // Read pin state of enable-switch
// Sample potmeter and time for zero-cross
if ( microsNow - pDelay >= iDelay ) {
pDelay = microsNow;
potValue = analogRead(pot_pin); // Read value from potensiometer
// Map the delay time from the potentiometer
// from "minimumDelay" to "zero-cross delta time"
// Unit: µseconds
rawFireDelay = map(potValue, 1023, 0, minimumDelay, dT_ZC_INT);
// Low Pass filtering of raw values
delayValAvg = delayValAvg * smoothFactor + rawFireDelay * (1-smoothFactor);
}
// Firing-algorithm
if ( enable ) {
digitalWrite(lamp_pin, HIGH); // Turn on indicator
// Firing L1 SCR if trig'd
if ( L1_ZC_Trg && (microsNow - pL1_ZC) >= (int)delayValAvg ) {
L1_ZC_Trg = 0; // Disable bit for L1 Trigger
digitalWrite(L1_SCR_Pin, HIGH);
}
if ( L2_ZC_Trg && (microsNow - pL2_ZC) >= (int)delayValAvg ) {
L2_ZC_Trg = 0; // Disable bit for L2 Trigger
digitalWrite(L2_SCR_Pin, HIGH);
}
if ( L3_ZC_Trg && (microsNow - pL3_ZC) >= (int)delayValAvg ) {
L3_ZC_Trg = 0; // Disable bit for L3 Trigger
digitalWrite(L3_SCR_Pin, HIGH);
}
} else {
digitalWrite(lamp_pin, HIGH);
}
// Error-function. Blinking if error-bit is enabled
if ( error && (microsNow - pErrorLamp) >= iLamp ){
errorLampState = !errorLampState;
digitalWrite(lamp_pin, errorLampState);
}
}
}
// ISR for Phase L1
void L1_ZC () {
digitalWrite(L1_SCR_Pin, LOW);
L1_ZC_Trg = 1; // Enable bit for L1 Trigger
dT_ZC_INT = microsNow - pL1_ZC; // Calculate current zero cross delta time
pL1_ZC = microsNow; // Set previous zero cross to "now"
}
// ISR for Phase L2
void L2_ZC () {
digitalWrite(L2_SCR_Pin, LOW);
L2_ZC_Trg = 1; // Enable bit for L2 Trigger
pL2_ZC = microsNow; // Set previous zero cross to "now"
}
// ISR for Phase L1
void L3_ZC () {
digitalWrite(L3_SCR_Pin, LOW);
L3_ZC_Trg = 1; // Enable bit for L3 Trigger
pL3_ZC = microsNow; // Set previous zero cross to "now"
}
Datasheet for the SCR is found in first post.
So where is the issue lying?
Should the missing resistor be fitted?
Is it necessary to add a snubber on each SCR due to cable inductance? Latest test was with approximately 5 meters 6mm^2 4-conductor cable from the component box.
Software issues?