A WiFiDipCortex based robot. Control is via sockets over WiFi. See also: https://github.com/mfurseman/robo-android
Dependencies: Motordriver USBDevice cc3000_hostdriver_mbedsocket_hacked mbed
main.cpp
- Committer:
- mfurseman
- Date:
- 2014-11-17
- Revision:
- 5:7f5fcee1737d
- Parent:
- 4:1b5c2a2cdeb7
- Child:
- 7:ee8b630b0a33
File content as of revision 5:7f5fcee1737d:
#include <stdint.h> #include <mbed.h> #include "motordriver.h" #include "cc3000.h" #include "TCPSocketConnection.h" #include "TCPSocketServer.h" /* MAC 08:00:28:57:43:b8 */ /* Quickly change debug flag to remove USB serial code */ //#define DEBUG #ifdef DEBUG #include "USBSerial.h" USBSerial serial; #define debug(x, ...) serial.printf(x, ##__VA_ARGS__); #else #define debug(x, ...) #endif /* Network constants */ #define SERVER_PORT 5678 /* Client commands */ #define CMD_NULL 0 #define CMD_C_ECHO 0x61 // 'a' #define CMD_C_LED_ON 0x62 // 'b' #define CMD_C_LED_OFF 0x63 // 'c' #define CMD_C_PRINT_UINT32 0x64 // 'd' #define CMD_C_MOTOR_LEFT_DUTY 0x65 // 'e' #define CMD_C_MOTOR_RIGHT_DUTY 0x66 // 'f' #define CMD_C_MOTOR_LEFT_COAST 0x67 // 'g' #define CMD_C_MOTOR_RIGHT_COAST 0x68 // 'h' #define CMD_C_MOTOR_LEFT_STOP 0x69 // 'i' #define CMD_C_MOTOR_RIGHT_STOP 0x70 // 'j' using namespace mbed_cc3000; /* On board LED */ DigitalOut led(P0_1); /* Motors: allow breaking */ Motor leftMotor(P0_8, P1_24, P0_4, true); Motor rightMotor(P0_9, P1_13, P1_14, true); /* Serial library for WiFi module */ cc3000 wifi(p28, p27, p30, SPI(p21, p14, p37)); /* Struct to hold connection data */ tNetappIpconfigRetArgs ipinfo; /** * Prints CC3000 connection info */ void printConnectionInfo() { if (( wifi.is_enabled() ) && ( wifi.is_dhcp_configured() )) { wifi.get_ip_config(&ipinfo); } if (! wifi.is_enabled() ) { debug("CC3000 Disabled\r\n"); } else if ( wifi.is_dhcp_configured() ) { debug("SSID : %-33s|\r\n", ipinfo.uaSSID); debug("IP : %-35s|\r\n", wifi.getIPAddress()); } else if ( wifi.is_connected() ) { debug("Connecting, waiting for DHCP\r\n"); } else { debug("Not Connected\r\n"); } } /** * WiFi DipCortex board setup */ void init() { NVIC_SetPriority(SSP1_IRQn, 0x0); NVIC_SetPriority(PIN_INT0_IRQn, 0x1); // SysTick set to lower priority than Wi-Fi SPI bus interrupt NVIC_SetPriority(SysTick_IRQn, 0x2); // Enable RAM1 LPC_SYSCON->SYSAHBCLKCTRL |= (0x1 << 26); // This may be neccassary for CC3000 wait(1); } /** * Connects WiFi assuming existing SmartConfig */ void connectWifi() { wifi.start(0); wait_ms(750); wifi._wlan.ioctl_set_connection_policy(0, 0, 1); // TODO: Timeout and switch on smart config here // TODO: Use static IP if possible } /** * Brute force check to see if the connection is connected. * CC3000 doesn't detect dropped connection until send is * called. */ bool isConnected(TCPSocketConnection *connection) { connection->set_blocking(false, 1000); return connection->send("abc\r\n", 5) < 0; } /** * Reads a long from the client and returns it as a float * between 0.0 and 1.0, which represents the relative * magnitude of the byte between 0 and UINT32_MAX. */ float getUint32AsFloat(TCPSocketConnection* connection) { uint32_t int_buffer; connection->set_blocking(false, 2000); int status = connection->receive_all((char*)&int_buffer, sizeof(int_buffer)); // 4 Bytes debug("Command print int32 recieved: %u with status: %d\r\n", int_buffer, status); int_buffer = ntohl(int_buffer); debug("Converted to host byte order: %u\r\n", int_buffer); debug("Conversion of uint32_t to float: %f\r\n", ((int_buffer*1.0f) / ((uint32_t)-1))); return (int_buffer*1.0f) / ((uint32_t)-1); } /** * Reads a byte from the client and returns it as a float * between 0.0 and 1.0, which represents the relative * magnitude of the byte between 0 and UINT8_MAX. */ float getUint8AsFloat(TCPSocketConnection* connection) { uint8_t char_buffer; connection->set_blocking(false, 2000); int status = connection->receive_all((char*)&char_buffer, sizeof(char_buffer)); // 1 Byte debug("Command left motor duty received: %d with status %d\r\n", char_buffer, status); debug("Converstion from uint8_t to float: %f\r\n", ((char_buffer*1.0f) / ((uint8_t)-1))); return (char_buffer*1.0f) / ((uint8_t)-1); } /** * Client connection loop. This monitors the socket for * connections and proccesses them when they are * recieved. It returns when the client disconnects. */ void monitorConnection(TCPSocketConnection* connection) { int timeout_counter = 1; while(1) { wait_ms(15); char command = 0; connection->set_blocking(false, 5); // 5 ms time out is min for CC3000 int status = connection->receive(&command, 1); if(status == 1) { debug("Recieved data from connection: %d with status %d\r\n", command, status); switch(command) { case CMD_C_ECHO: wait_ms(15); char buffer[3]; connection->set_blocking(false, 2000); status = connection->receive_all(buffer, sizeof(buffer)); debug("Echo test recieved: %s Status: %d\r\n", buffer, status); wait_ms(15); status = connection->send_all(buffer, sizeof(buffer)); debug("Echo test send completed with status: %d\r\n"); break; case CMD_C_LED_ON: led = 1; break; case CMD_C_LED_OFF: led = 0; break; case CMD_C_PRINT_UINT32: wait_ms(15); { // Variable declerations inside switch must be in higher scope. // This is only okay as it's debugging code. float printFloat = getUint32AsFloat(connection); debug("Print uint32 got float with value %f\r\n", printFloat); } break; case CMD_C_MOTOR_LEFT_DUTY: wait_ms(15); leftMotor.speed(2.0f * getUint8AsFloat(connection) - 1.0f); // Convert to +/- 1 break; case CMD_C_MOTOR_RIGHT_DUTY: wait_ms(15); rightMotor.speed(2.0f * getUint8AsFloat(connection) - 1.0f); // Convert to +/- 1 break; case CMD_C_MOTOR_LEFT_COAST: leftMotor.coast(); break; case CMD_C_MOTOR_RIGHT_COAST: rightMotor.coast(); break; case CMD_C_MOTOR_LEFT_STOP: wait_ms(15); leftMotor.stop(getUint8AsFloat(connection)); break; case CMD_C_MOTOR_RIGHT_STOP: wait_ms(15); rightMotor.stop(getUint8AsFloat(connection)); break; default: debug("Command %d not recognised\r\n", command); break; } } wait_ms(15); /* Check to see if the non-blocking socket is closed */ if((timeout_counter++) % 100 == 0) { if(!isConnected(connection)) { debug("Client disconected\r\n"); break; } } } } /** * Where it all begins. */ int main(void) { init(); debug("Completed init()\r\n"); printConnectionInfo(); connectWifi(); debug("Completed connectWifi()\r\n"); printConnectionInfo(); while(1) { debug("\r\nOne second client attachment loop\r\n"); printConnectionInfo(); TCPSocketConnection client; TCPSocketServer server; wait_ms(15); server.bind(SERVER_PORT); server.listen(); int32_t status = server.accept(client); debug("Accept client returned with status %d\r\n", status); if(status >= 0) { wait_ms(15); client.set_blocking(false, 1000); debug("Connection from: %s \r\n", client.get_address()); monitorConnection(&client); debug("Client connection lost\r\n"); } led = !led; wait(1); } }