![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
The MBED firmware used on the Chipin sorter, developed over 12 weeks for a 3rd year university systems project. Chipin is a token sorter, it sorts tokens by colours and dispenses them to order through an online booking system and card reader. This program interfaces with an FPGA, PC and LCD screen to control the sorter. The sorter has an operation mode where it can process orders when a card is entered into the machine. There is also a maintenance mode where the device responds to maintenance instructions such as 'dispense all'. More information at http://www.ionsystems.uk/
Dependencies: MCP23017 TCS3472_I2C WattBob_TextLCD mbed-rtos mbed
main.cpp
00001 bool operationMode = true; //the MBED starts in operation mode. 00002 00003 #include "mbed.h" 00004 Serial pc(USBTX, USBRX); 00005 Serial glcd(p13, p14); 00006 #include "rtos.h" 00007 #include "Language.h" 00008 DigitalIn languageButton(p30); 00009 Language currentLanguage = ENGLISH; 00010 #include <sstream> 00011 #include <string> 00012 #include "mbedStorage.h" 00013 #include "mbedLCD.h" 00014 #include "stateMachine.h" 00015 #include "FPGAcomms.h" 00016 #ifndef serialComm 00017 #define serialComm 00018 #include "serialCommunication.h" 00019 #endif 00020 00021 00022 DigitalOut led1(LED1); 00023 DigitalOut led2(LED2); 00024 DigitalOut led3(LED3); 00025 DigitalOut led4(LED4); 00026 00027 StateMachine stateMachine; 00028 00029 //Boolean values to easily enable and disable certain features for individual testing 00030 bool colourSensor = true; 00031 bool cardReader = true; 00032 bool sorter = true; 00033 bool dispensor = true; 00034 bool testFunctions = true; 00035 bool serialComms = true; 00036 00037 int mode = 0; //mode select 00038 int maintenanceModeSelect = 0; 00039 00040 //Call to check if an MBED button is pressed 00041 bool buttonPressed(int buttonNumber) 00042 { 00043 if(buttonNumber > -1 && buttonNumber < 4) { 00044 return par_port->read_bit(buttonNumber + 8); 00045 } 00046 return false; 00047 } 00048 //Run a mode, defined by 'mode'. 00049 void checkSortDispenseButtons() 00050 { 00051 00052 if(buttonPressed(3)) { 00053 mode = !mode; 00054 } 00055 /* NOTICE: Enable the modes below for more maintenace functions, good for debugging. 00056 */ 00057 00058 00059 /* 00060 if(mode == 0) { //Dispense Mode 00061 printLCD("Dispense Mode"); 00062 operationMode=false; 00063 if(buttonPressed(0)) { 00064 printLCD("Red Button pressed"); 00065 dispense(RED); 00066 } else if(buttonPressed(1)) { 00067 printLCD("Green Button pressed"); 00068 dispense(GREEN); 00069 } else if(buttonPressed(2)) { 00070 printLCD("Blue Button pressed"); 00071 dispense(BLUE); 00072 } 00073 00074 } *//*else if(mode == 1) { //Sort Mode 00075 printLCD("Sort Mode"); 00076 operationMode=false; 00077 if(buttonPressed(0)) { 00078 log("Red Button pressed"); 00079 sort(RED); 00080 } else if(buttonPressed(1)) { 00081 log("Green Button pressed"); 00082 sort(GREEN); 00083 } else if(buttonPressed(2)) { 00084 log("Blue Button pressed"); 00085 sort(BLUE); 00086 } 00087 00088 }*//* else if(mode == 2) { //Bin/Recycle Mode 00089 printLCD("Bin/Recycle Mode"); 00090 operationMode=false; 00091 if(buttonPressed(0)) { 00092 log("Bin button pressed"); 00093 sort(BIN); 00094 } else if(buttonPressed(1)) { 00095 log("Recycle Button"); 00096 recycle(); 00097 } 00098 } */ 00099 /*else if(mode == 4) { //Card Reader Mode 00100 operationMode= true; 00101 if(cardReader && cardDetect) { 00102 cardAcquisition(); 00103 00104 }*/ 00105 if(mode == 0) { //Storage Mode 00106 operationMode=true; 00107 stringstream ss; 00108 ss << "Operation: " << "R:" << redAmount << "G:" << greenAmount << "B:" << blueAmount << "RE:" << recycleAmount; 00109 string tmp = ss.str(); 00110 printLCD(tmp.c_str()); 00111 wait(0.1); 00112 if(buttonPressed(0)) { 00113 //log("Dispense all button pressed"); 00114 dispenseAll(); 00115 } else if(buttonPressed(1)) { 00116 //log("Clear stored numbers button pressed"); 00117 writeFile(0,0,0,recycleAmount); 00118 redAmount = 0; 00119 greenAmount = 0; 00120 blueAmount = 0; 00121 printLCD("Cleared values"); 00122 00123 } else if(buttonPressed(2)) { 00124 //log("Increment all stored values by 2."); 00125 redAmount += 2; 00126 greenAmount += 2; 00127 blueAmount += 2; 00128 writeFile(redAmount,greenAmount,blueAmount,recycleAmount); 00129 00130 printLCD("set values to 2"); 00131 00132 } 00133 } else if(mode == 1) { 00134 operationMode = false; 00135 stringstream ss; 00136 ss << maintenanceModeSelect; 00137 string mainModeSelect = ss.str(); 00138 printLCD("Maintenance: " + mainModeSelect); 00139 wait(0.1); //Maintenance Mode 00140 00141 if(buttonPressed(0)) { //Next maintenance function 00142 maintenanceModeSelect++; 00143 if(maintenanceModeSelect > 13) maintenanceModeSelect = 0; 00144 } else if(buttonPressed(1)) { //Previous maintenance function 00145 maintenanceModeSelect--; 00146 if(maintenanceModeSelect < 0) maintenanceModeSelect = 13; 00147 } else if(buttonPressed(2)) { //Process Instruction 00148 switch(maintenanceModeSelect) { 00149 case 0://RB_LEFT: 00150 printLCD("Moving Red/Blue Slider left."); 00151 maintain(RB_LEFT); 00152 break; 00153 00154 case 1://RB_CENTRE: 00155 printLCD("Centering Red/Blue Slider."); 00156 maintain(RB_CENTRE); 00157 break; 00158 00159 case 2://RB_RIGHT: 00160 printLCD("Moving Red/Blue Slider right."); 00161 maintain(RB_RIGHT); 00162 break; 00163 00164 case 3://GO_UP: 00165 printLCD("Moving Green Slider up."); 00166 maintain(GO_UP); 00167 break; 00168 00169 case 4://GO_CENTRE: 00170 printLCD("Centering Green Slider."); 00171 maintain(GO_CENTRE); 00172 break; 00173 00174 case 5://GO_DOWN: 00175 printLCD("Moving Green Slider down."); 00176 maintain(GO_DOWN); 00177 break; 00178 00179 case 6://BR_LEFT: 00180 printLCD("Moving Bin Slider left."); 00181 maintain(BR_LEFT); 00182 break; 00183 00184 case 7://BR_RIGHT: 00185 printLCD("Moving Bin Slider right."); 00186 maintain(BR_RIGHT); 00187 break; 00188 00189 case 8://R_PUSH: 00190 printLCD("Pushing red dispensor"); 00191 maintain(R_PUSH); 00192 break; 00193 00194 case 9://R_HOME: 00195 printLCD("Homing red dispensor"); 00196 maintain(R_HOME); 00197 break; 00198 00199 case 10://GB_LEFT: 00200 printLCD("Pushing green dispensor"); 00201 maintain(GB_LEFT); 00202 break; 00203 00204 case 11://GB_CENTRE: 00205 printLCD("Centre green/blue dispensor"); 00206 maintain(GB_CENTRE); 00207 break; 00208 00209 case 12://GB_RIGHT: 00210 printLCD("Pushing blue dispensor"); 00211 maintain(GB_RIGHT ); 00212 break; 00213 00214 case 13: //MaintenanceEND 00215 printLCD("Ending Maintenance Mode"); 00216 maintain(maintenanceEND); 00217 break; 00218 } 00219 printLCD("Ready for next command"); 00220 wait(1); 00221 } 00222 } 00223 } 00224 //Coordinate changing language on PC and Arduino. 00225 void changeLanguage() 00226 { 00227 currentLanguage = nextLanguage(currentLanguage); //Change the language on teh MBED. 00228 sendLanguageCharacter(); //Tell PC & Arduino to change language. 00229 wait(1); 00230 } 00231 00232 /* void sortFunction() 00233 * Read sensor and sort according to the colour. 00234 */ 00235 void sortFunction() 00236 { 00237 //Read the colour twice and make sure both are the same. If not then return and try again. 00238 Thread::wait(100); 00239 Colour colour = readColourSensor(); 00240 Thread::wait(100); 00241 Colour colour2 = readColourSensor(); 00242 if(colour != colour2) { 00243 return; 00244 } 00245 //Ensure a bin read is valid by ensuring it is the same as earlier. Prevents a bin read being valid if the chip is out of place on the sensor. 00246 if(colour == BIN) { 00247 Thread::wait(100); 00248 Colour binCheck = readColourSensor(); 00249 if(binCheck != colour) { 00250 return; 00251 } 00252 } 00253 00254 //log("Sorting colour"); 00255 sort(colour); 00256 } 00257 00258 //Run sortFunction with a small delay between iterations, pulses LED. 00259 void sortMode(void const* args) 00260 { 00261 while(colourSensor && sorter) { 00262 if(operationMode) { 00263 led2 = 1; 00264 sortFunction(); 00265 led2 = 0; 00266 Thread::wait(50); 00267 } 00268 } 00269 } 00270 00271 bool pcReady = false; //Defines whether the PC is ready to accept characters on the COM port. 00272 //handles dispensing from a card, changing language 00273 void dispenseFunction() 00274 { 00275 if(!pcReady) { 00276 if(pc.getc() == '*') { 00277 pcReady = true; 00278 } 00279 } else { 00280 //Check language button 00281 if(languageButton) { 00282 changeLanguage(); 00283 } 00284 if(cardReader && cardDetect) { 00285 //Read card 00286 int cardNumber = cardAcquisition(); 00287 00288 //Send message to pc 00289 pc.putc('*'); 00290 wait(0.5); 00291 00292 //Send card number to pc 00293 pc.printf("%i\n",cardNumber); 00294 00295 int red = 0; 00296 int green = 0; 00297 int blue = 0; 00298 00299 //Get order from pc, convert characters to integers. 00300 red = (int) pc.getc() - '0'; 00301 green = (int) pc.getc() - '0'; 00302 blue = (int) pc.getc() - '0'; 00303 00304 //Check if there are enough chips to dispense order 00305 Thread::wait(100); 00306 if(red > redAmount || green > greenAmount || blue > blueAmount) { 00307 //If not then do not dispense 00308 pc.putc('<'); 00309 pcReady = false; 00310 } else if(red ==0 && green == 0 && blue ==0) { 00311 pc.putc('@'); 00312 pcReady = false; 00313 } else { 00314 //Otherwise there are enough tokens so dispense the order 00315 pc.putc('>'); 00316 00317 //Display order on LCD 00318 glcd.putc(27); 00319 glcd.putc(18); 00320 glcd.putc(red + '0'); //Convert int to char 00321 glcd.putc(green + '0');//Convert int to char 00322 glcd.putc(blue + '0');//Convert int to char 00323 glcd.putc(255); 00324 00325 //Dispense Order 00326 dispenseOrder(red,green,blue); 00327 00328 //Display finished dispensing on lcd 00329 glcd.putc(27); 00330 glcd.putc(19); 00331 glcd.putc(255); 00332 00333 //Reset pc ready 00334 pcReady = false; 00335 wait(1); 00336 pc.putc('('); 00337 } 00338 00339 } 00340 } 00341 } 00342 //Runs dispenseFunction with a small delay between iterations, pulses LED. 00343 void dispenseMode(void const* args) 00344 { 00345 00346 while(true) { 00347 if(operationMode) { 00348 led3 = 1; 00349 dispenseFunction(); 00350 led3 =0; 00351 Thread::wait(50); 00352 } 00353 00354 } 00355 } 00356 00357 00358 int main() 00359 { 00360 led1 = 0; 00361 setupLCD(); 00362 printLCD("Welcome to the Chipin Sorter"); 00363 Thread::wait(1000); 00364 readChipNumbers(); 00365 printStoredChipValues(); 00366 printLCD("Resetting all sliders"); 00367 maintain(maintenanceEND); //reset sliders on FPGA 00368 printLCD(""); 00369 Thread::wait(1000); 00370 sendLanguageCharacter(); //Synchronise language on PC and arduino 00371 00372 Thread sortThread(sortMode); //Start the sorting thread. 00373 if(!languageButton) { //Decide whether to start in operation mode or maintenance mode. 00374 operationMode = true; 00375 mode = 0; 00376 00377 } else { 00378 operationMode = false; 00379 mode = 1; 00380 } 00381 Thread dispenseThread(dispenseMode); //Start the dispensing thread. 00382 while(true) { 00383 led1 = 1; //pulse led1 00384 led4 = cardDetect; 00385 00386 if(!operationMode) { //Check for maintenance commands if in maintenance mode. 00387 checkSerial(); 00388 } 00389 if(testFunctions) checkSortDispenseButtons(); //Run the MBED modes if enabled. 00390 Thread::wait(100); 00391 led1=0; 00392 Thread::wait(100); 00393 } 00394 }
Generated on Thu Jul 14 2022 19:06:18 by
![doxygen](doxygen.png)