Hi Sky:
TO do that Im using a PWM library for the leonardo..but.. it was set to do only phase correct
PWM, in that mode if you change duty on the fly it creates a double pulse... so I modified the
library by changing the control bit to be FastPWM.. So if you use the library the following code
will allow one to control the PWM duty cycle on a pulse by pulse basis.
(I include the PWM library as the one I modified). Ive modified a coupdl fo the system files for
this project.. so just be aware when I post a library it may or may not match with the Arduino libraries
as released.
#define PulsePin 9
setup()
{
bool timeron = SetPinFrequency( PulsePin, 5000 ); //set pulsepin to 5Khz, modified for fast pwm mode
//this turns on the timer interrupt so that duty cycle can be set pulse by pulse..
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt, we'll use this one for firing the laser if a fire is called for.
//this is the slow way of setting the pwm duty cycle..
pwmWrite( PulsePin, 16); //set for 1us for laser tickle , never go below this and tickle will be all good.
}
//this is a decalaration of an interrupt to be called at the start of every PWM period..
ISR(TIMER1_OVF_vect)
{
//I keep track of the PWM periods as a way of coordinating power in other code
cnt++;
Duty = FireLaser(); //find the next power level..
OCR1A = Duty; //this is the fast way fo changing the upcoming duty cycle period.
}
Arduino based Laser Control
-
ArtF
- Global Moderator

- Posts: 4557
- Joined: Sun Sep 05, 2010 5:14 pm
- Contact:
Re: Arduino based Laser Control
You do not have the required permissions to view the files attached to this post.
Last edited by ArtF on Mon Sep 08, 2014 2:00 pm, edited 1 time in total.
-
ArtF
- Global Moderator

- Posts: 4557
- Joined: Sun Sep 05, 2010 5:14 pm
- Contact:
Re: Arduino based Laser Control
Hi All:
I dont normally draw schematics, so forgive the poor quality. Here is the wiring of the laser
panel, as you can see its pretty simple, just a few buttons, an led and a few wires. Not shown is the
5vdc and 0vdc wires connected to a breakout baord or external 5vdc power supply. You also need to hook
the negative of the 5vdc t0 the ground of the breakout board..
(Schematic Modified Oct 1/2014)
Art
I dont normally draw schematics, so forgive the poor quality. Here is the wiring of the laser
panel, as you can see its pretty simple, just a few buttons, an led and a few wires. Not shown is the
5vdc and 0vdc wires connected to a breakout baord or external 5vdc power supply. You also need to hook
the negative of the 5vdc t0 the ground of the breakout board..
(Schematic Modified Oct 1/2014)
Art
You do not have the required permissions to view the files attached to this post.
Last edited by ArtF on Wed Oct 01, 2014 7:37 pm, edited 1 time in total.
-
Richard Cullin
- Site Admin
- Posts: 152
- Joined: Sat Jun 02, 2012 4:45 pm
Re: Arduino based Laser Control
do you think it might be "safer" to put 47k pull down resistors on your analog button reading pins ? . I'm assuming you have weak pullpowns turned on but a noise spike on the fire button could be nasty.
-
ArtF
- Global Moderator

