A web server for monitoring and controlling a MakerBot Replicator over the USB host and ethernet.

Dependencies:   IAP NTPClient RTC mbed-rtos mbed Socket lwip-sys lwip BurstSPI

Fork of LPC1768_Mini-DK by Frank Vannieuwkerke

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // Copyright (c) 2013, jake (at) allaboutjake (dot) com
00002 // All rights reserved.
00003 // 
00004 // Redistribution and use in source and binary forms, with or without
00005 // modification, are permitted provided that the following conditions are met:
00006 //     * Redistributions of source code must retain the above copyright
00007 //       notice, this list of conditions and the following disclaimer.
00008 //     * Redistributions in binary form must reproduce the above copyright
00009 //       notice, this list of conditions and the following disclaimer in the
00010 //       documentation and/or other materials provided with the distribution.
00011 //     * The name of the author and/or copyright holder nor the
00012 //       names of its contributors may be used to endorse or promote products
00013 //       derived from this software without specific prior written permission.
00014 // 
00015 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00016 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00018 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, AUTHOR, OR ANY CONTRIBUTORS
00019 // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00020 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00021 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00022 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00023 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00024 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026 // DESCRIPTION OF FILE:
00027 //
00028 // This file contains the main entry point for the firmware.  It sets up 
00029 // the necessary hardware peripherals and starts the application threads.
00030 //
00031 
00032 
00033 #include "main.h"
00034 #include "stdio.h"
00035 #include "mbed.h"
00036 #include "Mini_DK.h"
00037 #include "EthernetInterface.h"
00038 #include "NTPClient.h"
00039 #include "RTC.h"
00040 #include "USBHostSerial.h"
00041 #include "makerbot.h"
00042 #include "SimpleSocket.h"
00043 #include "readline.h"
00044 #include "telnetd.h"
00045 #include "httpd.h"
00046 #include "NTPClient.h"
00047 #include "NTPClient.h"
00048 
00049 #ifdef TARGET_MINIDK
00050     //Define the pins and objects related to the Mini_DK2 development board
00051     DigitalOut led1(DK_LED1);
00052     DigitalOut led2(DK_LED2);
00053     DigitalOut usbpwr(USB_PPWR);
00054 
00055     InterruptIn key1(DK_KEY1);
00056     InterruptIn key2(DK_KEY2);
00057 #ifdef MINIDK_HAS_LCD
00058     // TFT -> mosi, miso, sclk, cs
00059     SPI_TFT TFT(LCD_SDI, LCD_SDO, LCD_SCK, LCD_CS,"TFT");
00060 
00061     // ADS7843 -> mosi, miso, sclk, cs, irq, SPI_TFT
00062     //TouchScreenADS7843 TP(TP_SDI ,TP_SDO ,TP_SCK ,TP_CS ,TP_IRQ, &TFT);
00063 #endif
00064 
00065 #endif
00066 
00067 #ifdef TARGET_MBED
00068     DigitalOut led1(LED1);
00069     DigitalOut led2(LED2);
00070 #endif
00071 
00072 //Declare the serial interface
00073 Serial pc(USBTX, USBRX);
00074 
00075 //Declare the USBHostSerial and Makerbot object pointers
00076 USBHostSerial* serial;
00077 Makerbot* bot;
00078 
00079 //function to initialize the LCD (for Mini-DK2 only)
00080 void initialize_TFT() {
00081 #if defined(TARGET_MINIDK) && defined(MINIDK_HAS_LCD)
00082     //TFT.claim(stdout);        // send stdout to the TFT display
00083     TFT.background(Black);    // set background to black
00084     TFT.foreground(White);    // set chars to white
00085     
00086     TFT.cls();
00087     TFT.set_orientation(1);
00088     TFT.set_font((unsigned char*) Arial12x12);
00089     TFT.locate(0,0);
00090 #endif
00091 }
00092 
00093 // Configure and wait for a the USB cable to be connected to the Makerbot
00094 void serial_task(void const*) {
00095     //Create the USBHostSerial object    
00096     serial = new USBHostSerial;
00097     
00098     DISPLAY("Initializing USBHostSerial.\r\n");
00099     DISPLAY("Trying to connect to serial device.\r\n");
00100         
00101     // try to connect a serial device.  Wait and retry if no connection
00102     while(!serial->connect())
00103         Thread::wait(500);
00104 
00105     //Set N,8,1
00106     DISPLAY("Setting serial parameters.\r\n");
00107     serial->format(8, USBHostSerial::None, 1);
00108     
00109     //Set baud to 115200 (as is used by the Makerbot)
00110     DISPLAY("Setting baud to 115200\r\n");
00111     serial->baud(115200);
00112     
00113     //All done!
00114     DISPLAY("Serial initialized.\r\n");
00115     
00116     //Create the bot object for interacting with the machine over the s3g protocol
00117     bot = new Makerbot(serial);
00118     
00119     //Quick synchronizaton of the packet stream
00120     bot->getMakerbotVersion();
00121     bot->flushInputChannel();
00122     
00123     //Get the version of the makerbot
00124     float version = bot->getMakerbotVersion();
00125     DISPLAY("Makerbot version: %0.1f\r\n", version);
00126     
00127     //Get the bot name
00128     char* bot_name = bot->getMachineName();   
00129     DISPLAY("Machine name: %s\r\n", bot_name);
00130     
00131 }
00132 
00133 
00134 
00135 
00136 // A pointer for the task that acts on the button interrupts
00137 Thread* buttonTask;
00138 
00139 // Interrupt handler for the first button
00140 void isr_key1() {
00141     //Set a signal 0b00000001 = button 1.
00142     buttonTask->signal_set(0x1);
00143 }
00144  
00145 // Interrupt handler for the second button
00146 void isr_key2() {
00147     //Set a signal 0b00000010 = button 2.
00148     buttonTask->signal_set(0x2);
00149 }
00150 
00151 //The task that handles the button presses
00152 void button_task(void const*) {
00153     while (1) {
00154         //Wait for any signal to this thread
00155         osEvent evt = Thread::signal_wait(0);
00156         
00157         // If button=1 then send the pause/resume command;        
00158         if (evt.value.signals & 0x01) {
00159             if (bot) {
00160                 Makerbot::MakerbotBuildState state = bot->getBuildState();
00161                 if (state.build_state == Makerbot::BUILD_STATE_ERROR) {
00162                     //DISPLAY("Error: unable to determine build state.  Sending pause/resume command in the blind.\r\n");
00163                     bot->pauseResume();
00164                 } else if (state.build_state == Makerbot::BUILD_RUNNING) {
00165                     bot->pauseResume();
00166                     //DISPLAY("Pausing build.\r\n");
00167                 } else {
00168                     //DISPLAY("Error: Not currently building, cannot pause\r\n");
00169                 }
00170             } else {
00171                //DISPLAY("Error: connection to Makerbot not established.\r\n");                                    
00172             }
00173         }
00174         
00175         // If button=2 print a message to the LCD (debug purposes)
00176         //TODO: replace this with something useful
00177         if (evt.value.signals & 0x02) {
00178             if (bot) {
00179                 Makerbot::MakerbotBuildState state = bot->getBuildState();
00180                 if (state.build_state == Makerbot::BUILD_STATE_ERROR) {
00181                     //DISPLAY("Error: unable to determine build state.  Sending pause/resume command in the blind.\r\n");
00182                     bot->pauseResume();
00183                 } else if (state.build_state == Makerbot::BUILD_PAUSED) {
00184                     bot->pauseResume();
00185                     //DISPLAY("Pausing build.\r\n");
00186                 } else {
00187                     //DISPLAY("Error: Not currently paused.  Cannot resume.\r\n");
00188                 }
00189             } else {
00190                 //DISPLAY("Error: connection to Makerbot not established.\r\n");                                    
00191             }
00192             break;
00193         }        
00194         Thread::wait(250);
00195     }
00196 }
00197  
00198 
00199 int main() {
00200     //Set the baud rate off the serial debug console.
00201     pc.baud(115200);
00202     pc.printf("Firmware Version: %s\r\n", FIRMWARE_VERSION);
00203      
00204 #ifdef TARGET_MINIDK  
00205 
00206 #ifdef MINIDK_HAS_LCD
00207     //Initialize the LCD
00208     initialize_TFT();
00209     DISPLAY("Firmware Version: %s\r\n", FIRMWARE_VERSION);
00210 #endif
00211     //Attach the ISR's to the buttons
00212     key1.fall(isr_key1);
00213     key2.fall(isr_key2);
00214 
00215     //Start the task that watches for button press signals
00216     buttonTask = new Thread(button_task, NULL, osPriorityNormal, 128 * 4);
00217     
00218     usbpwr=1; //turn on power to the USBHost port.
00219 #endif
00220 
00221     // Print the MAC address for reference
00222     char mac[6];
00223     mbed_mac_address(mac);
00224     DISPLAY("MAC ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 
00225 
00226     
00227     DISPLAY("Negotiating network.\r\n");
00228     EthernetInterface::init();
00229     EthernetInterface::connect();
00230     DISPLAY("IP Address: %s\r\n", EthernetInterface::getIPAddress());
00231     
00232     DISPLAY("Attempting to set clock...\r\n");
00233     NTPClient* ntp = new NTPClient;
00234     if (ntp->setTime("0.pool.ntp.org") == 0) {      
00235       time_t ctTime;
00236       ctTime = time(NULL);
00237       DISPLAY("Time is set to (UTC): %s\r\n", ctime(&ctTime));
00238     } else {
00239       printf("Unable to set time\r\n");
00240     }
00241     delete ntp;
00242     
00243     // Turn on LED1 (LED1 will blink once we get to main loop)
00244     led1=1;
00245     bot = NULL; //Initialize bot object to NULL so we know when there's a bot object by testing for null
00246     
00247     //Setup the serial and server tasks
00248     Thread serialTask(serial_task, NULL, osPriorityNormal, 256 * 4); 
00249     Thread serverTask(telnet_server_task, NULL, osPriorityNormal, 512 * 4);     
00250     Thread serverTask2(http_server_task, NULL, osPriorityNormal, 512 * 4);     
00251     
00252     //Main loop-- blink the LED and yield to other tasks during WAIT.
00253     while(1) {    
00254         led1=!led1;
00255         Thread::wait(500);
00256     }
00257 }