Arduino based Laser Control

A forum for the Arduino based Mach4/Darwin Laser Control Panel
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

I found a mistake may be it is here

int8_t  PulsePin = 9;         //Pin 9 will control the laser.

then you have  

pwmWrite( PulsePin, 8); //set for 1us for laser tickle,  should this be pin 9 not pin 8 what is a button pin
 if( timeron ) //if the timercall worked..

but you have
//int8_t  Buttons  = 8;        //analogue and digital are same numbers..be carefull if you use other pins..

correct me if wrong have not be able to do machine running test still waiting for parts from 500 km away, stuff from china bet it here ordered last week


also if some one wont to run a small screen a 1 x 20 or a 2 x 20 only they will have to work out how to change the screen button settings to do the different laser setting as if you disconnect the 3 buttons pin 10, the 4 buttons pin 8 will do what the 3 buttons do and and the same happens the other way around don't know why this happens but does.

its not a problem for be as I am using a 4 x 20 screen

I have set up a 2 x 20 screen so I can do some testing to the 4 X 20 turns up

it seems to be working ok with all buttons, pot and 2 x 20 screen connected with serial commented out.

some one could use serial with one comment only as that has about a 10 ms differences to it not commented out. the scope I am using is not that grate so it could be more or less. I need to get a decent one one day


that's about all for today's testing
Last edited by DanL on Wed Oct 29, 2014 11:19 pm, edited 1 time in total.
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4586
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

Hi DanL:

>>I found a mistake may be it is here
>>int8_t  PulsePin = 9;        //Pin 9 will control the laser.
>>then you have 
>>pwmWrite( PulsePin, Cool; //set for 1us for laser tickle,  should this be pin 9 not pin 8 what is a button pin

            Looks like Pin9 to me.? The 8 above is just the bit size.. Pin8 is buttons..Pin9 is pulse.. Pin 9 is the PWM pin..

>>t8_t  Buttons  = 8;        //analogue and digital are same numbers.. be carefull if you use other pins..

  That comment was a warniong to me that Arduino numbers pins a few ways. Pin 4 is digital for example but it also pin 6 if used for analog.

>>also if some one wont to run a small screen a 1 x 20 or a 2 x 20 only they will have to work out how to change the screen button settings to do the different laser setting as if you disconnec t the 3 buttons pin 10, the 4 buttons pin 8 will do what the 3 buttons do and and the same happens the other way around don't know why this happens but does.

  I didnt know this, you mean disconnecting one butotn input screws the other? Must be my code.. I image the pins jump to fuill voltage and hoses the logic..


>>it seems to be working ok with all buttons, pot and 2 x 20 screen connected with serial commented out.

Excellent. :)


Good luck
Art
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

yes if one button is disconnected it makes the other buttons work wrong.

yes its the code, it does not matter if using all the switches

if using same set up as you its not a problem. its a good way to tall if any of the buttons don't work.

I have added a serial section in the code for using when connected everything up to check that all buttons, pot and leds are working ok. rejig of console
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

hi all have been doing some more playing I have found you cant have serial.print running in the code if you use a screen you have to have one or the other.

I have changed the code a little, I have removed all the yun parts from the code it still runs fine.

added a serial.print section for checking that the buttons and pot work and what order they are in, has to be commented out when using a screen

one problem you get with serial running buttons change order by there self at any random time.

I have got everything connected with out a laser using a led to see if the output is working properly.

on a side note you can test the outputs in Darwin after the run time has expired but no motor movement
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4586
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

Hi Dan:

I knew the serial could interfere.. I find now with the latest version I can engrave at about 9000mm/min with no real noise issues, so
mine is working better all the time.. I guess next time Ill have to use a processor with more oomph...

Art
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

yer a faster board will be a full rewrite had a look at doing at my self but its way above what I can do at this time its bad enough trying to work out Lua
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

hi all I think I have everything working have not connected a laser up yet just using a arduino Oscilloscope it seems to be working ok.

I have added my version of the code it has a couple of different bits in for testing only they are commented where they are.

don't use serial when using for laser work it makes it go mad testing only.

if anyone makes changes please re name or change the T1 to T2 or whatever


Code: Select all

