Skip to main content
Bounty Awarded with 50 reputation awarded by beard999
added 621 characters in body
Source Link
Juraj
  • 18.3k
  • 4
  • 32
  • 50

EDIT 4: the PID outputs high values for high power and small values for lower power. but the Triac period is the off time. so the period should be something like period = 11000 - (75 * output)

here are the input and output values of mike's code based on this answer (blue is temperature, red is output for the Triac period):

enter image description here

The PID control gets smoother over time as it finetunes its parameters, but I think a simple PID has some problems with the sine relation between the output (time) and the resulting heating power.

EDIT 4: the PID outputs high values for high power and small values for lower power. but the Triac period is the off time. so the period should be something like period = 11000 - (75 * output)

here are the input and output values of mike's code based on this answer (blue is temperature, red is output for the Triac period):

enter image description here

The PID control gets smoother over time as it finetunes its parameters, but I think a simple PID has some problems with the sine relation between the output (time) and the resulting heating power.

added 101 characters in body
Source Link
Juraj
  • 18.3k
  • 4
  • 32
  • 50

I need some help in making the connection between the PID library and output in the code

PID calculates the value of output and it is used in int dimtime = (75*output);.

The aaa_PID object gets the reference to variable output with & so when the PID algorithm sets the output value it sets the value of this variable in your sketch.

output should be volatile double output = 0; because it is used in interrupt.

EDIT 2:

I hope you wired the zero crossing detector to pin 2, because that is the pin for external interrupt 0. And don't use pin 1 for Triac, it is wired to USB chip too.

EDIT: Your code stays too long in interrupt. You exit the interrupt only in the time after firing the TRIAC and the next zero crossing.

In this Arduino SE answer I offer two sketches which demonstrate Triac control. This is one of them:

#include <TimerOne.h>

const byte INTERRUPT_PIN = 2;
const byte TRIAC_PIN = 4;
const byte TRIAC_PULSE_MICROS = 30;

const int FADE_MAX = 9800;
const int FADE_MIN = 2000;

volatile bool triacOn;
volatile int period = FADE_MIN; // microseconds cut out from AC pulse

int fadeAmount = 10;

void zeroCrossing() {
  triacOn = false; // triac tuns off self at zero crossing
  Timer1.setPeriod(period); // to call triacPulse() after off period
}

void triacPulse() {
  if (triacOn) { // stop pulse
    digitalWrite(TRIAC_PIN, LOW);
    Timer1.stop();
  } else { // start pulse
    digitalWrite(TRIAC_PIN, HIGH);
    triacOn = true;
    Timer1.setPeriod(TRIAC_PULSE_MICROS);
  }
}

void setup() {
  pinMode(TRIAC_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), zeroCrossing, RISING);
  Timer1.initialize();
  Timer1.attachInterrupt(triacPulse);
}

void loop() {
  period = period + fadeAmount;
  if (period <= FADE_MIN || period >= FADE_MAX) {
    fadeAmount = -fadeAmount;
  }
  delay(25);
}

the other uses direct registers access o AVR.

EDIT 3: mike's oscilloscope output of the sketch above: https://www.youtube.com/watch?v=dnfy_EsPlVI

I need some help in making the connection between the PID library and output in the code

PID calculates the value of output and it is used in int dimtime = (75*output);.

The aaa_PID object gets the reference to variable output with & so when the PID algorithm sets the output value it sets the value of this variable in your sketch.

output should be volatile double output = 0; because it is used in interrupt.

EDIT 2:

I hope you wired the zero crossing detector to pin 2, because that is the pin for external interrupt 0. And don't use pin 1 for Triac, it is wired to USB chip too.

EDIT: Your code stays too long in interrupt. You exit the interrupt only in the time after firing the TRIAC and the next zero crossing.

In this Arduino SE answer I offer two sketches which demonstrate Triac control. This is one of them:

#include <TimerOne.h>

const byte INTERRUPT_PIN = 2;
const byte TRIAC_PIN = 4;
const byte TRIAC_PULSE_MICROS = 30;

const int FADE_MAX = 9800;
const int FADE_MIN = 2000;

volatile bool triacOn;
volatile int period = FADE_MIN; // microseconds cut out from AC pulse

int fadeAmount = 10;

void zeroCrossing() {
  triacOn = false; // triac tuns off self at zero crossing
  Timer1.setPeriod(period); // to call triacPulse() after off period
}

