zero cross control pin?

narco

Member
I want to control some light dimmers with a teensy.

I'm looking at this:

https://www.aliexpress.com/item/32975095882.html

however, in the list of Arduino's, it lists some of them as only having one pin suitable for the input (zero cross). I'm not sure why there is this limitation. I assume the teensy (4.0 or 4.1) will have a suitable pin(s)?


thanks

Screen Shot 2022-03-08 at 9.43.51 AM.jpg
 
Just found some more info, but it still doesn't answer my question. Perhaps someone else will understand more than I do?

Dimmer is connected to Arduino controllers via two digital pins. First (Zero) to control the passing of Phase Null of AC, which is used to initiate the interrupt signal. Second (DIM/PSM) to control (dim) current.
Note that Zero requires connection to designated microcontroller pins (which are different depending on the model of Uno, Nano, Leonardo, Mega), since it tied to microcontroller interrupts.
 
And now I've realised that this is not a trailing edge dimmer, so its not suitable. I'm still interested as to why there was this pin limitation, and how it applies to teensies though...
 
My worry is that unit may be completely uncertified for mains use. They don't show the underneath of the PCB to allow assessment of
the clearance and creepages across the opto-isolators. The triacs are not isolated-tab packages so the heatsinks are all live, that alone is worrying.
 
There are 2 ways to answer this question.

First, the easy answer is every pin on Teensy 4.0 & 4.1 is capable of interrupts.

But the harder answer involves what the software you will actually use really does. I see this link on the Aliexpress page.

https://github.com/RobotDynOfficial/RBDDimmer

You'll probably first encounter "This library only supports boards with an AVR, ESP32, ESP8266, SAMD, SAM, STM32F1/F4 processor." due to line #21.

The code for each type of chip involves use of timers. I haven't studied the code much, but a first casual glance looks like the timer is just running a function at regular intervals which does all the work with digitalWrite(), but the timing interval gets adjusted. This code could probably be ported to work with IntervalTimer. But that is not a quick and easy matter. Careful testing would be needed.
 
The reason there is even a zero crossing pin in the first place is the optocouplers they use are CHEAP and do not have zero crossing detection. this is a tactic to get rig of old outdated stock and save money. the MOC3041, 42. and 43 has zero crossing built in thus negating the need for a Z-C pin. the original can be desoldered and the new MOC series can be resoldered thus no need for zero pin. this then can easily be controlled with PWM of any controller.
you can they modify the original program negating the ZC pin all together simplifying the program.

My suggestion is do not buy it unless it has zero cross built in or like i said modify it to work right. also another note is the Triac could have zero cross built in which these do not.

PS. i am working on a PWM voice activated control module using such a circuit.

Triac Controll 120v circuit.jpg



Regards,
Marathonman
 
Last edited:
Thanks, I appreciate the answer.
Although I’ve decided to go an entirely different route anyway, but thanks for the explanation and good luck with your project :)
 
I've developed a 4 channel trailing edge dimmer circuit which works well. It uses a zero crossing circuit to trigger a hardware interrupt and switch on active channels then I've used the 4 IntervalTimers to generate interrupts to switch off the 4 channels. Unfortunately, one of the third party libraries must use one of the timers, so my the last dimmer channel to switch on isn't controlled.
Is there a way to use 4 PWM timers to trigger from my zero crossing interrupt and run once or to use one of the special timers - GPT1 or GPT2 - to provide an interrupt for the fourth channel?
Or can someone suggest a neater way altogether.
I'm using the Arduino development environment if anyone has any coding suggestions.
Thanks as always, loving the Teensy 4.1 - awesome product.
 
I've developed a 4 channel trailing edge dimmer circuit which works well. It uses a zero crossing circuit to trigger a hardware interrupt . . .
Or can someone suggest . . .

