509,528 active members
4,796 visitors online
Register for free
Login
Page 30 of 34 202829303132
Results 349 to 360 of 397
  1. #349
    Registered
    Join Date
    May 2012
    Posts
    438

    Re: Adding a Tool Changer

    Hi Troy,

    Heres how it works on my Fadal. I have no orientation feature in the VFD. On my machine there is a hall effect sensor on the spindle that changes state when at orientate position. And there is a small air cylinder with a roller that fits in a notch on spindle at the orientate position.

    What I did was set the spindle turning very slow (you will need to override the commanded S value somehow), delay to be sure its up to constant speed, then wait for orientation signal, delay again until maybe another 3/4 of a rotation, and then I turn spindle off, turn air cylinder on, and with a little tuning of the delay and speed it will coast and stop right into the orientation notch for the air cylinder.

    This all worked really well, but my VFD is really old technology and has very noticeable cogging or fluctuations in rpm at low speed. So because of the variation in speed it occasionally misses (maybe 1 in 20 times). So I set my orientation command and toolchange program to make 3 attempts and this always works. I changed the code later to reset the spindle encoder count after reading the first orientation pulse, and measure rotation before shutting off spindle instead of delays. This gave me a small improvement but its a bit more work to setup.

    I attached my toolchange code, which also has the orientation code as well. Let me know if you have any questions. good luck with it.

    Mark

  2. #350
    Registered
    Join Date
    Jun 2004
    Posts
    344

    Re: Hurco BMC20 Dynomotion Retrofit

    I've attached the files from my little mill, which has a carousel changer rotated via a Geneva mechanism requiring two rotations between each pocket.

    The tool change code is based of one of the example files (I think it's the one for the wine rack changer, but I can't remember the file name), and makes extensive use of state machines.

    TriacTC.c contains the code that physically controls everything related to the tool changer. Everything happens using state machines, so the code should never block any other functions. It has the ServiceToolChanger() function, which gets called by the infinite loop in the TriacInit.c. (I'll also mention there is an infinite loop at the end of TriacTC, which I used for testing, as it meant I could edit/re-compile/download TriacTC without having to reinitialise the entire machine).

    TriacM6.c controls the flow for tool changes, ensuring things happen in the correct order.

    TriacTCInit.c handles initialising the tool changer. It checks things are where they should be, before asking the operator to confirm carousel location, and if there is a tool loaded in the spindle.


    When I first wrote the code, TriacTC handled the complete flow. TriacM6 simply started the process, however when it came to adding recovery/initialisation functionality, I realised it would make more sense to have each individual step, so I moved the flow control to TriacM6, and is why after each step in TriacTC, the TC state goes back to T_PAUSED (if successful, or T_FAILED if not successful), with only TriacM6 or TriacTCInit being able to set TC state back to TC_IDLE.
    Using this method, each individual control step of the tool changer can be commanded by any C program, so for example if I wanted to only rotate the carousel for tool loading, I can simply create a C program that sets the new carousel position, changes ChangerState to T_CRSLROTATE, then once ChangerState returns to TC_PAUSED, can set ChangerState back to TC_IDLE.

    It's worth noting the carousel position stored, is a multiple of 4, so I can track exactly where the carousel is. I.e. 4 is pocket position 1. 5 is the Geneva mechanism has moved of the index slot, 6 is on the index slot but the mid point between pockets 1 and 2, 7 is again of the index slot, and 8 is back on the index slot and at pocket 2.

  3. #351
    Junior Member
    Join Date
    Dec 2007
    Posts
    471

    Tool Changer Spindle Orientate

    Thanks guys,
    This is what i was looking for. Nice to see a working example.

    Got my VFD configured last night to use the Z phase of spindle encoder and use a parameter in VFD to orientate spindle from the Z phase location. I am activating this VFD function with a prox switch on spindle sensing a set screw. Does anyone know if a prox switch being used like this should be turned off when not being used? Because of the constant switching at high RPMs? Thinking the life would be very short if it was left on?

    Thanks,
    Troy
    http://www.homecncstuff.elementfx.com/

  4. #352
    Junior Member
    Join Date
    May 2006
    Posts
    3210

    Re: Hurco BMC20 Dynomotion Retrofit

    Hi Troy,

    If it is an inductive proximity sensor I think it should be basically a coil of wires with no moving parts and never wear out.
    TK
    http://dynomotion.com

  5. #353
    Junior Member
    Join Date
    Dec 2007
    Posts
    471

    Re: Hurco BMC20 Dynomotion Retrofit

    Got things mounted up and all is wired to Konnect and Kanalog.
    http://www.homecncstuff.elementfx.com/

  6. #354
    Junior Member
    Join Date
    Dec 2007
    Posts
    471

    Re: Hurco BMC20 Dynomotion Retrofit

    Already know i am going to need help with the C code, as this tool changer is like a whole machine by itself.
    The tool changer is a Geneva mechanism that holds 16 tools. Each rotation of motor is one tool position.

    This is my tool changer homing sequence.
    1.Konnect output to rotate Carousel CW.
    2.Konnect input from Carousel limit switch that indicates tool position 16.

    Here is my tool change sequence that i have so far.

    1. Z axis goes home.
    2.Spindle Off, then Spindle on at a low rpm of 25.
    3.Kanalog SW4 enabled to turn on Spindle Orientate Proximity sensor.
    4. KMCNC watches a Konnect input for Spindle Orientate Prox sensor then Konnect output to VFD input that zeros,orintates and holds spindle in position.
    5.KMCNC waits for 0 RPM and then delays a set amount of time to insure spindle is in position.
    6.Konnect output to OUT solenoid moves Carousel out.
    7.Konnect input from Carousel OUT limit switch.
    8. Konnect output to Tool Release Solenoid.
    9.Konnect input from Tool Release Proximity sensor and then delay to insure tool is released.
    10.Konnect output to DOWN solenoid lowering the Carousel.
    11. Konnect input from Carousel down limit switch.
    12.Konnect output to rotate Carousel CW or CCW.Which ever direction is closer to new tool.
    13.Konnect input of Carousel Proximity sensor that counts rotation of Carousel motor until desired tool is reached.
    14. After tool desired is reached delay a set amount of time and release CW or CCW Carousel rotation. The delay allows motor to rotate a little more,fully engaging the half circle in Geneva wheel, locking into position.
    15.Konnect output to UP solenoid, raising Carousel and new tool up to spindle.
    16. Konnect input from Carousel UP limit switch.
    17.Konnect output releases Tool Release Solenoid clamping drawbar onto new tool.
    18.Konnect input Tool Release proximity sensor switches off and delay to insure tool is clamped.
    19.Konnect ouput to IN solenoid,moving Carousel away from spindle.
    20. Konnect input from Carousel IN limit switch.

    And the part i fear the most...C code. Going to try and alter the C code examples and see how far i get.

    Troy
    http://www.homecncstuff.elementfx.com/

  7. #355
    Junior Member
    Join Date
    Dec 2007
    Posts
    471

    Re: Hurco BMC20 Dynomotion Retrofit

    Below is an edited version of mmurray's code, which iam sure i have missed something. Also,what all do i need to configure in KMCNC to use this code? And is there more code that needs to be added to my main INIT code?
    Troy

    Code:
    #include "KMotionDef.h"
    #define TMP 10 // which spare persist to use to transfer data
    #include "KflopToKMotionCNCFunctions.c"
    
    // Current tool = persist.UserData[157]
    // Requested tool = persist.UserData[6]
    
    
    
    main()
    {
    
    if (!ReadBit(137)) return 0;	// if in Estop, Exit program
    
    
    // Option to move table to front. Uncomment to move in Y.
    
    
    	//MoveAtVel(1, 1100000, 800000);
    	//while (!CheckDone(1)) WaitNextTimeSlice(); // wait until we are stopped
    
    
    // Wait until spindle is orientated, if started already by M100 in G code
    
    	while (persist.UserData[164] == 1) WaitNextTimeSlice(); // wait until orientated
    			
    
    
    // 1. Determine how many pockets to rotate
    
    	int pockets = persist.UserData[6] - persist.UserData[157]; // pockets = requested tool - current tool
    
    	if (pockets == 0) return 0;  // No toolchange needed, End
    	if (pockets >= 8) pockets = -16 + pockets; // If more then halfway CW, reverse
    	if (pockets <= -8) pockets = 16 + pockets; // If more then halfway CCW, reverse
    
    	
    	persist.UserData[161] = 1; // Toolchanger active disable feedhold button
    	ResumeCoordinatedMotion(); // Clear feedhold
    
    
    // 2. Turn off Flood Coolant if left on
    
    	int coolanton = 0;
    	if (ReadBit(157)) // if flood coolant on
    	{
    	coolanton = 1;  //  set variable to 1
    	ClearBit(157); // Flood coolant off
    	Delay_sec(.2); // delay
    	}
    
    // 3. Turn off spindle
    
    	if (ReadBit(147) || ReadBit(148)) //check if spindle is running forward or reverse
    	{
    	SetBit(147); // turn off spindle clockwise
    	SetBit(148); // turn off spindle counterclockwise
    	Delay_sec(1.6);
    	}
    
    
    
    // 4. Move to toolchange position Z0.000
       {
        MDI("G0 G53 Z-1.025");  // Move Z to -1.025inches from Reference Position
    	//MoveAtVel(2, 0, 800000);
    	//while (!CheckDone(2)) WaitNextTimeSlice(); // wait until we are stopped
       }
    
    // 5. Orientate
    	
    	
    	//if (!ReadBit(1045) || !ReadBit(63)) // if not orientated
    	//{
    		
    		
    		//if (ReadBit(63)) //check if locked and not orientated
    		//{
    			//ClearBit(63); // unlock
    			//Delay_sec(0.5);
    		//}
    	
    	
    		if (!ReadBit(1035)) // if toolchanger slide is not home estop
    		{
    			ClearBit(137); // E-stop
    			printf("E-stop Toolchanger not Home");
    		}
    		
    
    	
    		//if (ReadBit(156)) // If in high gear
    		{
    			persist.UserData[155] = 1; 		// Enable orientate speed override
    			SetBit(156);                    // Kanalog Switch4 to turn on SpindleOrientateProxSensor
    			Delay_sec(0.1);					// Delay 0.1s
                MDI("M03 S25");                 // set motor rpm 25
              //DAC(7,-43); 					// set motor rpm approx 100
    			SetBit(147); 					// spindle on		
    			Delay_sec(0.2);					// wait for spindle to reach speed	
    			while (!ReadBit(1038)) WaitNextTimeSlice(); 	// wait for SpindleOrientateProx signal
    			SetBit(48); 					// Signal to VFD, set VFD to ZeroServoCommand
    			Delay_sec(0.50); 				// Delay for spindle to stop at orientation that is set in VFD parameter
    		}
    
    		//if (ReadBit(157)) // If in low gear
    		{
    			//persist.UserData[155] = 1; 			// Enable orientate speed override
    			//Delay_sec(0.1);					// Delay 0.1s
    			//DAC(3,-76); 					// set motor rpm approx 100
    			//SetBit(154); 					// spindle on		
    			//Delay_sec(0.5);					// wait for spindle to reach speed	
    			//while (!ReadBit(1045)) WaitNextTimeSlice(); 	// wait for orientation signal
    			//Delay_sec(0.3); 				// Wait until past notch
    			//SetBit(63); 					// turn on orientation air cylinder
    			//Delay_sec(0.5); 				// Delay for spindle to stop at orientation notch
    			//ClearBit(154); 					// turn spindle off
    		
    
    		persist.UserData[155] = 0; // Spindle speed normal
    
    		Delay_sec(0.75); // wait before checking if successfull
    	}
    
    
    	while (!ReadBit(1038) || !ReadBit(63)) WaitNextTimeSlice(); // Wait if not Orientated
    	
    
    // 6. Tool Chnager OUT
    
    	SetBit(63);  // TC_OUT solenoid
    	Delay_sec(0.9);
    	ClearBit(63); //TC_OUT solenoid
    	double TF = Time_sec() + 2;  // timeout in 2 seconds
    
    	while (!ReadBit(1034)) // Wait for TC_OUT limit switch
    	{
    		WaitNextTimeSlice();			
    		
    		if (Time_sec() > TF)  // Timed out?
          		{
             		if (MsgBox("TC OUT Not Extended.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
                		{
                    		DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0; // toolchanger finished
                    		return 0;  //exit program
                		}
                		else
                		{
                    		TF = Time_sec() + 3;  // continue and timeout after 3 seconds
                		}			
            	}
    			
    	}
    
    
    // 7. Unclamp Tool
    
    	SetBit(59); //Tool Release Solenoid
    	
    	double TF = Time_sec() + 2;  // timeout in 2 seconds	
    
    	while (!ReadBit(1039)) // Wait for ToolReleaseProxSensor
    	{
    		WaitNextTimeSlice();			
    		
    		if (Time_sec() > TF)  // Timed out?
          		{
             		if (MsgBox("Tool Release Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
                		{
                    		DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0; // toolchanger finished
                    		return 0;  //exit program
                		}
                		else
                		{
                    		TF = Time_sec() + 3;  // continue and timeout after 3 seconds
                		}			
            	}
    			
    	}
    	
    
    // 8. Move Tool Changer DOWN
    
        SetBit(61); // TC_DOWN Solenoid
        Delay_sec(0.9);
    	ClearBit(61); //TC_DOWN solenoid
        
    	double TF = Time_sec() + 2;  // timeout in 2 seconds	
    
    	while (!ReadBit(1036)) // Wait for TC_DOWN Limit Switch
    	{
    		WaitNextTimeSlice();			
    		
    		if (Time_sec() > TF)  // Timed out?
          		{
             		if (MsgBox("TC DOWN Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
                		{
                    		DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0; // toolchanger finished
                    		return 0;  //exit program
                		}
                		else
                		{
                    		TF = Time_sec() + 3;  // continue and timeout after 3 seconds
                		}			
            	}
    			
    	}
    // 9. Rotate Carousel 
    
    	while (pockets >= 1) // Rotate Turret CW whatever number of pockets
    	{
    		SetBit(49); // TC Carousel Motor On	CW
    		while (!ReadBit(1033)) WaitNextTimeSlice(); // Wait for CarouselMotorProxSensor
    		Delay_sec(0.5);
    		ClearBit(49); // TC_Carousel CW Motor Off
    		Delay_sec(0.5);
    		pockets = pockets-1;
    	}
    
    	while (pockets <= -1) // Rotate Turret CCW whatever number of pockets
    	{
    		SetBit(50); // TC Carousel Motor On	CCW
    		while (!ReadBit(1033)) WaitNextTimeSlice(); // Wait for CarouselMotorProxSensor
    		Delay_sec(0.5);
    		ClearBit(50); // TC_Carousel CCW Motor Off
    		Delay_sec(0.5);
    		pockets = pockets+1;
    	}
    
    
    // 10. Move Tool Changer UP
    
    	SetBit(60); // TC_UP Solenoid
        Delay_sec(0.9);
    	ClearBit(60); //TC_UP solenoid
    	double TF = Time_sec() + 2;  // timeout in 2 seconds	
    
    	while (!ReadBit(1037)) // Wait for TC_UP Limit Switch
    	{
    		WaitNextTimeSlice();			
    		
    		if (Time_sec() > TF)  // Timed out?
          		{
             		if (MsgBox("TC UP Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
                		{
                    		DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0; // toolchanger finished
                    		return 0;  //exit program
                		}
                		else
                		{
                    		TF = Time_sec() + 3;  // continue and timeout after 3 seconds
                		}			
            	}
    			
    	}
    
    // 11. Clamp tool
    
    	ClearBit(59); //Tool Release Solenoid
    	
    	double TF = Time_sec() + 2;  // timeout in 2 seconds
    	
    	while (ReadBit(1039)) // Wait for Tool Release Proximity Sensor
    	{
    		WaitNextTimeSlice();			
    		
    		if (Time_sec() > TF)  // Timed out?
          		{
             		if (MsgBox("Tool Clamp Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
                		{
                    		DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0; // toolchanger finished
                    		return 0;  //exit program
                		}
                		else
                		{
                    		TF = Time_sec() + 3;  // continue and timeout after 3 seconds
                		}			
            	}
    			
    	}
    
    
    // 12. Tool Changer IN
    	SetBit(62);  // TC_IN solenoid
    	Delay_sec(0.7);	
    	ClearBit(62);  // TC_IN solenoid
    	
    
    	double TF = Time_sec() + 2;  // timeout in 2 seconds
    
    	while (!ReadBit(1035)) // Check TC_IN limit switch
    	{
    		WaitNextTimeSlice();			
    		
    		if (Time_sec() > TF)  // Timed out?
          		{
             		if (MsgBox("TC Not Home.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
                		{
                    		DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0; // toolchanger finished
                    		return 0;  //exit program
                		}
                		else
                		{
                    		TF = Time_sec() + 3;  // continue and timeout after 3 seconds
                		}			
            	}
    			
    	}
    
    
    
    // 13. Set Variables
    
    	persist.UserData[157] = persist.UserData[6]; // Update current tool number
    	persist.UserData[161] = 0; // toolchanger finished
    
    	printf("Tool changed to T%d\n", persist.UserData[157]);  // send message to console
    
    
    // 16. Write current tool # disk
    
    	FILE *f;
        	char s[256];
        	
        	float CTool = persist.UserData[157]; // s value from g code       
        	
        	f=fopen("c:\\KMotion Files\\KFlopData.txt","wt");
        	fprintf(s,"%f\n",CTool);
        	fclose(f);
    
    
    // 15. Wait if feedhold pushed
    
    	//while (persist.UserData[160] == 1) // Wait if feedhold is on
    	//{
    		//WaitNextTimeSlice(); 
    		//if (ReadBit(1039)) return 0; // If Reset pushed while waiting in feedhold, End
    	//}
    
    
    // 16. Turn coolant back on
    
    	if (coolanton == 1) SetBit(157);   // if flood coolant was on, turn on again
    
    }
    http://www.homecncstuff.elementfx.com/

  8. #356
    Junior Member
    Join Date
    May 2006
    Posts
    3210

    Re: Hurco BMC20 Dynomotion Retrofit

    Hi Troy,

    Have no fear

    One bug I see is fprintf requires a FILE parameter not a char array parameter. Note Compiling with the TI Compiler flagged this error. Change:
    Code:
    // 16. Write current tool # disk
    
    	FILE *f;
    	char s[256];
    
    	float CTool = persist.UserData[157];	// s value from g code       
    
    	f = fopen("c:\\KMotion Files\\KFlopData.txt", "wt");
    	fprintf(s, "%f\n", CTool);
    	fclose(f);
    To:
    Code:
    // 16. Write current tool # disk
    
    	FILE *f;
    
    	float CTool = persist.UserData[157];	// s value from g code       
    
    	f = fopen("c:\\KMotion Files\\KFlopData.txt", "wt");
    	fprintf(f, "%f\n", CTool);
    	fclose(f);

    TF is declared multiple times within the same code block. Better to define it only once with:
    double TF = Time_sec() + 2; // timeout in 2 seconds


    then later just use the same variable:
    TF = Time_sec() + 2; // timeout in 2 seconds


    Also it is not allowed to use an MDI command within an MCode (M6) because MDI uses the GCode Interpreter and the Interpreter is already in use running a GCode Program executing a Tool Change M6 (Interpreter is not re-enterable). You will need to change these to use KFLOP function to do whatever is necessary.

    Code:
    // 4. Move to toolchange position Z0.000
    	{
    		MDI("G0 G53 Z-1.025");	// Move Z to -1.025inches from Reference Position
    		//MoveAtVel(2, 0, 800000);
    		//while (!CheckDone(2)) WaitNextTimeSlice(); // wait until we are stopped
    	}


    Please Indent your code properly to make it more readable. There is now a context menu button in Version 4.35b to do this automatically

    https://youtu.be/CsIijoLMq8U


    Also,what all do i need to configure in KMCNC to use this code? And is there more code that needs to be added to my main INIT code?
    To use this code assign the program to the KMotionCNC M6 Action. Use some unused Thread. The var should be set to 6 as your program is expecting the Requested Tool to be in Persist Variable 6.

    Note you will somehow need to initialize the Current Tool (Persist Variable 157) after powering up KFLOP before doing the first Tool Change. Most likely by reading from the disk file in your Initialization C Program.
    TK
    http://dynomotion.com

  9. #357
    Registered
    Join Date
    May 2012
    Posts
    438

    Re: Hurco BMC20 Dynomotion Retrofit

    Quote Originally Posted by Need TECH Help! View Post
    Below is an edited version of mmurray's code, which iam sure i have missed something. Also,what all do i need to configure in KMCNC to use this code? And is there more code that needs to be added to my main INIT code?
    Hi Troy,

    Looks like your on the right track. I like how you made a list of every step needed, thats important to know first. There are a few things I have going on outside of my toolchange program as well that might make things confusing. Ill try and explain a little.


    1. First thing is the way I am setting spindle speeds. You probably have a spindle.c file now that sets the DAC value for the proper spindle speed. But you need to override that during orientation, and return to previous value when done. So I have my init file actually setting the DAC value for the spindle in the forever loop. I used a persist variable (persist.UserData[155] = 1) to indicate i will be orientating. These variables work across all running C programs, so my forever loop in my init file will notice im orientating and will stop setting the current DAC value for the spindle speed. Then I can command any spindle speed (DAC value) in the toolchange program. As soon as im done i set persist.UserData[155] = 0, and the forever loop then goes back to commanding the current programmed S value from G code.

    Note that ive used persist variables all over the place for simple flags like this, but ive been told after it would be much smarter to simply set a bit equal to 1 or 0. I think there are a range of bit numbers that are not used for inputs and outputs but can be used to keep track of things like this across all your C programs. I was in way too deep to go back and change all this again lol.



    2. I would forget about these lines at the top for now:

    // Wait until spindle is orientated, if started already by M100 in G code

    while (persist.UserData[164] == 1) WaitNextTimeSlice(); // wait until orientated

    Orientating takes 2-3 seconds on my machine which is kinda slow, so I setup another M code to orientate the spindle WHILE the Z axis is moving toward the toolchange position. So instead of the normal execute wait program, I have this M100 (orientate) code to execute and NOT wait. Of course I still want to make sure the toolchange program doesnt start while this is still happening. So I set another flag in the M100 orientation program that the M6 program will wait for, if not completed.

    Note that setting bits would have been a better idea here too. Also I would recommend setting up an orientation M code and getting all that working properly before trying to do the whole toolchange program. Setup a M code to extend and another to retract the carosel as well. Someday you will have to use them to recover from some kind of problem or even just a power failure.



    3. Step 15. Wait if feedhold pushed. I added this because the machine would ignore a feedhold if button was pushed while it was in the middle of a toolchange, which i tend to do often to double check things before next tool runs. Sometimes i forget optional stop. I think it would also ignore feedholes if M codes were running. For example spindle start up. So whenever I push my feedhold button on my machine it just sets another flag (persist.UserData[160]) and then the init file sends the stopcoordinatedmotion command as soon as it starts to move again.



    4. Theres also a flag (161) that toolchanger is active. I use this to block out a bunch of other things from running in the init file, M3/M4, mpg, etc.



    5. The init file reads the saved file from the disk with the current tool number and sets up that variable on startup. Not sure if the bug that Tom found applies to me too, or something you changed, but this has been tested and does work. It saves tool number and reads proper number on start up.


    Good luck with it. I havent had a chance to read through all your code, but just thought I would point out all the strange things im doing that may not make sense. If theres anything else in my program you dont understand feel free to ask and ill try and explain it.

  10. #358

    Re: Hurco BMC20 Dynomotion Retrofit

    Quote Originally Posted by Need TECH Help! View Post
    Got things mounted up and all is wired to Konnect and Kanalog.
    Looks nice and the wiring is good.
    http://cncmakers.com/cnc/controllers/CNC_Controller_System/CNC_Retrofit_Package.html

  11. #359
    Junior Member
    Join Date
    Dec 2007
    Posts
    471

    Re: Hurco BMC20 Dynomotion Retrofit

    Hi Tom and mmuray,

    Got some success in that the tool changer is working. The code still needs cleaned up and some adjustments made, like a way to wait for spindle to come to a complete stop before starting Tool Change sequence, other than a delay. Example: If spindle was running at 3800RPM the delay needs to be about 8seconds for spindle to come to a complete stop. But if RPM was at 500RPM the delay needs to be much less.

    Also still need to make a reference sequence c-code for Tool Changer and temp store of current tool for restarting machine.
    Here is the M6ToolChange code currently.

    Thanks again guys,
    Troy


    Code:
    #include "KMotionDef.h"
    #define TMP 10					// which spare persist to use to transfer data
    #include "KflopToKMotionCNCFunctions.c"
    #define Z 2
    
    
    
    main()
    {
    	if (!ReadBit(137))
    		return 0;				// if in Estop, Exit program
    
    
    // 1. Determine how many pockets to rotate
    
    	int pockets = persist.UserData[6] - persist.UserData[157];	// pockets = requested tool - current tool
    
    	if (pockets == 0)
    		return 0;				// No toolchange needed, End
    	if (pockets >= 8)
    		pockets = -16 + pockets;	// If more then halfway CW, reverse
    	if (pockets <= -8)
    		pockets = 16 + pockets;	// If more then halfway CCW, reverse
    
    
    	persist.UserData[161] = 1;	// Toolchanger active disable feedhold button
    	ResumeCoordinatedMotion();	// Clear feedhold
    
    
    // 2. Turn off Flood Coolant if left on
    
    	int coolanton = 0;
    	if (ReadBit(157))			// if flood coolant on
    	{
    		coolanton = 1;			//  set variable to 1
    		ClearBit(157);			// Flood coolant off
    		Delay_sec(.2);			// delay
    	}
    
    // 3. Turn off spindle
    
    	if (ReadBit(147) || ReadBit(148))	//check if spindle is running forward or reverse
    	{
    		ClearBit(147);			// turn off spindle clockwise
    		ClearBit(148);			// turn off spindle counterclockwise
    		Delay_sec(8.);
    	}
    
    
    
    // 4. Move to toolchange position Z-1.025inches from Reference Position
    	{
    		Move(Z, -20528);
    		while (!CheckDone(2))
    			WaitNextTimeSlice();	// wait until we are stopped
    	}
    
    // 5. Orientate
    
    	if (!ReadBit(1035))			// if toolchanger slide is not home estop
    	{
    		ClearBit(137);			// E-stop
    		printf("E-stop Toolchanger not Home");
    	}
    
    
    	{
    		persist.UserData[155] = 1;	// Enable orientate speed override
    		SetBit(156);			// Kanalog Switch4 to turn on SpindleOrientateProxSensor
    		Delay_sec(0.1);			// Delay 0.1s
    		DAC(7, -16);			// set motor rpm approx 30
    		SetBit(147);			// spindle on CW        
    		Delay_sec(0.2);			// wait for spindle to reach speed  
    		while (!ReadBit(1038))
    			WaitNextTimeSlice();	// wait for SpindleOrientateProx signal
    		SetBit(48);				// Signal to VFD, set VFD to ZeroServoCommand
    		Delay_sec(0.90);		// Delay for spindle to stop at orientation that is set in VFD parameter
    	}
    
    
    	{
    
    		persist.UserData[155] = 0;	// Spindle speed normal
    		Delay_sec(0.75);		// wait before checking if successfull
    	}
    
    
    	while (!ReadBit(1035) || !ReadBit(1037))
    		WaitNextTimeSlice();	// Check TC is at home position.
    
    
    // 6. Tool Chnager OUT
    
    	SetBit(63);					// TC_OUT solenoid
    	Delay_sec(1.1);
    	ClearBit(63);				//TC_OUT solenoid
    	double TF = Time_sec() + 2;	// timeout in 2 seconds
    
    	while (!ReadBit(1034))		// Wait for TC_OUT limit switch
    	{
    		WaitNextTimeSlice();
    
    		if (Time_sec() > TF)	// Timed out?
    		{
    			if (MsgBox("TC OUT Not Extended.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    			{
    				DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0;	// toolchanger finished
    				return 0;		//exit program
    			}
    			else
    			{
    				TF = Time_sec() + 3;	// continue and timeout after 3 seconds
    			}
    		}
    
    	}
    
    
    // 7. Unclamp Tool
    
    	SetBit(59);					//Tool Release Solenoid
    	Delay_sec(.6);
    
    	double TF = Time_sec() + 2;	// timeout in 2 seconds    
    
    	while (!ReadBit(1039))		// Wait for ToolReleaseProxSensor
    	{
    		WaitNextTimeSlice();
    
    		if (Time_sec() > TF)	// Timed out?
    		{
    			if (MsgBox("Tool Release Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    			{
    				DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0;	// toolchanger finished
    				return 0;		//exit program
    			}
    			else
    			{
    				TF = Time_sec() + 3;	// continue and timeout after 3 seconds
    			}
    		}
    
    	}
    
    
    // 8. Move Tool Changer DOWN
    
    	SetBit(61);					// TC_DOWN Solenoid
    	Delay_sec(0.9);
    	ClearBit(61);				//TC_DOWN solenoid
    
    	double TF = Time_sec() + 2;	// timeout in 2 seconds    
    
    	while (!ReadBit(1036))		// Wait for TC_DOWN Limit Switch
    	{
    		WaitNextTimeSlice();
    
    		if (Time_sec() > TF)	// Timed out?
    		{
    			if (MsgBox("TC DOWN Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    			{
    				DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0;	// toolchanger finished
    				return 0;		//exit program
    			}
    			else
    			{
    				TF = Time_sec() + 3;	// continue and timeout after 3 seconds
    			}
    		}
    
    	}
    // 9. Rotate Carousel 
    
    	while (pockets >= 1)		// Rotate Turret CW whatever number of pockets
    	{
    		SetBit(49);				// TC Carousel Motor On CW
    		while (!ReadBit(1033))
    			WaitNextTimeSlice();	// Wait for CarouselMotorProxSensor
    		Delay_sec(.4);
    		ClearBit(49);			// TC_Carousel CW Motor Off
    		pockets = pockets - 1;
    	}
    
    	while (pockets <= -1)		// Rotate Turret CCW whatever number of pockets
    	{
    		SetBit(50);				// TC Carousel Motor On CCW
    		while (!ReadBit(1033))
    			WaitNextTimeSlice();	// Wait for CarouselMotorProxSensor
    		Delay_sec(.4);
    		ClearBit(50);			// TC_Carousel CCW Motor Off
    		pockets = pockets + 1;
    	}
    
    
    // 10. Move Tool Changer UP
    
    	SetBit(60);					// TC_UP Solenoid
    	Delay_sec(0.9);
    	ClearBit(60);				//TC_UP solenoid
    	double TF = Time_sec() + 2;	// timeout in 2 seconds    
    
    	while (!ReadBit(1037))		// Wait for TC_UP Limit Switch
    	{
    		WaitNextTimeSlice();
    
    		if (Time_sec() > TF)	// Timed out?
    		{
    			if (MsgBox("TC UP Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    			{
    				DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0;	// toolchanger finished
    				return 0;		//exit program
    			}
    			else
    			{
    				TF = Time_sec() + 3;	// continue and timeout after 3 seconds
    			}
    		}
    
    	}
    
    // 11. Clamp tool
    
    	ClearBit(59);				//Tool Release Solenoid
    
    	double TF = Time_sec() + 2;	// timeout in 2 seconds
    
    	while (ReadBit(1039))		// Wait for Tool Release Proximity Sensor
    	{
    		WaitNextTimeSlice();
    
    		if (Time_sec() > TF)	// Timed out?
    		{
    			if (MsgBox("Tool Clamp Failed.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    			{
    				DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0;	// toolchanger finished
    				return 0;		//exit program
    			}
    			else
    			{
    				TF = Time_sec() + 3;	// continue and timeout after 3 seconds
    			}
    		}
    
    	}
    
    
    // 12. Tool Changer IN
    	SetBit(62);					// TC_IN solenoid
    	Delay_sec(0.7);
    	ClearBit(62);				// TC_IN solenoid
    
    
    	double TF = Time_sec() + 2;	// timeout in 2 seconds
    
    	while (!ReadBit(1035))		// Check TC_IN limit switch
    	{
    		WaitNextTimeSlice();
    
    		if (Time_sec() > TF)	// Timed out?
    		{
    			if (MsgBox("TC Not Home.  Halt?", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    			{
    				DoPC(PC_COMM_HALT);
    				persist.UserData[161] = 0;	// toolchanger finished
    				return 0;		//exit program
    			}
    			else
    			{
    				TF = Time_sec() + 3;	// continue and timeout after 3 seconds
    			}
    		}
    
    	}
    
    
    
    // 13. Set Variables
    
    	persist.UserData[157] = persist.UserData[6];	// Update current tool number
    	persist.UserData[161] = 0;	// toolchanger finished
    
    	printf("Tool changed to T%d\n", persist.UserData[157]);	// send message to console
    
    
    // 14. Write current tool # disk
    
    
    	FILE *f;
    
    	float CTool = persist.UserData[157];	// s value from g code       
    
    	f = fopen("c:\\KMotion Files\\KFlopData.txt", "wt");
    	fprintf(f, "%f\n", CTool);
    	fclose(f);
    
    
    
    // 15. Turn coolant back on
    
    	if (coolanton == 1)
    		SetBit(157);			// if flood coolant was on, turn on again
    	ClearBit(156);
    	ClearBit(48);
    	ClearBit(147);
    }
    http://www.homecncstuff.elementfx.com/

  12. #360
    Registered
    Join Date
    May 2012
    Posts
    438

    Re: Hurco BMC20 Dynomotion Retrofit

    Awesome! Post some videos of your progress.

    The delay is real easy one. Just calculate the delay based on your current speed. Heres the code I use in my M5 program. I didnt bother to do the calculations within the toolchange program since thats only a "just in case" thing. Normally M5 is used to stop. Do the same for M3 and M4 as well. Also, 8 seconds seems a little high, may want to tweak your VFD a little faster. Better to do it now as it may change all the speeds/delays etc used for orientating, may end up having to tune all over if you tweak it down the road.

    Code:
    float spd = *(float *)&persist.UserData[9]; // s value from g code, used for delay
    	float delay;
    
    	if (ReadBit(156)) // spindle in high range 
    	{
    	delay = (spd*0.0002); // set stop time
    	}
    
    	if (ReadBit(157)) // spindle in low range
    	{
    	delay = (spd*0.0007); // set stop time
    	}
    	
    	Delay_sec(delay); // wait for spindle to stop

    And here is the code to read file from disk. Put this in your init file, before forever loop. You may need to create that file first, make sure paths match up. Mine is just a txt file with the tool number in it. Mine has 6 decimal places, not sure if it makes a difference. Currently says 16.000000

    Code:
    FILE *f;
        	char s[256];
    	double CTool=0;
    	int result;
    
        	f=fopen("c:\\KMotion Files\\KFlopData.txt","rt");
        	if (!f)
        	{
           	 printf("Unable to open file\n");
            	return;
        	}
        	result=fscanf(f,"%lf",&CTool);
        	fclose(f);    
    	persist.UserData[157] = CTool;
    	printf("Current tool=%f\n",CTool);
    
    	// Send MDI code to kmotion to display proper tool
    	char s[80];
       	sprintf(s,"T%d",persist.UserData[157]);
    	MDI(s);  //send the T word

Page 30 of 34 202829303132

Similar Threads

  1. Hurco BMC20
    By sheppey in forum General Off Topic Discussions
    Replies: 0
    Last Post: 12-06-2016, 01:30 PM
  2. Local repairman for '92 Hurco bmc20 around Bristol, IN
    By Benkerst5278 in forum CNC Machining Centers
    Replies: 0
    Last Post: 07-13-2010, 03:32 PM
  3. HURCO BMC20
    By PCM in forum HURCO
    Replies: 3
    Last Post: 05-03-2009, 08:03 PM
  4. Hurco BMC20 with Ultimax 2 control
    By kwmkoester in forum HURCO
    Replies: 6
    Last Post: 04-30-2009, 11:52 PM
  5. Hurco BMC20 Post Prosser help
    By moorport in forum General CNC (Mill / Lathe) Control Software (NC)
    Replies: 12
    Last Post: 02-06-2007, 05:19 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •