Andy K / Mbed 2 deprecated Roomba

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Roomba.cpp Source File

Roomba.cpp

00001 /*
00002     Copyright (c) 2010 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021     
00022     @file          Roomba.cpp
00023     @purpose       http://mbed.org/forum/mbed/topic/1476
00024     @version       0.1 (untested)
00025     @date          Dec 2010
00026     @author        Andy Kirkham    
00027     @see           http://mbed.org/forum/mbed/topic/1476 
00028 */
00029 
00030 #include "Roomba.h"
00031 
00032 void
00033 Roomba::init(PinName tx, PinName rx)
00034 {
00035     state = Idle;    
00036     uart = new MODSERIAL(tx, rx);
00037     tick = new Ticker;
00038     uart->attach(this, &Roomba::cbSerial, MODSERIAL::RxIrq);
00039     tick->attach(this, &Roomba::cbTicker, 0.1);   
00040 }
00041 
00042 int
00043 Roomba::command(RoombaState cmd, int opts, char *opt, bool block) {
00044     if (state != Idle) return (int)NotIdle;
00045     
00046     // Impose our state on teh system. Use a loop to
00047     // make sure no interrupt "nips in" and alters 
00048     // the state machine.
00049     while (state != cmd) {
00050         state = cmd;
00051     }
00052     
00053     // Send command.
00054     uart->putc(cmd);
00055     
00056     // Send any additional option bytes.
00057     if (opts > 0) {
00058         for (int i = 0; i < opts; i++) {
00059             uart->putc(opt[i]);
00060         }
00061     }
00062     
00063     // Wait until the serial characters have left the Mbed.
00064     // Only do this is arg block is true (which is the default).
00065     if (block) while (uart->txIsBusy() || uart->txBufferGetCount() != 0);
00066     
00067     // Return state back to idle
00068     state = Idle;
00069     
00070     return cmd;
00071 }
00072 
00073 int
00074 Roomba::cmdSensors(CallType type)
00075 {
00076     if (type == Invoke) {
00077         if (state != Idle) {
00078             return (int)NotIdle;
00079         }
00080         
00081         // We are already in interrupt context
00082         // so no need to loop here, nothing is
00083         // going to interrupt us.
00084         state = CmdSensors;
00085         
00086         // Flush the buffers and send teh command+opt
00087         uart->rxBufferFlush();
00088         uart->putc(CmdSensors);
00089         uart->putc(0); 
00090         
00091         // Leave state in CmdSensors so nothing else can use the
00092         // serial port until the CmdSensors has completed. See
00093         // below where the command end is detected and terminated.
00094     }
00095     
00096     if (type == SerialCallback) {
00097         if (state == CmdSensors && uart->rxBufferGetCount() == 26) {
00098             sensors8bit[bumpsWheeldrops]        =  uart->getc();
00099             sensors8bit[wall]                   =  uart->getc();
00100             sensors8bit[cliffLeft]              =  uart->getc();
00101             sensors8bit[cliffFrontLeft]         =  uart->getc();
00102             sensors8bit[cliffFrontRight]        =  uart->getc();
00103             sensors8bit[cliffRight]             =  uart->getc();
00104             sensors8bit[virtualWall]            =  uart->getc();
00105             sensors8bit[motorOvercurrents]      =  uart->getc();
00106             sensors8bit[dirtDetectorLeft]       =  uart->getc();
00107             sensors8bit[dirtDetectorRight]      =  uart->getc();
00108             sensors8bit[remoteControlCommand]   =  uart->getc();
00109             sensors8bit[buttons]                =  uart->getc();
00110             sensors16bit[distance]              = (uart->getc() << 8) | uart->getc();
00111             sensors16bit[angle]                 = (uart->getc() << 8) | uart->getc();
00112             sensors8bit[chargingState]          =  uart->getc();
00113             sensors16bit[voltage]               = (uart->getc() << 8) | uart->getc();
00114             sensors16bit[current]               = (uart->getc() << 8) | uart->getc();
00115             sensors8bit[temperature]            =  uart->getc();
00116             sensors16bit[charge]                = (uart->getc() << 8) | uart->getc();
00117             sensors16bit[capacity]              = (uart->getc() << 8) | uart->getc();             
00118             
00119             // All done, release teh serial port back to idle.
00120             state = Idle;                       
00121         }
00122     }   
00123     
00124     return Ok;
00125 }
00126 
00127