void triacPulse() {
  if (triacOn) { // stop pulse
    digitalWrite(TRIAC_PIN, LOW);
    Timer1.stop();
  } else { // start pulse
    digitalWrite(TRIAC_PIN, HIGH);
    triacOn = true;
    Timer1.setPeriod(TRIAC_PULSE_MICROS);
  }
}

void setup() {
  pinMode(TRIAC_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), zeroCrossing, RISING);
  Timer1.initialize();
  Timer1.attachInterrupt(triacPulse);
}

void loop() {
  period = period + fadeAmount;
  if (period <= FADE_MIN || period >= FADE_MAX) {
    fadeAmount = -fadeAmount;
  }
  delay(25);
}

the other uses direct registers access o AVR.

I need some help in making the connection between the PID library and output in the code

PID calculates the value of output and it is used in int dimtime = (75*output);.

The aaa_PID object gets the reference to variable output with & so when the PID algorithm sets the output value it sets the value of this variable in your sketch.

output should be volatile double output = 0; because it is used in interrupt.

EDIT 2:

I hope you wired the zero crossing detector to pin 2, because that is the pin for external interrupt 0. And don't use pin 1 for Triac, it is wired to USB chip too.

EDIT: Your code stays too long in interrupt. You exit the interrupt only in the time after firing the TRIAC and the next zero crossing.

In this Arduino SE answer I offer two sketches which demonstrate Triac control. This is one of them:

#include <TimerOne.h>

const byte INTERRUPT_PIN = 2;
const byte TRIAC_PIN = 4;
const byte TRIAC_PULSE_MICROS = 30;

const int FADE_MAX = 9800;
const int FADE_MIN = 2000;

volatile bool triacOn;
volatile int period = FADE_MIN; // microseconds cut out from AC pulse

int fadeAmount = 10;

void zeroCrossing() {
  triacOn = false; // triac tuns off self at zero crossing
  Timer1.setPeriod(period); // to call triacPulse() after off period
}

void triacPulse() {
  if (triacOn) { // stop pulse
    digitalWrite(TRIAC_PIN, LOW);
    Timer1.stop();
  } else { // start pulse
    digitalWrite(TRIAC_PIN, HIGH);
    triacOn = true;
    Timer1.setPeriod(TRIAC_PULSE_MICROS);
  }
}

void setup() {
  pinMode(TRIAC_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), zeroCrossing, RISING);
  Timer1.initialize();
  Timer1.attachInterrupt(triacPulse);
}

void loop() {
  period = period + fadeAmount;
  if (period <= FADE_MIN || period >= FADE_MAX) {
    fadeAmount = -fadeAmount;
  }
  delay(25);
}

the other uses direct registers access o AVR.

EDIT 3: mike's oscilloscope output of the sketch above: https://www.youtube.com/watch?v=dnfy_EsPlVI

Mod Moved Comments To Chat
added 177 characters in body
Source Link
Juraj
  • 18.3k
  • 4
  • 32
  • 50

I need some help in making the connection between the PID library and output in the code

PID calculates the value of output and it is used in int dimtime = (75*output);.

The aaa_PID object gets the reference to variable output with & so when the PID algorithm sets the output value it sets the value of this variable in your sketch.

output should be volatile double output = 0; because it is used in interrupt.

EDIT 2:

I hope you wired the zero crossing detector to pin 2, because that is the pin for external interrupt 0. And don't use pin 1 for Triac, it is wired to USB chip too.

EDIT: Your code stays too long in interrupt. You exit the interrupt only in the time after firing the TRIAC and the next zero crossing.

In this Arduino SE answer I offer two sketches which demonstrate Triac control. This is one of them:

#include <TimerOne.h>

const byte INTERRUPT_PIN = 2;
const byte TRIAC_PIN = 4;
const byte TRIAC_PULSE_MICROS = 30;

const int FADE_MAX = 9800;
const int FADE_MIN = 2000;

volatile bool triacOn;
volatile int period = FADE_MIN; // microseconds cut out from AC pulse

int fadeAmount = 10;

void zeroCrossing() {
  triacOn = false; // triac tuns off self at zero crossing
  Timer1.setPeriod(period); // to call triacPulse() after off period
}

void triacPulse() {
  if (triacOn) { // stop pulse
    digitalWrite(TRIAC_PIN, LOW);
    Timer1.stop();
  } else { // start pulse
    digitalWrite(TRIAC_PIN, HIGH);
    triacOn = true;
    Timer1.setPeriod(TRIAC_PULSE_MICROS);
  }
}

