pwm for laser control

Hi, my circuit is quite simple and I could realize it just with an opto-coupler / transistors, but I later want to add some adjustment in it.

So i have simple 5V on-off (input1) and continous pwm (input2) from cnc control board which I need to combine together to one output. Frequency is not important, I only need to control the duty cycle.

So logic could be like: If (input1 == high) { analogWrite (output1, duty cycle of pwm-input2) } ...or maybe somehow just passing the input2 pwm modulation switched by input1.

I need to do it in continous and relatively fast (delays lets say within few ms).

What is the simplest way to realise this, just with inputs or with interrupts? How I'm reading the input2 duty cycle on the fly?

kmin:
So logic could be like:

If (input1 == high) {

analogWrite (output1, duty cycle of pwm-input2)
}

…and what happens when you try this approach?

…don’t know because I don’t have enough knowledge to get that duty cycle out from input2… and pass it to the output in realtime. So I only have the logic at the moment :confused:

What is the voltage and frequency of the pwm signal from the cnc control board?

What do you want to do with the 5v mirrored pwm output of the Arduino? I

There are lots of examples around for measuring pwm frequency and duty cycle. Use the search box on the fouum, or try Mr Google with "Arduhino measure pwm frequency and duty cycle".

t sounds like the pwm and the on/off signal from the cnc control board are independent, and using the on/off to control a switch to "pass" the pwm it will be less complex coding than pulse measurement.

cattledog: What is the voltage and frequency of the pwm signal from the cnc control board?

What do you want to do with the 5v mirrored pwm output of the Arduino? I

There are lots of examples around for measuring pwm frequency and duty cycle. Use the search box on the fouum, or try Mr Google with "Arduhino measure pwm frequency and duty cycle".

t sounds like the pwm and the on/off signal from the cnc control board are independent, and using the on/off to control a switch to "pass" the pwm it will be less complex coding than pulse measurement.

Voltage is 0-5, frequency would be around 100hz, I can adjust it a bit. So pwm I'm geting from cnc control board and I'm willing to pass it to the laser driver (analog/pwm modulation input) to adjust the intensity. Problem is that modulation changes from the cnc software have too much delay, so I have to combine it with on-off input that is almost instant.

There are a lot of examples to measure the pwm and I have done quite much IR work with arduino, but I haven't found how to repeat it instantly. Basically would work like arduino-DAC without output filters. But I guess you are right, it's easier to pass the modulation, I just don't know how... What you think? Thanks for your answer.

Problem is that modulation changes from the cnc software have too much delay, so I have to combine it with on-off input that is almost instant.

Can you please add more information about how you plan to control the laser intensity as a slave to the cnc output if the cnc output pwm changes duty cycle in a manner which is too delayed (delayed to what?). What is controlling the pwm output from the cnc controller? What is it representing?

If, for example, the cnc output pwm changes duty cycle for 20% to 60% over 30 seconds, what do you want the laser to do?

I'm not clear from your description how the on/off control fits into the scheme? Do you only want to apply pwm to the laser when the cnc signal is unchanging and turn the laser off during any transitions?

The whole problem is my cnc software, Mach3, which is not suited well for laser application. X-Y axis movements are instant from sw to the control board, so to have my laser control synchronized to those movements is fundamental. I can get on-off output for the laser instant as well, but if I'm trying to modulate the intensity (like my laser driver is built for) there is a small delay relative to the axis movements. All together, I can't control lasing start and stop just with pwm modulation because X-Y axis would already move before the laser starts lasing. Instead modulating the intensity, let's say from 90 to 70% while it's lasing would still be delayed, but wouldn't result as an noticeable error on the output.

So pwm modulation could this way run continously, even when not lasing and to be immediately available when start lasing. Still far from perfect but nobody has buit a pulse-distance laser control for Mach3 and with my coding skills I'm not going to be the one. For other setups like grbl it's available.

