Code sample to be used with Bluemix for education purpose
Dependencies: C12832 EthernetInterface LM75B MMA7660 MQTT mbed-rtos mbed
Fork of IBMIoTClientEthernetExample by
Diff: main.cpp
- Revision:
- 0:cae064bcbe5e
- Child:
- 1:1f187285667c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jul 16 12:03:54 2014 +0000 @@ -0,0 +1,397 @@ +/******************************************************************************* +* Copyright (c) 2014 IBM Corporation and other Contributors. +* +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: Sam Danbury +* IBM - Initial Contribution +*******************************************************************************/ + +#include "stdio.h" +#include "mbed.h" +#include "rtos.h" +#include "C12832.h" +#include "LM75B.h" +#include "MMA7660.h" +#include "C12832.h" +#include "MQTTEthernetIoT.h" +#include "MQTTClient.h" +#include "ConfigFile.h" + +#include <string> +#include <sstream> +#include <algorithm> + +using namespace std; + +#ifdef TARGET_LPC1768 + +#warning "Compiling for mbed LPC1768" + +LocalFileSystem local("local"); +C12832 lcd(p5, p7, p6, p8, p11); +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +MMA7660 MMA(p28, p27); +LM75B sensor(p28, p27); +DigitalIn Down(p12); +DigitalIn Left(p13); +DigitalIn Click(p14); +DigitalIn Up(p15); +DigitalIn Right(p16); +AnalogIn ain1(p19); +AnalogIn ain2(p20); + +#elif TARGET_K64F + +#warning "Compiling for mbed K64F" + +//#define ORGANISATION "<org>"; +//#define TYPE "<type>"; +//#define ID "<id>"; +//#define AUTHMETHOD "<auth-method>"; +//#define AUTHTOKEN "<auth-token>"; + +C12832 lcd(D11, D13, D12, D7, D10); +DigitalOut led1(LED_RED); +DigitalOut led2(LED_GREEN); +DigitalOut led3(LED_BLUE); +MMA7660 MMA(PTE25, PTE24); +LM75B sensor(PTE25, PTE24); +DigitalIn Up(A2); +DigitalIn Down(A3); +DigitalIn Right(A4); +DigitalIn Left(A5); +DigitalIn Click(D4); +AnalogIn ain1(A0); +AnalogIn ain2(A1); + +#else + +LocalFileSystem local("local"); +C12832 lcd(D11, D13, D12, D7, D10); +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +MMA7660 MMA(D14, D15); +LM75B sensor(D14,D15); +DigitalIn Up(A2); +DigitalIn Down(A3); +DigitalIn Left(A4); +DigitalIn Right(A5); +DigitalIn Click(D4); +AnalogIn ain1 (A0); +AnalogIn ain2 (A1); + +#endif + +//Joystick +string joystickPos; +void joystickThread(void const *args); + +//Commands +enum command { + blink +}; +command getCommand (std::string const& command); +void messageArrived(MQTT::MessageData& md); +int interval; +string getUUID48(); + +//Config +void parseConfig(); +bool quickstartMode = true; +string org = ""; +string type = ""; +string id = ""; +string auth_method = ""; +string auth_token = ""; +string mac = ""; + + +void parseConfig() { + + ConfigFile cfg; + + char value[30]; + char value1[30]; + char value2[30]; + char value3[30]; + + if (cfg.read("/local/device.cfg")) { + quickstartMode = false; + + if (cfg.getValue("org", value, sizeof(value))) { + stringstream ss(value); + ss >> org; + } + if (cfg.getValue("type", value1, sizeof(value1))) { + stringstream ss(value1); + ss >> type; + } + if (cfg.getValue("id", value2, sizeof(value2))) { + stringstream ss(value2); + ss >> id; + } + if (cfg.getValue("auth-token", value3, sizeof(value3))) { + stringstream ss(value3); + ss >> auth_token; + } + + } else { + quickstartMode = true; + org = "quickstart"; + type = "iotsample-mbed-lpc1768"; + id = mac; + } + + #ifdef TARGET_K64F + #ifdef ORGANISATION + quickstartMode = false; + org = ORGANISATION; + + #ifdef TYPE + type = TYPE; + #else + lcd.printf("Type is not defined"); + #endif + + #ifdef ID + id = ID; + #else + lcd.printf("ID is not defined"); + #endif + + #ifdef AUTHMETHOD + auth_method = AUTHMETHOD; + #else + lcd.printf("Auth method is not defined"); + #endif + + #ifdef AUTHTOKEN + auth_token = AUTHTOKEN; + #else + lcd.printf("Auth token is not defined"); + #endif + #endif + #endif +} + +int main() +{ + lcd.locate(0,0); + lcd.printf("ARM IBM IoT\n"); + lcd.printf("Network connecting\n"); + + //Connect to network + MQTTEthernetIoT ipstack = MQTTEthernetIoT(); + MQTT::Client<MQTTEthernetIoT, Countdown, 250> client = MQTT::Client<MQTTEthernetIoT, Countdown, 250>(ipstack); + + //Obtain mac address of mbed + #ifdef TARGET_K64F + mac = getUUID48(); + #else + mac = ipstack.getMACAddress(); + + //Remove colons from mac address + mac.erase(remove(mac.begin(), mac.end(), ':'), mac.end()); + #endif + + //Parse config file if present + parseConfig(); + + //TCP Connect + lcd.printf("Attempting TCP connect"); + string ip = org + ".messaging.internetofthings.ibmcloud.com"; + + char* hostname = new char[ip.length() + 1]; + strcpy(hostname, ip.c_str()); + + int port = 1883; + int rc = ipstack.connect(hostname, port); + if (rc != 0) { + lcd.printf("TCP connect failed"); + } + + //Construct clientId based on config + string str = string("d:") + org + ":" + type + ":" + id; + char clientId[str.size()]; + memcpy(clientId, str.c_str(), str.size() + 1); + + //MQTT Connect + lcd.cls(); + lcd.locate(0,0); + lcd.printf("Attempting MQTT Connect\n"); + MQTTPacket_connectData data = MQTTPacket_connectData_initializer; + data.MQTTVersion = 3; + data.clientID.cstring = clientId; + + if (!quickstartMode) { + char* password = new char[auth_token.length() + 1]; + strcpy(password, auth_token.c_str()); + + data.username.cstring = "use-token-auth"; + data.password.cstring = password; + } + + if ((rc = client.connect(&data)) != 0) + lcd.printf("rc from MQTT connect is %d\n", rc); + + if (!quickstartMode) { + lcd.printf("Attempting MQTT Subscribe\n"); + char* subTopic = "iot-2/cmd/+/fmt/json"; + if ((rc = client.subscribe(subTopic, MQTT::QOS1, messageArrived)) != 0) + lcd.printf("rc from MQTT subscribe is %d\n", rc); + } + + //Initialize lcd + lcd.cls(); + lcd.locate(0,0); + lcd.printf("http://ibm.biz/iotcloud\n"); + lcd.printf("Mac address: %s\n", mac); + + //Start thread to read data from joystick + joystickPos = "CENTRE"; + Thread jThd(joystickThread); + + interval = 0; + int i = 0; + + + while(1) + { + //Message published every second + if (i == 100) { + //MQTT Publish + MQTT::Message message; + char* pubTopic = "iot-2/evt/status/fmt/json"; + + char buf[250]; + sprintf(buf, + "{\"d\":{\"myName\":\"IoT mbed\",\"accelX\":%0.4f,\"accelY\":%0.4f,\"accelZ\":%0.4f,\"temp\":%0.4f,\"joystick\":\"%s\",\"potentiometer1\":%0.4f,\"potentiometer2\":%0.4f}}", + MMA.x(), MMA.y(), MMA.z(), + sensor.temp(), + joystickPos, + ain1.read(), + ain2.read()); + message.qos = MQTT::QOS0; + message.retained = false; + message.dup = false; + message.payload = (void*)buf; + message.payloadlen = strlen(buf); + + if ((rc = client.publish(pubTopic, &message)) != 0) + lcd.printf("MQTT publish failed"); + + i = 0; + led1 = !led1; + } + + if (interval == 0) { + led2 = 0; + } else { + if (i%(interval)==0) { + led2 = !led2; + } + } + + wait(0.01); + i++; + client.yield(1); + } +} + +void messageArrived(MQTT::MessageData& md) { + MQTT::Message &message = md.message; + + char* topic = new char[md.topicName.lenstring.len + 1]; + sprintf(topic, "%.*s", md.topicName.lenstring.len, md.topicName.lenstring.data); + + char* payload = new char[message.payloadlen + 1]; + sprintf(payload, "%.*s", message.payloadlen, (char*)message.payload); + + string topicStr = topic; + string payloadStr = payload; + + //Command topic: iot-2/cmd/blink/fmt/json + string cmd = topicStr.substr(10, topicStr.find("/fmt/") - 10); + + switch(getCommand(cmd)) { + case blink: { + string str = payloadStr.substr(8, payloadStr.find("}") - 8); + int rate = atoi(str.c_str()); + + if (rate == 0) { + interval = 0; + } else if (rate > 50) { + interval = 1; + } else if (rate > 0) { + interval = 50/rate; + } + + break; + } + default: + lcd.printf("Unsupported command: %s\n", cmd); + } + + if (topic) { + delete[] topic; + } + if (payload) { + delete[] payload; + } + +} + +command getCommand (string const& command) { + if (command == "blink") + return blink; +} + +void joystickThread(void const *args) { + while (true) { + if (Down) + joystickPos = "DOWN"; + else if (Left) + joystickPos = "LEFT"; + else if (Click) + joystickPos = "CLICK"; + else if (Up) + joystickPos = "UP"; + else if (Right) + joystickPos = "RIGHT"; + else + joystickPos = "CENTRE"; + } +} + +string getUUID48 () { + + unsigned int UUID_LOC_WORD0 = 0x40048060; + unsigned int UUID_LOC_WORD1 = 0x4004805C; + + + // Fetch word 0 + uint32_t Word0 = *(uint32_t *)UUID_LOC_WORD0; + + // Fetch word 1 + // we only want bottom 16 bits of word1 (MAC bits 32-47) + // and bit 9 forced to 1, bit 8 forced to 0 + // Locally administered MAC, reduced conflicts + // http://en.wikipedia.org/wiki/MAC_address + uint32_t Word1 = *(uint32_t *)UUID_LOC_WORD1; + Word1 |= 0x00000200; + Word1 &= 0x0000FEFF; + + string sd; + char stemp[100] = ""; + snprintf(stemp, 100, "%4X%08X", Word1,Word0); // I use the safer version of sprintf() -- snprintf() + sd = stemp; // the contents of sd are now "This is a string!" + + return (sd); +} \ No newline at end of file