void setup() {
  pinMode(TRIAC_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), zeroCrossing, RISING);
  Timer1.initialize();
  Timer1.attachInterrupt(triacPulse);
}

void loop() {
  period = period + fadeAmount;
  if (period <= FADE_MIN || period >= FADE_MAX) {
    fadeAmount = -fadeAmount;
  }
  delay(25);
}

the other uses direct registers access o AVR.

I need some help in making the connection between the PID library and output in the code

PID calculates the value of output and it is used in int dimtime = (75*output);.

The aaa_PID object gets the reference to variable output with & so when the PID algorithm sets the output value it sets the value of this variable in your sketch.

output should be volatile double output = 0; because it is used in interrupt.

EDIT: Your code stays too long in interrupt. You exit the interrupt only in the time after firing the TRIAC and the next zero crossing.

In this Arduino SE answer I offer two sketches which demonstrate Triac control. This is one of them:

#include <TimerOne.h>

const byte INTERRUPT_PIN = 2;
const byte TRIAC_PIN = 4;
const byte TRIAC_PULSE_MICROS = 30;

const int FADE_MAX = 9800;
const int FADE_MIN = 2000;

volatile bool triacOn;
volatile int period = FADE_MIN; // microseconds cut out from AC pulse

int fadeAmount = 10;

void zeroCrossing() {
  triacOn = false; // triac tuns off self at zero crossing
  Timer1.setPeriod(period); // to call triacPulse() after off period
}

void triacPulse() {
  if (triacOn) { // stop pulse
    digitalWrite(TRIAC_PIN, LOW);
    Timer1.stop();
  } else { // start pulse
    digitalWrite(TRIAC_PIN, HIGH);
    triacOn = true;
    Timer1.setPeriod(TRIAC_PULSE_MICROS);
  }
}

void setup() {
  pinMode(TRIAC_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), zeroCrossing, RISING);
  Timer1.initialize();
  Timer1.attachInterrupt(triacPulse);
}

void loop() {
  period = period + fadeAmount;
  if (period <= FADE_MIN || period >= FADE_MAX) {
    fadeAmount = -fadeAmount;
  }
  delay(25);
}

the other uses direct registers access o AVR.

I need some help in making the connection between the PID library and output in the code

PID calculates the value of output and it is used in int dimtime = (75*output);.

The aaa_PID object gets the reference to variable output with & so when the PID algorithm sets the output value it sets the value of this variable in your sketch.

output should be volatile double output = 0; because it is used in interrupt.

EDIT 2:

I hope you wired the zero crossing detector to pin 2, because that is the pin for external interrupt 0. And don't use pin 1 for Triac, it is wired to USB chip too.

EDIT: Your code stays too long in interrupt. You exit the interrupt only in the time after firing the TRIAC and the next zero crossing.

In this Arduino SE answer I offer two sketches which demonstrate Triac control. This is one of them:

#include <TimerOne.h>

const byte INTERRUPT_PIN = 2;
const byte TRIAC_PIN = 4;
const byte TRIAC_PULSE_MICROS = 30;

const int FADE_MAX = 9800;
const int FADE_MIN = 2000;

volatile bool triacOn;
volatile int period = FADE_MIN; // microseconds cut out from AC pulse

int fadeAmount = 10;

void zeroCrossing() {
  triacOn = false; // triac tuns off self at zero crossing
  Timer1.setPeriod(period); // to call triacPulse() after off period
}

void triacPulse() {
  if (triacOn) { // stop pulse
    digitalWrite(TRIAC_PIN, LOW);
    Timer1.stop();
  } else { // start pulse
    digitalWrite(TRIAC_PIN, HIGH);
    triacOn = true;
    Timer1.setPeriod(TRIAC_PULSE_MICROS);
  }
}

void setup() {
  pinMode(TRIAC_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), zeroCrossing, RISING);
  Timer1.initialize();
  Timer1.attachInterrupt(triacPulse);
}

void loop() {
  period = period + fadeAmount;
  if (period <= FADE_MIN || period >= FADE_MAX) {
    fadeAmount = -fadeAmount;
  }
  delay(25);
}

the other uses direct registers access o AVR.

added 1666 characters in body
Source Link
Juraj
  • 18.3k
  • 4
  • 32
  • 50
Loading
Source Link
Juraj
  • 18.3k
  • 4
  • 32
  • 50
Loading