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

Dependencies:   FXOS8700CQ mbed

Files at this revision

API Documentation at this revision

Comitter:
JMF
Date:
Sun Jul 10 00:52:49 2016 +0000
Parent:
1:af7a42f7d465
Child:
3:26b3cc155f39
Commit message:
Adding in WNC code from Fred

Changed in this revision

config_me.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
wnc_control.cpp Show annotated file Show diff for this revision Revisions of this file
wnc_control.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config_me.h	Sun Jul 10 00:52:49 2016 +0000
@@ -0,0 +1,10 @@
+#ifndef __CONFIG_ME_H_
+#define __CONFIG_ME_H_
+
+// User must set these for own context:
+static const char * MY_FLOW_DEVICE_ID_STR = "48482f";
+static const char * MY_SERVER_URL         = "run-east.att.io";
+static const char * MY_APN_STR            = "m2m.com.attz";
+static const char * MY_PORT_STR           = "80";
+
+#endif
--- a/main.cpp	Sat Jul 09 00:45:53 2016 +0000
+++ b/main.cpp	Sun Jul 10 00:52:49 2016 +0000
@@ -3,6 +3,9 @@
 #include <string>
 #include "SerialBuffered.h"
 #include "HTS221.h"
+#include "config_me.h"
+#include "wnc_control.h"
+
 
 // comment out the following line if color is not supported on the terminal
 #define USE_COLOR
@@ -54,56 +57,6 @@
 
 #define MAX_AT_RSP_LEN                          255
 
-//
-// The modem will return strings of HEX encoded data.  This function takes
-// a pointer to a string of HEX ASCII data and converts it into a string
-// of ASCII data.  It takes a pointer to the string of HEX ASCII data and
-// a pointer to the destination string.  It returns the number of characters
-// it converted.
-//
-int DecodeASCIIstr(string& ins, string& outs) {
-    int val, n = 0;
-    char ts[] = {0,0,0};
-    
-    while(n<ins.length()) {
-        ts[0] = ins[n];
-        ts[1] = ins[n+1];
-        sscanf(ts,"%X",&val);
-        sprintf(ts,"%c",val);
-        outs.append(ts);
-        n += 2;
-     }
-     return outs.length();
-}
-
-
-//
-// Modem expects data to be passed to it in the form of HEX encoded strings.  This
-// function takes a pointer to a users supplied ASCII string, and converts it into
-// an ASCII string of equivelent HEX numbers encoded as a string.  The function takes
-// a pointer to the users input string, and a pointer to the output string.  The
-// function returns the number of characters converted or 0 if an error occurs or more
-// than 750 characters were converted.  The 750 chacter limit is because the modem
-// will only accept up to 1500 characters, and the converted srings will be 2x the
-// input string since the hex representation of 1 character is a two digit hex value.
-//
-int CreateASCIIstr(string& ins, string& outs) {
-    int i = 0;
-    char ts[3];
-
-    if( ins.length() > 749 )
-      return 0;
-
-    while(ins[i] != 0x00) {
-        sprintf(ts,"%02X", ins[i]);
-        outs.append(ts);
-        i++;
-        }
-    return outs.length();
-}
-
-
-
 ssize_t mdm_getline(char *buff, size_t size, int timeout_ms) {
     int cin = -1;
     int cin_last;
@@ -128,7 +81,7 @@
         }
         wait_ms(1);
     }
-    buff[len] = NULL;
+    buff[len] = (char)NULL;
     
     return len;
 }
@@ -189,6 +142,10 @@
     
     // initialze comm with the modem
     mdm.baud(115200);
+    // clear out potential garbage
+    while (mdm.readable())
+      mdm.getc();
+
     mdm_uart1_cts = 0;
     
     // enable the signal level translator to start
@@ -210,15 +167,76 @@
     return false;       
 }
 