- Posts: 4557
- Joined: Sun Sep 05, 2010 5:14 pm
- Contact:
Re: Arduino based Laser Control
Hi Richard:
Noise spikes typically have very little current capability behind them, but with 1k to ground as worst case
button press we get about 5 ma in normal operation, the pin will only source about 50 ma I think.. so even if the voltage
on a noise spike got to 50 volts, you'd still be at max about 50ma and even then for so small a period that actual power
dissipation would be too small to care about. Induction of enough power to hurt the arduino would be near impossible
on the button lines, so 1k is likely more than enough. Feel free though to use pretty much any resistance you like as
its truly not critical in this type of circuit. Its more about the ratio than the actual values.. I would worry about too high
a value making the circuit a bit more susceptible to noise.
(All just my opinion of course, I make no pretence at an engineering degree.
). All that having been said, those are
the reason I picked those values, and since you ( or anyone) may know better than I, please use any values you might
calculate and let us know. Id worry on 47K though ( if used on all pins ) that youd then max out at around 200K for one of the
button presses and with that low a current flow noise could give wrong indications. ( 4.7K perhaps though)
The reason I state ratio's are more important than values is simply the code gets easier if all values are the same.
Button code such as this:
int16_t val = analogRead(Buttons); //read the jog buttons.
thisbut = (val >> 8);
So too high a value could in theory make the buttons a bit less responsive or error prone, and with a fire button as one
of the buttons in the loop I figured Id keep it as reliably set as I could in terms of returned analogue count.
Art
Noise spikes typically have very little current capability behind them, but with 1k to ground as worst case
button press we get about 5 ma in normal operation, the pin will only source about 50 ma I think.. so even if the voltage
on a noise spike got to 50 volts, you'd still be at max about 50ma and even then for so small a period that actual power
dissipation would be too small to care about. Induction of enough power to hurt the arduino would be near impossible
on the button lines, so 1k is likely more than enough. Feel free though to use pretty much any resistance you like as
its truly not critical in this type of circuit. Its more about the ratio than the actual values.. I would worry about too high
a value making the circuit a bit more susceptible to noise.
(All just my opinion of course, I make no pretence at an engineering degree.
the reason I picked those values, and since you ( or anyone) may know better than I, please use any values you might
calculate and let us know. Id worry on 47K though ( if used on all pins ) that youd then max out at around 200K for one of the
button presses and with that low a current flow noise could give wrong indications. ( 4.7K perhaps though)
The reason I state ratio's are more important than values is simply the code gets easier if all values are the same.
Button code such as this:
int16_t val = analogRead(Buttons); //read the jog buttons.
thisbut = (val >> 8);
So too high a value could in theory make the buttons a bit less responsive or error prone, and with a fire button as one
of the buttons in the loop I figured Id keep it as reliably set as I could in terms of returned analogue count.
Art
-
ArtF
- Global Moderator

- Posts: 4557
- Joined: Sun Sep 05, 2010 5:14 pm
- Contact:
Re: Arduino based Laser Control
Hi All:
Here is the code for the Arduino Im currently using. With it comes a few pointers about why it is what it is. ( Again, please keep
in mind this is my first arduino project, so its messy , poorly written but works fine so far, hopefully together we can make it better
and more fireproof. Its the result of several recodes as I discovered limitations in the arduino's capabilities.
So lets discuss whats here.
Firstly, its just a few routines, BUT I did a change to the systems Winterrupts.c file that you will have to duplicate
for this to compile. Find the WInterrupts.c file and comment out the following lines
//ISR(INT0_vect) {
// if(intFunc[EXTERNAL_INT_0])
// intFunc[EXTERNAL_INT_0]();
//}
//ISR(INT1_vect) {
// if(intFunc[EXTERNAL_INT_1])
// intFunc[EXTERNAL_INT_1]();
//}
//ISR(INT6_vect) {
// if(intFunc[EXTERNAL_INT_4])
// intFunc[EXTERNAL_INT_4]();
//}
This was necessary because I found the interrupt time with AttachInterrupt(..) was too slow. The library was attempting
to figure out too much and wasted over 25us as a result, by recoding to direct calls and giving Attach() a dummy process in
its call while providing the actual interrupt routine I was able to get much better responce at higher speeds. So the interrupt
calls may look a bit weird to you.
attachInterrupt( 0, DUMMY, RISING ); //pulse external monitor
The above sets up the interrupt but the routine DUMMY isnt used, the routine
is directly set by the use of ISR(INT0_vect) further down in the code.
the program uses three interrupts, though really only 2 at once. The Int6 routine is used only for PWM
sensing and gives me a number of 0-100 as a current PWM setting at 50hz. It does this by
counting the 5Khz laser base and reporting how many "ticks" of that occur between PWM rise and fall
(thus at 50hz PWM you get a values of 0-100 which is a good slick way of getting pwm in this case. )
PWM though is used only in CNC mode which is the worst mode. In NGrave mode we user a power value
sent via serial by interrupt #1, this is a raw serial clock/data pulsing at kernal frequency. I use very noisy
servo's so to eliminate as much error as I could, I frame the power level in between hex f's, so the power is
sent as 0xfppf where pp is 8 bits of power. In addition the 8 power bits must be less than 100 else
the system will reject it as noise. As further noise reduction the same value is always sent twice and must
match, or its rejected as well.
This is not a great serial routine, we could probably do much better but I came up with it in frustration
at the level of noise I was getting from my servos. ( I shouldn't have put them in my breakout board
cabinet as they have their own AC/DC conversion which makes them very noisy.
SO the power once received is used as the next duty cycle to be used when a "stepflag" is seen, this is
on Interrupt 0.
if( (OpMode != DIAGS && SpindleOn))
{
FireCount = ReLoad;
FIRE = true;
}
Its code simple fires the laser if we're in NGrave or CNC mode and the spindle
is known to be running.
SO just keep in mind the code is pretty badly coded as a result of many many attempts
with various theories, text comments may be totally wrong from cut and pastes
during its development, but that as it stands it does engraving very well and with high
repetition rates. Changes to make it better as we have more testers will be great so
once anyone has a unit working, please let us know what changes you do and what their effect
is. I'm very willing to revise Darwin to comply with what any users feel would work better.
I suspect changes in theory that makes for good engraving will evolve to other hardware
like the smoothstepper in future, so ideas here are good for everyone.
Have fun
Art
Here is the code for the Arduino Im currently using. With it comes a few pointers about why it is what it is. ( Again, please keep
in mind this is my first arduino project, so its messy , poorly written but works fine so far, hopefully together we can make it better
and more fireproof. Its the result of several recodes as I discovered limitations in the arduino's capabilities.
So lets discuss whats here.
Firstly, its just a few routines, BUT I did a change to the systems Winterrupts.c file that you will have to duplicate
for this to compile. Find the WInterrupts.c file and comment out the following lines
//ISR(INT0_vect) {
// if(intFunc[EXTERNAL_INT_0])
// intFunc[EXTERNAL_INT_0]();
//}
//ISR(INT1_vect) {
// if(intFunc[EXTERNAL_INT_1])
// intFunc[EXTERNAL_INT_1]();
//}
//ISR(INT6_vect) {
// if(intFunc[EXTERNAL_INT_4])
// intFunc[EXTERNAL_INT_4]();
//}
This was necessary because I found the interrupt time with AttachInterrupt(..) was too slow. The library was attempting
to figure out too much and wasted over 25us as a result, by recoding to direct calls and giving Attach() a dummy process in
its call while providing the actual interrupt routine I was able to get much better responce at higher speeds. So the interrupt
calls may look a bit weird to you.
attachInterrupt( 0, DUMMY, RISING ); //pulse external monitor
The above sets up the interrupt but the routine DUMMY isnt used, the routine
is directly set by the use of ISR(INT0_vect) further down in the code.
the program uses three interrupts, though really only 2 at once. The Int6 routine is used only for PWM
sensing and gives me a number of 0-100 as a current PWM setting at 50hz. It does this by
counting the 5Khz laser base and reporting how many "ticks" of that occur between PWM rise and fall
(thus at 50hz PWM you get a values of 0-100 which is a good slick way of getting pwm in this case. )
PWM though is used only in CNC mode which is the worst mode. In NGrave mode we user a power value
sent via serial by interrupt #1, this is a raw serial clock/data pulsing at kernal frequency. I use very noisy
servo's so to eliminate as much error as I could, I frame the power level in between hex f's, so the power is
sent as 0xfppf where pp is 8 bits of power. In addition the 8 power bits must be less than 100 else
the system will reject it as noise. As further noise reduction the same value is always sent twice and must
match, or its rejected as well.
This is not a great serial routine, we could probably do much better but I came up with it in frustration
at the level of noise I was getting from my servos. ( I shouldn't have put them in my breakout board
cabinet as they have their own AC/DC conversion which makes them very noisy.
SO the power once received is used as the next duty cycle to be used when a "stepflag" is seen, this is
on Interrupt 0.
if( (OpMode != DIAGS && SpindleOn))
{
FireCount = ReLoad;
FIRE = true;
}
Its code simple fires the laser if we're in NGrave or CNC mode and the spindle
is known to be running.
SO just keep in mind the code is pretty badly coded as a result of many many attempts
with various theories, text comments may be totally wrong from cut and pastes
during its development, but that as it stands it does engraving very well and with high
repetition rates. Changes to make it better as we have more testers will be great so
once anyone has a unit working, please let us know what changes you do and what their effect
is. I'm very willing to revise Darwin to comply with what any users feel would work better.
I suspect changes in theory that makes for good engraving will evolve to other hardware
like the smoothstepper in future, so ideas here are good for everyone.
Have fun
Art
You do not have the required permissions to view the files attached to this post.
-
ArtF
- Global Moderator

- Posts: 4557
- Joined: Sun Sep 05, 2010 5:14 pm
- Contact:
Re: Arduino based Laser Control
Hi:
I should add one more thing.. the labels for the button names are wrong in the schematic, I just relaised
I used an old napkin sketch and cant find my final layout paper, so Ill have to trace the code to see what
button is actually which in their respective groups.
Art
I should add one more thing.. the labels for the button names are wrong in the schematic, I just relaised
I used an old napkin sketch and cant find my final layout paper, so Ill have to trace the code to see what
button is actually which in their respective groups.
Art
-
Richard Cullin
- Site Admin
- Posts: 152
- Joined: Sat Jun 02, 2012 4:45 pm
Re: Arduino based Laser Control
art
my concern is that the analog input pins are essentially floating until a button is pressed . floating pins are very subject to noise
my concern is that the analog input pins are essentially floating until a button is pressed . floating pins are very subject to noise
-
ArtF
- Global Moderator

- Posts: 4557
- Joined: Sun Sep 05, 2010 5:14 pm
- Contact:
Re: Arduino based Laser Control
Richard:
In this case I turned on the internal pullup resistor with a digitalwrite to that analogue pin, it keeps it pulled high until a button is pressed, that seems to make it resistive enough to noise .. or at least on the buttons I haven't seen any..
Art
In this case I turned on the internal pullup resistor with a digitalwrite to that analogue pin, it keeps it pulled high until a button is pressed, that seems to make it resistive enough to noise .. or at least on the buttons I haven't seen any..
Art
-
Richard Cullin
- Site Admin
- Posts: 152
- Joined: Sat Jun 02, 2012 4:45 pm
Re: Arduino based Laser Control
art
I'm mainly thinking of others making this , where the buttons may have longer cables attached and or high voltage laser supplies may be employed , the internal rpu (pullup resistor) can be as high as 50 k . a lower impedence wont affect the readings and will give greater noise immunity.
just a thought , great project though
I'm mainly thinking of others making this , where the buttons may have longer cables attached and or high voltage laser supplies may be employed , the internal rpu (pullup resistor) can be as high as 50 k . a lower impedence wont affect the readings and will give greater noise immunity.
just a thought , great project though
-
ArtF
- Global Moderator

- Posts: 4557
- Joined: Sun Sep 05, 2010 5:14 pm
- Contact:
Re: Arduino based Laser Control
Richard:
Very good point. I hadn't considered the folks with high voltage supplies.
I will change the documentation to show 47K's as the resistors. Your quite
right that there really shouldn't be any downside to it, though Ill wait till
I hear from someone with higher values before making it official.
Im sure over time many such changes will take place , as this is my first
arduino project Im happy to hear such suggestions for change. So long as the
same values are used for all of the resistors the code should remain valid.
Thx
Art
Very good point. I hadn't considered the folks with high voltage supplies.
I will change the documentation to show 47K's as the resistors. Your quite
right that there really shouldn't be any downside to it, though Ill wait till
I hear from someone with higher values before making it official.
Im sure over time many such changes will take place , as this is my first
arduino project Im happy to hear such suggestions for change. So long as the
same values are used for all of the resistors the code should remain valid.
Thx
Art