Arduino based Laser Control
Re: Arduino based Laser Control
Hi Dan;
I do not have any of that information here in front of me, all of it is at Art's place. Hope you don't mind waiting until he gets back to get the answer, which should be towards the weekend sometimes? Sorry..
Cheers
Bob
>:(
I do not have any of that information here in front of me, all of it is at Art's place. Hope you don't mind waiting until he gets back to get the answer, which should be towards the weekend sometimes? Sorry..
Cheers
Bob
>:(
Gearotic Motion
Bob
Bob
Re: Arduino based Laser Control
Got this from line 50
//initialize the lcd..its on a0-a6 lines in my leonardo..
this is what worked for me.
Not pretty as I can not seem to write well with a mouse. ;D
I added the pot to control the contrast
Re: Arduino based Laser Control
char bro I don't mind waiting at all it will be a few weeks before all the parts show up
Re: Arduino based Laser Control
Thx Guys:
Yes, those seem correct as numbers. ( Preciate it ). The call to LCDInit shows the numbers
I used and what controls them. The line in the code for
LiquidCrystal lcd( 23,22,21,20,19,18);
shows the init of the lcd and its settings as to pin. So looking at the call above... the pins in order are
RS pin -- 23
Enable -- 22
D4 - D7 pins 21,20,19,18
These pin numbers correspond to A5 - A0 on the Leonardo..I suspect the pin numbering differs because
the library wasnt originally written for a leonardo so at the time I traced them by schematic as I recall..
If anyone has trouble with that usage let me know and Ill tear mine down to double check it, but I think
YaNvrNo has it right..
Art
Yes, those seem correct as numbers. ( Preciate it ). The call to LCDInit shows the numbers
I used and what controls them. The line in the code for
LiquidCrystal lcd( 23,22,21,20,19,18);
shows the init of the lcd and its settings as to pin. So looking at the call above... the pins in order are
RS pin -- 23
Enable -- 22
D4 - D7 pins 21,20,19,18
These pin numbers correspond to A5 - A0 on the Leonardo..I suspect the pin numbering differs because
the library wasnt originally written for a leonardo so at the time I traced them by schematic as I recall..
If anyone has trouble with that usage let me know and Ill tear mine down to double check it, but I think
YaNvrNo has it right..
Art
Re: Arduino based Laser Control
Hi All:
Schematic has been corrected as to pushbutton wiring ... the post at
http://gearotic.com/ESW/FavIcons/http:/ ... 7232#p7232
has been updated to show the fixes.
Thx
Art
Schematic has been corrected as to pushbutton wiring ... the post at
http://gearotic.com/ESW/FavIcons/http:/ ... 7232#p7232
has been updated to show the fixes.
Thx
Art
Re: Arduino based Laser Control
morning all I need some advice about what to use for a drive for a laser I will be using this is it
http://www.ebay.com/itm/2W-445nm-M140-B ... 2a2158fe9d
its a 2w 445nm Diode laser I will be running it at 2A 4.7vdc. what I need is advice on what to drive it with there is lot of info on driving a laser with a LT1121.
I Have a Schematic for it see attachment I know it is only for up to 1.5A I can get a bigger chip 2A+ for it is this schematic good enough to run with your controller art.
also I have striped back the sketch so it only has the Laser control stuff on it can someone have a look and see if I got it correct as I don't have all the parts yet so cant test it.I have disabled the LCD part as I am porting it over to run on a TI board
http://www.ebay.com/itm/2W-445nm-M140-B ... 2a2158fe9d
its a 2w 445nm Diode laser I will be running it at 2A 4.7vdc. what I need is advice on what to drive it with there is lot of info on driving a laser with a LT1121.
I Have a Schematic for it see attachment I know it is only for up to 1.5A I can get a bigger chip 2A+ for it is this schematic good enough to run with your controller art.
also I have striped back the sketch so it only has the Laser control stuff on it can someone have a look and see if I got it correct as I don't have all the parts yet so cant test it.I have disabled the LCD part as I am porting it over to run on a TI board
Code: Select all
#include <Wire.h>
#include <LiquidCrystal.h>
#include <PWM.h>
//Setup for Diags..
#define DIAGS 0
#define CNCMODE 1
#define NGRAVE 2
//frequency and pins used.
int32_t basefrequency = 5000; //5khz base freq
int8_t PulsePin = 9; //Pin 9 will control the laser.
int8_t BoardLED = 13;
int8_t FireLED = 12;
int8_t PowerLED = 5;
int8_t Pot = 4;
int8_t Buttons = 8; //analogue and digital are same numbers..be carefull if you use other pins..
int8_t Buttons1 = 10;
int8_t CurButton = 0; //currently pressed button
int8_t CountMode = 0; //the mode of the up/down counter..
bool WaitButtonZero = false;
int8_t OneMicro = 16;
int8_t OpMode = 0;
volatile unsigned short SerialIn = 0;
volatile unsigned short LastSerial = 0;
//volatile unsigned long SpinOnCnt = 0;
//volatile unsigned long SpinOffCnt = 0;
//volatile bool SpindleOn = false; //remote spindle command..
//volatile bool SpindlePWM = false; //remote spindle command current state..
//vars for control
bool PowerOn = false;
bool Tickle = false; // On Off Safety watchdog .. monitor the tickle for laser health
volatile int16_t Duty = OneMicro; //this is the pulse to pulse firepower during a shot.
volatile int32_t cnt = 0; //this is a global interrupt counter..
volatile bool FIRE = false;
//initialize the lcd..its on a0-a6 lines in my leonardo..
//LiquidCrystal lcd( 23,22,21,20,19,18); // set the LCD address to 0x27 for a 20 chars and 4 line display
// the main control variable for diags mode..
int16_t Power = 50; //0 - 100%
unsigned long PWMPower = 0;//0- 100% for the incoming PWM..
int16_t Freq = 5000; // frequency of pulses..
int8_t PotMode = 0;
volatile int32_t FireCount = 0; //number of pulses to fire in diags
volatile int16_t ReLoad = 1;
void setup()
{
// lcd.begin(20,4); // initialize the lcd
// lcd.setCursor(3,0);
// lcd.print("Gearotic Laser");
// lcd.setCursor(0,2);
// lcd.print("Waiting for Unix.");
InitTimers(); //start up the timers.
bool timeron = SetPinFrequency( PulsePin, basefrequency ); //set pulsepin to 5Khz
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt, we'll use this one for fastpwm
attachInterrupt( 0, DUMMY, RISING ); //pulse external monitor
attachInterrupt( 4, DUMMY, CHANGE ); //sets the routine to call..
pwmWrite( PulsePin, 8); //set for 1us for laser tickle
if( timeron ) //if the timercall worked..
{
pinMode( BoardLED, INPUT); // board led life
pinMode( FireLED, OUTPUT); // fire button led
pinMode( PowerLED, OUTPUT); //power control led & control
pinMode( 2, INPUT); //inputs from breakout board
digitalWrite( 2, LOW );
pinMode( 3, INPUT); //inputs from breakout board
digitalWrite( 3, LOW );
pinMode( 11, INPUT); //inputs from breakout board
digitalWrite( 11, HIGH );
digitalWrite( PowerLED, PowerOn); //turn off led for power at start
pinMode( Pot, INPUT); //pot for variable control
digitalWrite(4, HIGH); //set for a pullup resistor
pinMode( Buttons, INPUT); //Jog buttons as analogue input
digitalWrite(Buttons, HIGH);
pinMode( Buttons1, INPUT); //Rest of buttons
digitalWrite(Buttons1, HIGH);
}
//SetDisplay( true ); //and draw the display mask
}
//main idle loop..
void loop()
{
HeartBeat(); //flash the board led if fire isnt flashing..
FlashFire(); // flash the fire button if we are going to fire..
WatchDog(); // ensure all is safe.
DiagsOut(); //display test text if demanded..not used
PotControl(); //use the pot for values..
GetButton();
if( OpMode == DIAGS ) DiagFire();
//if( OpMode == NGRAVE) NGraveFire();
LaserOnOff();
DoButtonCount(); // make freq or firecount set by button if needed.
//set power and other vars, then display..
//SetDisplay( false );
}
void DoButtonCount()
{
int8_t Accel = 1; //this is the accel of button freq, adjust as needed.
static int16_t Adder = Accel;
int16_t Freqmax = 200;
static int32_t Bres = Freqmax;
if( CurButton == 0)
{
Adder = Accel;
Bres = Freqmax;
return;
}
int16_t oldfire = FireCount;
Bres += Adder;
while( Bres > Freqmax ) //not very ellegant, fix later. just a timer for easier button press
{
if( CurButton == 4 ) //left arrow, switch pot to count mode..
CountMode--;
if( CurButton == 6 ) //left arrow, switch pot to dutycyle..
CountMode++;
if( CountMode < 0) CountMode = 2;
if( CountMode > 2) CountMode = 0;
Bres -= Freqmax;
if( CountMode == 0 && CurButton == 5) Freq++;
if( CountMode == 2 && CurButton == 5) FireCount++;
if( CountMode == 0 && CurButton == 7) Freq--;
if( CountMode == 2 && CurButton == 7) FireCount--;
if( FireCount < 0 ) FireCount = 5000;
if( FireCount > 5000 ) FireCount = 0;
if( Freq <= 0 ) Freq = 1;
if( Freq > 5000 ) Freq = 5000;
int oldop = OpMode;
if( CountMode == 1 && CurButton == 5 ) OpMode++;
if( CountMode == 1 && CurButton == 7 ) OpMode--;
if( OpMode > 2 ) OpMode = 0; //these two lines just make the opMode toggle up or down..
if( OpMode < 0 ) OpMode = 2;
//reopen file if required.
if( OpMode == NGRAVE && oldop != NGRAVE)
{
//detach the spindle interrupts.
detachInterrupt(4);
attachInterrupt( 1, DUMMY, RISING ); //reattach the spindle interrupt
}
if( OpMode != NGRAVE && oldop == NGRAVE )
{
attachInterrupt( 4, DUMMY, CHANGE ); //reattach the spindle interrupt
detachInterrupt(1);
}
}
if( oldfire != FireCount ) ReLoad = FireCount;
Adder += Accel;
//faster..damnit..faster. :)
if( Adder == 100 ) Adder *= 2;
if( Adder == 400) Adder *= 2;
if( Adder == 1000) Adder *= 2;
}
void DiagFire()
{
if( CurButton == 2 ) FireCount = ReLoad;
//FIRE!!!!
if( CurButton == 1 && FireCount > 0 ) FIRE = true;
if( CurButton == 0 && FIRE && OpMode == DIAGS ) FIRE = false; //turn it off if no button is pressed in Diags mode.
}
void LaserOnOff()
{
//this controls Laser ON/OFF
if( CurButton == 3 ) //power call , but only once per press
{
if( !WaitButtonZero) PowerOn = !PowerOn;
digitalWrite( PowerLED, PowerOn); //Set Power condition;
WaitButtonZero = true;
}
}
void DUMMY()
{
}
int16_t FireLaser()
{
int16_t ret = OneMicro; //usually we'll return 1 microsecond.
static int16_t Counter = basefrequency;
if( FIRE )
{
if( OpMode == DIAGS )
ret = Power << 5; //we'll return this power only if the counter says so..
else
ret = PWMPower << 5; //in CNC modes we return the duty cycle power
if( ret > 3191 ) ret = 3191; //set a maximum pulse wdith here for your cpu speed
//now decide on a frequcny basis is this is a shot time..
Counter += Freq;
if( Counter >= basefrequency )
{
Counter -= basefrequency;
//if( SpindleOn && FireCount > 2000 ) FireCount = 2000;
if( FireCount != 5000) FireCount--;
if( FireCount <= 0 ) FIRE = false;
}
else
ret = OneMicro;
}
if( ret < OneMicro ) ret = OneMicro; //no msaller than 1 microsecnd
return ret;
}
//display the text
///// Text Blockout
////////////////////////
// Pwr //
//Frq-hz 100 Pulses //
// 5000 <---> 5000 //
////////////////////////
//void SetDisplay( bool clear )
//{
// if( clear )
// {
// lcd.clear(); //x,y
// lcd.setCursor(8, 0);
// lcd.print("Pwr");
// lcd.setCursor(0, 1);
// lcd.print("Frq-hz");
// lcd.setCursor(14,1);
// lcd.print("Pulses");
// }
// static int8_t slw = 0;
// slw++;
// if( slw % 8 )
// if( SpindleOn && OpMode == CNCMODE ) //display of remote power setting..
// {
// lcd.setCursor(11, 0);
// lcd.print("-Rem:");
// lcd.setCursor(16, 0);
// lcd.print(" ");
// lcd.setCursor(16, 0);
// lcd.print(PWMPower,10);
// }
// else
// if( OpMode == NGRAVE )
// {
// lcd.setCursor(11, 0);
// lcd.print("-Rem:");
// lcd.setCursor(16, 0);
// lcd.print(" ");
// lcd.setCursor(16, 0);
// lcd.print(LastSerial,10);
// }
// else
// {
// lcd.setCursor(11, 0);
// lcd.print(" ");
// lcd.setCursor(16, 0);
// lcd.print(" ");
// }
//power
// lcd.setCursor(8,1);
// lcd.print( Power , 10 );
// lcd.print( "% " );
//frequency
// lcd.setCursor(3,3);
// lcd.print( Freq , 10 );
// lcd.print(" ");
//fire count
// lcd.setCursor(15,3);
// if( FireCount != 5000)
// {
// lcd.print( FireCount , 10 );
// lcd.print(" ");
// }
// else
// lcd.print(" CW ");
//and count mode
//lcd.setCursor(8,3);
// switch( CountMode )
// {
// case (0) :
// lcd.print("<<---");
// break;
// case (1) :
// lcd.print(" ^^^ ");
// break;
// case (2) :
// lcd.print("--->>");
// break;
// }
//static int toggle = 0;
// static bool twinkle = true;
// toggle++;
// if( toggle > 20 )
// {
// toggle = 0;
// twinkle = !twinkle;
// lcd.setCursor( 0,4 );
// if( twinkle ) lcd.print("*");
// else lcd.print("#");
// }
//erase the mopde line..
// lcd.setCursor( 0,2 );
// lcd.print(" ");
// if( SpindleOn && OpMode == DIAGS)
// OpMode = CNCMODE; //auto switch from Diags
// switch (OpMode)
// {
// case(0):
// lcd.setCursor( 8,2 );
// lcd.print("Diag");
// break;
// case(1):
// lcd.setCursor( 7,2 );
// lcd.print("CNC-CW");
// break;
// case(2):
// lcd.setCursor( 7,2 );
// lcd.print("NGRAVE");
// break;
//}
//}
//helper functions
void FlashFire()
{
static int8_t Flashtime = 0;
static bool fireledstate;
if( FireCount == 0 )
fireledstate = false;
if( Flashtime++ > 10 ) //this 10 should be change for a pleasant flash tempo..
{
digitalWrite( FireLED, fireledstate );
fireledstate = !fireledstate;
Flashtime = 0;
}
}
//flash the board led to show we're alive
void HeartBeat()
{
static int8_t Beat = 0;
static bool beatstate;
if( FireCount != 0 ) return;
if( Beat++ > 10 ) //this 10 should be change for a pleasant flash tempo..
{
//digitalWrite( BoardLED, beatstate );
beatstate = !beatstate;
Beat = 0;
}
}
//watchdog function, kill laser power if tickle stops..
//or other checks all of which can be put here..
void WatchDog()
{
static int lastcnt = cnt; //activity monitor
if( lastcnt != cnt ) Tickle = true;
else Tickle = false;
lastcnt = cnt;
//set other checks here... too long a shot maybe...
if( !Tickle )
{
PowerOn = false;
digitalWrite( PowerLED, PowerOn); //turn off led for power at start
}
}
//use of the pot for duty or frequency.
void PotControl()
{
int32_t val = analogRead( Pot + 2 ); //the analogue for the pot pin
if( PotMode == 0 ) // duty cycle.. only mode at present..
{
Power = val / 10.23;
if( Power < 1 ) Power = 1;
if( Power > 100) Power = 100;
Power = 101 - Power;
}
}
//diags text for testing and debugging..
void DiagsOut()
{
//just for testing pins..
return; //only use if we demand it in setup..
int16_t d1 = 0, d2 = 0, d3 = 0;
if( cnt > 2000)
{
cnt = 0;
d1 = analogRead(Pot + 2);
d2 = analogRead(8);
d3 = analogRead(10);
//Console.print("pins 6,8,10 --- " );
//Console.print(" ");
// Console.print( d1 );
//Console.print(" ");
//Console.print( d2 );
//Console.print(" ");
//Console.print( d3 );
//Console.print(" ");
//Console.print( CurButton );
//Console.println();
}
}
//figure out a button press, only one button
//at any time with noise rejection. This uses 2 analogue pins
//which multiplexes many buttons on each pin.
void GetButton()
{
int8_t setbounce = 4; //set a debounce here..
static int8_t debounce = setbounce;
static int8_t LastButton = 0;
int8_t thisbut = 0;
int16_t val = analogRead(Buttons); //fire,reload and laser
if( val < 900 )
{
thisbut = 3 - (val >> 8);
}
val = analogRead(Buttons1); //ok, read the fire buttons then..
if( val < 900 )
{
//figure out the button in the fire group
thisbut = (val >> 8) + 4;
}
if( LastButton == thisbut ) debounce--;
else debounce = setbounce;
if( debounce == 0 )
{
CurButton = thisbut;
debounce = setbounce;
}
if( WaitButtonZero && CurButton == 0)
WaitButtonZero = false;
LastButton = thisbut;
}
//make the frerq and count registers count by button.
//this gets called at timer reset time..
ISR(TIMER1_OVF_vect)
{
cnt++;
Duty = FireLaser(); //find the next power level..
OCR1A = Duty;
}
//these three interrupts are for step/dir and spindle pwm.
//used as direct vectors to get the speed required..
//this interrupt is for the step pulses..any step pulses, to
//set a firepulse..
ISR(INT0_vect)
{
//step interrupt...very fast
//if( (OpMode != DIAGS && SpindleOn))
{
FireCount = ReLoad;
FIRE = true;
}
}
//this is for recieving serial data power
//for 16 slice sequences.
ISR(INT1_vect)
{
//count the X steps as well for future use
if( PINB & ( 1 << 7))
SerialIn |= 0x8000;
if( (SerialIn & 0xf00f ) == 0xf00f)
{
// LastSerial = SerialIn & 0x0ff0;
LastSerial = (SerialIn >> 4) & 0xff;
SerialIn = 0;
if( LastSerial < 100 )
{
static unsigned short prev = 0;
if( prev == LastSerial ) //must be a repeated power..
PWMPower = LastSerial;
prev = LastSerial;
}
SerialIn = SerialIn >> 1; //we got a clock, so shift it..
}
}
Re: Arduino based Laser Control
Hi DanL:
Wow, nice diode. Being blue it could also harden oxalic acid infused fibreglass resin ... nice thing to play with..
Schematic looks like it could be used, take not of just how important cooling is with such devices, I have a few lower
power ones that I run for small periods at times and cooling is really very very important as you get up to 2 watts. A blue 2 watt is quite powerfull really, be interesting to see how you make out..
Id change the line in the code at
pwmWrite( PulsePin, 8); //set for 1us for laser tickle
to 0, as you dont want 1us tickles, you want 0us as a tickle and only want the
PWM to be on when the laser is. Set the variable OneMicro to 0 as well, it defines the PWM timer's
one microsecond setting. That will then make the laser only fire when given a power from Dariwn greater
than 0%. Probably take some fudging about in the rest of the code but those two changes should
make it run as youd expect, making the PWM really into a TTL trigger in PWM form..
Ill be interested in how you make out, feel free to ask questions if you run into trouble
as you test. Hard to say without testing what trouble youll run into , youll probably want
to use some sort of console messaging for feedback to tell you whats up during testing...
Art
Wow, nice diode. Being blue it could also harden oxalic acid infused fibreglass resin ... nice thing to play with..
Schematic looks like it could be used, take not of just how important cooling is with such devices, I have a few lower
power ones that I run for small periods at times and cooling is really very very important as you get up to 2 watts. A blue 2 watt is quite powerfull really, be interesting to see how you make out..
Id change the line in the code at
pwmWrite( PulsePin, 8); //set for 1us for laser tickle
to 0, as you dont want 1us tickles, you want 0us as a tickle and only want the
PWM to be on when the laser is. Set the variable OneMicro to 0 as well, it defines the PWM timer's
one microsecond setting. That will then make the laser only fire when given a power from Dariwn greater
than 0%. Probably take some fudging about in the rest of the code but those two changes should
make it run as youd expect, making the PWM really into a TTL trigger in PWM form..
Ill be interested in how you make out, feel free to ask questions if you run into trouble
as you test. Hard to say without testing what trouble youll run into , youll probably want
to use some sort of console messaging for feedback to tell you whats up during testing...
Art
-
- Old Timer
- Posts: 152
- Joined: Sat Jun 02, 2012 5:45 am
Re: Arduino based Laser Control
the datasheet for a LT1121 indicates ~ max output current is 150 mA (0.15 amps) that won't even warm up a 2w laser .
-
- Old Timer
- Posts: 152
- Joined: Sat Jun 02, 2012 5:45 am
Re: Arduino based Laser Control
Good point... 150ma wont cut it..
Art
Art
Re: Arduino based Laser Control
I will bring the console back in, its like that as arduino ide went mental yesterday I had to delete all the copy's and temp files to do with this, that's the copy I am using for porting over to Ti`s ide I am striping it back in the arduino ide so when I know its working properly with arduino I will move it over and change it to work with TI`s MSP430 boards then do it again to there C2000 boards.
Ill will be making a head for the laser to go into so I can run air through it so it keeps the smoke away from the lens and cools it at the same time, it will be a pieces of bronze what I will cut fins into it and fit it into a aluminium block what I more than likely will add a fan onto it as-well. or run water though it or forced air.
the forced air idea comes from a diy mister I made for my big router, when I run water though it the temp of the housing drop by quite a bit
I have a big computer coiling fan and block what I will be using to keep the driver cool.
quite a few of the parts I will be using are recycled from computers and a machinists junk box I was given what had quite a few good bits of metals in it.
Ill will be making a head for the laser to go into so I can run air through it so it keeps the smoke away from the lens and cools it at the same time, it will be a pieces of bronze what I will cut fins into it and fit it into a aluminium block what I more than likely will add a fan onto it as-well. or run water though it or forced air.
the forced air idea comes from a diy mister I made for my big router, when I run water though it the temp of the housing drop by quite a bit
I have a big computer coiling fan and block what I will be using to keep the driver cool.
quite a few of the parts I will be using are recycled from computers and a machinists junk box I was given what had quite a few good bits of metals in it.
Re: Arduino based Laser Control
I know its not enough to run a 2W laser that's why I said I can get a 2W+ driver its just checking the circuit is correct to use with this project. or I might use a LT1764A - 3A, Fast Transient Response, Low Noise, LDO Regulators or the Ti equivalent.
or just buy something that will work
or just buy something that will work
Re: Arduino based Laser Control
Hi Dan,
A group of us have been working with diode lasers for some time now and something you may wish to consider is fitting a Lasorb (or similar) across your laser diode terminals. When you consider the cost of replacing the diode these little devices are a pretty good insurance policy against the unexpected. http://www.lasorb.com
Tweakie.
A group of us have been working with diode lasers for some time now and something you may wish to consider is fitting a Lasorb (or similar) across your laser diode terminals. When you consider the cost of replacing the diode these little devices are a pretty good insurance policy against the unexpected. http://www.lasorb.com
Tweakie.
Re: Arduino based Laser Control
Tweakie:
Thx, I hadnt heard of those... happy to read up on that one..
Art
Thx, I hadnt heard of those... happy to read up on that one..
Art
Who is online
Users browsing this forum: No registered users and 32 guests