//Arts_laser_control_Leonardo_T1
#include <Wire.h>
#include <LiquidCrystal.h>
#include <PWM.h>

//Setup for Diags..
#define DIAGS&nbsp;  0
#define CNCMODE 1
#define NGRAVE&nbsp; 2
 
//frequency and pins used.
int32_t basefrequency = 5000; //5khz base freq
int8_t&nbsp; PulsePin = 9;&nbsp; &nbsp; &nbsp; &nbsp;  //Pin 9 will control the laser. 
int8_t&nbsp; BoardLED = 13;
int8_t&nbsp; FireLED&nbsp; = 12;
int8_t&nbsp; PowerLED&nbsp; = 5;
int8_t&nbsp; Pot&nbsp; = 4;
int8_t&nbsp; Buttons&nbsp; = 8;&nbsp; &nbsp; &nbsp; &nbsp; //analogue and digital are same numbers..be carefull if you use other pins..
int8_t&nbsp; Buttons1 = 10;
int8_t&nbsp; CurButton = 0;&nbsp; &nbsp; &nbsp;  //currently pressed button
int8_t&nbsp; CountMode = 0;&nbsp; &nbsp; &nbsp;  //the mode of the up/down counter..
bool&nbsp; &nbsp; WaitButtonZero = false;
int8_t&nbsp; OneMicro = 0;
int8_t&nbsp; Spindle = 6; //interrupt, its on pin7
int8_t&nbsp; 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..

volatile unsigned int OutPower[101];

//vars for control
bool&nbsp; &nbsp; &nbsp; PowerOn = false;
bool&nbsp; &nbsp; &nbsp; 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;&nbsp; //this is a global interrupt counter..
volatile bool FIRE = false;

//initialize the lcd..its on a0-a6 lines in my leonardo..
LiquidCrystal&nbsp; lcd( 23,22,21,20,19,18);&nbsp; // set the LCD address to 0x27 for a 20 chars and 4 line display

// the main control variable for diags mode..
int16_t&nbsp;  Power =&nbsp; 50; //0 - 100%
unsigned long&nbsp; PWMPower = 0;//0- 100% for the incoming PWM..
int16_t&nbsp;  Freq = 5000; // frequency of pulses..
int8_t&nbsp; &nbsp; PotMode = 0;

volatile int32_t&nbsp;  FireCount = 0;&nbsp;  //number of pulses to fire in diags 
volatile int16_t&nbsp;  ReLoad = 1;

void setup()&nbsp;  
{
&nbsp; ///////////////////////////////////////////////////////////
&nbsp; //serial for testing switches comment out when not used
&nbsp; 
&nbsp; //Serial.begin (1200); 
 // while the serial stream is not open, do nothing
&nbsp; //while (!Serial);
&nbsp; lcd.begin(20,4); // initialize the lcd 
&nbsp; lcd.setCursor(3,0);&nbsp;  lcd.print("Gearotic Laser");
&nbsp; lcd.setCursor(0,2);&nbsp;  lcd.print("Waiting for Unix.");
 
&nbsp; InitTimers();&nbsp; &nbsp; //start up the timers.
&nbsp; bool timeron = SetPinFrequency( PulsePin, basefrequency ); //set pulsepin to 5Khz
&nbsp; TIMSK1 |= (1 << TOIE1);&nbsp; // enable timer overflow interrupt, we'll use this one for fastpwm
&nbsp;  
&nbsp; attachInterrupt( 0, DUMMY, RISING ); //pulse external monitor 
&nbsp; attachInterrupt( 4, DUMMY, CHANGE ); //sets the routine to call..&nbsp; &nbsp; 

&nbsp; pwmWrite( PulsePin, 0); //set for 1us for laser tickle 
&nbsp; if( timeron ) //if the timercall worked..
&nbsp; {
&nbsp; &nbsp; pinMode( BoardLED, INPUT); // board led life
	pinMode( FireLED,&nbsp; OUTPUT); // fire button led
	pinMode( PowerLED, OUTPUT); //power control led & control

	pinMode( 2,&nbsp;  INPUT); //inputs from breakout board
	digitalWrite( 2, LOW );

	pinMode( 3,&nbsp;  INPUT); //inputs from breakout board
	digitalWrite( 3, LOW );

	pinMode( 11,&nbsp; &nbsp; INPUT); //inputs from breakout board
	digitalWrite( 11, HIGH );

	pinMode( 6,&nbsp; &nbsp; INPUT); //inputs from breakout board
	digitalWrite( 6, HIGH );

	pinMode( Spindle, INPUT); //inputs from breakout board

	 
	digitalWrite( PowerLED, PowerOn); //turn off led for power at start
	pinMode( Pot, INPUT); //pot for variable control
&nbsp; &nbsp; digitalWrite(4, HIGH); //set for a pullup resistor
	pinMode( Buttons, INPUT); //Jog buttons as analogue input
&nbsp; &nbsp; digitalWrite(Buttons, HIGH); 
	pinMode( Buttons1, INPUT); //Rest of buttons
	digitalWrite(Buttons1, HIGH); 
 
&nbsp; } 
&nbsp; SetDisplay( true ); //and draw the display mask
 
}

