Final code for our 4180 Drawing Robot!

Dependencies:   4DGL-uLCD-SE gCodeParser mbed

main.cpp

Committer:
jford38
Date:
2014-04-30
Revision:
1:ad895d72e9ed
Parent:
0:40576dfac535

File content as of revision 1:ad895d72e9ed:

#include "mbed.h"
#include "gparser.h"
#include "MODSERIAL.h"
#include "motor.h"
#include "drawBot.h"
#include "uLCD_4DGL.h"
#include <ctype.h>

MODSERIAL gpc(USBTX, USBRX);
uLCD_4DGL uLCD(p9, p10, p11);

G_cmd gcmd_list[CMD_LIST_SIZE]; // buffer to be filled with commands, main program retrieves commands from here

extern int list_position;

Motor mL(p29, p30, p26, p27, p28, p25, RIGHT_MOTOR);
Motor mR(p12, p13, p16, p15, p14, p17, LEFT_MOTOR);
DrawBot bot(&mL, &mR, p21, 0.5, 45.125);

int main() {
        
        parserInit();
    
        fillInCmdList();
        uLCD.printf("Commands copied %d\n", list_position);
        
        for(int i=0; i<list_position; i++) {           
            //uLCD.printf("G:%d X:%.2f Y:%.2f Z:%.2f I:%.2f J:%.2f F:%.2f\r\n", gcmd_list[i].G, gcmd_list[i].X, gcmd_list[i].Y, gcmd_list[i].Z, gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].F);
            //wait(10);
            //uLCD.cls();              
            switch(gcmd_list[i].G) {
                case 0:
                case 1:
                    //Draw a line.
                    if(gcmd_list[i].X != -1 && gcmd_list[i].Y != -1) {
                        //uLCD.printf("Going to: %.2f, %.2f\n",gcmd_list[i].X,gcmd_list[i].Y);
                        bot.line_safe(gcmd_list[i].X, -1*gcmd_list[i].Y+20);
                    }
                    if(gcmd_list[i].Z > 0) {
                        //uLCD.printf("PEN UP\n");
                        bot.pen_up();    
                    }else if(gcmd_list[i].Z < 0) {
                        //uLCD.printf("PEN DOWN\n");
                        bot.pen_down();    
                    }
                break;
                case 2:
                    //Draw an arc or something.
                    bot.arc(gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].X, gcmd_list[i].Y, CCW_ARC);
                break;
                case 3:
                    //Draw a different arc or something.
                    bot.arc(gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].X, gcmd_list[i].Y, CW_ARC);
                break;
                default:
                break;
                
            }
        }   
        bot.disable();
}

//===================================================
/*
 * mbed GCode parsing Library
 *
 */



#define FEEDME 10
#define END_OF_TRANSMISSION 23
//extern MODSERIAL gpc;

/************VARS*******************************/
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

// buffer used to transfer the serial buffer contents and parse them into cmd structure
char rx_buff[CMD_BUFFER_SIZE];

volatile bool received;     // indicates when a new cmd is available in the serial buffer
bool endTransmission;       // indicates that all the commands have been sent from the pc

int list_position;  // counter to index the array of command structures


/* This initializes the serial port params to match the PC application
 * the interrupt handlers are also initialized here
 */
void parserInit()
{
    list_position = 0;
    received = false;
    endTransmission = false;
    gpc.baud(921600);
    gpc.autoDetectChar('\0');  //<--to catch the null terminator at the end
    gpc.attach(&cmd_Received, MODSERIAL::RxAutoDetect); // declares callback for when cmd is ready
    gpc.rxBufferFlush();    // flush the buffer just in case
}

/* Parses the received messages into a G_cmd structure
 * it waits for the serial buffer to contain an entire command,
 * parses the gcode and sends the FEEDME command
 * to the pc to request another gcode line
 * returns a pointer to the allocated list of commands.
 */