+int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len) {
+
+    static char cmd_buf[3200];  // Need enough room for the WNC sockreads (over 3000 chars)
+
+    if (cmd && strlen(cmd) > 0) {
+        if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
+            printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
+        }
+        mdm.printf("%s\r\n", cmd);
+    }
+
+    if (rsp_list) {
+        rsp->erase(); // Clean up from prior cmd response
+        *len = 0;
+        Timer   timer;
+        timer.start();
+        while (timer.read_ms() < timeout_ms) {
+            int lenCmd = mdm_getline(cmd_buf, sizeof(cmd_buf), timeout_ms - timer.read_ms());
+
+            if (lenCmd == 0)
+                continue;
+
+            if (lenCmd < 0)
+                return MDM_ERR_TIMEOUT;
+            else {
+                *len += lenCmd;
+                *rsp += cmd_buf;
+            }
+
+            if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
+                printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", cmd_buf);
+            }
+
+            int rsp_idx = 0;
+            while (rsp_list[rsp_idx]) {
+                if (strcasecmp(cmd_buf, rsp_list[rsp_idx]) == 0) {
+                    return rsp_idx;
+                }
+                rsp_idx++;
+            }
+        }
+        return MDM_ERR_TIMEOUT;
+    }
+    pc.printf("D %s",rsp);
+    return MDM_OK;
+}
+
+void reinitialize_mdm(void)
+{
+    // Initialize the modem
+    printf(GRN "Modem RE-initializing..." DEF "\r\n");
+    if (!mdm_init()) {
+        printf(RED "\n\rModem RE-initialization failed!" DEF "\n");
+    }
+    printf("\r\n");
+}
+// These are built on the fly
+string MyServerIpAddress;
+string MySocketData;
+
+// These are to be built on the fly
+string my_temp;
+string my_humidity;
+
 #define CTOF(x)  ((x)*1.8+32)
 
 int main() {
+    int i;
     HTS221 hts221;
     pc.baud(115200);
-    int i,
-        CreateASCIIstr(string& in, string& out), 
-        DecodeASCIIstr(string& ins, string& outs);
-    string ins, outs;
     
     void hts221_init(void);
 
@@ -233,15 +251,6 @@
 
     printf("Temp  is: %0.2f F \n\r",CTOF(hts221.readTemperature()));
     printf("Humid is: %02d %%\n\r",hts221.readHumidity());
-
-    string newstr, outstr, instr = "0123456789aAbBcCdDeEfFxXyYzZ";
-    pc.printf("\n\rTest ASCII String creation: \n\r");
-    i = CreateASCIIstr(instr,outstr);
-    pc.printf(">Initially the string is '%s' (%d long)\n\r>after encode it is '%s' (%d characters long).\n\r",
-               instr.c_str(),instr.length(),outstr.c_str(),i);
-    i = DecodeASCIIstr(outstr, newstr);
-    pc.printf(">after decoding the encoded string, it is '%s' (%d long)\n\r\n\r",newstr.c_str(),i);
-    
     
     // Initialize the modem
     printf(GRN "Modem initializing... will take up to 60 seconds" DEF "\r\n");
@@ -251,34 +260,23 @@
         while (1);
     }
     
