Nucleo board and sensor, sending data to myDevices

Dependencies:   Cayenne-MQTT-mbed-M1 X_NUCLEO_IKS01A1 mbed mtsas-m1

Fork of Dragonfly_Cayenne_Sprint_IKS01A1 by Peter Ferland

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 #include "mtsas.h"
00004 
00005 #include "MQTTTimer.h"
00006 #include "CayenneMQTTClient.h"
00007 #include "MQTTNetwork.h"
00008 
00009 #include "x_nucleo_iks01a1.h"
00010 
00011 #include <string>
00012 #include <sstream>
00013 
00014 using std::string;
00015 typedef CayenneMQTT::MQTTClient<MQTTNetwork<Cellular>, MQTTTimer> MQTTClient;
00016 
00017 // Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
00018 string username = "3f842710-8e51-11e7-a5d9-9de9b49680ec";
00019 string password = "46f0e2add1dbcd1d7cab6fde2a2b93c4423a377a";
00020 string clientID = "b0358dd0-8f43-11e7-b153-197ebdab87be";
00021 
00022 DigitalOut Led1Out(LED1);
00023 
00024 // Debug serial port
00025 //static Serial debug(USBTX, USBRX);
00026 Serial pc(USBTX, USBRX);
00027 // MTSSerialFlowControl - serial link between processor and radio
00028 static MTSSerialFlowControl* io;
00029 
00030 // Cellular - radio object for cellular operations (SMS, TCP, etc)
00031 Cellular* radio;
00032 
00033 /* Instantiate the expansion board */
00034 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL);
00035 
00036 /* Retrieve the composing elements of the expansion board */
00037 static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
00038 static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
00039 static MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
00040 static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;
00041 static PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor;
00042 static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
00043 static TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor;
00044 
00045 
00046 CayenneMQTT::MessageData lastMessage;
00047 bool messageReady;
00048 
00049 /*
00050 * Initialize cellular radio.
00051 */
00052 bool init_mtsas()
00053 {
00054 
00055     io = new MTSSerialFlowControl(D8,D2,D3,D6);//This is the only thing that I have changed!
00056     if (! io)
00057         return false;
00058     
00059     io->baud(115200);
00060     radio = CellularFactory::create(io);
00061     if (! radio)
00062         return false;
00063 
00064     //radio->setApn("wireless.twilio.com");
00065     Transport::setTransport(radio);
00066     while (! radio->connect()) {
00067         logError("failed to bring up PPP link");
00068         wait(2);
00069     }
00070     
00071     printf("Signal Strength: %d\n\r", radio->getSignalStrength()); 
00072     return true;
00073 }
00074 
00075 /**
00076 * Print the message info.
00077 * @param[in] message The message received from the Cayenne server.
00078 */
00079 void outputMessage(CayenneMQTT::MessageData& message)
00080 {
00081     switch (message.topic)  {
00082     case COMMAND_TOPIC:
00083         pc.printf("topic=Command");
00084         break;
00085     case CONFIG_TOPIC:
00086         printf("topic=Config");
00087         break;
00088     default:
00089         printf("topic=%d", message.topic);
00090         break;
00091     }
00092     printf(" channel=%d", message.channel);
00093     if (message.clientID) {
00094         printf(" clientID=%s", message.clientID);
00095     }
00096     if (message.type) {
00097         printf(" type=%s", message.type);
00098     }
00099     for (size_t i = 0; i < message.valueCount; ++i) {
00100         if (message.getValue(i)) {
00101             printf(" value=%s", message.getValue(i));
00102         }
00103         if (message.getUnit(i)) {
00104             printf(" unit=%s", message.getUnit(i));
00105         }
00106     }
00107     if (message.id) {
00108         printf(" id=%s", message.id);
00109     }
00110     printf("\r\n");
00111 }
00112 
00113 /**
00114 * Handle messages received from the Cayenne server.
00115 * @param[in] message The message received from the Cayenne server.
00116 */
00117 void messageArrived(CayenneMQTT::MessageData& message)
00118 {
00119     int error = 0;
00120     //note: if you change this example to use mbed-os you will need a mutex
00121     lastMessage = message;
00122     messageReady = true;
00123 
00124 }
00125 
00126 /**
00127 * Connect to the Cayenne server.
00128 * @return Returns CAYENNE_SUCCESS if the connection succeeds, or an error code otherwise.
00129 */
00130 int connectClient(MQTTClient &mqttClient, MQTTNetwork<Cellular> &network)
00131 {
00132     int error = 0;
00133     // Connect to the server.
00134     printf("Connecting to %s:%d\r\n", CAYENNE_DOMAIN, CAYENNE_PORT);
00135     while ((error = network.connect(CAYENNE_DOMAIN, CAYENNE_PORT)) != 0) {
00136         printf("TCP connect failed, error: %d\r\n", error);
00137         wait(2);
00138     }
00139 
00140     if ((error = mqttClient.connect()) != MQTT::SUCCESS) {
00141         printf("MQTT connect failed, error: %d\r\n", error);
00142         return error;
00143     }
00144     printf("Connected\r\n");
00145 
00146     // Subscribe to required topics.
00147     if ((error = mqttClient.subscribe(COMMAND_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) {
00148         printf("Subscription to Command topic failed, error: %d\r\n", error);
00149     }
00150     if ((error = mqttClient.subscribe(CONFIG_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) {
00151         printf("Subscription to Config topic failed, error:%d\r\n", error);
00152     }
00153 
00154     // Send device info. Here we just send some example values for the system info. These should be changed to use actual system data, or removed if not needed.
00155     mqttClient.publishData(SYS_VERSION_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, CAYENNE_VERSION);
00156     mqttClient.publishData(SYS_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "mbedDevice");
00157     //mqttClient.publishData(SYS_CPU_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "CPU Model");
00158     //mqttClient.publishData(SYS_CPU_SPEED_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "1000000000");
00159 
00160     return CAYENNE_SUCCESS;
00161 }
00162 
00163 /**
00164 * Main loop where MQTT code is run.
00165 */
00166 void loop(MQTTClient &mqttClient, MQTTNetwork<Cellular> &network)
00167 {
00168     // Start the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval.
00169     MQTTTimer timer(1000);
00170     printf("Starting loop.\r\n");
00171     while (true) {
00172         // Yield to allow MQTT message processing.
00173         mqttClient.yield(10);
00174         if(messageReady){
00175             int error = 0;
00176             messageReady = false;
00177             // Add code to process the message. Here we just ouput the message data.
00178             outputMessage(lastMessage);
00179         
00180             if (lastMessage.topic == COMMAND_TOPIC) {
00181                 switch(lastMessage.channel) {
00182                 case 0:
00183                     // Set the onboard LED state
00184                     Led1Out = atoi(lastMessage.getValue());
00185                     // Publish the updated LED state
00186                     if ((error = mqttClient.publishData(DATA_TOPIC, lastMessage.channel, NULL, NULL, Led1Out.read())) != CAYENNE_SUCCESS) {
00187                         printf("Publish LED state failure, error: %d\r\n", error);
00188                     }
00189                     break;
00190                 }
00191                 
00192                 // If this is a command message we publish a response. Here we are just sending a default 'OK' response.
00193                 // An error response should be sent if there are issues processing the message.
00194                 if ((error = mqttClient.publishResponse(lastMessage.id, NULL, lastMessage.clientID)) != CAYENNE_SUCCESS) {
00195                     printf("Response failure, error: %d\r\n", error);
00196                 }
00197             }
00198         }
00199 
00200         // Check that we are still connected, if not, reconnect.
00201         if (!network.connected() || !mqttClient.connected()) {
00202             network.disconnect();
00203             mqttClient.disconnect();
00204             printf("Reconnecting\r\n");
00205             while (connectClient(mqttClient, network) != CAYENNE_SUCCESS) {
00206                 wait(2);
00207                 printf("Reconnect failed, retrying\r\n");
00208             }
00209         }
00210 
00211         // Publish some example data every few seconds. This should be changed to send your actual data to Cayenne.
00212         if (timer.expired()) {
00213             int error = 0;
00214             float temp_data;
00215             temp_sensor1->get_temperature(&temp_data);
00216             printf("Temperature was: %f \r\n", temp_data);
00217             if ((error = mqttClient.publishData(DATA_TOPIC, 1, TYPE_TEMPERATURE, UNIT_CELSIUS, temp_data)) != CAYENNE_SUCCESS) {
00218                 printf("Publish temperature failed, error: %d\r\n", error);
00219             }
00220             humidity_sensor->get_humidity(&temp_data);
00221             printf("Humidity was: %f \r\n", temp_data);
00222             if ((error = mqttClient.publishData(DATA_TOPIC, 2, TYPE_RELATIVE_HUMIDITY, UNIT_PERCENT, temp_data)) != CAYENNE_SUCCESS) {
00223                 printf("Publish luminosity failed, error: %d\r\n", error);
00224             }
00225             pressure_sensor->get_pressure(&temp_data);
00226             printf("Pressure was: %f \r\n", temp_data);
00227             if ((error = mqttClient.publishData(DATA_TOPIC, 3, TYPE_BAROMETRIC_PRESSURE, UNIT_HECTOPASCAL, temp_data)) != CAYENNE_SUCCESS) {
00228                 printf("Publish barometric pressure failed, error: %d\r\n", error);
00229             }
00230             printf("Led is: %s\r\n", Led1Out.read() ? "on" : "off");
00231              if ((error = mqttClient.publishData(DATA_TOPIC, 0, "digital_actuator", UNIT_DIGITAL, Led1Out.read())) != CAYENNE_SUCCESS) {
00232                 printf("Publish LED status failed, error: %d\r\n", error);
00233             }
00234             // Restart the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval.
00235             timer.countdown_ms(5000);
00236         } else {
00237            // debug
00238            // printf("Timer: %d", timer.left_ms());
00239         }
00240     }
00241 }
00242 
00243 int main()
00244 {
00245     pc.baud(115200);
00246     Led1Out = 0;
00247     mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
00248     // init radio, setup Cayenne connection
00249     if (!init_mtsas()) {
00250         while (true) {
00251             logError("failed to initialize cellular radio");
00252             wait(1);
00253         }
00254     }
00255     // Test with a ping
00256     if(radio->ping("www.google.com")){
00257         printf("Ping test succeeded!\r\n");
00258     } else {
00259         printf("Failed ping test!\r\n");
00260     }
00261     MQTTNetwork<Cellular> network(*radio);
00262     messageReady = false;
00263     MQTTClient mqttClient(network, username.c_str(), password.c_str(), clientID.c_str());
00264 
00265     // Set the default function that receives Cayenne messages.
00266     mqttClient.setDefaultMessageHandler(messageArrived);
00267 
00268     // Connect to Cayenne.
00269     if (connectClient(mqttClient, network) == CAYENNE_SUCCESS) {
00270         // Run main loop.
00271         loop(mqttClient, network);
00272     }
00273     else {
00274         printf("Connection failed, exiting\r\n");
00275     }
00276 
00277     if (mqttClient.connected())
00278         mqttClient.disconnect();
00279     if (network.connected())
00280         network.disconnect();
00281     
00282     return 0;
00283 }