Cheerlights client using WiFiDIPCortex and WS2801 RGB LED strip
Dependencies: Adafruit_WS2801 HTTPClient cc3000_hostdriver_mbedsocket mbed
Revision 0:98d83f5b309f, committed 2014-02-11
- Comitter:
- SomeRandomBloke
- Date:
- Tue Feb 11 21:30:21 2014 +0000
- Child:
- 1:40027344b249
- Commit message:
- Cheerlights using WiFiDIPCortex
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_WS2801.lib Tue Feb 11 21:30:21 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/SomeRandomBloke/code/Adafruit_WS2801/#6ff477690983
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPClient.lib Tue Feb 11 21:30:21 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/donatien/code/HTTPClient/#1f743885e7de
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cc3000_hostdriver_mbedsocket.lib Tue Feb 11 21:30:21 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Kojto/code/cc3000_hostdriver_mbedsocket/#ca8c234997c0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Feb 11 21:30:21 2014 +0000 @@ -0,0 +1,337 @@ +/** WiFiDIPCortex Cheerlights + * + * @author Andrew Lindsay + * + * @section LICENSE + * + * Copyright (c) 2012 Andrew Lindsay (andrew [at] thiseldo [dot] co [dot] uk) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @section DESCRIPTION + * + * This is a basic cheerlights client, http://www.cheerlights.com/ It uses the + * API url http://api.thingspeak.com/channels/1417/field/1/last.txt to read the last + * colour selected. + * + * The hardware is the WiFiDIPCortex from SolderSplash Labs http://www.soldersplash.co.uk/products/wifi-dipcortex/ + * This is a small, yet powerful LPC1347 Cortex M3 dev board with built in CC3000 WiFi module. + * The CC3000 uses the TI SmartConfig to setup the WiFi connection without having to update any code. + * + * The WiFiDIPCortex requires 2 pushbuttons connected between: + * Reset: Pin 1 (Reset) and GND, plus 10K resistor between Pin 1 and 3.3V, Pin 11 + * Config: Pin 6 (P1_31) and GND, plus 10K resistor between Pin 1 and 3.3V, Pin 11 + * + * The LED strip used in this example is based on the WS2801 chips and requires a CLK and DATA to use it. + * Pin 27 (P0_7) LED strip Data + * Pin 28 (P1_28) LED strip Clk. + * Ideally strip should be powered from a external 3.3V source and the GNDs connected between Power supply and + * WiFiDIPCortex. + * + * Debug output is sent to UART connected to pins 19 and 20. + * + * To use SmartConfig you'll need either the Android or iOS app from http://www.ti.com/tool/SmartConfig. + * The Java version hasnt worked so far, but could also be used. + * To enter SmartConfig mode, hold down the Config button, then press and release Reset, release Config. + * You then use the SmartConfig app to set your network parameters, when you get the notification that + * it was successful the WiFiDIPCortex is configured. The settings are saved and available next time it is powered up. + * + * If SmartConfig fails, try again. + * + * After starting the WiFiDIPCortex will connect to cheerlights.com and retrieve the latest colour and + * set the lights to the colour. + * Every minute the colour is retrieved and if its different to the last one the new colour is shown. + * + * The basic framework can be changed to use different LEDs to suit your available hardware. + * + */ + +#include "mbed.h" +#include "cc3000.h" +#include "HTTPClient.h" +// Library to drive the LED strip +#include "Adafruit_WS2801.h" + +// Some local defines + +#define SERIAL_BAUD_RATE 115200 + +#define WIGO 1 +#define WIFI_DIPCORTEX 2 +#define UNDEFINED 3 + +#define MY_BOARD WIFI_DIPCORTEX + +using namespace mbed_cc3000; + +// LED to indicate smart config is running +DigitalOut LedSC(P0_1); +// +DigitalIn SCButton(P1_31); + +PinName dataPin(P1_28); // Yellow wire on Adafruit Pixels +PinName clockPin(P0_7); // Green wire on Adafruit Pixels + +/* cc3000 module declaration specific for user's board. Check also init() */ +#if (MY_BOARD == WIGO) +cc3000 wifi(PTA16, PTA13, PTD0, SPI(PTD2, PTD3, PTC5), PORTA_IRQn); +Serial uart(USBTX,USBRX); +#elif (MY_BOARD == WIFI_DIPCORTEX) +cc3000 wifi(p28, p27, p30, SPI(p21, p14, p37)); +Serial uart(p19, p20); +#else + +#endif + +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG +const uint8_t smartconfigkey[] = {0x73,0x6d,0x61,0x72,0x74,0x63,0x6f,0x6e,0x66,0x69,0x67,0x41,0x45,0x53,0x31,0x36}; +#else +const uint8_t smartconfigkey = 0; +#endif + +tNetappIpconfigRetArgs ipinfo; +extern char tmpBuffer[512]; + +bool Connected = false; +bool UsingSmartConfig = false; +char _deviceName[] = "CC3000"; + +HTTPClient http; +//char str[128]; +uint32_t lastColour = 0; + +// Set the first variable to the number of rows, the second to number of pixels. 32 = 32 pixels in a row +Adafruit_WS2801 strip = Adafruit_WS2801(1,32, dataPin, clockPin); + +// Setup the colour table and mappings +#define NUM_COLOURS 12 +struct ColourTable { + char name[12]; + uint32_t value; +} colTable[NUM_COLOURS] = { + { "red", 0xFF0000 }, + { "green", 0x008000 }, + { "blue", 0x0000FF }, + { "cyan", 0x00FFFF }, + { "white", 0xFFFFFF }, + { "warmwhite", 0xFDF5E6 }, + { "purple", 0x800080 }, + { "magenta", 0xFF00FF }, + { "yellow", 0xFFFF00 }, + { "orange", 0xFFA500 }, + { "pink", 0xff69b4 }, + { "oldlace", 0xfd5e56 } +}; + + + +/** Get status of WiFi connection + * displays and returns value + */ +int32_t getWiFiStatus(void) +{ + int32_t status = 0; + const char * WIFI_STATUS[] = {"Disconnected", "Scanning", "Connecting", "Connected"}; + + status = wifi._wlan.ioctl_statusget(); + if (( status > -1 ) && ( status < 4 )) { + uart.printf(" Wifi Status : %s\r\n", WIFI_STATUS[status]); + } else { + uart.printf(" Wifi Status : %d\r\n", status); + } + + return status; +} + +/** Print info from CC3000 + * + */ +void print_cc3000_info() +{ + uint8_t myMAC[8]; + uint8_t buffer[2]; + tNetappIpconfigRetArgs ipinfo2; + tUserFS cc_user_info; + + wifi.get_user_file_info((uint8_t *)&cc_user_info, sizeof(cc_user_info)); + wifi.get_mac_address(myMAC); + uart.printf(" MAC address : %02x:%02x:%02x:%02x:%02x:%02x\r\n", myMAC[0], myMAC[1], myMAC[2], myMAC[3], myMAC[4], myMAC[5]); + + if (! wifi._nvmem.read_sp_version( (unsigned char*)&buffer ) ) { + uart.printf(" CC3000 Firmware Version : %u.%u \r\n", buffer[0], buffer[1]); + } else { + uart.printf(" CC3000 Read nvmem failed!"); + } + getWiFiStatus(); + + if ( wifi.is_dhcp_configured() ) { + wifi.get_ip_config(&ipinfo2); + uart.printf(" Connected to : %s \r\n", ipinfo2.uaSSID); + uart.printf(" IP : %d.%d.%d.%d \r\n", ipinfo2.aucIP[3], ipinfo2.aucIP[2], ipinfo2.aucIP[1], ipinfo2.aucIP[0]); + uart.printf(" Gateway : %d.%d.%d.%d \r\n", ipinfo2.aucDefaultGateway[3], ipinfo2.aucDefaultGateway[2], ipinfo2.aucDefaultGateway[1], ipinfo2.aucDefaultGateway[0]); + uart.printf(" Subnet : %d.%d.%d.%d \r\n", ipinfo2.aucSubnetMask[3], ipinfo2.aucSubnetMask[2], ipinfo2.aucSubnetMask[1], ipinfo2.aucSubnetMask[0]); + uart.printf(" DNS : %d.%d.%d.%d \r\n", ipinfo2.aucDNSServer[3], ipinfo2.aucDNSServer[2], ipinfo2.aucDNSServer[1], ipinfo2.aucDNSServer[0]); + + uart.printf(" Cached IP : %s \r\n", wifi.getIPAddress()); + uart.printf(" Cached Gateway : %s \r\n", wifi.getGateway()); + uart.printf(" Cached Subnet : %s \r\n", wifi.getNetworkMask()); + + } else { + uart.printf(" Not connected \r\n"); + } +} + + +/** Convert name to colour + * @param colStr Received colour name + */ +void setColour( char *colStr ) +{ +// uart.printf("received %s\r\n",colStr); + + for( int i=0; i < NUM_COLOURS; i++ ) { + if( strncmp( colTable[i].name, colStr, strlen(colTable[i].name) ) == 0 ) { + for (int n=0; n < strip.numPixels(); n++) { + strip.setPixelColor(n, colTable[i].value); + strip.show(); + wait_ms(50); + } + return; + } + } + uart.printf("No colour found\r\n"); + +} + +/** Read Cheerlights colour + * Use http call to get last Cheerlights colour + */ +void readCheerlight( void ) +{ + char str[128]; + //GET data + uart.printf("\r\nTrying to fetch page...\r\n"); + int ret = http.get("http://api.thingspeak.com/channels/1417/field/1/last.txt", str, 128); + if (!ret) { + uart.printf("Page fetched successfully - read %d characters\r\n", strlen(str)); + uart.printf("Result: %s\r\n", str); + setColour( str ); + } else { + uart.printf("Error - ret = %d - HTTP return code = %d\r\n", ret, http.getHTTPResponseCode()); + } + +} + + +/** Initialisations + * Hardware initialisations and any other setup needed + */ +void init() +{ + LedSC = 0; + SCButton.mode(PullUp); + 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); + + uart.baud(SERIAL_BAUD_RATE); + + strip.begin(); + + // Update LED contents, to start they are all 'off' + strip.show(); +} + +/** Main loop, handle WiFi connection, check for button press to start SmartConfig process + * + */ +int main( void ) +{ + // Initalise the WiFi Module + init(); + + uart.printf("WiFiDIPCortex Smartconfig Cheerlights\r\n"); + wifi.start(0); + + // Check if button pressed during startup, if so then go into SmartConfig mode + // otherwise just start wifi + if(!SCButton) { + uart.printf("Smartconfig button pressed\r\n"); + + //SmartConfig(); + uart.printf("\r\nStarting Smart config, waiting for message from smartphone app ....\r\n"); + LedSC = 1; + // We dont want to auto reconnect to an access point + wifi._wlan.ioctl_set_connection_policy(0, 0, 0); + + // start smart config will disconnect, set the prefix + // wait for a message via a SmartConfig app, store it to the profile list + // finally it will reenable auto connection, triggering the module to connect to the new access point + wifi.start_smart_config(0); + LedSC = 0; + UsingSmartConfig = true; + + uart.printf("Back from SmartConfig\r\n"); + + wait(2); // for dhcp to configure + + if ( wifi.is_dhcp_configured() ) { + if (!Connected) { + // We have just connected + Connected = true; + + // Start the mdns service, this tells any smart config apps listening we have succeeded + wifi._socket.mdns_advertiser(1, (uint8_t *)_deviceName, strlen(_deviceName)); + + UsingSmartConfig = false; + } + } else { + Connected = false; + + } + } else { + uart.printf("Normal startup\r\n"); + } + + wait_ms(750); + + LedSC = 0; + print_cc3000_info(); + + // Check if we're connected to WiFi and have an IP address, if not then just flash LED + uint32_t status = getWiFiStatus(); + if( status != 3 || !wifi.is_dhcp_configured() ) { + while( 1 ) { + LedSC = !LedSC; + wait_ms(500); + } + } + + while (1) { + getWiFiStatus(); + readCheerlight(); + // Pause for a minute before checking again + wait(60); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Feb 11 21:30:21 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/824293ae5e43 \ No newline at end of file