Arduino default frequency for PWM (on pin 9) is 490.20 Hz, if you need to change the default frequency, Arduino has only a few selectable frequencies, 122.55 is about as close as you can get to 100, just uncomment one of the following lines and add to setup()

//TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
// TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz (The DEFAULT)
//TCCR1B = TCCR1B & B11111000 | B00000100; // set timer 1 divisor to 256 for PWM frequency of 122.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to 1024 for PWM frequency of 30.64 Hz

Then in setup() add

pinMode(9, OUTPUT);

the in setup() or loop() add the line

analogWrite(9, value); // value: the duty cycle: between 0 (always off) and 255 (always on).

Hope this helps

Thank's Kris, even the default is fine, my driver can take from DC to 100kHz. But my question was, how I'm getting the duty cycle from cnc control board to be replicated in real time?

@kmin

I am not familiar with the Mach3 software, so I am not understanding your situation.

Is this a correct interpretation?

You have a software file defining XY positions and a desired pwm intensity, including on/off, at each position.

That file is sent to a machine controller which starts moving the XY axes, issues correct on/off commands, but the pwm pulse output from the machine controller is not synchronized with the on/off or the axis movements. Rather, for some reason, it is delayed. I envision that an on signal is issued, the movement begins, but there is no pwm pulse train issued until the motion has proceeded for a while.

If this is correct, it sounds to me that here is no real time pulse signal to be relayed or replicated coming from the controller. There are only delayed pulses.

It certainly is possible to have the Arduino set up to issue pwm at some duty cycle, and have it turn on and off based on the signal from the controller.

Is the physical X Y axis position data available to the Arduino? If it is, you should be able to write a program which generates a pwm signal dependent upon position, and changes the duty cycle, without ever referencing the delayed pwm signal coming out of the controller.

Not quite sure if I follow it but you have a pwm signal that you basically want to switch on or off?

If so you don't need to measure the PWM input. The below code will reflect the state of a pin called 'pwmIN' on a pin called 'pwmOUT', only when signal on the pin called 'switch' is high.