//main idle loop..

void loop() 
{
 /* 
&nbsp; //diags text for testing and debugging..
&nbsp; //uses if only needed comment out if not used

&nbsp; int16_t&nbsp; d1 = 0, d2 = 0, d3 = 0;
&nbsp; if( cnt > 2000)
&nbsp; {
&nbsp; &nbsp;  cnt = 0;
&nbsp; &nbsp;  d1 = analogRead(Pot + 2);
	 d2 = analogRead(8);
	 d3 = analogRead(10);

&nbsp; &nbsp; Serial.print("pin 6,8,10" );
	Serial.print(" "); 
	Serial.print( d1 );
	Serial.print(" "); 
	Serial.print( d2 );
	Serial.print(" "); 
	Serial.print( d3 );
	Serial.print(" "); 
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print("current button");
	Serial.print(" ");
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( CurButton );
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print(" ");
&nbsp; &nbsp; &nbsp; &nbsp; Serial.println();
&nbsp;  
 /////////////////////////////////////////////////////////////////////////////////
&nbsp;  // /*pwm power to serial monitor use for setting pwm power
&nbsp; &nbsp; &nbsp; //comment out if not needed 
&nbsp; &nbsp; 
&nbsp; &nbsp; 
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print("pwm");
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print(" ");
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print( PWMPower );
&nbsp; &nbsp; &nbsp; &nbsp; Serial.print(" ");
	Serial.println();&nbsp; 
&nbsp; }
*/
////////////////////////////////////////////////////////////////////////////
 
&nbsp; HeartBeat(); //flash the board led if fire isnt flashing..
&nbsp; FlashFire(); // flash the fire button if we are going to fire..
&nbsp; WatchDog();&nbsp; // ensure all is safe.
&nbsp; //DiagsOut();&nbsp; //display test text if demanded..not used
&nbsp; PotControl(); //use the pot for values..
&nbsp; GetButton();&nbsp;  
&nbsp; if( OpMode == CNCMODE) SpindleCalc(); //only for CNC cut/profile op's..
&nbsp; if( OpMode == DIAGS )&nbsp; DiagFire();
&nbsp; //if( OpMode == NGRAVE)&nbsp; NGraveFire();
&nbsp; LaserOnOff();
&nbsp; DoButtonCount();&nbsp; // make freq or firecount set by button if needed.
&nbsp; //set power and other vars, then display..
&nbsp; SetDisplay( false );
}