-    // Now that the modem is up and running, transfer characters
-    // between the pc terminal and the modem to give the user
-    // a virtual terminal to the modem.
-    pc.printf(YEL "\rAT command interface ready, completed in %d seconds.  You may now type AT commands" DEF "\r\n",i);
-   
-    while(1) {
-        if(pc.readable()) {
-            char char_in = TOUPPER(pc.getc());
-            
-            static char last_char_in = 0;
+    //Software init
+    software_init_mdm();
+    
+    // Resolve URL to IP address to connect to
+    resolve_mdm();
 
-            if (('\r' == char_in) || ('\n' == char_in))
-            {
-                if (('\r' == char_in) || ('\r' != last_char_in))
-                {
-                    mdm.puts("\r\n");
-                }
-            }
-            else
-            {
-                pc.putc(char_in);
-                mdm.putc(char_in);
-            }
-            last_char_in = char_in;
-        }
-        if(mdm.readable()) {
-            char ser_char = mdm.getc();
-                pc.putc(ser_char);
-            }
+    // Send and receive data perpetually
+    while(1) {
+        sockopen_mdm();
+        sockwrite_mdm("GET /f653d97537235/a31c2684a02c/d35e42196968fd6/in/flow/climate?deviceID=e5ee19804bd500c8fe69a809342384c2&temp=41.0&humidity=87.33 HTTP/1.1 Host: run-east.att.io:80 Accept: */*\r\n\r\n");
+        sockread_mdm(&MySocketData, 1024, 20);
+        sockclose_mdm();
+    }
+
+    string * pStr;
+    while (1)
+    {
+       send_wnc_cmd("AT", &pStr, WNC_TIMEOUT_MS);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wnc_control.cpp	Sun Jul 10 00:52:49 2016 +0000
@@ -0,0 +1,331 @@
+#include "mbed.h"
+#include <cctype>
+#include <string>
+#include "config_me.h"
+#include "SerialBuffered.h"
+#include "wnc_control.h"
+
+extern Serial pc;
+extern Serial mdm;
+extern string MyServerIpAddress;
+extern string MySocketData;
+
+int reinitialize_mdm(void);
+
+enum WNC_ERR_e {
+    WNC_OK =0,
+    WNC_CMD_ERR = -1,
+    WNC_NO_RESPONSE = -2
+};
+
+// Contains result of last call to send_wnc_cmd(..)
+WNC_ERR_e WNC_MDM_ERR = WNC_OK;
+
+// Contains the RAW WNC UART responses
+static string wncStr;
+
+void software_init_mdm(void)
+{
+  do
+  {
+    WNC_MDM_ERR = WNC_OK;
+    at_init_wnc();
+    if (WNC_MDM_ERR != WNC_OK)
+      reinitialize_mdm();
+  } while (WNC_MDM_ERR != WNC_OK); 
+}
+
+void resolve_mdm(void)
+{
+    do
+    {
+      WNC_MDM_ERR = WNC_OK;
+      at_dnsresolve_wnc(MY_SERVER_URL, &MyServerIpAddress);
+      if (WNC_MDM_ERR == WNC_NO_RESPONSE)
+      {
+        reinitialize_mdm();
+        software_init_mdm();
+      }
+      else if (WNC_MDM_ERR == WNC_CMD_ERR)
+      {
+        pc.puts("Bad URL!!!!!!\r\n");
+        MyServerIpAddress = "192.168.0.1";
+        WNC_MDM_ERR = WNC_OK;
+      }
+    } while (WNC_MDM_ERR != WNC_OK);
+    
+    pc.printf("My Server IP: %s\r\n", MyServerIpAddress.data());
+}
+
+void sockopen_mdm(void)
+{
+    do
+    {
+      WNC_MDM_ERR = WNC_OK;
+      at_sockopen_wnc(MyServerIpAddress, MY_PORT_STR);
+      if (WNC_MDM_ERR == WNC_NO_RESPONSE)
+      {
+        reinitialize_mdm();
+        software_init_mdm();
+      }
+      else if (WNC_MDM_ERR == WNC_CMD_ERR)
+        pc.puts("Socket open fail!!!!\r\n");
+    } while (WNC_MDM_ERR != WNC_OK);
+}
+
+void sockwrite_mdm(const char * s)
+{
+    do
+    {
+      WNC_MDM_ERR = WNC_OK;
+      at_sockwrite_wnc(s);
+      if (WNC_MDM_ERR == WNC_NO_RESPONSE)
+      {
+        reinitialize_mdm();
+        software_init_mdm();
+      }
+      else if (WNC_MDM_ERR == WNC_CMD_ERR)
+      {
+        pc.puts("Socket Write fail!!!\r\n");
+        // Have seen when write fails modem gets stuck in bad state, try to recover
+        reinitialize_mdm();
+        software_init_mdm();
+      }
+    } while (WNC_MDM_ERR != WNC_OK);
+}
+
+void sockread_mdm(string * sockData, int len, int retries)
+{
+    do
+    {
+      WNC_MDM_ERR = WNC_OK;
+      at_sockread_wnc(sockData, len, retries);
+      if (WNC_MDM_ERR == WNC_NO_RESPONSE)
+      {
+        reinitialize_mdm();
+        software_init_mdm();
+      }
+      else if (WNC_MDM_ERR == WNC_CMD_ERR)
+        puts("Sock read fail!!!!\r\n");
+    } while (WNC_MDM_ERR != WNC_OK);
+}
+
+void sockclose_mdm(void)
+{
+    do
+    {
+      WNC_MDM_ERR = WNC_OK;
+      at_sockclose_wnc();
+      if (WNC_MDM_ERR == WNC_NO_RESPONSE)
+      {
+        reinitialize_mdm();
+        software_init_mdm();
+      }
+      else if (WNC_MDM_ERR == WNC_CMD_ERR)
+        puts("Sock close fail!!!\r\n");
+    } while (WNC_MDM_ERR != WNC_OK);
+}
+
+/**                                                                                                                                                          
+ * C++ version 0.4 char* style "itoa":                                                                                                                       
+ * Written by Lukás Chmela                                                                                                                                   
+ * Released under GPLv3.                                                                                                                                     
+*/
+ 
+char* itoa(int value, char* result, int base)                                                                                                          
+{                                                                                                                                                        
+    // check that the base if valid                                                                                                                      
+    if ( base < 2 || base > 36 ) {                                                                                                                       
+        *result = '\0';                                                                                                                                  
+        return result;                                                                                                                                   
+    }                                                                                                                                                    
+ 
+    char* ptr = result, *ptr1 = result, tmp_char;                                                                                                        
+    int tmp_value;                                                                                                                                       
+ 
+    do {                                                                                                                                                 
+        tmp_value = value;                                                                                                                               
+        value /= base;                                                                                                                                   
+        *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];                             
+    } while ( value );                                                                                                                                   
+ 
+    // Apply negative sign                                                                                                                               
+    if ( tmp_value < 0 )                                                                                                                                 
+    *ptr++ = '-';                                                                                                                                    
+    *ptr-- = '\0';                                                                                                                                       
+ 
+    while ( ptr1 < ptr ) {                                                                                                                               
+    tmp_char = *ptr;                                                                                                                                 
+    *ptr-- = *ptr1;                                                                                                                                  
+    *ptr1++ = tmp_char;                                                                                                                              
+    }                                                                                                                                                    
+ 
+    return result;                                                                                                                                       
+}
+
+extern int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len);
+
+// Sets a global with failure or success, assumes 1 thread all the time
+int send_wnc_cmd(const char * s, string ** r, int ms_timeout)
+{
+  static const char * rsp_lst[] = { "OK", "ERROR", NULL };
+  int len;
+  
+  pc.printf("Send: %s\r\n",s);
+  int res = mdm_sendAtCmdRsp(s, rsp_lst, ms_timeout, &wncStr, &len);
+  *r = &wncStr;   // Return a pointer to the static string
+      
+  if (res >= 0)
+  {
+      pc.puts("[");
+      pc.puts(wncStr.data());
+      pc.puts("]\n\r");
+      if (res > 0)
+      {
+          if (WNC_MDM_ERR != WNC_NO_RESPONSE)
+            WNC_MDM_ERR = WNC_CMD_ERR;
+          return -1;
+      }
+      else
+          return 0;
+  }
+  else
+  {
+      WNC_MDM_ERR = WNC_NO_RESPONSE;
+      pc.puts("No response from WNC!\n\r");
+      return -2;
+  }
+}
+
+void at_init_wnc(void)
+{
+  string * pRespStr;
+  send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS);             // Heartbeat?
+  send_wnc_cmd("ATE1", &pRespStr, WNC_TIMEOUT_MS);           // Echo ON
+  string cmd_str("AT%PDNSET=1,");
+  cmd_str += MY_APN_STR;
+  cmd_str += ",IP";
+  send_wnc_cmd(cmd_str.data(), &pRespStr, 2*WNC_TIMEOUT_MS); // Set APN, cmd seems to take a little longer sometimes
+  send_wnc_cmd("AT@INTERNET=1", &pRespStr, WNC_TIMEOUT_MS);  // Internet services enabled
+  send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, WNC_TIMEOUT_MS);
+}
+
+void at_sockopen_wnc(const string & ipStr, const char * port )
+{
+  string * pRespStr;
+  send_wnc_cmd("AT@SOCKCREAT=1", &pRespStr, WNC_TIMEOUT_MS);
+  string cmd_str("AT@SOCKCONN=1,\"");
+  cmd_str += ipStr;
+  cmd_str += "\",";
+  cmd_str += port;
+  send_wnc_cmd(cmd_str.data(), &pRespStr, WNC_TIMEOUT_MS);
+}
+
+void at_sockclose_wnc(void)
+{
+  string * pRespStr;
+  send_wnc_cmd("AT@SOCKCLOSE=1", &pRespStr, WNC_TIMEOUT_MS);
+}
+
+int at_dnsresolve_wnc(const char * s, string * ipStr)
+{
+  string * pRespStr;
+  string str(s);
+  str = "AT@DNSRESVDON=\"" + str;
+  str += "\"\r\n";
+  if (send_wnc_cmd(str.data(), &pRespStr, WNC_TIMEOUT_MS) == 0)
+  {
+    size_t pos_start = pRespStr->find(":\"") + 2;
+    if (pos_start !=  string::npos)
+    {
+      size_t pos_end = pRespStr->rfind("\"") - 1;
+      if (pos_end != string::npos)
+      {
+        if (pos_end > pos_start)
+        {
+          // Make a copy for use later (the source string is re-used)
+          *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
+          return 1;
+        }
+        else
+          pc.puts("URL Resolve fail, substr Err\r\n");
+      }
+      else
+        pc.puts("URL Resolve fail, no 2nd quote\r\n");
+    }
+    else
+      pc.puts("URL Resolve fail, no quotes\r\n");
+  }
+  else
+    pc.puts("URL Resolve fail, WNC cmd fail\r\n");
+  
+  return -1;
+}
+
+void at_sockwrite_wnc(const char * s)
+{
+  string * pRespStr;
+  char num2str[6];
+  size_t sLen = strlen(s);
+  if (sLen <= 99999)
+  {
+    string cmd_str("AT@SOCKWRITE=1,");
+    itoa(sLen, num2str, 10);
+    cmd_str += num2str;
+    cmd_str += ",\"";
+    while(*s != '\0')
+    {
+      itoa((int)*s++, num2str, 16);
+      // Always 2-digit ascii hex:
+      if (strlen(num2str) == 1)
+      {
+        num2str[2] = '\0';
+        num2str[1] = num2str[0];
+        num2str[0] = '0';
+      }
+      cmd_str += num2str;
+    }
+    cmd_str += "\"";
+    send_wnc_cmd(cmd_str.data(), &pRespStr, WNC_TIMEOUT_MS);
+  }
+  else
+    pc.puts("sockwrite Err, string to long\r\n");
+}
+
+unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries = 0)
+{
+  unsigned i;
+  string * pRespStr;
+  string cmd_str("AT@SOCKREAD=1,");
+  if (n <= 1500)
+  {
+    char num2str[6];
+    itoa(n, num2str, 10);
+    cmd_str += num2str;
+    retries += 1;
+    while (retries--)
+    {
+      send_wnc_cmd(cmd_str.data(), &pRespStr, WNC_TIMEOUT_MS);
+      size_t pos_start = pRespStr->find("\"")  + 1;
+      size_t pos_end   = pRespStr->rfind("\"") - 1;
+      i = pos_end - pos_start + 1;
+      if (i > 0)
+      {
+        retries = 0;  // If any data found stop retrying
+        string byte;
+        pS->erase();
+        while (pos_start < pos_end)
+        {
+          byte = pRespStr->substr(pos_start, 2);
+          *pS += (char)strtol(byte.data(), NULL, 16);
+          pos_start += 2;
+        }
+        return i;
+      }
+    }
+  }
+  else
+    pc.puts("sockread Err, to many to read\r\n");
+  
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wnc_control.h	Sun Jul 10 00:52:49 2016 +0000
@@ -0,0 +1,28 @@
+
+#ifndef __WNC_CONTROL_H_
+#define __WNC_CONTROL_H_
+
+static const unsigned WNC_TIMEOUT_MS = 5000;
+
+// Core function that sends data to the WNC UART
+extern int send_wnc_cmd(const char * s, string ** r, int ms_timeout);
+
+// Low level command functions
+extern void at_init_wnc(void);
+extern void at_sockopen_wnc(const string & ipStr, const char * port );
+extern void at_sockclose_wnc(void);
+extern int at_dnsresolve_wnc(const char * s, string * ipStr);
+extern void at_sockwrite_wnc(const char * s);
+extern unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries);
+
+// High level functions that attempt to correct for things going bad with the WNC
+extern void software_init_mdm(void);
+extern void resolve_mdm(void);
+extern void sockopen_mdm(void);
+extern void sockwrite_mdm(const char * s);
+extern void sockread_mdm(string * sockData, int len, int retries);
+extern void sockclose_mdm(void);
+
+#endif
+
+