int fillInCmdList()
{
    // end_flag_received should be detected in parseGcode()
    while(endTransmission == false) {
        // Light up LED1 to indicate the mbed is ready to receive Serial commands
        led1 = 1;
        if(received == true) {  //if the buffer has received the null terminator

            // Signal that we are now parsing by lighting LED2
            //led1 = 0;
            led2 = 1;
            parseGcode();
            gpc.rxBufferFlush();        // flushing the buffer just in case
            received = false;
            gpc.putc(FEEDME);           // requesting next command from the pc
            led2 = 0;                   // parsing stage is over
        }
    }
    
    //uLCD.printf("Commands copied %d\n", list_position);
    //for(int i = 0; i < list_position; i++) {
    //    uLCD.printf("G:%d X:%.2f Y:%.2f Z:%.2f I:%.2f J:%.2f F:%.2f\r\n", gcmd_list[i].G, gcmd_list[i].X, gcmd_list[i].Y, gcmd_list[i].Z, gcmd_list[i].I, gcmd_list[i].J, gcmd_list[i].F);
    //wait(10);
    //uLCD.cls();
    //}
    
    led1 = 1;
    wait(0.5);
    led1 = 0;
    led2 = 1;
    wait(0.5);
    led2 = 0;
    led3 = 1;
    wait(0.5);
    led3 = 0;
    led1 = 1;
    wait(0.5);
    led3 = 1;
    led2 = 1;
    return (list_position);
}

//interrupt routine called when the null terminator is received
void cmd_Received(MODSERIAL_IRQ_INFO *q)
{
    MODSERIAL *sys = q->serial;
    sys->move(rx_buff, CMD_BUFFER_SIZE);;
    received = true;
}
//TODO: Detect the connection finish characters and set a flag so fillInCmdBuff can return
// Parses the received message and populates the structure
void parseGcode()
{
    // checking for the termination of connection
    if(rx_buff[0] == END_OF_TRANSMISSION) {
        led4 = 1;       //received end of transmission from pc
        endTransmission = true;
        return;
    }

    // in case there are leading spaces
    char* cmdP = strtok(rx_buff, " G");

    char coord_label[2];

    //int g = atoi(cmdP);

    //uLCD.printf("list pos is: %d\n", list_position);

    //fill out the command number field
    gcmd_list[list_position].G = atoi(cmdP);
    gcmd_list[list_position].X = -1;
    gcmd_list[list_position].Y = -1;
    gcmd_list[list_position].Z = 0; 
    gcmd_list[list_position].F = -1;
    gcmd_list[list_position].I = -1;
    gcmd_list[list_position].J = -1;

    //uLCD.printf("%d: ", gcmd_list[list_position].G);

    // Looping to get the arguments
    while (cmdP != NULL) {
        // Retrieve the next Label
        cmdP = strtok (NULL, " G");
        // cmdP should be pointing to a letter now
        //uLCD.printf("Coord: %s.\n", cmdP);
        coord_label[0] = cmdP[0];
        coord_label[1] = cmdP[1];

        // retrieve the number after the letter
        cmdP = strtok (NULL, " G");

        // now print the number
        //uLCD.printf("%s ", cmdP);
        /*
        gcmd_list[list_position].X = -1;
        gcmd_list[list_position].Y = -1;
        gcmd_list[list_position].Z = -2;
        gcmd_list[list_position].F = -1;
        gcmd_list[list_position].I = -1;
        gcmd_list[list_position].J = -1;
        */
        switch(coord_label[0]) {
            case 'X':
                gcmd_list[list_position].X = atof(cmdP);
                break;
            case 'Y':
                gcmd_list[list_position].Y = atof(cmdP);
                break;
            case 'Z':
                gcmd_list[list_position].Z = atof(cmdP);
                break;
            case 'F':
                gcmd_list[list_position].F = atof(cmdP);
                break;
            case 'I':
                gcmd_list[list_position].I = atof(cmdP);
                break;
            case 'J':
                gcmd_list[list_position].J = atof(cmdP);
                break;
            default:

                break;
        }// switch
    } // while
    list_position++;
}