void DoButtonCount()
{
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int8_t&nbsp;  Accel = 1; //this is the accel of button freq, adjust as needed.
&nbsp;  static&nbsp;  int16_t&nbsp; Adder = Accel;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int16_t&nbsp; Freqmax&nbsp; = 200;
&nbsp;  static&nbsp;  int32_t&nbsp; Bres = Freqmax;&nbsp; 
&nbsp;  if( CurButton == 0)
&nbsp;  {
&nbsp; &nbsp; &nbsp;  Adder = Accel;
&nbsp; &nbsp; &nbsp;  Bres = Freqmax; 
	&nbsp;  return;
&nbsp;  }
&nbsp;  int16_t oldfire = FireCount;
&nbsp;  Bres += Adder;
&nbsp;  while( Bres > Freqmax ) //not very ellegant, fix later. just a timer for easier button press
&nbsp;  {
	&nbsp;  if( CurButton == 4 ) //left arrow, switch pot to count mode..
&nbsp; 	&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CountMode--;
	&nbsp;  if( CurButton == 6 ) //left arrow, switch pot to dutycyle..
&nbsp; 	&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CountMode++;
&nbsp; &nbsp; &nbsp;  if( CountMode < 0) CountMode = 2; 
&nbsp; &nbsp; &nbsp;  if( CountMode > 2) CountMode = 0;

	&nbsp;  Bres -= Freqmax;
	&nbsp;  if( CountMode == 0&nbsp; && CurButton == 5) Freq++;
&nbsp; &nbsp; &nbsp;  if( CountMode == 2&nbsp; && CurButton == 5) FireCount++;
&nbsp; &nbsp; &nbsp;  if( CountMode == 0&nbsp; && CurButton == 7) Freq--;
&nbsp; &nbsp; &nbsp;  if( CountMode == 2&nbsp; && CurButton == 7) FireCount--;
	&nbsp;  if( FireCount < 0 ) FireCount = 5000;
	&nbsp;  if( FireCount >&nbsp; 5000 ) FireCount = 0;
	&nbsp;  if( Freq <= 0 ) Freq = 1;
	&nbsp;  if( Freq > 5000 ) Freq = 5000;
	&nbsp;  int oldop = OpMode;
	&nbsp;  if( CountMode == 1 && CurButton == 5 ) OpMode++;
&nbsp; &nbsp; &nbsp;  if( CountMode == 1 && CurButton == 7 ) OpMode--;
	&nbsp;  if( OpMode > 2 ) OpMode = 0; //these two lines just make the opMode toggle up or down..
&nbsp; &nbsp; &nbsp;  if( OpMode < 0 ) OpMode = 2;

	&nbsp;  //reopen file if required.
	&nbsp;  if( OpMode == NGRAVE && oldop != NGRAVE)
	&nbsp; &nbsp;  {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  //detach the spindle interrupts.
		&nbsp;  detachInterrupt(4);
		&nbsp;  attachInterrupt( 1, DUMMY, RISING ); //reattach the spindle interrupt
		&nbsp;  
	&nbsp; &nbsp;  }
		 if( OpMode != NGRAVE && oldop == NGRAVE )
		 {
		&nbsp; &nbsp; attachInterrupt( 4, DUMMY, CHANGE ); //reattach the spindle interrupt
			detachInterrupt(1);
		 }
	&nbsp;  

&nbsp;  }
&nbsp;  if( oldfire != FireCount ) ReLoad = FireCount;
&nbsp;  Adder += Accel;
&nbsp;  //faster..damnit..faster. :)
&nbsp;  if( Adder == 100 )&nbsp;  Adder *= 2;
&nbsp;  if( Adder == 400)&nbsp; &nbsp; Adder *= 2;
&nbsp; &nbsp; if( Adder == 1000)&nbsp; Adder *= 2;
}

void DiagFire()
{
&nbsp; if( CurButton == 2 ) FireCount = ReLoad;
&nbsp; //FIRE!!!!
&nbsp; if( CurButton == 1 && FireCount > 0 ) FIRE = true;
&nbsp; if( CurButton == 0 && FIRE && OpMode == DIAGS ) FIRE = false; //turn it off if no button is pressed in Diags mode.
}


void SpindleCalc()
{
	if( OpMode == NGRAVE )
		return;
	if( !SpindleOn ) return;

	if( cnt - SpinOffCnt > 225 ) 
	{
		SpindleOn = false; //turn it off.
		PWMPower = 0;
		return;
	}
	if( SpinOffCnt < SpinOnCnt )
	{ //probably a on/off spindle control
		if( PWMPower == 0 ) PWMPower = Power;
&nbsp; 	&nbsp; &nbsp; return;
	}
	int per = SpinOffCnt - SpinOnCnt;

&nbsp; &nbsp; static int xc = 0;
	static int yc = 0;
	static int lastpwm = 0;
	 
	if( per > 98 ) per = 98;
	if( per < 5 ) per = 5;
	PWMPower = per;

	//switch to base pot power
&nbsp; &nbsp; if( (cnt - SpinOnCnt) > 130&nbsp; && digitalRead(7) )
&nbsp; 	&nbsp; &nbsp; PWMPower = Power; //looks like no pwm, just a spindle on command
&nbsp; &nbsp; if( (cnt - SpinOffCnt) > 130&nbsp; && !digitalRead(7) )
 	&nbsp; &nbsp; SpindleOn = false; //looks like no pwm, just a spindle on command

}

