This program simply connects to a HTS221 I2C device to read Temperature

Dependencies:   FXOS8700CQ mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include <cctype>
00003 #include <string>
00004 #include "SerialBuffered.h"
00005 #include "HTS221.h"
00006 #include "config_me.h"
00007 #include "wnc_control.h"
00008 #include "sensors.h"
00009 
00010 #include "hardware.h"
00011 I2C i2c(PTC11, PTC10);    //SDA, SCL -- define the I2C pins being used
00012 
00013 // comment out the following line if color is not supported on the terminal
00014 #define USE_COLOR
00015 #ifdef USE_COLOR
00016  #define BLK "\033[30m"
00017  #define RED "\033[31m"
00018  #define GRN "\033[32m"
00019  #define YEL "\033[33m"
00020  #define BLU "\033[34m"
00021  #define MAG "\033[35m"
00022  #define CYN "\033[36m"
00023  #define WHT "\033[37m"
00024  #define DEF "\033[39m"
00025 #else
00026  #define BLK
00027  #define RED
00028  #define GRN
00029  #define YEL
00030  #define BLU
00031  #define MAG
00032  #define CYN
00033  #define WHT
00034  #define DEF
00035 #endif
00036 
00037 #define MDM_DBG_OFF                             0
00038 #define MDM_DBG_AT_CMDS                         (1 << 0)
00039 int mdm_dbgmask = MDM_DBG_OFF;
00040 
00041 Serial         pc(USBTX, USBRX);
00042 SerialBuffered mdm(PTD3, PTD2, 128);
00043 DigitalOut led_green(LED_GREEN);
00044 DigitalOut led_red(LED_RED);
00045 DigitalOut led_blue(LED_BLUE);
00046 
00047 DigitalOut  mdm_uart2_rx_boot_mode_sel(PTC17);  // on powerup, 0 = boot mode, 1 = normal boot
00048 DigitalOut  mdm_power_on(PTB9);                 // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem)
00049 DigitalOut  mdm_wakeup_in(PTC2);                // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield
00050 
00051 DigitalOut  mdm_reset(PTC12);                   // active high      
00052 
00053 DigitalOut  shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active
00054 DigitalOut  mdm_uart1_cts(PTD0);
00055 
00056 #define TOUPPER(a) (a) //toupper(a)
00057 
00058 const char ok_str[] = "OK";
00059 const char error_str[] = "ERROR";
00060 
00061 #define MDM_OK                                  0
00062 #define MDM_ERR_TIMEOUT                         -1
00063 
00064 #define MAX_AT_RSP_LEN                          255
00065 
00066 ssize_t mdm_getline(char *buff, size_t size, int timeout_ms) {
00067     int cin = -1;
00068     int cin_last;
00069     
00070     if (NULL == buff || size == 0) {
00071         return -1;
00072     }
00073 
00074     size_t len = 0;
00075     Timer timer;
00076     timer.start();
00077     while ((len < (size-1)) && (timer.read_ms() < timeout_ms)) {
00078         if (mdm.readable()) {
00079             cin_last = cin;
00080             cin = mdm.getc();
00081             if (isprint(cin)) {
00082                 buff[len++] = (char)cin;
00083                 continue;
00084             } else if (('\r' == cin_last) && ('\n' == cin)) {
00085                 break;
00086             }
00087         }
00088         wait_ms(1);
00089     }
00090     buff[len] = (char)NULL;
00091     
00092     return len;
00093 }
00094 
00095 int mdm_sendAtCmd(const char *cmd, const char **rsp_list, int timeout_ms) {
00096     if (cmd && strlen(cmd) > 0) {
00097         if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
00098             printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
00099         }
00100         mdm.printf("%s\r\n", cmd);
00101     }
00102     
00103     if (rsp_list) {
00104         Timer   timer;
00105         char    rsp[MAX_AT_RSP_LEN+1];
00106         int     len;
00107         
00108         timer.start();
00109         while (timer.read_ms() < timeout_ms) {
00110             len = mdm_getline(rsp, sizeof(rsp), timeout_ms - timer.read_ms());
00111             
00112             if (len < 0)
00113                 return MDM_ERR_TIMEOUT;
00114 
00115             if (len == 0)
00116                 continue;
00117                 
00118             if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
00119                 printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", rsp);
00120             }
00121         
00122             if (rsp_list) {
00123                 int rsp_idx = 0;
00124                 while (rsp_list[rsp_idx]) {
00125                     if (strcasecmp(rsp, rsp_list[rsp_idx]) == 0) {
00126                         return rsp_idx;
00127                     }
00128                     rsp_idx++;
00129                 }
00130             }
00131         }
00132         return MDM_ERR_TIMEOUT;
00133     }
00134     return MDM_OK;
00135 }
00136 
00137 int mdm_init(void) {
00138     // Hard reset the modem (doesn't go through
00139     // the signal level translator)
00140     mdm_reset = 0;
00141 
00142     // disable signal level translator (necessary
00143     // for the modem to boot properly).  All signals
00144     // except mdm_reset go through the level translator
00145     // and have internal pull-up/down in the module. While
00146     // the level translator is disabled, these pins will
00147     // be in the correct state.  
00148     shield_3v3_1v8_sig_trans_ena = 0;
00149 
00150     // While the level translator is disabled and ouptut pins
00151     // are tristated, make sure the inputs are in the same state
00152     // as the WNC Module pins so that when the level translator is
00153     // enabled, there are no differences.
00154     mdm_uart2_rx_boot_mode_sel = 1;   // UART2_RX should be high
00155     mdm_power_on = 0;                 // powr_on should be low
00156     mdm_wakeup_in = 1;                // wake-up should be high
00157     mdm_uart1_cts = 0;                // indicate that it is ok to send
00158 
00159    // Now, wait for the WNC Module to perform its initial boot correctly
00160     wait(1.0);
00161   
00162     // The WNC module initializes comms at 115200 8N1 so set it up
00163     mdm.baud(115200);
00164     
00165     //Now, enable the level translator, the input pins should now be the
00166     //same as how the M14A module is driving them with internal pull ups/downs.
00167     //When enabled, there will be no changes in these 4 pins...
00168     shield_3v3_1v8_sig_trans_ena = 1;
00169 
00170     // Now, give the modem 60 secons to start responding by
00171     // sending simple 'AT' commands to modem once per second.
00172     Timer timer;
00173     timer.start();
00174     while (timer.read() < 60) {
00175         const char * rsp_lst[] = { ok_str, error_str, NULL };
00176         int rc = mdm_sendAtCmd("AT", rsp_lst, 500);
00177         if (rc == 0)
00178             return true; //timer.read();
00179         wait_ms(1000 - (timer.read_ms() % 1000));
00180         pc.printf("\r%d",timer.read_ms()/1000);
00181     }
00182     return false;       
00183 }
00184 
00185 int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len) {
00186         printf("\n\nENTERING SEND AT CMD REP \n\n");
00187     static char cmd_buf[3200];  // Need enough room for the WNC sockreads (over 3000 chars)
00188     size_t n = strlen(cmd);
00189     if (cmd && n > 0) {
00190         if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
00191             printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
00192         }
00193         while (n--) {
00194             mdm.putc(*cmd++);
00195             wait_ms(1);
00196         };
00197         mdm.putc('\r');
00198         wait_ms(1);
00199         mdm.putc('\n');
00200         wait_ms(1);
00201         printf("\n\nAAAA\n\n");
00202     }
00203 
00204     if (rsp_list) {
00205         rsp->erase(); // Clean up from prior cmd response
00206         *len = 0;
00207         Timer   timer;
00208         timer.start();
00209         while (timer.read_ms() < timeout_ms) {
00210             int lenCmd = mdm_getline(cmd_buf, sizeof(cmd_buf), timeout_ms - timer.read_ms());
00211 
00212             if (lenCmd == 0)
00213                 continue;
00214 
00215             if (lenCmd < 0)
00216                 return MDM_ERR_TIMEOUT;
00217             else {
00218                 *len += lenCmd;
00219                 *rsp += cmd_buf;
00220             }
00221 
00222             if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
00223                 printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", cmd_buf);
00224             }
00225 
00226             int rsp_idx = 0;
00227             while (rsp_list[rsp_idx]) {
00228                 if (strcasecmp(cmd_buf, rsp_list[rsp_idx]) == 0) {
00229                     return rsp_idx;
00230                 }
00231                 rsp_idx++;
00232             }
00233         }
00234         return MDM_ERR_TIMEOUT;
00235     }
00236     pc.printf("D %s",rsp);
00237     printf("\n\nBBBB\n\n");
00238     return MDM_OK;
00239 }
00240 
00241 void reinitialize_mdm(void)
00242 {
00243     // Initialize the modem
00244     printf(GRN "Modem RE-initializing..." DEF "\r\n");
00245     if (!mdm_init()) {
00246         printf(RED "\n\rModem RE-initialization failed!" DEF "\n");
00247     }
00248     printf("\r\n");
00249 }
00250 // These are built on the fly
00251 string MyServerIpAddress;
00252 string MySocketData;
00253 
00254 // These are to be built on the fly
00255 string my_temp;
00256 string my_humidity;
00257 
00258 #define CTOF(x)  ((x)*1.8+32)
00259 
00260 //********************************************************************************************************************************************
00261 //* Create string with sensor readings that can be sent to flow as an HTTP get
00262 //********************************************************************************************************************************************
00263 K64F_Sensors_t  SENSOR_DATA =
00264 {
00265     .Temperature        = "0",
00266     .Humidity           = "0",
00267     .AccelX             = "0",
00268     .AccelY             = "0",
00269     .AccelZ             = "0",
00270     .MagnetometerX      = "0",
00271     .MagnetometerY      = "0",
00272     .MagnetometerZ      = "0",
00273     .AmbientLightVis    = "0",
00274     .AmbientLightIr     = "0",
00275     .UVindex            = "0",
00276     .Proximity          = "0",
00277     .Temperature_Si7020 = "0",
00278     .Humidity_Si7020    = "0"
00279 };
00280 
00281 void GenerateModemString(char * modem_string)
00282 {   
00283    // iSensorsToReport = TEMP_HUMIDITY_ONLY;
00284     switch(iSensorsToReport)
00285     {
00286         case TEMP_HUMIDITY_ONLY:
00287         {
00288             sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, FLOW_URL_TYPE, MY_SERVER_URL);
00289             break;
00290         }
00291         case TEMP_HUMIDITY_ACCELEROMETER:
00292         {
00293             //sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s&accelX=%s&accelY=%s&accelZ=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, SENSOR_DATA.AccelX,SENSOR_DATA.AccelY,SENSOR_DATA.AccelZ, FLOW_URL_TYPE, MY_SERVER_URL);
00294             sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s&proximity=%s&accelY=%s&accelZ=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, SENSOR_DATA.AccelX,SENSOR_DATA.AccelY,SENSOR_DATA.AccelZ, FLOW_URL_TYPE, MY_SERVER_URL);
00295             break;
00296         }
00297         case TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS:
00298         {
00299             sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s&accelX=%s&accelY=%s&accelZ=%s&proximity=%s&light_uv=%s&light_vis=%s&light_ir=%s %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity, SENSOR_DATA.AccelX,SENSOR_DATA.AccelY,SENSOR_DATA.AccelZ, SENSOR_DATA.Proximity, SENSOR_DATA.UVindex, SENSOR_DATA.AmbientLightVis, SENSOR_DATA.AmbientLightIr, FLOW_URL_TYPE, MY_SERVER_URL);
00300             break;
00301         }
00302         default:
00303         {
00304             sprintf(modem_string, "Invalid sensor selected\r\n\r\n");
00305             break;
00306         }
00307     } //switch(iSensorsToReport)
00308 } //GenerateModemString        
00309             
00310             
00311 //Periodic timer
00312 Ticker OneMsTicker;
00313 volatile bool bTimerExpiredFlag = false;
00314 int OneMsTicks = 0;
00315 int iTimer1Interval_ms = 1000;
00316 //********************************************************************************************************************************************
00317 //* Periodic 1ms timer tick
00318 //********************************************************************************************************************************************
00319 void OneMsFunction() 
00320 {
00321     OneMsTicks++;
00322     if ((OneMsTicks % iTimer1Interval_ms) == 0)
00323     {
00324         bTimerExpiredFlag = true;
00325     }            
00326 } //OneMsFunction()
00327 
00328 //********************************************************************************************************************************************
00329 //* Set the RGB LED's Color
00330 //* LED Color 0=Off to 7=White.  3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue) 
00331 //********************************************************************************************************************************************
00332 void SetLedColor(unsigned char ucColor)
00333 {
00334     //Note that when an LED is on, you write a 0 to it:
00335     led_red = !(ucColor & 0x1); //bit 0
00336     led_green = !(ucColor & 0x2); //bit 1
00337     led_blue = !(ucColor & 0x4); //bit 2
00338 } //SetLedColor()
00339 
00340 //********************************************************************************************************************************************
00341 //* Process JSON response messages
00342 //********************************************************************************************************************************************
00343 bool extract_JSON(char* search_field, char* found_string)
00344 {
00345     char* beginquote;
00346     char* endquote;
00347     beginquote = strchr(search_field, '{'); //start of JSON
00348     endquote = strchr(search_field, '}'); //end of JSON
00349     if (beginquote != 0)
00350     {
00351         uint16_t ifoundlen;
00352         if (endquote != 0)
00353         {
00354             ifoundlen = (uint16_t) (endquote - beginquote) + 1;
00355             strncpy(found_string, beginquote, ifoundlen );
00356             found_string[ifoundlen] = 0; //null terminate
00357             return true;
00358         }
00359         else
00360         {
00361             endquote = strchr(search_field, '\0'); //end of string...  sometimes the end bracket is missing
00362             ifoundlen = (uint16_t) (endquote - beginquote) + 1;
00363             strncpy(found_string, beginquote, ifoundlen );
00364             found_string[ifoundlen] = 0; //null terminate
00365             return false;
00366         }
00367     }
00368     else
00369     {
00370         return false;
00371     }
00372 } //extract_JSON
00373 
00374 bool parse_JSON(char* json_string)
00375 {
00376     char* beginquote;
00377     char token[] = "\"LED\":\"";
00378     beginquote = strstr(json_string, token );
00379     if ((beginquote != 0))
00380     {
00381         char cLedColor = beginquote[strlen(token)];
00382         printf(GRN "LED Found : %c" DEF "\r\n", cLedColor);
00383         switch(cLedColor)
00384         {
00385             case 'O':
00386             { //Off
00387                 SetLedColor(0);
00388                 break;
00389             }
00390             case 'R':
00391             { //Red
00392                 SetLedColor(1);
00393                 break;
00394             }
00395             case 'G':
00396             { //Green
00397                 SetLedColor(2);
00398                 break;
00399             }
00400             case 'Y':
00401             { //Yellow
00402                 SetLedColor(3);
00403                 break;
00404             }
00405             case 'B':
00406             { //Blue
00407                 SetLedColor(4);
00408                 break;
00409             }
00410             case 'M':
00411             { //Magenta
00412                 SetLedColor(5);
00413                 break;
00414             }
00415             case 'T':
00416             { //Turquoise
00417                 SetLedColor(6);
00418                 break;
00419             }
00420             case 'W':
00421             { //White
00422                 SetLedColor(7);
00423                 break;
00424             }
00425             default:
00426             {
00427                 break;
00428             }
00429         } //switch(cLedColor)
00430         return true;
00431     }
00432     else
00433     {
00434         return false;
00435     }
00436 } //parse_JSON
00437 
00438 int main() {
00439     int i;
00440     HTS221 hts221;
00441     pc.baud(115200);
00442     
00443     void hts221_init(void);
00444 
00445     // Set LED to RED until init finishes
00446     SetLedColor(0x1);
00447 
00448     pc.printf(BLU "Hello World from AT&T Shape!\r\n\n\r");
00449     pc.printf(GRN "Initialize the HTS221\n\r");
00450 
00451     i = hts221.begin();  
00452     if( i ) 
00453         pc.printf(BLU "HTS221 Detected! (0x%02X)\n\r",i);
00454     else
00455         pc.printf(RED "HTS221 NOT DETECTED!!\n\r");
00456 
00457     printf("Temp  is: %0.2f F \n\r",CTOF(hts221.readTemperature()));
00458     printf("Humid is: %02d %%\n\r",hts221.readHumidity());
00459     
00460     sensors_init();
00461     read_sensors();
00462 
00463     // Initialize the modem
00464     printf(GRN "Modem initializing... will take up to 60 seconds" DEF "\r\n");
00465     do {
00466         i=mdm_init();
00467         if (!i) {
00468             pc.printf(RED "Modem initialization failed!" DEF "\n");
00469         }
00470     } while (!i);
00471     
00472     //Software init
00473     software_init_mdm();
00474  
00475     // Resolve URL to IP address to connect to
00476     resolve_mdm();
00477 
00478     //Create a 1ms timer tick function:
00479     OneMsTicker.attach(OneMsFunction, 0.001f) ;
00480 
00481     iTimer1Interval_ms = SENSOR_UPDATE_INTERVAL_MS;
00482 
00483     // Open the socket (connect to the server)
00484     sockopen_mdm();
00485 
00486     // Set LED BLUE for partial init
00487     SetLedColor(0x4);
00488 
00489     // Send and receive data perpetually
00490     while(1) {
00491         static unsigned ledOnce = 0;
00492         if  (bTimerExpiredFlag)
00493         {
00494             bTimerExpiredFlag = false;
00495             sprintf(SENSOR_DATA.Temperature, "%0.2f", CTOF(hts221.readTemperature()));
00496             sprintf(SENSOR_DATA.Humidity, "%02d", hts221.readHumidity());
00497             read_sensors(); //read available external sensors from a PMOD and the on-board motion sensor
00498             char modem_string[512];
00499             GenerateModemString(&modem_string[0]);
00500             printf(BLU "Sending to modem : %s" DEF "\n", modem_string); 
00501             printf("\n\nStarting SOCKWRITE\n\n");
00502             sockwrite_mdm(modem_string);
00503             printf("\n\nENDING SOCKWRITE\n\n");
00504             sockread_mdm(&MySocketData, 1024, 20);
00505             
00506             // If any non-zero response from server, make it GREEN one-time
00507             //  then the actual FLOW responses will set the color.
00508             if ((!ledOnce) && (MySocketData.length() > 0))
00509             {
00510                 ledOnce = 1;
00511                 SetLedColor(0x2);
00512             }
00513             
00514             printf(BLU "Read back : %s" DEF "\n", &MySocketData[0]);
00515             char * myJsonResponse;
00516             if (extract_JSON(&MySocketData[0], &myJsonResponse[0]))
00517             {
00518                 printf(GRN "JSON : %s" DEF "\n", &myJsonResponse[0]);
00519                 //parse_JSON(&myJsonResponse[0]);
00520             }
00521             else
00522             {
00523                 printf(RED "JSON : %s" DEF "\n", &myJsonResponse[0]); //most likely an incomplete JSON string
00524                 //parse_JSON(&myJsonResponse[0]); //This is risky, as the string may be corrupted
00525             }
00526             printf("\n\nEND OF LOOP\n\n");
00527         } //bTimerExpiredFlag
00528       //NVIC_SystemReset();
00529     } //forever loop
00530 }