I have not messed with either a zero-crossing circuit or with dimmers (since the long-ago TRIAC choppers . . . I'm showing my age !!), but could you use the following:

- globally define & initialize (each to full on) an array variable to hold the duration (in microseconds, ranging from 0-16667, representing 0-100% illumination) for each channel as:
Code:
unsigned int channel_duration_in_micros[4] = { 16667, 16667, 16667, 16667 };
- globally define & initialize a timing variable as:
Code:
volatile unsigned long base_micros = micros();
- use your circuit to generate an interrupt (presumably, like you are currently doing)

- in the interrupt handler, set the global variable as:
Code:
   base_micros = micros();
- in the interrupt handler, do the following to potentially turn each channel ON:
Code:
   for (int channel=0; channel < 4; channel++)
   {
      if (channel_duration_in_micros[channel] > 0)
      {
         turn this channel on
      }
   }
- in your regular loop(), do the following to turn each channel OFF:
Code:
   unsigned long current_micros = micros();

   for (int channel=0; channel < 4; channel++)
   {
      if (current_micros >= base_micros + channel_duration_in_micros[channel])
      {
         turn this channel off
      }
   }

Maybe this might work for your application without using any timers ??. . .

Mark J Culross
KD5RXT
 
Hi Mark

Thanks for the very detailed reply.

I started with pretty much this solution, but my main loop can take milliseconds to run, so the switch off time fluctuates from one loop to another which causes dreadful flicker.

I then tried running an IntervalTimer which 'ticked' 100 times every mains half cycle. I then compare a counter with each channels counter and turn off if it is equal, but again that led to flicker.

Think it needs to be interrupt based and with 3 channels working perfectly (or 4 if 2 channels are set to the same level) I'm so close!

Thanks again.
Chris
 
I started with pretty much this solution, but my main loop can take milliseconds to run, so the switch off time fluctuates from one loop to another which causes dreadful flicker.

You beat me to the punch . . . sorry to come late to the party, but happy that I'm at least walking a similar path !!

So, how about if, in addition to the interrupt at zero crossing which manages turn-on, you run a single timer that ticks every microsecond. Then, use the same turn-off logic presented above to process the turn-offs in the handler for that microsecond timer ?? Blindly throwing things up against the wall, hoping that something might stick . . .

Mark J Culross
KD5RXT
 
The problem at hand seems very much like servos. The servo library drives 12 ( I think ) servos with one timer without any jitter. There are differences in that servos are pulsed one at a time, and here you turn on all the dimmers at once and then time the turn off for each.

Use just one interval timer. Sort the times from shortest to long. The first interval will be the time of the shortest, following intervals will be the delta time needed. For example if you had times of 9, 20, 30, 35 your array of times would be 9,11,10,5.
 
We're certainly walking a similar path kd5rxt-mark. Your second suggestion was my second attempt! I had a timer tick every 100uS (we're 50Hz in UK) which corresponds to 1% resolution. Having an interrupt every 100uS which has to do 4 comparisons seemed to be eating up too much time and causing flicker, so I then went to using 3 timers with one shared between channels 3 and 4, similar to rcarr's suggestion but with the load spread across 3 timers. This still produced flicker occasionally.

I'm overclocking the T4.1 to 816MHz and feel there should be plenty of processing time to achieve what I want, so maybe there are fault conditions in my programming (as if...) I'll go back and analyse/test my code some more.

I'd still be interested to know if a GPT timer can do what I want though - anyone?
 
WOW, way to go Paul. mighty nice to help out and join in. so cool!
Yes I am following this thread.

Just so people know PWM can NOT be used on zero cross Triacs. this would take a random Triac which can be had for cheap. the BT139-800E is 800 Volt 16 amp for only a $1.01 at mouser. They are sensitive gate "series E" triac's intended to be interfaced directly to microcontrollers, logic integrated circuits and other low power gate trigger circuits. for better triggering use a Diac though. just FYI.

Regards,
Marathonman
 
Back
Top