trigger control PWM

My homework is to make the PWM start after reading a certain signal.

The signal I'm referring to is from a Zero Crossing Detector.
https://drive.google.com/file/d/0B7EHOI6yi950YXFCcUZFQk5GSUE/view?usp=sharing

Here, as attached, the blue color is ZCD wave. The yellow one is 12VAC.

For the time being, I connect that ZCD output signal to Arduino UNO A5 pin.
Hoping that the Arduino would read the pin and generate the PWM when the ZCD is at low state at the first time the Arduino read it and stop the PWM when the A5 pin is unplugged.

But instead, my code only let the PWM start after the A5 pin is unplugged and can't be stopped unless manually push the reset button or turn the Arduino off.
Here's the code I use:

int fasa, x=62; 
void setup() {
Serial.begin(9600);
fasa=analogRead(A5); //to read zerocross
while (fasa!=0){
  fasa=analogRead(A5); 
  Serial.println(fasa);


void loop() {

digitalWrite(3,HIGH); 
digitalWrite(9,LOW);
delayMicroseconds(x); //x is 62, the 50% duty cycle for 8Khz
digitalWrite(3,LOW);
digitalWrite(9,HIGH);
delayMicroseconds(125-x); 
}

So, the goal is: to make the Arduino UNO generate PWM but the time it starts is based on the input signal.

I have no idea how to code it. :confused:

Any response is appreciated.
Thanks and Regards.

How do you have a zero CROSSING when the values you read are all zero or positive?

Enjoyneering2222:
So, the goal is: to make the Arduino UNO generate PWM but the time it starts is based on the input signal.

I have no idea how to code it. :confused:

Something like this ?

if (zeroCross == true) {
  analogWrite(pwmPin, pwmValue);
}

...R

The OP's linked image:

PaulS:
How do you have a zero CROSSING when the values you read are all zero or positive?

Hi, Paul.
You mean the waveform? That's just the nature of the Zero Crossing Detectors. :smiley:
It goes 'positive' when the grid it detected is at zero phase and 'zero' when the grid is at 1 and -1 state.
for reference to the zerocrossing circuitry: Zero-Crossing Detectors Circuits and Applications

Robin2:
Something like this ?

if (zeroCross == true) {

analogWrite(pwmPin, pwmValue);
}




...R

Thanks, Robin! I don't think we can use the true logic, as when there is no waveform, the zerocross generate constant voltage output, therefore resulting as 'true' as well :confused: but I'll try it to the circuitry tomorrow as I left the project at the lab and it is now midnight here, so the lab is closed.

Your zero-cross waveform seems to be between 312mV and -232mV. Are you feeding that negative component into the MCU's ADC pin? I'm wondering if that is healthy for the MCU and how it will affect the readings. It is supposed to stay within 0 - VCC.

Am I right in thinking that the end goal is to generate a short beep after every zero crossing?

arduarn:
Your zero-cross waveform seems to be between 312mV and -232mV. Are you feeding that negative component into the MCU's ADC pin? I'm wondering if that is healthy for the MCU and how it will affect the readings. It is supposed to stay within 0 - VCC.

Am I right in thinking that the end goal is to generate a short beep after every zero crossing?

Hi, Arduarn.

Yes. I think it's only the oscilloscope readings. As I got 0,7VDC and 2VAC from multimeter readings.
However, I threw one UNO out yesterday because it can't get detected on my PC and I can't download codes to it. That's another problem then.... :confused:

hmm its quite the opposite. the goal is to generate continuous PWM after a short beep of zero crossing.

The zero crossing detector circuit should be designed to output a digital pulse. Then you can read the output with an interrupt and not analogRead(). In the isr for the interrupt you can set a boolean flag zeroCross = true

Enjoyneering2222:
Thanks, Robin! I don't think we can use the true logic, as when there is no waveform, the zerocross generate constant voltage output, therefore resulting as 'true' as well

I had assumed, from your Original Post, that you already have the ability to identify when the zero is crossed.

...R

cattledog:
The zero crossing detector circuit should be designed to output a digital pulse. Then you can read the output with an interrupt and not analogRead(). In the isr for the interrupt you can set a boolean flag zeroCross = true

Hi, Cattledog.

Yes, it is a digital pulse. May I know what command to use so I can read it with the interrupt? Or is there any links you can recommend for me to understand interrupt codes? I'm just getting started to learn programming.

Robin2:
I had assumed, from your Original Post, that you already have the ability to identify when the zero is crossed.

...R

yesss I just don't know how to translate it into codes lol

Enjoyneering2222:
yesss I just don't know how to translate it into codes lol

I don't understand. What do you mean by "it".

I guess I don't understand where you have got to with your project and what extra step you are struggling with.

...R

Enjoyneering2222:
Yes. I think it's only the oscilloscope readings. As I got 0,7VDC and 2VAC from multimeter readings.
However, I threw one UNO out yesterday because it can't get detected on my PC and I can't download codes to it. That's another problem then.... :confused:

I'm sure someone will correct me if I'm wrong (very possible), but aren't the multimeter readings even worse? 2V AC component, so roughly about 2.8V peak, and offset with the 0.7V DC potentially -2.1V to the ADC input? (though it is nowhere near a sine wave, so maybe this is all crap)

Enjoyneering2222:
hmm its quite the opposite. the goal is to generate continuous PWM after a short beep of zero crossing.

But for your 100Hz signal as soon as you turn the Arduino on and connect the signal, it will immediately generate the PWM. I don't see the point.

Enjoyneering2222:
Yes, it is a digital pulse. May I know what command to use so I can read it with the interrupt? Or is there any links you can recommend for me to understand interrupt codes? I'm just getting started to learn programming.

See the notes for attachInterrupt()
Nick Gammon has an excellent page about interrupts, though it may be too much for you at this stage.

You would need to boost the pulses to something resembling logic level though, 312mV isn't going to be enough.

1 Like

You would need to boost the pulses to something resembling logic level though, 312mV isn't going to be enough.

Can you please post the circuit diagram or part number for your zero cross detector. The output levels do not seem right. You should have an open collector output pulled up to Vcc.

Take a look at the h11aa1 for a common solution to a zero cross detector.

Robin2:
I don't understand. What do you mean by "it".

I guess I don't understand where you have got to with your project and what extra step you are struggling with.

...R

Overall, my project is a full h-bridge DC to AC inverter circuit using IGBT. The Zero-Crossing Detector in the circuitry is to read when is the ACgrid reach zero, so the PWM is generated after the ZCD detects the zero phase in the ACgrid. When the ZCD detects the zero phase, it formed the HIGH signal, it goes LOW when the ACgrid is at +1 state or -1 state in the waveform.

The purpose of the Zero Crossing Detector feed to PWM is to make the transistors stop switching when the grid is off. and make it switch and form AC squarewave when the grid is on.

This inverter need PWM for the driver to drive the transistor gate. The driver (IR 2110) works with HIGH logic input and LOW logic input, producing HIGH Output and LOW Output. It is a logic level driver.

The PWM output from Arduino will connect to the input pins of the driver. The output of the driver will be connected to the IGBTs to activate the gate, switching based on the PWM frequency.

I'm posting this at the Programming part since my code in my first post is still not letting me reach my goal.

In short, I have to generate PWM by using arduino, with a signal to activate the PWM. A signal to tell the PWM when to start and when to stop.

That signal is the falling edge of the zerocrossing signal from the circuity. I'll have to connect the zerocross circuitry output into one of the arduino pin, create a code to read that pin and start PWM when the zerocross is at falling edge of the waveform, stop PWM when the pin doesn't get any signal from the zerocrossing.

I guess it's like what cattledog said above, I need to use Interrupt. I'm still trying to figure it out.

I'm struggling to come up with the code as I have very little experience in coding.

Is my explanation understandable? :confused: Sorry I'm not a native speaker.

cattledog:
Can you please post the circuit diagram or part number for your zero cross detector. The output levels do not seem right. You should have an open collector output pulled up to Vcc.

Take a look at the h11aa1 for a common solution to a zero cross detector.

Yes, I am using h11aa1.

In the schematic below, i put 4n25 because ISIS Proteus doesn't have H11aa1. And the 5V VCC comes from a power supply unit.

Your English is very good. What I still don't understand is what part is working and what part you need help with.

If you need help trying to figure out then when the zero-cross happens then I am probably not going to be able to help.

...R
Edit to change "then" to "when" - stupid typo, sorry, I hope it did not cause too much confusion.

arduarn:
I'm sure someone will correct me if I'm wrong (very possible), but aren't the multimeter readings even worse? 2V AC component, so roughly about 2.8V peak, and offset with the 0.7V DC potentially -2.1V to the ADC input? (though it is nowhere near a sine wave, so maybe this is all crap)

But for your 100Hz signal as soon as you turn the Arduino on and connect the signal, it will immediately generate the PWM. I don't see the point.

See the notes for attachInterrupt()
Nick Gammon has an excellent page about interrupts, though it may be too much for you at this stage.

You would need to boost the pulses to something resembling logic level though, 312mV isn't going to be enough.

:frowning: Thanks a lot for pointing it out. I didn't realize. I'm going to review my circuitry again.

Robin2:
Your English is very good. What I still don't understand is what part is working and what part you need help with.

If you need help trying to figure out then the zero-cross happens then I am probably not going to be able to help.

...R

Oh, I figured the common sense, translating the common sense to programming language is one of the challenges I am facing now.
The problem is: how to code the Arduino to read the zero-cross signal that will be connected to one of the Arduino pin to control the start and stop for the PWM as I described before..

I think I understand that you are trying to manage/control/synchonize the stop and start of a grid tied inverter.

Turning the unit on when the grid is running seems straightforward. Detect zero crossings, and start the pwm.

I think the hard part is knowing when to turn the invertor off if the grid is down, as I think the zero cross detector will detect the ac output from the inverter.

Grid tied inverters are common commercial products, so I am sure there is a known solution. It is a safety issue to have local power sources adding power to a grid which is supposed to be off .

So let me see if I have understood:

  • you have an AC supply (which you have been calling ACgrid)
  • you are using an opto-coupler as a zero detector to detect that the ACgrid supply is active
  • you only want to know if the ACgrid is active or not
  • the ACgrid waveform and the required PWM output waveform bear no relationship
  • there is no precise timing requirement for when the PWM starts and when it stops

Enjoyneering2222:
:frowning: Thanks a lot for pointing it out. I didn't realize. I'm going to review my circuitry again.

I could be wrong. Looking at your circuit diagram I don't even see how the -ve voltage could occur...

Take the output from the h11aa1(with the 5v pull up) and bring it to an arduino external interrupt pin(pin D2 or D3 on a uno).

You should be able to use this code to see if you are reading the grid frequency. In your actual program you will turn the pwm on from the ISR. You should see zero count if the grid is not active. Grid frequency count if active.

Turn off is a different issue.

volatile unsigned long  count = 0;
unsigned long copyCount = 0;

unsigned long lastRead = 0;
unsigned long interval = 1000;//one second

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");
  
  pinMode(2,INPUT_PULLUP);
  EIFR = bit (INTF0);  // clear flag for interrupt 0 in case it was set
  attachInterrupt(0, isrCount, RISING); //interrupt signal to pin 2
  

  
}

void loop()
{
  if (millis() - lastRead >= interval) //read interrupt count every second
  {
    lastRead  += interval;
    // disable interrupts,make copy of count,reenable interrupts
    noInterrupts();
    copyCount = count;
    count = 0;
    interrupts();
 
    Serial.println(copyCount);

  }
}

void isrCount()
{
  count++;
}