This is the firmware for the LaOS - Laser Open Source project. You can use it to drive a laser cutter. For hardware and more information, look at our wiki: http://wiki.laoslaser.org

Dependencies:   EthernetNetIf mbed

Revision:
0:3852426a5068
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LaosMenu/LaosMenu.cpp	Fri Jun 08 09:26:40 2012 +0000
@@ -0,0 +1,434 @@
+/*
+ * LaosMenu.cpp
+ * Menu structure and user interface. Uses LaosDisplay
+ *
+ * Copyright (c) 2011 Peter Brier & Jaap Vermaas
+ *
+ *   This file is part of the LaOS project (see: http://wiki.laoslaser.org/)
+ *
+ *   LaOS is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   LaOS is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with LaOS.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "LaosMenu.h"
+
+static const char *menus[] = {
+    "STARTUP",     //0
+    "MAIN",        //1
+    "START JOB",   //2
+    "DELETE JOB",  //3
+    "HOME",        //4
+    "MOVE",        //5
+    "FOCUS",       //6
+    "ORIGIN",      //7
+    "REMOVE ALL JOBS", //8
+    "IP",          //9
+    "REBOOT", //10
+    // "POWER / SPEED",//11
+    // "IO", //12
+};
+
+static const char *screens[] = {
+    //0: main, navigate to  MOVE, FOCUS, HOME, ORIGIN, START JOB, IP, 
+    // DELETE JOB, POWER
+#define STARTUP (0)
+    "$$$$$$$$$$$$$$$$"
+    "$$$$$$$$$$$$$$$$",
+
+#define MAIN (STARTUP+1)
+    "$$$$$$$$$$$$$$$$"
+    "<----- 10 ----->",
+
+#define RUN (MAIN+1)
+    "RUN:            "
+    "$$$$$$$$$$$$$$$$",
+
+#define DELETE (RUN+1)
+    "DELETE:         "
+    "$$$$$$$$$$$$$$$$",
+
+#define HOME (DELETE+1)
+    "HOME?           "
+    "      [ok]      ",
+
+#define MOVE (HOME+1)
+    "X: +6543210 MOVE"
+    "Y: +6543210     ",
+
+#define FOCUS (MOVE+1)
+    "Z: +543210 FOCUS"
+    "                ",
+
+#define ORIGIN (FOCUS+1)
+    "  SET ORIGIN?   "
+    "      [ok]      ",
+
+#define DELETE_ALL (ORIGIN+1)
+    "DELETE ALL FILES"
+    "      [ok]      ",
+
+#define IP (DELETE_ALL+1)
+    "210.210.210.210 "
+    "$$$$$$$$[ok]    ",
+
+#define REBOOT (IP+1)
+    "REBOOTING...    "
+    "Please wait...  ",
+
+#define POWER (REBOOT+1)
+    "$$$$$$$: 6543210"
+    "      [ok]      ",
+
+#define IO (POWER+1)
+    "$$$$$$$$$$$=0 IO"
+    "      [ok]      ",
+
+// Intermediate screens
+#define DELETE_OK (IO+1)
+    "DELETE 10?      "
+    "      [ok]      ",
+
+#define HOMING (DELETE_OK+1)
+    "HOMING...       "
+    "                ",
+
+#define RUNNING (HOMING+1)
+    "RUNNING...   10%"
+    "[cancel]        ",
+
+#define BUSY (RUNNING+1)
+    "BUSY: $$$$$$$$$$"
+    "[cancel][ok]    ",
+
+#define PAUSE (BUSY+1)
+    "PAUSE: $$$$$$$$$"
+    "[cancel][ok]    ",
+
+};
+
+static  const char *ipfields[] = { "IP", "NETMASK", "GATEWAY", "DNS" };
+//static  const char *powerfields[] = { "Pmin %", "Pmax %", "Voff", "Von" };
+//static  const char *iofields[] = { "o1:PURGE", "o2:EXHAUST", "o3:PUMP", "i1:COVER", "i2:PUMPOK", "i3:LASEROK", "i4:PURGEOK" };
+
+
+/**
+*** Make new menu object
+**/
+LaosMenu::LaosMenu(LaosDisplay *display) {
+    waitup=timeout=iofield=ipfield=0;
+    sarg = NULL;
+    x=y=z=0;
+    xoff=yoff=zoff=0;
+    screen=prevscreen=lastscreen=speed=0;
+    menu=1;
+    strcpy(jobname, "");
+    dsp = display;
+    if ( dsp == NULL ) dsp = new LaosDisplay();
+    dsp->cls();
+    SetScreen(NULL);
+    runfile = NULL;
+}
+
+/**
+*** Destroy menu object
+**/
+LaosMenu::~LaosMenu() {
+}
+
+/**
+*** Goto specific screen
+**/
+void LaosMenu::SetScreen(int screen) {
+    sarg = NULL;
+    this->screen = screen;
+    Handle();
+    Handle();
+    Handle();
+}
+
+/**
+*** Goto specific screen
+**/
+void LaosMenu::SetScreen(char *msg) {
+    if ( msg == NULL ) {
+        sarg = NULL;
+        screen = MAIN;
+    } else if ( msg[0] == 0 ) {
+        screen = MAIN;
+    } else {
+        sarg = msg;
+        screen = STARTUP;
+    }
+    prevscreen = -1; // force update
+    Handle();
+    Handle();
+    Handle();
+}
+
+/**
+*** 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;
+                                screen=MAIN;
+                            } else {
+                                nodisplay = 1;
+                            }
+                        }
+                }
+                break;
+
+            default:
+                screen = MAIN;
+                break;
+        }
+        //if (nodisplay == 0) {
+            dsp->ShowScreen(screens[screen], args, sarg);
+        //}
+         prevscreen = screen;
+    }
+
+}
+
+void LaosMenu::SetFileName(char * name) {
+    strcpy(jobname, name);
+}