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 »

thanks art I will strip it today a run some ruff tests not connected to Darwin I am getting a bob tomorrow so I will test it over the next few days
It will take a couple of days.
I have some advertising work to do engraving a label on 40 pot holders boring as sin to do, 1 minute per cut 1 minute to change pot holders.
DanL
Old Timer
Posts: 362
Joined: Wed Sep 10, 2014 1:35 pm

Re: Arduino based Laser Control

Post by DanL »

Hi art an all I have removed all of the yun stuff, als I have got the board connected up to some switches an leds, with serial monitor for feed back it took a bits of mucking around to get the switch to work properly they do know.

everything seems to be working I will connect up to a bob and Darwin in the next few days.

I will repost the code when I have got everything working.
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4591
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

DanL:

  Excellent. Yell if and when you need help. My darwin is different from yours by a bit, the m4 guys need to fix licensing
before I can release it, as well as a new version since 2068 breaks all plugins again.. though Darwin is ready for 2068.

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

Re: Arduino based Laser Control

Post by DanL »

cool one thing I have found the serial monitor does not play well with 32u4 boards.

I have set the serial writes in the same place in the program so it will be easy to comment them out so when the switches are working you will just be left with pwm, what is ok if only one thing is running on the serial monitor
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4591
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

DanL:

  Yes, the timing as the panel is now is pretty critical, I limit myself to 30Khz for that reason.. I may have to update mine some day to a
arduino due at 80mhz to get the speed so I can go faster .. Serial monitor is a interrupt driven protocol in the end so it takes time
away from the system.  Its OK for testing and debugging, but youll want to stop all messages when your using it for the laser.. Its
one reaosn the lcd is not using a two wire interface.. the 6 wire one is faster cpu wise..

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

Re: Arduino based Laser Control

Post by DanL »

using the serial monitor for testing with only Serial.print( PWMPower );  it has a slight effect on speed, any more than that has a big effect I could see it on my arduino oscilloscope when just sending out a tickle it has a longer delay for lasing.

I have added in a pwm out put for a 1 x 20 or 1 x 16 screen it can be used with a 2 x as well other wise when testing and doing a job it will be a guess as to what to set it to with the serial monitor not used it will be enough of a differences that it not worth the effort to use the serial monitor.

so it needs to done with a screen unless some gets this working on a faster board.

I will play some more tomorrow and see what I can come up with.
User avatar
ArtF
Global Moderator
Global Moderator
Posts: 4591
Joined: Sun Sep 05, 2010 6:14 am
Contact:

Re: Arduino based Laser Control

Post by ArtF »

DanL:

  Way to go, experiment all you like and let us know what works and what doesnt. Once I release the
CAM module Ill be taking a coupel weeks break for debugging troubles and playing with laser routines while
I consider how to best do the 4th axis work..

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

Re: Arduino based Laser Control

Post by DanL »

will do
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: 4591
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: 4591
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;
 
}
Post Reply

Who is online

Users browsing this forum: No registered users and 36 guests