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