void loop()
{
  if (digitalRead(switchONOFF) == HIGH)
  {
    digitalWrite(pwmOUT, digitalRead(pwmIN);
  }
  else
  {
    digitalWrite(pwmOUT, LOW);
  }
}

//Edit If this is the only thing your Arduino has to do, a simple AND gate is a lot cheaper ;)

cattledog:
@kmin

I am not familiar with the Mach3 software, so I am not understanding your situation.

Is this a correct interpretation?

You have a software file defining XY positions and a desired pwm intensity, including on/off, at each position.

That file is sent to a machine controller which starts moving the XY axes, issues correct on/off commands, but the pwm pulse output from the machine controller is not synchronized with the on/off or the axis movements. Rather, for some reason, it is delayed. I envision that an on signal is issued, the movement begins, but there is no pwm pulse train issued until the motion has proceeded for a while.

If this is correct, it sounds to me that here is no real time pulse signal to be relayed or replicated coming from the controller. There are only delayed pulses.

It certainly is possible to have the Arduino set up to issue pwm at some duty cycle, and have it turn on and off based on the signal from the controller.

Is the physical X Y axis position data available to the Arduino? If it is, you should be able to write a program which generates a pwm signal dependent upon position, and changes the duty cycle, without ever referencing the delayed pwm signal coming out of the controller.

More less like you wrote, but makes more sense if you know Mach. All the signals x,y,z,an other outputs are let’s say instant and synchronous to make the cnc run correctly. The only ready built way to control the laser intensity in the gcode (which can be thousands of lines for a small simple work) is by using spindle speed control pwm output. And there is some delay, 50…150ms maybe. That’s fine for spindle motor speed control, to variate the actual spindle speed it’s taking even some seconds.

So using just pwm modulation output to control the laser would be like writing with old pen, every time you draw a line there are few millimeters before the ink comes out.
Instead combining with instant on/off signal the pen would start writing from the begining, even if the intensity for the first mm could be uncorrect.

To bring the actual position data to arduino would be an other argument, possible yes, easy not. That would be a pulse-distance control for laser that I mentioned before. The ideal way.

sterretje: Not quite sure if I follow it but you have a pwm signal that you basically want to switch on or off?

If so you don't need to measure the PWM input. The below code will reflect the state of a pin called 'pwmIN' on a pin called 'pwmOUT', only when signal on the pin called 'switch' is high.

void loop()
{
  if (digitalRead(switchONOFF) == HIGH)
  {
    digitalWrite(pwmOUT, digitalRead(pwmIN);
  }
  else
  {
    digitalWrite(pwmOUT, LOW);
  }
}

//Edit If this is the only thing your Arduino has to do, a simple AND gate is a lot cheaper ;)

That's what I was looking for, is it just that simple? :o without using interrupts... How much that read-write loop takes time?

I know I could do it with opto-coupler/transistors but I probably need to do some correction later to the intensity, so I choosed the arduino way.

  digitalWrite(pwmOUT, digitalRead(pwmIN);

If the pwmIN is delayed, then pwmOUT will be delayed. I believe that using this method, the intital pwmOUT will be zero, until the delayed signal arrives with 150 ms delay. You will still be writing with the old pen.

So using just pwm modulation output to control the laser would be like writing with old pen, every time you draw a line there are few millimeters before the ink comes out.

sterretje: Not quite sure if I follow it but you have a pwm signal that you basically want to switch on or off?

If so you don't need to measure the PWM input. The below code will reflect the state of a pin called 'pwmIN' on a pin called 'pwmOUT', only when signal on the pin called 'switch' is high.

void loop()
{
  if (digitalRead(switchONOFF) == HIGH)
  {
    digitalWrite(pwmOUT, digitalRead(pwmIN);
  }
  else
  {
    digitalWrite(pwmOUT, LOW);
  }
}

//Edit If this is the only thing your Arduino has to do, a simple AND gate is a lot cheaper ;)

That's what I was looking for, is it just that simple? :o without using interrupts... How much that read-write loop takes time?

I know I could do it with opto-coupler/transistors but I probably need to do some correction later to the intensity, so I choosed the arduino way.

cattledog:   digitalWrite(pwmOUT, digitalRead(pwmIN);

If the pwmIN is delayed, then pwmOUT will be delayed. I believe that using this method, the intital pwmOUT will be zero, until the delayed signal arrives with 150 ms delay. You will still be writing with the old pen.

No, because in my gcode I would not use that delayed pwm to switch off at all. That would be for example 80% untill the correct delayed singnal of 70% arrives. ...Like hand pressure of that pen... :)

Anyway, as far as I know you can't send pwm with digitalWrite, shouldn't it be analogWrite?

What device are you running the Mach 3 on. I recall problems with timing when laptops were used.

kmin: I can get on-off output for the laser instant as well, but if I'm trying to modulate the intensity (like my laser driver is built for) there is a small delay relative to the axis movements.

Rereading that it sounds as though the latency is in the startup time of the laser modulator can you confirm that ? Or am i misunderstanding the problem.

kmin: Hi,

So i have simple 5V on-off (input1) and continous pwm (input2) from cnc control board which I need to combine together to one output. Frequency is not important, I only need to control the duty cycle.

This sound like a simple logic circuit application but i am not sure that i fully understand the problem. If the laser has a separate modulation input and on off function combining the two to make use the on off input to the laser is unlikely to work.

kmin: Anyway, as far as I know you can't send pwm with digitalWrite, shouldn't it be analogWrite?

No. The sample that I provided just copies the level on the input pin to the output pin. So a PWM signal on the input will be a PWM signal on the output.

void loop()
{
  digitalWrite(anyPin, HIGH);
  delay(10);
  digitalWrite(anyPin, LOW);
  delay(90);
}

The above will write a PWM waveform with (roughly) a duty cycle of 10% and a frequency of 10 Hz on the pin anyPin. You don't need an PWM output (analogWrite) to create a PWM signal. The advantage of analogWrite is that it uses an built-in PWM generator that runs on its own; you set the frequency and the dutycycle once and the internals of the microcontroller take care of the rest. The other advantage is that you can achieve higher frequencies with ease; but 100Hz should not be a problem for the code I presented earlier.

The classic blink example is actually also an example of PWM; in a cycle of 0.5 Hz, it switches the LED on and OFF and the duty cycle is 50%.

If your Arduino gets to do more stuff, timing might become an issue. The loop that I presented in the earlier post will run in below 1ms (I don't have a chance to test now). You can easily measure it yourself

void loop()
{
  static unsigned long lasttime = 0;
  if (digitalRead(switchONOFF) == HIGH)
  {
    digitalWrite(pwmOUT, digitalRead(pwmIN);
  }
  else
  {
    digitalWrite(pwmOUT, LOW);
  }

  unsigned long currenttime = micros();
  Serial.println(currenttime - lasttime);
  lasttime = micros();
}

If you really run into timing issues, a hardware solution will be a better option. A simple AND gate will do what is needed (with virtually no delay).

             +---------+
             |         |
ON/OFF ------+         |
             |   AND   +----- pwmOUT
pwnIN  ------+         |
             |         |
             +---------+

Boardburner2,

No, I’m running on desktop and the delay is not related to the laser driver.
Why you think combining the two signals is not likely to work on the laser? Tha laser modulation input would receive either low or pwm.

sterretje,

Didn’t think you could copy the input level that way, basically you read if the pwm signal is high or low at the moment and repeat it quickly. So 1ms read/write cycle would give me 10% resolution at 100Hz, right?

Anyway, doing it this way I don’t really have a opportunity to adjust the duty cycle within arduino, so it really is like the simple AND-gate…
For example, if I want to output 5% pwm instead of low when input1 is low.

kmin: Didn't think you could copy the input level that way, basically you read if the pwm signal is high or low at the moment and repeat it quickly.

Yes

kmin: So 1ms read/write cycle would give me 10% resolution at 100Hz, right?

If your loop takes 1ms, you basically have a delay of 1ms compared to the incoming PWM signal.

kmin: Anyway, doing it this way I don't really have a opportunity to adjust the duty cycle within arduino, so it really is like the simple AND-gate.... For example, if I want to output 5% pwm instead of low when input1 is low.

I think there are still plenty of options. The below will (should, not tested ;)) write a PWM signal (100Hz, 5% duty cycle) when the ON/OFF switch is LOW. You can apply similar principles if you want to adjust the duty cycle while the ON/OFF switch is HIGH. Alternatively you can use a simple analogWrite to let the Arduino hardware produce a 5% PWM when the ON/OFF switch is low and use the 'copy' using digitalWrite when the signal is high.

#define switchONOFF 3
#define pwmIN 4
#define pwmOUT 5

unsigned long period = 10000;   // 10000 us / 100Hz
unsigned long pulsewidth = 500; // 500 us / 5%
void setup()
{
  pinMode(switchONOFF, INPUT_PULLUP);
  pinMode(pwmIN, INPUT);
  pinMode(pwmOUT, OUTPUT);
}

void loop()
{
  static unsigned long starttime = 0;

  if (digitalRead(switchONOFF) == HIGH)
  {
    // duplicate input PWM on output
    digitalWrite(pwmOUT, digitalRead(pwmIN));
  }
  else
  {
    // if PWM not started
    if (starttime == 0)
    {
      // start high part of PWM
      digitalWrite(pwmOUT, HIGH);
      // indicate started
      starttime = micros();
    }
    // check if the duration of the high part has lapsed
    if (micros() - starttime >= pulsewidth)
    {
      // start low part of PWM
      digitalWrite(pwmOUT, LOW);
    }
    // check if total duration has lapsed
    if (micros() - starttime >= period)
    {
      // indicate period has lapsed so the next PWM period will be started
      starttime = 0;
    }
  }
}

It highly depends on what you want to achieve how feasible the approach is. Get your user requirements in place first before deciding on the approach.