Circuit can be found at the link in the opening post (AC phase control)
Channel B green is the zero cross detection - H11AA1
Channel A yellow is the Arduino signal to the triac driver (MOC...), output defined by the timer compare and overflow.
1V per division
1ms per division
Those signals look good. The yellow trace is showing the 'triac on' point which corresponds to the DVM measuring the highest voltage - it is closer to the center of the voltage half cycle. It should be at the beginning, unless my DVM is not capable. I do need to scope the AC voltage signals - have to purchase some additional hardware or a different scope since mine (bit scope) does not accept >50V. I don't want this to be a wild goose chase, but if anyone has seen this issue (max V at 1/4 cycle instead of 1/2 cycle), and can comment on having connection issues using breadboard for 120VAC and chunky Q60 leads, that would be appreciated.
I am running the below code.
//PID loop include statements
#include <PID_v1.h>
// #define PIN_INPUT A0
// #define PIN_OUTPUT 3 now connected to AC Phase control
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
double Kp=1, Ki=.5, Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, REVERSE);
// photoresistor for testing purposes only
//int sensorValue;
//int sensorLow = 1023;
//int sensorHigh = 0;
// AC Control V1.1
//
// This arduino sketch is for use with the heater
// control circuit board which includes a zero
// crossing detect fucntion and an opto-isolated triac.
//
// AC Phase control is accomplished using the internal
// hardware timer1 in the arduino
//
// Timing Sequence
// * timer is set up but disabled
// * zero crossing detected on pin 2
// * timer starts counting from zero
// * comparator set to "delay to on" value
// * counter reaches comparator value
// * comparator ISR turns on triac gate
// * counter set to overflow - pulse width
// * counter reaches overflow
// * overflow ISR truns off triac gate
// * triac stops conducting at next zero cross
// The hardware timer runs at 16MHz. Using a
// divide by 256 on the counter each count is
// 16 microseconds. 1/2 wave of a 60Hz AC signal
// is about 520 counts (8,333 microseconds).
#include <avr/io.h>
#include <avr/interrupt.h>
#define DETECT 2 //zero cross detect
#define GATE 9 //triac gate
#define PULSE 4 //trigger pulse width (counts)
int i=483;
void setup(){
Serial.begin(9600);
// pinMode(PIN_INPUT, INPUT);
// while (millis() < 5000) // for photoresistor testing only
// {
// sensorValue = analogRead(PIN_INPUT);
// if (sensorValue > sensorHigh) {
// sensorHigh = sensorValue;
// }
// if (sensorValue < sensorLow){
// sensorLow = sensorValue;
// }
// }
// set up pins
pinMode(DETECT, INPUT); //zero cross detect INPUT_PULLUP
// digitalWrite(DETECT, HIGH); //enable pull-up resistor
pinMode(GATE, OUTPUT); //triac gate control
// set up Timer1
//(see ATMEGA 328 data sheet pg 134 for more details)
OCR1A = 100; //initialize the comparator
TIMSK1 = 0x03; //enable comparator A and overflow interrupts
TCCR1A = 0x00; //timer control registers set for
TCCR1B = 0x00; //normal operation, timer disabled
// set up zero crossing interrupt
attachInterrupt(0,zeroCrossingInterrupt, RISING);
//IRQ0 is pin 2. Call zeroCrossingInterrupt
//on rising signal
//Set up the PID loop
//initialize the variables we're linked to
// Input = 145;
// Setpoint = 225;
//turn the PID on
// myPID.SetMode(AUTOMATIC);
// SetOutputLimits()
// SetTunings()
// SetSampleTime()
}
//Interrupt Service Routines
void zeroCrossingInterrupt(){ //zero cross detect
TCCR1B=0x04; //start timer with divide by 256 input
TCNT1 = 0; //reset timer - count from zero TCNT1 is the Timer/counter Register for timer 1
}
ISR(TIMER1_COMPA_vect){ //comparator match
digitalWrite(GATE,HIGH); //set triac gate to high
Serial.println(TCNT1);
TCNT1 = 65536-PULSE; //trigger pulse width
}
ISR(TIMER1_OVF_vect){ //timer1 overflow
digitalWrite(GATE,LOW); //turn off triac gate
TCCR1B = 0x00; //disable timer stopd unintended triggers
//Serial.print(" on");
//Serial.println(" ");
}
void loop(){ // sample code to exercise the circuit
//use photoresistor for input for testing only
//sensorValue = analogRead(PIN_INPUT);
//Input = map(sensorValue,sensorLow,sensorHigh, 0, 255);
//PID calculation
// Input = analogRead(PIN_INPUT);
// myPID.Compute();
// analogWrite(PIN_OUTPUT, Output); now feeds to the AC Phase control
i--;
OCR1A = i; //set the compare register brightness desired.
if (i<25){i=483;}
delay(150);
//OCR1A = 110;
// OCR1A = map(Output,0,255, 0, 521); //send the PID value to the triac
//Serial.print(sensorValue);
//Serial.print(" ");
//Serial.print(Input);
//Serial.print(" ");
//Serial.print(i);
//Serial.print(" ");
//Serial.print(OCR1A);
//Serial.println(" ");
}