void Buzzer::check_time_out() { if(flag == 1) { ON(); wait(3); mbed_reset(); } else { OFF(); } }
int main() { state = new LaosStatus(); state->setState(BOOTING); if (! check_sd()) mbed_reset(); if (SDcheckFirmware()) mbed_reset(); cfg = new GlobalConfig("config.txt"); mot = new LaosMotion(); // wait until cover is closed state->setState(WAITFORCOVER); while (! mot->isStart() ); // home state->setState(HOMING); mot->home(cfg->xhome,cfg->yhome, cfg->zhome); // clean sd card? if (cfg->cleandir) cleandir(); // configure network eth_speed = 0; eth = EthConfig(); eth_speed = 1; // set up TFTP server thread osThreadCreate(osThread(tftp_thread), NULL); // set up Queue (planner-filler) thread osThreadCreate(osThread(queue_thread), NULL); while (1) { if (mot->qstate == IDLE) { mot->filename = getLaosFile(); if (mot->filename) mot->qstate = NEW; } if (mot->qstate == DONE) { removefile(mot->filename); delete(mot->filename); } osDelay(500); } }
// Test I2C again when config file is read void LaosDisplay::testI2C() { char key; sim = i2c.read(_I2C_ADDRESS ,&key, 1) != 0; if (sim) mbed_reset(); }
/** *** Main function **/ int main() { systime.start(); //float x, y, z; eth_speed = 1; dsp = new LaosDisplay(); printf( VERSION_STRING "...\nBOOT...\n" ); mnu = new LaosMenu(dsp); eth_speed=0; printf("TEST SD...\n"); char testfile[] = "test.txt"; FILE *fp = sd.openfile(testfile, "wb"); if ( fp == NULL ) { mnu->SetScreen("SD NOT READY!"); wait(2.0); mbed_reset(); } else { printf("SD: READY...\n"); fclose(fp); removefile(testfile); } // See if there's a .bin file on the SD // if so, put it on the MBED and reboot if (SDcheckFirmware()) mbed_reset(); mnu->SetScreen(VERSION_STRING); printf("START...\n"); cfg = new GlobalConfig("config.txt"); mnu->SetScreen("CONFIG OK...."); printf("CONFIG OK...\n"); if (!cfg->nodisplay) dsp->testI2C(); printf("MOTION...\n"); mot = new LaosMotion(); eth = EthConfig(); eth_speed=1; printf("SERVER...\n"); srv = new TFTPServer(cfg->port); mnu->SetScreen("SERVER OK...."); wait(0.5); mnu->SetScreen(10); // IP wait(1.0); printf("RUN...\n"); // Wait for key, and then home if ( cfg->autohome ) { printf("WAIT FOR COVER...\n"); wait(1); // Start homing mnu->SetScreen("WAIT FOR COVER...."); //if ( cfg->waitforstart ) while ( !mot->isStart() ); mnu->SetScreen("HOME...."); printf("HOME...\n"); mot->home(cfg->xhome,cfg->yhome, cfg->zhome); // if ( !mot->isHome ) exit(1); printf("HOME DONE. (%d,%d, %d)\n",cfg->xhome,cfg->yhome,cfg->zhome); } else printf("Homing skipped: %d\n", cfg->autohome); // clean sd card? if (cfg->cleandir) cleandir(); mnu->SetScreen(""); if (cfg->nodisplay) { printf("No display set\n\r"); main_nodisplay(); } else { printf("Entering display\n\r"); main_menu(); } }
int main() { pc.baud(115200); NUCLEO.baud(921600); printf("HEXACOPTER MBED SOFTWARE\n"); init(); wait(1); NUCLEO.putc('S'); wait(0.01); while(1) { safeGuard.attach(&safeGuardOff, 0.2); if (counter == 100) { counter = 0; led1 = !led1; if (Msg.err_state != 5 && !rec_msg) { led2 = !led1; } else if (Msg.err_state != 5) { led2 = 0; } rec_msg = false; switch (Msg.err_state) { case 2: led3 = !led1; if (led3 == 1) buzz.beep_once(); led2 = 0; led4 = 0; break; case 3: led2 = !led1; led3 = !led1; if (led3 == 1) buzz.beep_twice(); led4 = 0; break; case 4: led4 = !led1; if (led4 == 1) buzz.beep_thrice(); led2 = 0; led3 = 0; break; case 5: led4 = !led1; led3 = !led1; led2 = !led1; if (led4 == 1) buzz.long_beep(); if (res_err_cnt >= MAX_WAIT) { res_err_cnt = 0; mbed_reset(); } res_err_cnt++; break; default: led2 = 0; led3 = 0; led4 = 0; break; } } Msg.batt = bl.GetLevel(); char * msg_array = (char *)&Msg; for (int i = 0; i < msg_size; i++) { NUCLEO.getc(); NUCLEO.putc(msg_array[i]); } buffer = (char *) &Rec; while (!NUCLEO.readable()); for (int i = 0; i < rec_size; i++) { buffer[i] = NUCLEO.getc(); } for (int i = 0; i < 6; i++) { motors.pulsewidth(i,Rec.motor_speeds[i]); } switch (Rec.buzz_val) { case 0: //do nothing. break; case 1: buzz.beep_once(); break; case 2: buzz.beep_twice(); break; case 3: buzz.beep_thrice(); break; case 4: buzz.long_beep(); break; default: //do nothing. break; } counter++; safeGuard.detach(); } return 0; }
/** *** Handle menu system *** Read keys, and plan next action on the screen, output screen if *** something changed **/ void LaosMenu::Handle() { int xt, yt, zt, cnt=0, nodisplay = 0; extern LaosFileSystem sd; extern LaosMotion *mot; static int count=0; int c = dsp->read(); if ( count++ > 10) count = 0; // screen refresh counter (refresh once every 10 cycles( if ( c ) timeout = 10; // keypress timeout counter else if ( timeout ) timeout--; if ( screen != prevscreen ) waitup = 1; // after a screen change: wait for a key release, mask current keypress if ( waitup && timeout) // if we have to wait for key-up, c = 0; // cancel the keypress if ( waitup && !timeout ) waitup=0; if ( !timeout ) // increase speed if we keep button pressed longer speed = 5; else { speed *= 1.5; if ( speed >= 100 ) speed = 100; } if ( c || screen != prevscreen || count >9 ) { switch ( screen ) { case STARTUP: if ( sarg == NULL ) sarg = (char*) VERSION_STRING; break; case MAIN: switch ( c ) { case K_RIGHT: menu+=1; waitup=1; break; case K_LEFT: menu-=1; waitup=1; break; case K_UP: lastscreen=MAIN; screen=MOVE; menu=MAIN; break; case K_DOWN: lastscreen=MAIN; screen=MOVE; menu=MAIN; break; case K_OK: screen=menu; waitup=1; lastscreen=MAIN; break; case K_CANCEL: menu=MAIN; break; case K_FUP: lastscreen=MAIN; screen=FOCUS; menu=MAIN; break; case K_FDOWN: lastscreen=MAIN; screen=FOCUS; menu=MAIN; break; case K_ORIGIN: lastscreen=MAIN; screen=ORIGIN; waitup=1; break; } if (menu==0) menu = (sizeof(menus) / sizeof(menus[0])) -1; if (menu==(sizeof(menus) / sizeof(menus[0]))) menu = 1; sarg = (char*)menus[menu]; args[0] = menu; break; case RUN: // START JOB select job to run if (strlen(jobname) == 0) getprevjob(jobname); switch ( c ) { case K_OK: screen=RUNNING; break; case K_UP: case K_FUP: getprevjob(jobname); waitup = 1; break; // next job case K_RIGHT: screen=DELETE; waitup=1; break; case K_DOWN: case K_FDOWN: getnextjob(jobname); waitup = 1; break;// prev job case K_CANCEL: screen=1; waitup = 1; break; } sarg = (char *)&jobname; break; case DELETE: // DELETE JOB select job to run switch ( c ) { case K_OK: removefile(jobname); screen=lastscreen; waitup = 1; break; // INSERT: delete current job case K_UP: case K_FUP: getprevjob(jobname); waitup = 1; break; // next job case K_DOWN: case K_FDOWN: getnextjob(jobname); waitup = 1; break;// prev job case K_LEFT: screen=RUN; waitup=1; break; case K_CANCEL: screen=lastscreen; waitup = 1; break; } sarg = (char *)&jobname; break; case MOVE: // pos xy mot->getPosition(&x, &y, &z); xt = x; yt= y; switch ( c ) { case K_DOWN: y+=1000*speed; break; case K_UP: y-=1000*speed; break; case K_LEFT: x-=1000*speed; break; case K_RIGHT: x+=1000*speed; break; case K_OK: case K_CANCEL: screen=MAIN; waitup=1; break; case K_FUP: screen=FOCUS; break; case K_FDOWN: screen=FOCUS; break; case K_ORIGIN: screen=ORIGIN; break; } if ((mot->ready()) && ( (x!=xt) || (y != yt) )) { mot->moveTo(x, y, z, speed); } else { // if (! mot->ready()) // printf("Buffer vol\n"); } args[0]=x-xoff; args[1]=y-yoff; break; case FOCUS: // focus mot->getPosition(&x, &y, &z); switch ( c ) { case K_FUP: z+=speed; if (z>cfg->zmax) z=cfg->zmax; break; case K_FDOWN: z-=speed; if (z<0) z=0; break; case K_LEFT: screen=MOVE; break; case K_RIGHT: screen=MOVE; break; case K_UP: screen=MOVE; break; case K_DOWN: screen=MOVE; break; case K_ORIGIN: screen=ORIGIN; break; case K_OK: case K_CANCEL: screen=MAIN; waitup=1; break; case 0: break; default: screen=MAIN; waitup=1; break; } if ( mot->ready() && (z!=zt) ) mot->moveTo(x, y, z, speed); args[0]=z-zoff; break; case HOME:// home switch ( c ) { case K_OK: screen=HOMING; break; case K_CANCEL: screen=MAIN; menu=MAIN; waitup=1; break; } break; case ORIGIN: // origin switch ( c ) { case K_CANCEL: screen=MAIN; menu=MAIN; waitup=1; break; case K_OK: case K_ORIGIN: xoff = x; yoff = y; zoff = z; mot->setOrigin(x,y,z); screen = lastscreen; waitup = 1; break; } break; case DELETE_ALL: // Delete all files switch ( c ) { case K_OK: // delete current job cleandir(); screen=MAIN; waitup = 1; strcpy(jobname, ""); break; case K_CANCEL: screen=MAIN; waitup = 1; break; } break; case IP: // IP switch ( c ) { case K_RIGHT: ipfield++; waitup=1; break; case K_LEFT: ipfield--; waitup=1; break; case K_OK: screen=MAIN; menu=MAIN; break; case K_CANCEL: screen=MAIN; menu=MAIN; break; } ipfield %= 4; sarg = (char*)ipfields[ipfield]; switch (ipfield) { case 0: memcpy(args, cfg->ip, 4*sizeof(int) ); break; case 1: memcpy(args, cfg->nm, 4*sizeof(int) ); break; case 2: memcpy(args, cfg->gw, 4*sizeof(int) ); break; case 3: memcpy(args, cfg->dns, 4*sizeof(int) ); break; default: memset(args,0,4*sizeof(int)); break; } break; case REBOOT: // RESET MACHINE mbed_reset(); break; /* case IO: // IO switch ( c ) { case K_RIGHT: iofield++; waitup=1; break; case K_LEFT: iofield--; waitup=1; break; case K_OK: screen=lastscreen; break; case K_CANCEL: screen=lastscreen; break; } iofield %= sizeof(iofields)/sizeof(char*); sarg = (char*)iofields[iofield]; args[0] = ipfield; args[1] = ipfield; break; case POWER: // POWER switch ( c ) { case K_RIGHT: powerfield++; waitup=1; break; case K_LEFT: powerfield--; waitup=1; break; case K_UP: power[powerfield % 4] += speed; break; case K_DOWN: power[powerfield % 4] -= speed; break; case K_OK: screen=lastscreen; break; case K_CANCEL: screen=lastscreen; break; } powerfield %= 4; args[1] = powerfield; sarg = (char*)powerfields[powerfield]; args[0] = power[powerfield]; break; */ case HOMING: // Homing screen x = cfg->xhome; y = cfg->yhome; while ( !mot->isStart() ); mot->home(cfg->xhome,cfg->yhome,cfg->zhome); screen=lastscreen; break; case RUNNING: // Screen while running switch ( c ) { /* case K_CANCEL: while (mot->queue()); mot->reset(); if (runfile != NULL) fclose(runfile); runfile=NULL; screen=MAIN; menu=MAIN; break; */ default: if (runfile == NULL) { runfile = sd.openfile(jobname, "rb"); if (! runfile) screen=MAIN; else mot->reset(); } else { while ((!feof(runfile)) && mot->ready()) mot->write(readint(runfile)); if (feof(runfile) && mot->ready()) { fclose(runfile); runfile = NULL; mot->moveTo(cfg->xrest, cfg->yrest, cfg->zrest); screen=MAIN; } else { nodisplay = 1; } } } break; default: screen = MAIN; break; } if (nodisplay == 0) { dsp->ShowScreen(screens[screen], args, sarg); } prevscreen = screen; } }
/** *** Handle menu system *** Read keys, and plan next action on the screen, output screen if *** something changed **/ void LaosMenu::Handle() { // int xt, yt, zt, int nodisplay = 0; extern LaosFileSystem sd; extern LaosMotion *mot; extern GlobalConfig *cfg; static int count=0; int c = dsp->read(); if ( count++ > 10) count = 0; // screen refresh counter (refresh once every 10 cycles( if ( c ) timeout = 10; // keypress timeout counter else if ( timeout ) timeout--; if ( screen != prevscreen ) waitup = 1; // after a screen change: wait for a key release, mask current keypress if ( waitup && timeout) // if we have to wait for key-up, c = 0; // cancel the keypress if ( waitup && !timeout ) waitup=0; if ( !timeout ) { // keyboard timeout (i.e. all keys are released): // reset jog/focus speed: speed = 3; } if( (c != 0) || (timeout == 0)) { if(m_PrevKey != c) { // and when starting a new move, wait till the previous movements are completely finished. // This is needed, otherwise back-and-forth moves could result in a far move being // done at a low speed, which would take a long time to finish: m_MoveWaitTillQueueEmpty = true; } m_PrevKey = c; } if ( c || screen != prevscreen || count >9 ) { switch ( screen ) { case STARTUP: if ( sarg == NULL ) sarg = (char*) VERSION_STRING; break; case MAIN: switch ( c ) { case K_RIGHT: menu+=1; waitup=1; break; case K_LEFT: menu-=1; waitup=1; break; case K_UP: lastscreen=MAIN; screen=MOVE; menu=MAIN; break; case K_DOWN: lastscreen=MAIN; screen=MOVE; menu=MAIN; break; case K_OK: screen=menu; waitup=1; lastscreen=MAIN; break; case K_CANCEL: menu=MAIN; break; case K_FUP: lastscreen=MAIN; screen=FOCUS; menu=MAIN; break; case K_FDOWN: lastscreen=MAIN; screen=FOCUS; menu=MAIN; break; case K_ORIGIN: lastscreen=MAIN; screen=ORIGIN; waitup=1; break; } if (menu==0) menu = (sizeof(menus) / sizeof(menus[0])) -1; if (menu==(sizeof(menus) / sizeof(menus[0]))) menu = 1; sarg = (char*)menus[menu]; args[0] = menu; break; case RUN: // START JOB select job to run if (strlen(jobname) == 0) getprevjob(jobname); switch ( c ) { case K_OK: screen = ANALYZING; m_StageAfterAnalyzing = RUNNING; break; case K_UP: case K_FUP: getprevjob(jobname); waitup = 1; break; // next job case K_RIGHT: screen=BOUNDARIES; waitup=1; break; case K_DOWN: case K_FDOWN: getnextjob(jobname); waitup = 1; break;// prev job case K_CANCEL: screen=1; waitup = 1; break; } sarg = (char *)&jobname; break; case DELETE: // DELETE JOB select job to run switch ( c ) { case K_OK: removefile(jobname); screen=lastscreen; waitup = 1; break; // INSERT: delete current job case K_UP: case K_FUP: getprevjob(jobname); waitup = 1; break; // next job case K_DOWN: case K_FDOWN: getnextjob(jobname); waitup = 1; break;// prev job case K_LEFT: screen=BOUNDARIES; waitup=1; break; case K_CANCEL: screen=lastscreen; waitup = 1; break; } sarg = (char *)&jobname; break; case MOVE: // pos xy { int x,y,z; int numinqueue=mot->queue(); mot->getCurrentPositionRelativeToOrigin(&x, &y, &z); int xt = x; int yt= y; switch ( c ) { case K_DOWN: y-=100*speed; break; case K_UP: y+=100*speed; break; case K_LEFT: x-=100*speed; break; case K_RIGHT: x+=100*speed; break; case K_OK: case K_CANCEL: screen=MAIN; waitup=1; break; // case K_FUP: screen=FOCUS; break; case K_FUP: // use the Focus Up button to display debugging data for the stepper interrupt: st_debug(); screen=FOCUS; break; case K_FDOWN: screen=FOCUS; break; case K_ORIGIN: screen=ORIGIN; break; } printf("Move: c: %d, numinqueue: %d, xt: %d, yt: %d, waitempty: %d\n", c, numinqueue, xt, yt, m_MoveWaitTillQueueEmpty? 1:0); int maxinqueue=m_MoveWaitTillQueueEmpty? 1:5; /* Currently (Jan 2015) an old version of grbl is used in Laos. This version is buggy in the sense that there is no proper synchronization between the stepper interrupt and the main thread. When adding a new move to the queue through plan_buffer_line(), planner_recalculate() is called. This updates the acceleration profile of existing moves in the queue, potentially including the move which is currently being executed by the stepper interrupt. Due to the lack of synchronization this will lead to problems, including potential crashes or hanging. This problem in particular manifests itself during jogging, because the queue is nearly emtpy and there's a big chance the frontmost item in the stepper queue will be updated. During regular laser cutting the problem is less likely to occur since the queue will continuously be kept nearly full. Recalculation will only affect some of the last moves in the queue. The real fix for this bug would be to update grbl to the latest version, this seems to include proper synchronization. For now we work around the problem by wating for the queue to empty before adding new jog moves. This results in sloppy jogging (continuous stops & moves) but at least it doesn't crash the machine. -joostn */ // always wait till queue is emptied: // just remove this line if grbl ever gets updated: maxinqueue=1; if ((numinqueue < maxinqueue) && ( (x!=xt) || (y != yt) )) { m_MoveWaitTillQueueEmpty=false; mot->moveToRelativeToOrigin(x, y, z, speed); printf("Move: %d %d %d %d\n", x,y,z, speed); speed=speed*3; if(speed > 100) speed=100; } else { // if (! mot->ready()) // printf("Buffer vol\n"); } args[0]=x; args[1]=y; } break; case FOCUS: // focus { int x,y,z; mot->getCurrentPositionRelativeToOrigin(&x, &y, &z); int zt = z; switch ( c ) { case K_FUP: z+=cfg->zspeed*speed; if (z>cfg->zmax) z=cfg->zmax; break; case K_FDOWN: z-=cfg->zspeed*speed; if (z<0) z=0; break; case K_LEFT: break; case K_RIGHT: break; case K_UP: z+=cfg->zspeed*speed; if (z>cfg->zmax) z=cfg->zmax; break; case K_DOWN: z-=cfg->zspeed*speed; if (z<0) z=0; break; case K_ORIGIN: screen=ORIGIN; break; case K_OK: case K_CANCEL: screen=MAIN; waitup=1; break; case 0: break; default: screen=MAIN; waitup=1; break; } int numinqueue=mot->queue(); if ( mot->ready() && (z!=zt) && (numinqueue == 0) ) { mot->moveToRelativeToOrigin(x, y, z, speed); printf("Focus: %d %d %d %d\n", x,y,z, speed); speed=speed*3; if(speed > 100) speed=100; } args[0]=z; } break; case HOME:// home switch ( c ) { case K_OK: screen=HOMING; break; case K_CANCEL: screen=MAIN; menu=MAIN; waitup=1; break; } break; case ERROR: switch ( c ) { case K_OK: case K_CANCEL: screen=MAIN; waitup=1; break; } break; case ORIGIN: // origin switch ( c ) { case K_CANCEL: screen=MAIN; menu=MAIN; waitup=1; break; case K_OK: case K_ORIGIN: if(cfg->BedHeight() == 0) { screen=ERROR; sarg=(char*)"bedheight unknwn"; } else { mot->MakeCurrentPositionOrigin(); screen = lastscreen; } waitup = 1; break; } break; case DELETE_ALL: // Delete all files switch ( c ) { case K_OK: // delete current job cleandir(); screen=MAIN; waitup = 1; strcpy(jobname, ""); break; case K_CANCEL: screen=MAIN; waitup = 1; break; } break; case IP: // IP int myip[4], mynm[4], mygw[4], mydns[4]; IpParse(cfg->ip, myip); IpParse(cfg->nm, mynm); IpParse(cfg->gw, mygw); IpParse(cfg->dns, mydns); switch ( c ) { case K_RIGHT: ipfield++; waitup=1; break; case K_LEFT: ipfield--; waitup=1; break; case K_OK: screen=MAIN; menu=MAIN; break; case K_CANCEL: screen=MAIN; menu=MAIN; break; } ipfield %= 4; sarg = (char*)ipfields[ipfield]; switch (ipfield) { case 0: memcpy(args, myip, 4*sizeof(int) ); break; case 1: memcpy(args, mynm, 4*sizeof(int) ); break; case 2: memcpy(args, mygw, 4*sizeof(int) ); break; case 3: memcpy(args, mydns, 4*sizeof(int) ); break; default: memset(args, 0, 4*sizeof(int)); break; } break; case REBOOT: // RESET MACHINE mbed_reset(); break; /* case IO: // IO switch ( c ) { case K_RIGHT: iofield++; waitup=1; break; case K_LEFT: iofield--; waitup=1; break; case K_OK: screen=lastscreen; break; case K_CANCEL: screen=lastscreen; break; } iofield %= sizeof(iofields)/sizeof(char*); sarg = (char*)iofields[iofield]; args[0] = ipfield; args[1] = ipfield; break; case POWER: // POWER switch ( c ) { case K_RIGHT: powerfield++; waitup=1; break; case K_LEFT: powerfield--; waitup=1; break; case K_UP: power[powerfield % 4] += speed; break; case K_DOWN: power[powerfield % 4] -= speed; break; case K_OK: screen=lastscreen; break; case K_CANCEL: screen=lastscreen; break; } powerfield %= 4; args[1] = powerfield; sarg = (char*)powerfields[powerfield]; args[0] = power[powerfield]; break; */ case HOMING: // Homing screen while ( !mot->isStart() ); mot->home(cfg->xhome,cfg->yhome,cfg->zhome); screen=lastscreen; break; case RUNNING: // Screen while running switch ( c ) { /* case K_CANCEL: while (mot->queue()); mot->reset(); if (runfile != NULL) fclose(runfile); runfile=NULL; screen=MAIN; menu=MAIN; break; */ default: if (runfile == NULL) { runfile = sd.openfile(jobname, "rb"); if (! runfile) screen=MAIN; else mot->reset(); } else { #ifdef READ_FILE_DEBUG printf("Parsing file: \n"); #endif while ((!feof(runfile)) && mot->ready()) { mot->write(readint(runfile)); if(cfg->disablecancelcheck == false) { if(dsp->read_nb() == K_CANCEL) { while (mot->queue()); mot->reset(); fseek(runfile, 0, SEEK_END); } } } #ifdef READ_FILE_DEBUG printf("File parsed \n"); #endif if (feof(runfile) && mot->ready()) { fclose(runfile); runfile = NULL; mot->moveToAbsolute(cfg->xrest, cfg->yrest, cfg->zrest); screen=MAIN; } else { nodisplay = 1; } } } break; case BOUNDARIES: if (strlen(jobname) == 0) getprevjob(jobname); switch ( c ) { case K_OK: screen = ANALYZING; m_StageAfterAnalyzing = CALCULATEDBOUNDARIES; break; case K_UP: case K_FUP: getprevjob(jobname); waitup = 1; break; // next job case K_DOWN: case K_FDOWN: getnextjob(jobname); waitup = 1; break;// prev job case K_LEFT: screen=RUN; waitup=1; break; case K_RIGHT: screen=DELETE; waitup=1; break; case K_CANCEL: screen=lastscreen; waitup = 1; break; } sarg = (char *)&jobname; break; case ANALYZING: // determine the boundaries of the file. This is done prior to running, and when executing the BOUNDAIES function // m_StageAfterAnalyzing is set to the menu stage that will be executed after this (RUNNING or CALCULATEDBOUNDARIES) runfile = sd.openfile(jobname, "rb"); if (! runfile) { screen=MAIN; } else { // when running we need the bounds including all moves // when executing BOUNDARIES we only need the actual lasered area bool boundsOnlyWithLaserOn = (m_StageAfterAnalyzing == CALCULATEDBOUNDARIES); m_Extent.Reset(boundsOnlyWithLaserOn); while (!feof(runfile)) { m_Extent.Write(readint(runfile)); } fclose(runfile); runfile = NULL; int fileMinx, fileMiny, fileMaxx, fileMaxy; LaosExtent::TError err=m_Extent.GetBoundary(fileMinx, fileMiny, fileMaxx, fileMaxy); bool outOfBounds=false; if(!err) { int minx, miny, minz, maxx, maxy, maxz; mot->getLimitsRelative(&minx, &miny, &minz, &maxx, &maxy, &maxz); if( (fileMinx < minx) || (fileMiny < miny) || (fileMaxx > maxx) || (fileMaxy > maxy) ) { outOfBounds = true; } } if(outOfBounds) { screen=ERROR; sarg=(char*)"Limit overrun"; waitup=1; } else { if(m_StageAfterAnalyzing == CALCULATEDBOUNDARIES) { args[0]=(fileMinx+500)/1000; args[1]=(fileMiny+500)/1000; args[2]=((fileMaxx-fileMinx)+500)/1000; args[3]=((fileMaxy-fileMiny)+500)/1000; screen=CALCULATEDBOUNDARIES; m_SubStage=0; } else if(m_StageAfterAnalyzing == RUNNING) { screen=RUNNING; } else { screen = MAIN; } waitup=1; } } break; case CALCULATEDBOUNDARIES: // Screen after calculating the boundaries of a file if(m_SubStage == 0) { m_Extent.ShowBoundaries(mot); m_SubStage++; } else { switch ( c ) { case K_OK: case K_CANCEL: screen=MAIN; break; } break; } break; case LASERTEST: enable = !cfg->enable; switch ( c ) { case K_OK: waitup = 1; if(m_LaserTestTime > 0) { double p = (double)(cfg->pwmmin/100.0 + ((m_LaserTestPower/100.0)*((cfg->pwmmax - cfg->pwmmin)/100.0))); pwm = p; *laser = LASERON; wait_ms(m_LaserTestTime); *laser = LASEROFF; pwm = cfg->pwmmax / 100.0; // set pwm to max; } break; case K_UP: case K_FUP: if(m_LaserTestPower <= 3) { m_LaserTestPower++; } else { m_LaserTestPower += (m_LaserTestPower>>1); if(m_LaserTestPower > 100) m_LaserTestPower=100; } break; case K_DOWN: case K_FDOWN: if(m_LaserTestPower <= 4) { m_LaserTestPower--; if(m_LaserTestPower < 0) m_LaserTestPower=0; } else { m_LaserTestPower -= (m_LaserTestPower>>2); } break; case K_RIGHT: if(m_LaserTestTime <= 3) { m_LaserTestTime++; } else { m_LaserTestTime += (m_LaserTestTime>>1); if(m_LaserTestTime > 250) m_LaserTestTime=250; } break; case K_LEFT: if(m_LaserTestTime <= 4) { m_LaserTestTime--; if(m_LaserTestTime < 0) m_LaserTestTime=0; } else { m_LaserTestTime -= (m_LaserTestTime>>2); } break; case K_CANCEL: { enable = cfg->enable; // home the machine: while ( !mot->isStart() ); mot->home(cfg->xhome,cfg->yhome,cfg->zhome); screen=MAIN; m_LaserTestPower=0; m_LaserTestTime=0; waitup = 1; } break; } args[0]=m_LaserTestTime; args[1]=m_LaserTestPower; break; default: screen = MAIN; break; } if (nodisplay == 0) { dsp->ShowScreen(screens[screen], args, sarg); } prevscreen = screen; } }