Thanks Tom, that's what I guessed.
This is part of my tool changer initialisation code, so there are a few prompts to get information, then various messages if something specific fails, followed by a generic failed message, and it's mostly done with non-blocking message boxes and state machines where needed.
The code is below for reference.
If I get time, I'll fix it, but I've added some printfs, so I'll at least get the real problem via the console for now.
Code: Select all
#include "KMotionDef.h"
#include "Triac.h"
#include "KflopToKMotionCNCFunctions.c"
#define IDLE 0
#define WAITING_RESPONSE 1
enum {TC_START, TC_CHKCRSLFLAT, TC_CHKDRBR, TC_CHKCRSLOUTUP, TC_CRSLPOSVALID, TC_TOOLVALID, TC_GETTOOLID, TC_CHKSTATE, TC_GETCRSLPOS, TC_GETPOS, TC_INDEX, TC_FAILED, TC_COMPLETE};
int TCStatus = TC_START;
float inputResult;
float awaitingResult = IDLE;
int Response = FALSE;
int Answer;
int *ChangerState = &persist.UserData[TOOL_STATE_VAR];
int *Tool = &persist.UserData[TOOL_VAR];
int *LastTool = &persist.UserData[LAST_TOOL_VAR];
int *CrslPos = &persist.UserData[CRSL_POS];
void tc_init(void)
{
switch(TCStatus)
{
case TC_START:
{
printf("TC_START\n");
// is TCINIT TRUE?
// If it is, then tool changer has already been initialised at some point, and nothing should of caused it now not to be,
// so we ask the operator if they really want to re-run init.
if(ReadBit(TCINITOK)){
if(awaitingResult == IDLE){
char MyMessage[80]; // String to be created and displayed
double CrslP = *CrslPos/4.0;
sprintf(MyMessage,"Tool Changer already initialized, with tool %d in spindle\n Carousel at position %.1f\n Are you sure you want to run Tool Changer Intialisation?",*Tool,CrslP); // build the message we want to show
MsgBoxNoWait(MyMessage,MB_YESNO);
awaitingResult = WAITING_RESPONSE;
printf("awaitingResult WAITING\n");
} else {
if (MsgBoxGetResponse(&Response)==0) //Communication successful?
{
printf("Response Succesful\n");
printf("Message Response was %d\n", Response);
// yes, show response
if(Response == IDYES){ // if yes, we want to re-run init
printf("Yes\n");
ClearBit(TCINITOK); // unset that we're initialised
TCStatus = TC_CHKCRSLFLAT; // move onto first step of initialisation
} else if (Response == IDNO){ // else we don't want to re-run init
printf("No\n");
TCStatus = TC_COMPLETE; // move onto the final state
} else {
printf("Invalid response\n"); // we shouldn't get here, but if we do, die!
ThreadDone();
}
awaitingResult = IDLE;
printf("awaitingResult IDLE\n");
}
}
} else {
TCStatus = TC_CHKCRSLFLAT;
}
break;
}
case TC_CHKCRSLFLAT: // Is carousel geneva mechanism on position, or transitioning?
{
printf("TC_CHKCRSLFLAT\n");
if(ReadBit(CRSLIDX)){ // if bit is high, then we're not on the flat, so quit and tell user to use TC Recovery
MsgBoxNoWait("Carousel not at index. Use TC Recovery",MB_OK|MB_ICONEXCLAMATION);
TCStatus = TC_FAILED;
} else {
TCStatus = TC_CHKDRBR;
}
break;
}
case TC_CHKDRBR: // Is carousel geneva mechanism on position, or transitioning?
{
printf("TC_CHKDRBR\n");
if(ReadBit(DRBR)){ // if bit is high, then drawbar is active (released) so quit and tell user to use TC Recovery
TCStatus = TC_FAILED;
MsgBoxNoWait("Drawbar Released. Use TC Recovery",MB_OK|MB_ICONEXCLAMATION);
} else {
TCStatus = TC_CHKCRSLOUTUP;
}
break;
}
case TC_CHKCRSLOUTUP: // Is carousel out/up?
{
if(ReadBit(CRSLINR) || ReadBit(CRSLDWNR)){ // if in or down relays active, quit and tell user to use TC Recovery
TCStatus = TC_FAILED;
MsgBoxNoWait("Carousel In and/or Down commanded. Use TC Recovery",MB_OK|MB_ICONEXCLAMATION);
} else if((!(ReadBit(CRSLOUT) && ReadBit(CRSLUP))) || awaitingResult == WAITING_RESPONSE) { // if we're still not out/up, or we've already prompted user
if(awaitingResult == IDLE){
MsgBoxNoWait("Carousel not Out and Up.\n Is air supply connected?\nPress OK after connecting air, or cancel to quit and use TC Recovery",MB_OK|MB_ICONEXCLAMATION);
awaitingResult = WAITING_RESPONSE;
printf("awaitingResult WAITING\n");
} else {
if (MsgBoxGetResponse(&Response)==0) //Communication successful?
{
// yes, show response
if(Response==IDOK){ // if OK, then we need to retrigger check, so we simply do nothing, and it'll get rechecked when
printf("OK\n");
} else { // else we want to quit TC Initialisation
printf("Cancel\n");
TCStatus = TC_FAILED; // so set flag to Failed
}
awaitingResult = IDLE;
printf("awaitingResult IDLE\n");
}
}
} else { // else carousle is out and up, so move on
TCStatus = TC_CRSLPOSVALID;
printf("TC_CHCKCRSLOUTUP complete. Moving to TC_CRSLPOSVALID\n");
}
break;
}
case TC_CRSLPOSVALID:
{
if((*CrslPos >= 1) && (*CrslPos<=24) && ((*CrslPos % 2) == 0 )){ // is carousel position is between 1 and 24, and it's equally divisable by 2, it's valid but maybe not correct
if(awaitingResult == IDLE){
char MyMessage[80]; // String to be created and displayed
double CrslP = *CrslPos/4.0;
printf("CrslPos = %d\n", *CrslPos);
printf("CrslP = %.1f\n", CrslP);
sprintf(MyMessage,"Is carousel at position %.1f",CrslP); // build the message we want to show
MsgBoxNoWait(MyMessage,MB_YESNO|MB_ICONEXCLAMATION);
awaitingResult = WAITING_RESPONSE;
printf("awaitingResult WAITING\n");
} else {
if (MsgBoxGetResponse(&Response)==0) //Communication successful?
{
// yes, show response
printf("Carousel position valid?\n");
printf("Message Response was %d\n", Response);
if(Response == IDYES){ // if Yes, then move onto Tool checks
printf("Yes\n");
printf("TC_CRSLPOSVALID complete, moving to TC_TOOLVALID\n");
TCStatus = TC_TOOLVALID;
} else if(Response == IDNO) { // else we need to prompt user for position
printf("No\n");
printf("TC_CRSLPOSVALID failed, moving to TC_GETCRSLPOS\n");
TCStatus = TC_GETCRSLPOS;
} else {
printf("Invalid response\n");
ThreadDone();
}
awaitingResult = IDLE;
printf("awaitingResult IDLE\n");
}
}
} else {
printf("CrslPos not valid, move to TC_GETCRSLPOS\n");
TCStatus = TC_GETCRSLPOS;
}
break;
}
case TC_GETCRSLPOS:
{
//printf("TC_GETCRSLPOS - ask operator for carousel position\n");
Answer = InputBox("Enter Carousel position (use 0.5 for mid positions)",&inputResult);
if (Answer){
printf("Operator Canceled\n");
TCStatus = TC_FAILED;
} else {
printf("Operator Entered Value of %.3f\n",inputResult);
int CrslP = inputResult * 4;
if((CrslP % 2) != 0) {
printf("Invalid value entered");
// display message box
}
if(CrslP == 26) // if user entered 6.5, we change it to 0.5
CrslP = 2;
*CrslPos = CrslP;
printf("Carousel position=%d",*CrslPos);
TCStatus = TC_CRSLPOSVALID; // we'll go back a step to confirm position with operator
}
break;
}
case TC_TOOLVALID:
{
if((*LastTool >= 1) && (*LastTool<=99)){ // is Lsst tool from 1 to 99?
if(awaitingResult == IDLE){
char MyMessage[80]; // String to be created and displayed
if(*LastTool != 99) { // is tool less than 99 (99 indicates no tool in spindle)
sprintf(MyMessage,"Is Tool %d in spindle?",*LastTool); // build the message we want to show
} else {
sprintf(MyMessage,"Is spindle empty?"); // build the message we want to show
}
MsgBoxNoWait(MyMessage,MB_YESNO|MB_ICONEXCLAMATION);
awaitingResult = WAITING_RESPONSE;
printf("awaitingResult WAITING\n");
} else {
if (MsgBoxGetResponse(&Response)==0) //Communication successful?
{
// yes, show response
printf("Tool valid?\n");
printf("Message Response was %d\n", Response);
if(Response == IDYES){ // if Yes, then move onto final completetion
printf("Yes\n");
TCStatus = TC_COMPLETE;
} else if(Response == IDNO){ // else we need to prompt user for tool
printf("No\n");
TCStatus = TC_GETTOOLID;
} else {
printf("Invalid response\n");
ThreadDone();
}
awaitingResult = IDLE;
printf("awaitingResult IDLE\n");
}
}
} else {
printf("LastTool not valid, move to TC_GETTOOLID\n");
TCStatus = TC_GETTOOLID;
}
break;
}
case TC_GETTOOLID:
{
printf("TC_GETTOOLID - ask operator for current tool\n");
Answer = InputBox("Enter current slot tool is stored\n or 99 if no tool in spindle",&inputResult);
if (Answer){
printf("Operator Canceled\n");
TCStatus = TC_FAILED;
} else {
printf("Operator Entered Value of %.3f\n",inputResult);
*LastTool = (int)inputResult;
printf("Tool position=%d",*LastTool);
TCStatus = TC_TOOLVALID; // we'll go back a step to confirm position with operator
}
break;
}
case TC_FAILED:
{
printf("TC_FAILED - TC either failed or cancelled\n");
MsgBoxNoWait("Tool change initialidation failed. Please Re-try",MB_OK);
ThreadDone();
break;
}
case TC_COMPLETE:
{
printf("TC_COMPLETE:Changer Intialised\n");
*Tool = *LastTool;
*ChangerState = T_IDLE;
double CrslP = *CrslPos/4.0;
SetBit(TCINITOK);
char MyMessage[80]; // String to be created and displayed
sprintf(MyMessage,"Tool Changer initialisation complete.\n Tool %d in spindle\n Carousel at position %.1f\n(If incorrect, rerun initialisation)",*Tool,CrslP); // build the message we want to show
MsgBoxNoWait(MyMessage,MB_OK);
ThreadDone(); // set TC as intialised and quit
break;
}
}
}
main()
{
printf("TCinit launched\n");
//printf("awaitingResult=%d\n",awaitingResult);
for(;;) // loop forever
{
WaitNextTimeSlice();
// we continually monitor for Z axis being homed, and exit thread with warning message if it's not homed
// (should an Estop occur, Z gets flagged as being unhomed, so we don't need to monitor anything else)
if(!ReadBit(ZHOMED))
{
MsgBox("Z axis not homed.\nHome Z axis before initialising Tool Changer",MB_OK);
ThreadDone();
}
tc_init();
}
}