void LaserOnOff()
{
&nbsp; //this controls Laser ON/OFF
&nbsp; if( CurButton == 3 ) //power call , but only once per press
&nbsp; { 
	if( !WaitButtonZero) PowerOn = !PowerOn; 
&nbsp; &nbsp; digitalWrite( PowerLED, PowerOn); //Set Power condition;
&nbsp; &nbsp; WaitButtonZero = true;
&nbsp; }

}


void DUMMY()
{
&nbsp; 
}

int16_t FireLaser()
{
	int16_t ret = OneMicro; //usually we'll return 1 microsecond.
	static int16_t Counter = basefrequency;
	if( FIRE )
	{&nbsp;  
		if( OpMode == DIAGS )
		&nbsp; ret = Power << 5; //we'll return this pot power only if the counter says so..
		else
&nbsp; &nbsp; &nbsp; &nbsp; if( OpMode == CNCMODE )
		&nbsp; ret = PWMPower;
		else 
		&nbsp; ret =&nbsp; OutPower[PWMPower]; //in NGrave mode we return the duty cycle power, or ngrave 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..
&nbsp; &nbsp; &nbsp; &nbsp; Counter += Freq;
		if( Counter >= basefrequency )
		{
			Counter -= basefrequency;
			if( SpindleOn && FireCount > 2000 ) FireCount = 2000;
&nbsp; &nbsp; 	&nbsp; &nbsp; if( FireCount != 5000) FireCount--;
		&nbsp; &nbsp; if( FireCount <= 0 ) FIRE = false;
		}
		else
			ret = OneMicro;
	
	}
	if( ret < OneMicro ) ret = OneMicro; //no msaller than 1 microsecnd
	return ret;
}
///*
///////////////////////////////////////////////////////////////////////////////////////////////////
//display the text
/////&nbsp; Text Blockout

////////////////////////
//&nbsp; &nbsp; &nbsp; &nbsp; Pwr&nbsp; &nbsp; &nbsp; &nbsp;  //
//Frq-hz&nbsp; 100&nbsp; Pulses //
//&nbsp; 5000 <--->&nbsp; 5000&nbsp; //
////////////////////////
void SetDisplay( bool clear )
{
&nbsp; if( clear ) 
&nbsp; {
	&nbsp; lcd.clear(); //x,y
	&nbsp; lcd.setCursor(8, 0);&nbsp; &nbsp; lcd.print("Pwr");
	&nbsp; lcd.setCursor(0, 1);&nbsp; &nbsp; lcd.print("Frq-hz");
	&nbsp; lcd.setCursor(14,1);&nbsp; &nbsp; lcd.print("Pulses");
 }
&nbsp; static int8_t slw = 0;
&nbsp; slw++;
&nbsp; if( slw % 8 )
&nbsp; if( SpindleOn && OpMode == CNCMODE ) //display of remote power setting..
&nbsp; {
	&nbsp; lcd.setCursor(11, 0);&nbsp; &nbsp; lcd.print("-Rem:");
	&nbsp; lcd.setCursor(16, 0);&nbsp; &nbsp; lcd.print("&nbsp; &nbsp;  ");
	&nbsp; lcd.setCursor(16, 0);&nbsp; &nbsp; lcd.print(PWMPower,10);
&nbsp; }
&nbsp; else
&nbsp; if( OpMode == NGRAVE )
&nbsp; {
&nbsp; &nbsp; &nbsp; lcd.setCursor(11, 0);&nbsp; &nbsp; lcd.print("-Rem:");
	&nbsp; lcd.setCursor(16, 0);&nbsp; &nbsp; lcd.print("&nbsp; &nbsp;  ");
	&nbsp; lcd.setCursor(16, 0);&nbsp; &nbsp; lcd.print(LastSerial,10);
&nbsp; }
&nbsp; else
&nbsp; {&nbsp;  
	&nbsp; lcd.setCursor(11, 0);&nbsp;  
&nbsp; &nbsp; &nbsp; lcd.print("&nbsp; &nbsp; &nbsp; &nbsp; ");
&nbsp; &nbsp; &nbsp; lcd.setCursor(16, 0);&nbsp;  
	&nbsp; lcd.print("&nbsp; &nbsp;  ");
&nbsp; }


&nbsp; //power
&nbsp; lcd.setCursor(8,1);
&nbsp; lcd.print( Power , 10 );
&nbsp; lcd.print( "%&nbsp; " );
&nbsp; //frequency
&nbsp; lcd.setCursor(3,3);
&nbsp; lcd.print( Freq , 10 );&nbsp; &nbsp; &nbsp; lcd.print("&nbsp;  ");
&nbsp; //fire count
&nbsp; lcd.setCursor(15,3);

&nbsp; if( FireCount != 5000)
&nbsp; { lcd.print( FireCount , 10 ); lcd.print("&nbsp;  "); }
&nbsp; else
&nbsp; &nbsp;  lcd.print(" CW&nbsp;  ");
 
&nbsp; //and count mode
&nbsp; lcd.setCursor(8,3);
&nbsp; switch( CountMode )
&nbsp; {
&nbsp; case (0) : lcd.print("<<---"); break;
&nbsp; case (1) : lcd.print(" ^^^ "); break;
&nbsp; case (2) : lcd.print("--->>"); break;
&nbsp; }
&nbsp;  
&nbsp; static int toggle = 0;
&nbsp; static bool twinkle = true;
&nbsp; toggle++;
&nbsp; if( toggle > 20 )
&nbsp; {
	&nbsp; toggle = 0;
	&nbsp; twinkle = !twinkle;
	&nbsp; lcd.setCursor( 0,4 ); 
	&nbsp; if( twinkle ) lcd.print("*"); else lcd.print("#");
&nbsp; }

//erase the mopde line..
lcd.setCursor( 0,2 );
lcd.print("&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ");

if( SpindleOn && OpMode == DIAGS)
&nbsp;  OpMode = CNCMODE; //auto switch from Diags
 
&nbsp; switch (OpMode)
&nbsp; {
&nbsp;  case(0): lcd.setCursor( 8,2 );&nbsp; lcd.print("Diag"); break;
&nbsp;  case(1): lcd.setCursor( 7,2 ); lcd.print("CNC-CW"); break;
&nbsp;  case(2): lcd.setCursor( 7,2 ); lcd.print("NGRAVE"); break;
&nbsp; }
}

///////////////////////////////////////////////////////////////////////////////////////
//helper functions
 
void FlashFire() 
{
&nbsp; static int8_t Flashtime = 0;
&nbsp; static bool&nbsp;  fireledstate;
&nbsp; if( FireCount == 0 ) 
&nbsp; &nbsp; fireledstate = false;
&nbsp; if( Flashtime++ > 10 ) //this 10 should be change for a pleasant flash tempo..
&nbsp; {
	&nbsp; digitalWrite( FireLED, fireledstate ); 
	&nbsp; fireledstate = !fireledstate;
	&nbsp; Flashtime = 0;
&nbsp; }
}

//flash the board led to show we're alive
void HeartBeat() 
{
&nbsp; static int8_t Beat = 0;
&nbsp; static bool&nbsp;  beatstate;
&nbsp; if( FireCount != 0 ) return; 
 
&nbsp; if( Beat++ > 10 ) //this 10 should be change for a pleasant flash tempo..
&nbsp; {
	&nbsp; //digitalWrite( BoardLED, beatstate ); 
	&nbsp; beatstate = !beatstate;
	&nbsp; Beat&nbsp; = 0;
&nbsp; }
}

