Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Cayenne-MQTT-mbed mbed X_NUCLEO_IKS01A2 X_NUCLEO_IDW01M1v2 NetworkSocketAPI
main.cpp
00001 /* Includes */ 00002 #include "mbed.h" 00003 #include "XNucleoIKS01A2.h" 00004 #include "MQTTTimer.h" 00005 #include "CayenneMQTTClient.h" 00006 #include "MQTTNetworkIDW01M1.h" 00007 #include "SpwfInterface.h" 00008 00009 /* Instantiate the expansion board */ 00010 static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5); 00011 00012 /* Retrieve the composing elements of the expansion board */ 00013 static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer; 00014 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; 00015 static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor; 00016 static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro; 00017 static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer; 00018 00019 // WiFi network info. 00020 char* ssid = "iPhone"; 00021 char* wifiPassword = "abcd1234"; 00022 00023 // Cayenne authentication info. This should be obtained from the Cayenne Dashboard. 00024 char* username = "4f3fbcb0-3796-11e9-ad96-c15442ccb423"; 00025 char* password = "9e099f3d9aaedd7b76ca94044c6bb488c3999e3c"; 00026 char* clientID = "4fb9dca0-3f13-11e9-a6b5-e30ec853fbf2"; 00027 00028 SpwfSAInterface interface(D8, D2); // TX, RX 00029 MQTTNetwork<SpwfSAInterface> network(interface); 00030 CayenneMQTT::MQTTClient<MQTTNetwork<SpwfSAInterface>, MQTTTimer> mqttClient(network, username, password, clientID); 00031 00032 /***********************************************************/ 00033 /* External sensor and output/actuators declared here */ 00034 /***********************************************************/ 00035 DigitalOut led1(LED1); 00036 //DigitalOut ledy(D1); 00037 00038 /* Helper function for printing floats & doubles */ 00039 static char *print_double(char* str, double v, int decimalDigits=2) 00040 { 00041 int i = 1; 00042 int intPart, fractPart; 00043 int len; 00044 char *ptr; 00045 00046 /* prepare decimal digits multiplicator */ 00047 for (;decimalDigits!=0; i*=10, decimalDigits--); 00048 00049 /* calculate integer & fractinal parts */ 00050 intPart = (int)v; 00051 fractPart = (int)((v-(double)(int)v)*i); 00052 00053 /* fill in integer part */ 00054 sprintf(str, "%i.", intPart); 00055 00056 /* prepare fill in of fractional part */ 00057 len = strlen(str); 00058 ptr = &str[len]; 00059 00060 /* fill in leading fractional zeros */ 00061 for (i/=10;i>1; i/=10, ptr++) { 00062 if (fractPart >= i) { 00063 break; 00064 } 00065 *ptr = '0'; 00066 } 00067 00068 /* fill in (rest of) fractional part */ 00069 sprintf(ptr, "%i", fractPart); 00070 00071 return str; 00072 } 00073 00074 /** 00075 * Print the message info. 00076 * @param[in] message The message received from the Cayenne server. 00077 */ 00078 void outputMessage(CayenneMQTT::MessageData& message) 00079 { 00080 switch (message.topic) { 00081 case COMMAND_TOPIC: 00082 printf("topic=Command"); 00083 break; 00084 case CONFIG_TOPIC: 00085 printf("topic=Config"); 00086 break; 00087 default: 00088 printf("topic=%d", message.topic); 00089 break; 00090 } 00091 printf(" channel=%d", message.channel); 00092 if (message.clientID) { 00093 printf(" clientID=%s", message.clientID); 00094 } 00095 if (message.type) { 00096 printf(" type=%s", message.type); 00097 } 00098 for (size_t i = 0; i < message.valueCount; ++i) { 00099 if (message.getValue(i)) { 00100 printf(" value=%s", message.getValue(i)); 00101 } 00102 if (message.getUnit(i)) { 00103 printf(" unit=%s", message.getUnit(i)); 00104 } 00105 } 00106 if (message.id) { 00107 printf(" id=%s", message.id); 00108 } 00109 printf("\n"); 00110 } 00111 00112 /** 00113 * Handle messages received from the Cayenne server. 00114 * @param[in] message The message received from the Cayenne server. 00115 */ 00116 void messageArrived(CayenneMQTT::MessageData& message) 00117 { 00118 int error = 0; 00119 // Add code to process the message. Here we just ouput the message data. 00120 outputMessage(message); 00121 00122 if (message.topic == COMMAND_TOPIC) { 00123 switch(message.channel) { /****************************************************/ 00124 case 0: /* the channel number for input */ 00125 // Set the onboard LED state /* */ 00126 led1 = atoi(message.getValue()); /*can add other function after received input signal*/ 00127 // Publish the updated LED state /****************************************************/ 00128 if ((error = mqttClient.publishData(DATA_TOPIC, message.channel, NULL, NULL, message.getValue())) != CAYENNE_SUCCESS) { 00129 printf("Publish LED state failure, error: %d\n", error); 00130 } 00131 break; 00132 } 00133 00134 // If this is a command message we publish a response. Here we are just sending a default 'OK' response. 00135 // An error response should be sent if there are issues processing the message. 00136 if ((error = mqttClient.publishResponse(message.id, NULL, message.clientID)) != CAYENNE_SUCCESS) { 00137 printf("Response failure, error: %d\n", error); 00138 } 00139 } 00140 } 00141 00142 /** 00143 * Connect to the Cayenne server. 00144 * @return Returns CAYENNE_SUCCESS if the connection succeeds, or an error code otherwise. 00145 */ 00146 int connectClient(void) 00147 { 00148 int error = 0; 00149 // Connect to the server. 00150 printf("Connecting to %s:%d\n", CAYENNE_DOMAIN, CAYENNE_PORT); 00151 while ((error = network.connect(CAYENNE_DOMAIN, CAYENNE_PORT)) != 0) { 00152 printf("TCP connect failed, error: %d\n", error); 00153 wait(2); 00154 } 00155 00156 if ((error = mqttClient.connect()) != MQTT::SUCCESS) { 00157 printf("MQTT connect failed, error: %d\n", error); 00158 return error; 00159 } 00160 printf("Connected\n"); 00161 00162 // Subscribe to required topics. 00163 if ((error = mqttClient.subscribe(COMMAND_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) { 00164 printf("Subscription to Command topic failed, error: %d\n", error); 00165 } 00166 if ((error = mqttClient.subscribe(CONFIG_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) { 00167 printf("Subscription to Config topic failed, error:%d\n", error); 00168 } 00169 00170 // 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. 00171 mqttClient.publishData(SYS_VERSION_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, CAYENNE_VERSION); 00172 mqttClient.publishData(SYS_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "mbedDevice"); 00173 //mqttClient.publishData(SYS_CPU_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "CPU Model"); 00174 //mqttClient.publishData(SYS_CPU_SPEED_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "1000000000"); 00175 00176 return CAYENNE_SUCCESS; 00177 } 00178 00179 /* Simple main function */ 00180 int main() { 00181 uint8_t id; 00182 float value1, value2, value3, value4; 00183 char buffer1[32], buffer2[32], buffer3[32], buffer4[32]; 00184 int32_t axes[3]; 00185 00186 /* Enable all sensors */ 00187 hum_temp->enable(); 00188 press_temp->enable(); 00189 magnetometer->enable(); 00190 accelerometer->enable(); 00191 acc_gyro->enable_x(); 00192 acc_gyro->enable_g(); 00193 00194 printf("\r\n--- Starting new run ---\r\n"); 00195 00196 hum_temp->read_id(&id); 00197 printf("HTS221 humidity & temperature = 0x%X\r\n", id); 00198 press_temp->read_id(&id); 00199 printf("LPS22HB pressure & temperature = 0x%X\r\n", id); 00200 magnetometer->read_id(&id); 00201 printf("LSM303AGR magnetometer = 0x%X\r\n", id); 00202 accelerometer->read_id(&id); 00203 printf("LSM303AGR accelerometer = 0x%X\r\n", id); 00204 acc_gyro->read_id(&id); 00205 printf("LSM6DSL accelerometer & gyroscope = 0x%X\r\n", id); 00206 00207 // Initialize the network interface. 00208 printf("Initializing interface\n"); 00209 interface.connect(ssid, wifiPassword, NSAPI_SECURITY_WPA2); 00210 00211 // Set the default function that receives Cayenne messages. 00212 mqttClient.setDefaultMessageHandler(messageArrived); 00213 00214 // Connect to Cayenne. 00215 if (connectClient() == CAYENNE_SUCCESS) { 00216 // Start the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval. 00217 MQTTTimer timer(5000); 00218 00219 while (true) { 00220 00221 // Yield to allow MQTT message processing. 00222 mqttClient.yield(1000); 00223 00224 // Check that we are still connected, if not, reconnect. 00225 if (!network.connected() || !mqttClient.connected()) { 00226 network.disconnect(); 00227 mqttClient.disconnect(); 00228 printf("Reconnecting\n"); 00229 while (connectClient() != CAYENNE_SUCCESS) { 00230 wait(2); 00231 printf("Reconnect failed, retrying\n"); 00232 } 00233 } 00234 00235 printf("\r\n"); 00236 00237 hum_temp->get_temperature(&value1); 00238 hum_temp->get_humidity(&value2); 00239 printf("HTS221: [temp] %7s C, [hum] %s%%\r\n", print_double(buffer1, value1), print_double(buffer2, value2)); 00240 00241 press_temp->get_temperature(&value3); 00242 press_temp->get_pressure(&value4); 00243 printf("LPS22HB: [temp] %7s C, [press] %s mbar\r\n", print_double(buffer1, value3), print_double(buffer2, value4)); 00244 00245 printf("---\r\n"); 00246 00247 magnetometer->get_m_axes(axes); 00248 printf("LSM303AGR [mag/mgauss]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00249 00250 acc_gyro->get_x_axes(axes); 00251 printf("LSM6DSL [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00252 00253 accelerometer->get_x_axes(axes); 00254 printf("LSM303AGR [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00255 00256 acc_gyro->get_g_axes(axes); 00257 printf("LSM6DSL [gyro/mdps]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00258 00259 wait(1.5); 00260 00261 00262 // Publish some example data every few seconds. This should be changed to send your actual data to Cayenne. 00263 if (timer.expired()) { 00264 int error = 0; /************************/ 00265 if ((error = mqttClient.publishData(DATA_TOPIC, 1, TYPE_TEMPERATURE, UNIT_CELSIUS, value1)) != CAYENNE_SUCCESS) { /* duplicate the if {} */ 00266 printf("Publish temperature failed, error: %d\n", error); /* for more channel */ 00267 } /************************/ 00268 if ((error = mqttClient.publishData(DATA_TOPIC, 2, TYPE_BAROMETRIC_PRESSURE, UNIT_PASCAL, value4)) != CAYENNE_SUCCESS) { 00269 printf("Publish barometric pressure failed, error: %d\n", error); 00270 } 00271 if ((error = mqttClient.publishData(DATA_TOPIC, 3, TYPE_PROXIMITY, UNIT_METER, axes[1])) != CAYENNE_SUCCESS) { 00272 printf("Publish proximity failed, error: %d\n", error); 00273 } 00274 // Restart the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval. 00275 timer.countdown_ms(5000); 00276 } 00277 } 00278 } 00279 else { 00280 printf("Connection failed, exiting\n"); 00281 } 00282 00283 if (mqttClient.connected()) 00284 mqttClient.disconnect(); 00285 if (network.connected()) 00286 network.disconnect(); 00287 }
Generated on Mon Aug 29 2022 10:41:57 by
1.7.2