Rick McConney
/
AvnetATT_shape_hackathon
This program simply connects to a HTS221 I2C device to proximity sensor
main.cpp
- Committer:
- elmkom
- Date:
- 2016-09-19
- Revision:
- 35:2e864bae3af0
- Parent:
- 34:029e07b67a41
- Child:
- 36:f8d96ff1dd1b
File content as of revision 35:2e864bae3af0:
#include "mbed.h" #include <cctype> #include <string> #include "SerialBuffered.h" #include "HTS221.h" #include "config_me.h" #include "wnc_control.h" #include "sensors.h" #include "hardware.h" I2C i2c(PTC11, PTC10); //SDA, SCL -- define the I2C pins being used I2C proximityi2c(PTE25, PTE24); // comment out the following line if color is not supported on the terminal #define USE_COLOR #ifdef USE_COLOR #define BLK "\033[30m" #define RED "\033[31m" #define GRN "\033[32m" #define YEL "\033[33m" #define BLU "\033[34m" #define MAG "\033[35m" #define CYN "\033[36m" #define WHT "\033[37m" #define DEF "\033[39m" #else #define BLK #define RED #define GRN #define YEL #define BLU #define MAG #define CYN #define WHT #define DEF #endif #define MDM_DBG_OFF 0 #define MDM_DBG_AT_CMDS (1 << 0) int mdm_dbgmask = MDM_DBG_OFF; Serial pc(USBTX, USBRX); SerialBuffered mdm(PTD3, PTD2, 128); DigitalOut led_green(LED_GREEN); DigitalOut led_red(LED_RED); DigitalOut led_blue(LED_BLUE); DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot DigitalOut mdm_power_on(PTB9); // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem) DigitalOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield DigitalOut mdm_reset(PTC12); // active high DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active DigitalOut mdm_uart1_cts(PTD0); #define TOUPPER(a) (a) //toupper(a) const char ok_str[] = "OK"; const char error_str[] = "ERROR"; #define MDM_OK 0 #define MDM_ERR_TIMEOUT -1 #define MAX_AT_RSP_LEN 255 short proximity = 0; void prox_write_reg(char address,char reg, char cmd) { char txbuffer [2]; txbuffer[0] = reg; txbuffer[1] = cmd; proximityi2c.write(address<<1, txbuffer, 2,false ); } void prox_write(char address, char cmd) { char txbuffer [1]; txbuffer[0] = cmd; proximityi2c.write(address<<1, txbuffer, 1,false ); } unsigned char prox_read_reg(char address,char reg) { char txbuffer [1]; char rxbuffer [1]; rxbuffer[0] = 0; txbuffer[0] = reg; proximityi2c.write(address<<1, txbuffer, 1,false ); proximityi2c.read(address<<1, rxbuffer, 1 ); return (unsigned char)rxbuffer[0]; } void init_proximity_sensor(int sensor) { char C25ma = 0x00; char C50ma = 0x01; char C100m1 = 0x02; char C200ma = 0x03; char GainAls1Ir1 = 0x00<<2; char GainAls2Ir1 = 0x04<<2; char GainAls2Ir2 = 0x05<<2; char GainAls64Ir64 = 0x0A<<2; char GainAls128Ir64 = 0x0D<<2; char GainAls128Ir128 = 0x0F<<2; char Als0Ps0 = 0x00; char Als0Ps10 = 0x01; char Als0Ps40 = 0x02; char Als0Ps100 = 0x03; char Als0Ps400 = 0x04; char Als100Ps0 = 0x05; char Als100Ps100 = 0x06; char Als100Ps400 = 0x07; char Als401Ps0 = 0x08; char Als401Ps100 = 0x09; char Als400Ps0 = 0x0A; char Als400Ps400 = 0x0B; char Als50Ps50 = 0x0C; char muxaddress = 0x70; char proxaddress = 0x39; prox_write(muxaddress,sensor); // sensor 2 prox_write_reg(proxaddress,0x41,Als0Ps400); // initiate ALS: and PS prox_write_reg(proxaddress,0x42,GainAls64Ir64|C25ma); // set ALS_VIS=ALS_IR GAIN = 64 current 25ma } short read_proximity(int sensor) { char muxaddress = 0x70; char proxaddress = 0x39; prox_write(muxaddress,sensor); // sensor 2 unsigned char prox_lsb = prox_read_reg(proxaddress,0x44); unsigned char prox_msb = prox_read_reg(proxaddress,0x45); unsigned char ALS_lsb = prox_read_reg(proxaddress,0x46); unsigned char ALS_msb = prox_read_reg(proxaddress,0x47); unsigned char IR_lsb = prox_read_reg(proxaddress,0x48); unsigned char IR_msb = prox_read_reg(proxaddress,0x49); short proximity = prox_msb*256+prox_lsb; short ALS = ALS_msb*256+ALS_lsb; short IR = IR_msb*256+IR_lsb; pc.printf(GRN "Sensor %d\n\r",sensor); pc.printf(GRN "Prox %d\n\r",proximity); pc.printf(GRN "ALS %d\n\r",ALS); pc.printf(GRN "IR %d\n\r",IR); return proximity; } /* I2C_w_3 (sfh_address*2, 0x41, 0x08); // initiate ALS: 400ms rep rate, T_int=100ms I2C_w_3 (sfh_address*2, 0x42, 0x28); // set ALS_VIS=ALS_IR GAIN = 64 I2C_w_2_r_1 (sfh_address*2, 0x46); // read lsb of ALS_VIS, register 0x46 Content1 = Content; I2C_w_2_r_1 (sfh_address*2, 0x47); // read msb of ALS_VIS, register 0x47 ALS_VIS = (Content * 256 + Content1); // combining LSB+MSB byte to decimal value I2C_w_2_r_1 (sfh_address*2, 0x48); // read lsb of ALS_IR, register 0x48 Content1 = Content; I2C_w_2_r_1 (sfh_address*2, 0x49); // read msb of ALS_IR, register 0x49 ALS_IR = (Content * 256 + Content1); // combining LSB+MSB byte to decimal value // Lux Calculation based on ALS Gain = 64 and ALS_Int_Time = 100 ms // Lux value in front of sensor, no cover glass IF ((ALS_IR / ALS_VIS) < 0.109) {LUX = (1.534 * ALS_VIS / 64 - 3.759 * ALS_IR / 64) * 1}; ELSE IF ((ALS_IR / ALS_VIS) < 0.429) {LUX = (1.339 * ALS_VIS / 64 – 1.972 * ALS_IR / 64) * 1}; ELSE IF ((ALS_IR/ALS_VIS) < (0.95 * 1.45)) {LUX = (0.701 * ALS_VIS / 64 – 0.483 * ALS_IR / 64) * 1}; ELSE IF ((ALS_IR/ALS_VIS) < (1.5 * 1.45)) {LUX = (2 * 0.701 * ALS_VIS / 64 – 1.18 * 0.483 * ALS_IR / 64) * 1}; ELSE IF ((ALS_IR/ALS_VIS) < (2.5 * 1.45)) {LUX = (4 * 0.701 * ALS_VIS / 64 – 1.33 * 0.483 * ALS_IR / 64) * 1}; Else {LUX = 8 * 0.701 * ALS_VIS / 64}; */ short oldread_proximity( void ) { char muxaddress = (0x70<<1); char proxaddress = (0x39<<1); char reg = 0x40; short muxvalue = 0; short value = 0; char sensor = 0x02; char txbuffer [1]; char rxbuffer [1]; rxbuffer[0] = 0; txbuffer[0] = sensor; proximityi2c.write(muxaddress, txbuffer, 1,false ); proximityi2c.read(muxaddress, rxbuffer, 1 ); muxvalue = (unsigned char)rxbuffer[0]; rxbuffer[0] = 0; txbuffer[0] = reg; proximityi2c.write(proxaddress, txbuffer, 1,false ); proximityi2c.read(proxaddress, rxbuffer, 1 ); value = (unsigned char)rxbuffer[0]; pc.printf(GRN "Mux %d\n\r",muxvalue); pc.printf(GRN "Proximity %d\n\r",value); return value; } ssize_t mdm_getline(char *buff, size_t size, int timeout_ms) { int cin = -1; int cin_last; if (NULL == buff || size == 0) { return -1; } size_t len = 0; Timer timer; timer.start(); while ((len < (size-1)) && (timer.read_ms() < timeout_ms)) { if (mdm.readable()) { cin_last = cin; cin = mdm.getc(); if (isprint(cin)) { buff[len++] = (char)cin; continue; } else if (('\r' == cin_last) && ('\n' == cin)) { break; } } wait_ms(1); } buff[len] = (char)NULL; return len; } int mdm_sendAtCmd(const char *cmd, const char **rsp_list, int timeout_ms) { 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) { Timer timer; char rsp[MAX_AT_RSP_LEN+1]; int len; timer.start(); while (timer.read_ms() < timeout_ms) { len = mdm_getline(rsp, sizeof(rsp), timeout_ms - timer.read_ms()); if (len < 0) return MDM_ERR_TIMEOUT; if (len == 0) continue; if (mdm_dbgmask & MDM_DBG_AT_CMDS) { printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", rsp); } if (rsp_list) { int rsp_idx = 0; while (rsp_list[rsp_idx]) { if (strcasecmp(rsp, rsp_list[rsp_idx]) == 0) { return rsp_idx; } rsp_idx++; } } } return MDM_ERR_TIMEOUT; } return MDM_OK; } int mdm_init(void) { // disable signal level translator (necessary // for the modem to boot properly) shield_3v3_1v8_sig_trans_ena = 0; // Hard reset the modem (doesn't go through // the signal level translator) mdm_reset = 1; // wait a moment for the modem to react wait_ms(10); // Let modem boot mdm_reset = 0; // wait a moment for the modem to react wait(1.0); // power modem on //off mdm_power_on = 0; //1; // insure modem boots into normal operating mode // and does not go to sleep when powered on mdm_uart2_rx_boot_mode_sel = 1; mdm_wakeup_in = 1; // initialze comm with the modem mdm.baud(115200); // clear out potential garbage while (mdm.readable()) mdm.getc(); mdm_uart1_cts = 0; // wait a moment for the modem to react to signal // conditions while the level translator is disabled // (sorry, don't have enough information to know // what exactly the modem is doing with the current // pin settings) wait(1.0); // enable the signal level translator to start // modem reset process (modem will be powered down) shield_3v3_1v8_sig_trans_ena = 1; // Give the modem 60 secons to start responding by // sending simple 'AT' commands to modem once per second. Timer timer; timer.start(); while (timer.read() < 60) { const char * rsp_lst[] = { ok_str, error_str, NULL }; int rc = mdm_sendAtCmd("AT", rsp_lst, 500); if (rc == 0) return true; //timer.read(); wait_ms(1000 - (timer.read_ms() % 1000)); pc.printf("\r%d",timer.read_ms()/1000); } return false; } int oldmdm_init(void) { // Hard reset the modem (doesn't go through // the signal level translator) mdm_reset = 0; // disable signal level translator (necessary // for the modem to boot properly). All signals // except mdm_reset go through the level translator // and have internal pull-up/down in the module. While // the level translator is disabled, these pins will // be in the correct state. shield_3v3_1v8_sig_trans_ena = 0; // While the level translator is disabled and ouptut pins // are tristated, make sure the inputs are in the same state // as the WNC Module pins so that when the level translator is // enabled, there are no differences. mdm_uart2_rx_boot_mode_sel = 1; // UART2_RX should be high mdm_power_on = 0; // powr_on should be low mdm_wakeup_in = 1; // wake-up should be high mdm_uart1_cts = 0; // indicate that it is ok to send // Now, wait for the WNC Module to perform its initial boot correctly wait(1.0); // The WNC module initializes comms at 115200 8N1 so set it up mdm.baud(115200); //Now, enable the level translator, the input pins should now be the //same as how the M14A module is driving them with internal pull ups/downs. //When enabled, there will be no changes in these 4 pins... shield_3v3_1v8_sig_trans_ena = 1; // Now, give the modem 60 secons to start responding by // sending simple 'AT' commands to modem once per second. Timer timer; timer.start(); while (timer.read() < 60) { const char * rsp_lst[] = { ok_str, error_str, NULL }; int rc = mdm_sendAtCmd("AT", rsp_lst, 500); if (rc == 0) return true; //timer.read(); wait_ms(1000 - (timer.read_ms() % 1000)); pc.printf("\r%d",timer.read_ms()/1000); } 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) size_t n = strlen(cmd); if (cmd && n > 0) { if (mdm_dbgmask & MDM_DBG_AT_CMDS) { printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd); } while (n--) { mdm.putc(*cmd++); wait_ms(1); }; mdm.putc('\r'); wait_ms(1); mdm.putc('\n'); wait_ms(1); } 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) //******************************************************************************************************************************************** //* Create string with sensor readings that can be sent to flow as an HTTP get //******************************************************************************************************************************************** K64F_Sensors_t SENSOR_DATA = { .Temperature = "0", .Humidity = "0", .AccelX = "0", .AccelY = "0", .AccelZ = "0", .MagnetometerX = "0", .MagnetometerY = "0", .MagnetometerZ = "0", .AmbientLightVis = "0", .AmbientLightIr = "0", .UVindex = "0", .Proximity = "0", .Temperature_Si7020 = "0", .Humidity_Si7020 = "0" }; void GenerateModemString(char * modem_string) { switch(iSensorsToReport) { case PROXIMITY: { sprintf(modem_string, "GET %s%s?serial=%s&temp=%s&humidity=%s&proximity=%d %s%s\r\n\r\n", FLOW_BASE_URL, FLOW_INPUT_NAME, FLOW_DEVICE_NAME, SENSOR_DATA.Temperature, SENSOR_DATA.Humidity,proximity, FLOW_URL_TYPE, MY_SERVER_URL); break; } case TEMP_HUMIDITY_ONLY: { 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); break; } case TEMP_HUMIDITY_ACCELEROMETER: { 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); break; } case TEMP_HUMIDITY_ACCELEROMETER_PMODSENSORS: { 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); break; } default: { sprintf(modem_string, "Invalid sensor selected\r\n\r\n"); break; } } //switch(iSensorsToReport) } //GenerateModemString //Periodic timer Ticker OneMsTicker; volatile bool bTimerExpiredFlag = false; int OneMsTicks = 0; int iTimer1Interval_ms = 1000; //******************************************************************************************************************************************** //* Periodic 1ms timer tick //******************************************************************************************************************************************** void OneMsFunction() { OneMsTicks++; if ((OneMsTicks % iTimer1Interval_ms) == 0) { bTimerExpiredFlag = true; } } //OneMsFunction() //******************************************************************************************************************************************** //* Set the RGB LED's Color //* LED Color 0=Off to 7=White. 3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue) //******************************************************************************************************************************************** void SetLedColor(unsigned char ucColor) { //Note that when an LED is on, you write a 0 to it: led_red = !(ucColor & 0x1); //bit 0 led_green = !(ucColor & 0x2); //bit 1 led_blue = !(ucColor & 0x4); //bit 2 } //SetLedColor() //******************************************************************************************************************************************** //* Process JSON response messages //******************************************************************************************************************************************** bool extract_JSON(char* search_field, char* found_string) { char* beginquote; char* endquote; beginquote = strchr(search_field, '{'); //start of JSON endquote = strchr(search_field, '}'); //end of JSON if (beginquote != 0) { uint16_t ifoundlen; if (endquote != 0) { ifoundlen = (uint16_t) (endquote - beginquote) + 1; strncpy(found_string, beginquote, ifoundlen ); found_string[ifoundlen] = 0; //null terminate return true; } else { endquote = strchr(search_field, '\0'); //end of string... sometimes the end bracket is missing ifoundlen = (uint16_t) (endquote - beginquote) + 1; strncpy(found_string, beginquote, ifoundlen ); found_string[ifoundlen] = 0; //null terminate return false; } } else { return false; } } //extract_JSON bool parse_JSON(char* json_string) { char* beginquote; char token[] = "\"LED\":\""; beginquote = strstr(json_string, token ); if ((beginquote != 0)) { char cLedColor = beginquote[strlen(token)]; printf(GRN "LED Found : %c" DEF "\r\n", cLedColor); switch(cLedColor) { case 'O': { //Off SetLedColor(0); break; } case 'R': { //Red SetLedColor(1); break; } case 'G': { //Green SetLedColor(2); break; } case 'Y': { //Yellow SetLedColor(3); break; } case 'B': { //Blue SetLedColor(4); break; } case 'M': { //Magenta SetLedColor(5); break; } case 'T': { //Turquoise SetLedColor(6); break; } case 'W': { //White SetLedColor(7); break; } default: { break; } } //switch(cLedColor) return true; } else { return false; } } //parse_JSON int main() { int i; HTS221 hts221; pc.baud(115200); proximityi2c.frequency(400000); for(int i = 0;i<8;i++) init_proximity_sensor(i); void hts221_init(void); // Set LED to RED until init finishes SetLedColor(0x1); pc.printf(BLU "Hello World from AT&T Shape!\r\n\n\r"); pc.printf(GRN "Initialize the HTS221\n\r"); i = hts221.begin(); if( i ) pc.printf(BLU "HTS221 Detected! (0x%02X)\n\r",i); else pc.printf(RED "HTS221 NOT DETECTED!!\n\r"); printf("Temp is: %0.2f F \n\r",CTOF(hts221.readTemperature())); printf("Humid is: %02d %%\n\r",hts221.readHumidity()); sensors_init(); read_sensors(); // Initialize the modem printf(GRN "Modem initializing... will take up to 60 seconds" DEF "\r\n"); do { i=mdm_init(); if (!i) { pc.printf(RED "Modem initialization failed!" DEF "\n"); } } while (!i); //Software init software_init_mdm(); // Resolve URL to IP address to connect to resolve_mdm(); //Create a 1ms timer tick function: OneMsTicker.attach(OneMsFunction, 0.001f) ; iTimer1Interval_ms = SENSOR_UPDATE_INTERVAL_MS; // Open the socket (connect to the server) sockopen_mdm(); // Set LED BLUE for partial init SetLedColor(0x4); // Send and receive data perpetually while(1) { static unsigned ledOnce = 0; if (bTimerExpiredFlag) { bTimerExpiredFlag = false; sprintf(SENSOR_DATA.Temperature, "%0.2f", CTOF(hts221.readTemperature())); sprintf(SENSOR_DATA.Humidity, "%02d", hts221.readHumidity()); read_sensors(); //read available external sensors from a PMOD and the on-board motion sensor for(int i = 0;i<8;i++) proximity = read_proximity(i); char modem_string[512]; GenerateModemString(&modem_string[0]); printf(BLU "Sending to modem : %s" DEF "\n", modem_string); sockwrite_mdm(modem_string); sockread_mdm(&MySocketData, 1024, 20); // If any non-zero response from server, make it GREEN one-time // then the actual FLOW responses will set the color. if ((!ledOnce) && (MySocketData.length() > 0)) { ledOnce = 1; SetLedColor(0x2); } printf(BLU "Read back : %s" DEF "\n", &MySocketData[0]); char myJsonResponse[512]; if (extract_JSON(&MySocketData[0], &myJsonResponse[0])) { printf(GRN "JSON : %s" DEF "\n", &myJsonResponse[0]); parse_JSON(&myJsonResponse[0]); } else { printf(RED "JSON : %s" DEF "\n", &myJsonResponse[0]); //most likely an incomplete JSON string parse_JSON(&myJsonResponse[0]); //This is risky, as the string may be corrupted } } //bTimerExpiredFlag } //forever loop }