//watchdog function, kill laser power if tickle stops..
//or other checks all of which can be put here..
void WatchDog()
{
&nbsp; static int lastcnt = cnt; //activity monitor
&nbsp; if( lastcnt != cnt ) Tickle = true; else&nbsp; Tickle = false;
&nbsp; lastcnt = cnt;

&nbsp; //set other checks here... too long a shot maybe...

&nbsp; if( !Tickle )
&nbsp; {
	&nbsp; PowerOn = false;
	&nbsp; digitalWrite( PowerLED, PowerOn); //turn off led for power at start
&nbsp; }

}
//use of the pot for duty or frequency.
void PotControl()
{
&nbsp; &nbsp; int32_t val = analogRead( Pot + 2 ); //the analogue for the pot pin
&nbsp; &nbsp; static int32_t oldval = 0;
	//lets only&nbsp; update the power tables if the pot has changed by 2 minimum..
	if( PotMode == 0 && abs(oldval - val) > 2 ) // duty cycle.. only mode at present..
	{
&nbsp; &nbsp; &nbsp;  Power =&nbsp; val / 10.23;
	&nbsp;  if( Power < 1 ) Power = 1;
	&nbsp;  if( Power > 100) Power = 100;
	&nbsp;  Power = 101 - Power;
	&nbsp;  //fill power tables for NGraving
	&nbsp;  OutPower[ 0 ] = 0;
	&nbsp;  double scale = ((double)(31 * Power))/(double)100;
	&nbsp;  for( int x = 1; x <= 100; x++ )
	&nbsp;  {
		 OutPower[ x ] = (unsigned int) (scale * x);&nbsp;  
	&nbsp;  }
	}
}

//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()
{
&nbsp; int8_t setbounce = 4; //set a debounce here..
&nbsp; static int8_t debounce = setbounce;
&nbsp; static int8_t LastButton = 0;
&nbsp; int8_t thisbut = 0;

&nbsp; int16_t val = analogRead(Buttons); //fire,reload and laser
&nbsp; if( val < 900 )
&nbsp; {
&nbsp; &nbsp;  
	&nbsp; thisbut = 3 - (val >> 8);
&nbsp; }
&nbsp; val = analogRead(Buttons1); //ok, read the fire buttons then..
&nbsp; if( val < 900 )
&nbsp; {
&nbsp; &nbsp; &nbsp; //figure out the button in the fire group
	&nbsp; thisbut = (val >> 8) + 4;
&nbsp; }

&nbsp; if( LastButton == thisbut ) debounce--;
&nbsp; else&nbsp;  debounce = setbounce;&nbsp; &nbsp; 
&nbsp; if( debounce == 0 )
&nbsp; {
	 CurButton = thisbut;
&nbsp; &nbsp;  debounce = setbounce;
&nbsp; }

&nbsp; if( WaitButtonZero && CurButton == 0)
		 WaitButtonZero = false;

&nbsp; LastButton = thisbut;

}

//make the frerq and count registers count by button.

//this gets called at timer reset time..
ISR(TIMER1_OVF_vect)
{
&nbsp; cnt++;
&nbsp; Duty = FireLaser();&nbsp;  //find the next power level..&nbsp; &nbsp; 
&nbsp; OCR1A = Duty;&nbsp; &nbsp; &nbsp; &nbsp;  
}
 
