Example showing the ublox Cellular GPS/GNSS module with the online PubNub service on an LPC4088 Experiment Base Board. This example uses an RTOS.
Dependencies: C027_Support EALib LM75B PubNub mbed-rtos mbed picojson
PubNubDemo.cpp
00001 #include <cstring> 00002 00003 #include "mbed.h" 00004 #include "rtos.h" 00005 //#include "C12832.h" 00006 //#include "MMA7660.h" 00007 #include "MMA7455.h" 00008 #include "LM75B.h" 00009 00010 #include "picojson.h" 00011 #include "PubNub.h" 00012 00013 #include "sdram.h" 00014 00015 //------------------------------------------------------------------------------------ 00016 // You need to configure these cellular modem / SIM parameters. 00017 // These parameters are ignored for LISA-C200 variants and can be left NULL. 00018 //------------------------------------------------------------------------------------ 00019 #include "MDM.h" 00020 //! Set your secret SIM pin here (e.g. "1234"). Check your SIM manual. 00021 #define SIMPIN NULL 00022 /*! The APN of your network operator SIM, sometimes it is "internet" check your 00023 contract with the network operator. You can also try to look-up your settings in 00024 google: https://www.google.de/search?q=APN+list */ 00025 #define APN "online.telia.se" 00026 //! Set the user name for your APN, or NULL if not needed 00027 #define USERNAME NULL 00028 //! Set the password for your APN, or NULL if not needed 00029 #define PASSWORD NULL 00030 //------------------------------------------------------------------------------------ 00031 00032 /* Demo of PubNub + the mbed application board. */ 00033 00034 /* How to get things set up: */ 00035 /* 1. Tune in at the PubNub Developer Console, with the following 00036 * keys (press Subscribe afterwards): */ 00037 const char pubkey[] = "demo"; 00038 const char subkey[] = "demo"; 00039 //const char channel[] = "mbed"; 00040 const char channel_pub[] = "mbed_data"; 00041 const char channel_sub[] = "mbed_cmd"; 00042 /* 2. Attach your mbed board to your computer. A folder should pop up like 00043 * if you plug in a USB memory stick. */ 00044 /* 3. Open this example in the mbed web IDE and hit the Compile button. */ 00045 /* 4. A download popup with a .bin file will appear; save it in the USB 00046 * mbed folder. */ 00047 /* 5. Press reset button on the mbed to start things up. */ 00048 00049 /* You will see the board publish a "status" message that shows its 00050 * current temperature and physical tilt. The board's LCD should 00051 * print some progress messages regarding that. */ 00052 /* You can make the board do things too, by sending messages like: 00053 * { "send_status": true } 00054 * { "lcd": "Hi there!" } 00055 * { "beep": true } 00056 * { "led": {"r": 0.5, "g": 1, "b": 0} } 00057 * Try it out! Paste these in the Message window and press the send icon. 00058 */ 00059 00060 Serial pc(USBTX, USBRX); // tx, rx 00061 //MMA7660 MMA(P0_27, P0_28); 00062 MMA7455 MMA(P0_27, P0_28); 00063 LM75B tmp(P0_27, P0_28, LM75B::ADDRESS_1); 00064 //C12832 lcd(D11, D13, D12, D7, D10); 00065 00066 PwmOut led_r(p25); // RGB LED with 3 PWM outputs for dimmer control 00067 PwmOut led_g(p28); 00068 PwmOut led_b(p26); 00069 //PwmOut speaker(D6); // Speaker with PWM driver 00070 00071 DigitalOut led1(LED1); 00072 DigitalOut led2(LED2); 00073 DigitalOut led3(LED3); 00074 DigitalOut led4(LED4); 00075 00076 00077 bool forceStatusUpdate = true; 00078 00079 Mutex stdio_mutex; 00080 00081 #define safe_printf(...) do { \ 00082 stdio_mutex.lock(); \ 00083 pc.printf(__VA_ARGS__); \ 00084 stdio_mutex.unlock(); \ 00085 } while(0) 00086 00087 #define safe_print_pnub_err(__prefix) do { \ 00088 stdio_mutex.lock(); \ 00089 if (pnub_err) { \ 00090 pc.printf("%s: ERR, code = %d, line = %d\n", (__prefix), pnub_code, pnub_line); \ 00091 pnub_err = false; \ 00092 } \ 00093 stdio_mutex.unlock(); \ 00094 } while(0) 00095 00096 void pnub_err_handler(PubNubRes code, int line) { 00097 stdio_mutex.lock(); 00098 if (code != PNR_OK) { 00099 pc.printf("PbuNub:%d ERROR %d\n", line, code); 00100 } 00101 stdio_mutex.unlock(); 00102 } 00103 00104 void process_msg(PubNub &pn, const char *jsonmsg) 00105 { 00106 /* Use the picojson parser since we want to deal with complex messages. 00107 * If you are short on memory, you can find an example for parsing simple 00108 * JSON messages in the PubNub::subscribe() API docs. */ 00109 picojson::value msg; 00110 std::string err = picojson::parse(msg, jsonmsg, jsonmsg + strlen(jsonmsg)); 00111 do { 00112 if (!err.empty()) { 00113 safe_printf("JSON parse: %s \n", err.c_str()); 00114 break; 00115 } 00116 00117 if (msg.get("send_status").get<bool>()) { 00118 //status_msg(pn); 00119 forceStatusUpdate = true; 00120 safe_printf("force_update\n"); 00121 break; 00122 } 00123 if (msg.get("lcd").is<std::string>()) { 00124 safe_printf("in: %s \n", msg.get("lcd").get<std::string>().c_str()); 00125 break; 00126 } 00127 if (msg.get("beep").is<bool>()) { 00128 //speaker = msg.get("beep").get<bool>() ? 0.5 : 0; 00129 break; 00130 } 00131 if (msg.get("led").is<picojson::object>()) { 00132 picojson::value led = msg.get("led"); 00133 safe_printf("Old RGB { %.3f, %.3f, %.3f }\n", led_r.read(), led_g.read(), led_b.read()); 00134 if (led.get("r").is<double>()) led_r = 1.0 - led.get("r").get<double>(); 00135 if (led.get("g").is<double>()) led_g = 1.0 - led.get("g").get<double>(); 00136 if (led.get("b").is<double>()) led_b = 1.0 - led.get("b").get<double>(); 00137 safe_printf("New RGB { %.3f, %.3f, %.3f }\n", led_r.read(), led_g.read(), led_b.read()); 00138 break; 00139 } 00140 } while(0); 00141 } 00142 00143 void publish_thread(void const *args) 00144 { 00145 PubNub pn(pubkey, subkey); 00146 Timer t; 00147 t.start(); 00148 Timer tDbg; 00149 int nDbg = 0; 00150 float lastTemp = -3.75f; 00151 while (true) { 00152 00153 /* Read sensors. */ 00154 int m[3]; 00155 MMA.read(m[0], m[1], m[2]); 00156 float temp = (float)tmp; 00157 00158 /* Print on LCD. */ 00159 safe_printf("cur: mx=%3d, my=%3d, mz=%3d, t=%.2f \n", m[0], m[1], m[2], temp); 00160 00161 if (forceStatusUpdate || (temp != lastTemp)) { 00162 lastTemp = temp; 00163 forceStatusUpdate = false; 00164 00165 /* Prepare JSON message. */ 00166 char jsonmsg[128]; 00167 // snprintf(jsonmsg, sizeof(jsonmsg), 00168 // "{\"status\":{\"mx\":%3d,\"my\":%3d,\"mz\":%3d,\"temp\":%.2f}}", 00169 // m[0], m[1], m[2], temp); 00170 snprintf(jsonmsg, sizeof(jsonmsg), 00171 "%%7B%%22status%%22:%%7B%%22mx%%22:%3d,%%22my%%22:%3d,%%22mz%%22:%3d,%%22temp%%22:%.2f%%7D%%7D", 00172 m[0], m[1], m[2], temp); 00173 00174 /* Publish on PubNub. */ 00175 safe_printf("before publishing\n"); 00176 led_r = 0; 00177 tDbg.start(); 00178 // PubNubRes ret = pn.publish(channel_pub, jsonmsg); 00179 PubNubRes ret = pn.publish_urlenc(channel_pub, jsonmsg); 00180 tDbg.stop(); 00181 if (++nDbg == 10) { 00182 safe_printf("10 requests took %d ms, i.e %d ms/req\n", tDbg.read_ms(), tDbg.read_ms()/10); 00183 tDbg.reset(); 00184 nDbg = 0; 00185 } 00186 00187 if (ret != PNR_OK) { 00188 safe_printf("puberr: %d \n", ret); 00189 //safe_print_pnub_err("pub"); 00190 forceStatusUpdate = true; // so that we can try again 00191 } 00192 led_r = 1; 00193 safe_printf("after publishing\n"); 00194 } 00195 00196 wait_ms(100); 00197 } 00198 } 00199 00200 void subscribe_thread(void const *args) 00201 { 00202 PubNub pn(pubkey, subkey); 00203 while(true) { 00204 char *reply = NULL; 00205 PubNubRes ret = pn.subscribe(channel_sub, &reply); 00206 if (ret != PNR_OK) { 00207 safe_printf("suberr: %d \n", ret); 00208 //safe_print_pnub_err("sub"); 00209 wait(1.0); 00210 continue; 00211 } 00212 00213 if (reply) { 00214 safe_printf("recv(%s)\n", reply); 00215 process_msg(pn, reply); 00216 } 00217 00218 wait(0.5); // avoid busy loop in bad situations 00219 } 00220 } 00221 00222 /** Cause the mbed to flash the BLOD (Blue LEDs Of Death) sequence 00223 */ 00224 void mbed_die(void) 00225 { 00226 led1 = led2 = 1; led3 = led4 = 0; // lights out 00227 while(1) { 00228 led1 = 1; 00229 led3 = 1; 00230 wait_ms(100); 00231 led2 = 1; 00232 led1 = 0; 00233 wait_ms(100); 00234 led4 = 0; 00235 led2 = 0; 00236 wait_ms(100); 00237 led3 = 0; 00238 led4 = 1; 00239 wait_ms(100); 00240 } 00241 } 00242 00243 int main() 00244 { 00245 if (sdram_init()) { 00246 pc.printf("Failed to initialize SDRAM\n"); 00247 } 00248 00249 /* For debugging, you may find it useful to print memory usage 00250 * stats. AvailableMemory may be flaky, but the following is nice. 00251 * It will get printed to the USB serial port interface. */ 00252 //printf("%d: ", __LINE__); __heapstats((__heapprt)fprintf, stdout); 00253 00254 /* Generate a 800Hz tone using PWM hardware output */ 00255 //speaker.period(1.0/800.0); // 800hz period 00256 led_r = led_g = led_b = 1.0; // lights out 00257 led1 = led2 = 1; led3 = led4 = 0; // lights out 00258 00259 //lcd.cls(); 00260 //lcd.locate(0,0); 00261 00262 if (!tmp.open()) { 00263 pc.printf("Failed to open LM75 temperature sensor\n"); 00264 } 00265 00266 // if (!MMA.testConnection()) 00267 // pc.printf("MMA error \n"); 00268 00269 // Initialize the accelerometer 00270 if (!MMA.setMode(MMA7455::ModeMeasurement)) { 00271 printf("Unable to set mode for MMA7455!\n"); 00272 } 00273 00274 // Calibrate it. It does not matter if it is on a level surface 00275 // as this test is only interested in relative values. 00276 if (!MMA.calibrate()) { 00277 printf("Failed to calibrate MMA7455!\n"); 00278 } 00279 00280 MDMRtos<MDMSerial> mdm; 00281 //mdm.setDebug(4); // enable this for debugging issues 00282 int i; 00283 for (i = 1; i <= 10; i++) { 00284 if (mdm.connect(SIMPIN, APN,USERNAME,PASSWORD)) { 00285 printf("Connected\n"); 00286 mdm.setDebug(0); // disable debug again 00287 break; 00288 } else { 00289 printf("Attempt %2d to connect to the modem FAILED.\n", i); 00290 wait(1); 00291 mdm.setDebug(min(i, 4)); // to add more and more debug output 00292 } 00293 } 00294 if (i > 10) { 00295 printf("Failed to connect to the modem\n"); 00296 mbed_die(); 00297 } 00298 00299 forceStatusUpdate = true; 00300 //status_msg(pn); 00301 // lcd.printf("pub... "); 00302 00303 Thread t_p(publish_thread); 00304 Thread t_s(subscribe_thread); 00305 00306 while (1) { 00307 Thread::wait(2000); 00308 safe_printf(".\n"); 00309 } 00310 00311 mdm.disconnect(); 00312 mdm.powerOff(); 00313 }
Generated on Wed Jul 13 2022 14:56:03 by 1.7.2