//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) 
{
&nbsp; &nbsp; //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) 
{
&nbsp; &nbsp; 
	if( PINB & ( 1 << 7))
	&nbsp; &nbsp;  SerialIn |= 0x8000;
	if( (SerialIn & 0xf00f ) == 0xf00f)
	&nbsp; {
&nbsp; &nbsp; &nbsp;  // LastSerial = SerialIn & 0x0ff0;
	&nbsp;  LastSerial = (SerialIn >> 4) & 0xff;
	&nbsp;  SerialIn = 0;
	&nbsp;  if( LastSerial < 100 )
	&nbsp;  {
	&nbsp; &nbsp; &nbsp; static unsigned short prev = 0;
	&nbsp; &nbsp;  if( prev == LastSerial )&nbsp; //must be a repeated power..
	&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PWMPower = LastSerial;
	&nbsp; &nbsp; &nbsp; prev = LastSerial;
	&nbsp;  }
	&nbsp;  //control the spindle
	&nbsp;  if( PWMPower != 0 ) SpindleOn = true;
	&nbsp; &nbsp;  else SpindleOn = false;&nbsp; 
	&nbsp;  
	&nbsp; }
	SerialIn = SerialIn >>&nbsp; 1; //we got a clock, so shift it..
}

//and finally a pwm spindle interrupt, basically Reads incoming PWM signal at 50hz..
ISR(INT6_vect) 
{
	if( PINE & ( 1<<6))
	{
		SpinOnCnt = cnt;
		SpindleOn = true;
	}
	else
		SpinOffCnt = cnt;
	return;
 
}
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

Hi art just a couple of questions what Darwin signal do you set the pwm to is it all or just one

I have set

step flag to 25 Hz

serial data to 25Hz

serial clock to 25Hz

I am running it in PWM mode with 25 Hz as base freq

just making sure I am doing it correctly as I think I may have a problem with the switches or pot not to sure yet will be testing tomorrow.

I have a junk laser I am going to put on it to see what is happening as for some reason when in test mode I cant get the laser output to fire it will just be a setting the switches or pot playing up. when I was scoping it, it only went up to 3.8v. it also may be that I have a 10k pot on it not a 5k pot.will play with pot settings and see what is happens.
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4586
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

Hi Dan:

&nbsp; You can set all to zero for frequency, it shouldnt be used. The Stepflag signal pulses whenever a motor ( any motor ) steps. So just jogging
will show that signal toggle as a test. Serial data will be gogin out all the time when using Darwin in Laser mode. Serial clock will pulse at 40khz or whatever the maximum kernal rate is set to.

&nbsp; Step Flag is used all the time, you can use it in PWM mode as well as laser mode, it just means the laser will fire only
when moving. In the most recent Darwins it will fire only whiel moving in G1 mode, no other mode will fire. I like this as it makes
it all much safer and easier to deal with.

&nbsp; If you execute a G1X100 , does the laser PWM go higher than the 1us tickle.. and when it does, does the laser fire.. Thats the
thing that needs to be done... or figured out. :)

Art
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

its not doing anything no laser fire nothing
tried G1 x100 nothing tried with laser on an off

did a pick linked to Mach4 with M3 S1000 F600 nothing, M3 F600 S1000 nothing
put G1 X100 M3 S1000 F600 nothing, G1 X100 F600 M3 F600 nothing,

tried it in diag nothing.

tried setting the signals active low nothing.
I have set the 3 signals to output 0,1,2 in Mach4 the leds don`t light up on dig screen

any suggestions as what to do

I am wondering if its haveing a 10k pot not a 5k pot doing it will get a 5k and see what happens
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4586
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

Dan:

Whoa.. slow down. Lets find whats working and what isnt and go from there..

OK, first, does the diags mode work. The Diags mode will not laser no matter
what Mach4 is doing. It will laser only when you dial up a count, and press the fire button.
Counter should run to zero, laser fires until zero. Pressing reload will relaod last count and fire will
flash again ready for the next shot. Does that all work?

So, use the buttons to get a count of 1000 , then press fire ( which should be flashing.. ). Does the laser fire?
Lets make sure that works , then we'll go to stage 2 and get PWM laser from the device in CNC Mode... then finally we'll
get NGrave mode running that does photo's..

Art
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

diags mode works I could see a pwm signal on my arduino scope.

I think it is the switches I am using sometime I can`t get a reading from them.

I am using a mb06 v2 from Homann Designs as the bob to run the laser that's working ok

the Leonardo and screen are fine I have tested them.

I have some switches I can change to so I will do that and try again
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4586
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

Dan:

If Diag mode works, then its time for the CNC mode test.. in that you setup Mach4 for a pwm spindle.. 50hz and dont turn on laser. The laser should fire when a g1 move is done whlie the spindle is turned on and a SWord is set. By the way, for all uses of the laser in MAch4, you need to set the spindle range from 0 - 100, and the SWord to use then must be 0-100 for the desired power. Its made this way on all modes to make it easier to pick power.&nbsp; I think the next logical test to make is to see if we can get CNC mode working.. and debug it till we know why it isnt if it wont..

Art
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

that's what I was doing wrong I was turning the laser on so it would of been turning it off what a dork lol
I will test now

DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

tried but cant get it working in cnc mode.
tried doing a engrave did not seem to work ever

and diag mode does work I will play some more tommorow
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest