Added a GPIO to power on/off for external I2C sensor(s) (with LEDs)
Dependencies: UniGraphic mbed vt100
18-Jun-2018 外部センサの電源オン・オフ機能は下位互換の為に無効になっていました。 この版で再度有効にしました。
Diff: edge_utils/edge_mgr.cpp
- Revision:
- 0:846e2321c637
- Child:
- 1:8d65cfc3a2e2
diff -r 000000000000 -r 846e2321c637 edge_utils/edge_mgr.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/edge_utils/edge_mgr.cpp Fri Apr 13 04:19:23 2018 +0000
@@ -0,0 +1,598 @@
+#include "mbed.h"
+#include "edge_mgr.h"
+#include "af_attributes.h"
+
+#include "edge_time.h"
+#include "edge_pin.h"
+#include "MMA8451Q.h"
+#include "VEML6040.h"
+#include "LM75B.h"
+#include "SMTC502AT.h"
+#include "PSE530.h"
+#include <ILI9341.h>
+#include "Arial12x12.h"
+#include "Arial24x23.h"
+#include "Arial28x28.h"
+
+#include "edge_sensor.h"
+#include "edge_accel.h"
+#include "edge_color.h"
+#include "edge_temp.h"
+#include "edge_pressure.h"
+#include "edge_reset_mgr.h"
+#include "edge_chart.h"
+
+#define MMA8451Q_I2C_ADDRESS 0x1C
+#define VEML6040_I2C_ADDRESS 0x10
+#define LM75B_I2C_ADDRESS 0x48
+#define SO1602A_I2C_ADDRESS 0x3C
+
+#define NUM_MAX_SENSOR 5
+
+uint16_t attr_to_set[] = {
+ATTR_ACCEL_PRESENT,
+ATTR_COLOR0_PRESENT,
+ATTR_COLOR1_PRESENT,
+ATTR_TEMP0_PRESENT,
+ATTR_GAS_PRESENT,
+} ;
+
+uint16_t attr_to_get[] = {
+// accel
+ATTR_ACCEL_ENABLE,
+ATTR_ACCEL_INTERVAL,
+// Color0
+ATTR_COLOR0_ENABLE,
+ATTR_COLOR0_INTERVAL,
+ATTR_COLOR0_ITIME,
+ATTR_COLOR0_PWM_PERIOD,
+ATTR_COLOR0_PWM_TARGET,
+ATTR_COLOR0_PWM_R,
+ATTR_COLOR0_PWM_G,
+ATTR_COLOR0_PWM_B,
+// Color1
+ATTR_COLOR1_ENABLE,
+ATTR_COLOR1_INTERVAL,
+ATTR_COLOR1_ITIME,
+ATTR_COLOR1_PWM_PERIOD,
+ATTR_COLOR1_PWM_TARGET,
+ATTR_COLOR1_PWM_R,
+ATTR_COLOR1_PWM_G,
+ATTR_COLOR1_PWM_B,
+// Temp
+ATTR_TEMP0_INTERVAL,
+ATTR_TEMP0_ENABLE,
+// Gas Pressure
+ATTR_GAS_ENABLE,
+ATTR_GAS_INTERVAL,
+ATTR_GAS_THR_MODE,
+ATTR_GAS_THR_HIGH,
+ATTR_GAS_THR_LOW,
+0 } ;
+
+bool verbos = true ;
+edge_sensor *sensor[NUM_MAX_SENSOR] ;
+int num_sensor = 0 ;
+
+edge_accel *accel = 0 ;
+edge_color *color[2] = {0, 0} ;
+edge_temp *temp = 0 ;
+edge_pressure *pressure = 0 ;
+
+PwmOut *led[3] = {0, 0, 0} ;
+uint16_t pwm[3] = { 0x5FA2, 0xB09B, 0x83DF } ;
+I2C *edge_i2c0 = 0 ;
+I2C *edge_i2c1 = 0 ;
+ILI9341 *display = 0 ;
+MMA8451Q *mma8451q = 0 ;
+VEML6040 *veml6040[2] = { 0, 0 } ;
+LM75B *lm75b0 = 0 ; /* for temp1 */
+AnalogIn *an0 = 0 ; /* for temp2 */
+SMTC502AT *smtc502at0 = 0 ;
+AnalogIn *an1 = 0 ; /* for temp3 */
+SMTC502AT *smtc502at1 = 0 ;
+LM75B *lm75b1 = 0 ; /* for temp4 */
+AnalogIn *an2 = 0 ; /* for gas pressure */
+PSE530 *pse530 = 0 ; /* gas pressure sensor */
+
+DigitalOut *tft_reset = 0 ;
+DigitalOut *tft_backlight = 0 ;
+DigitalOut *tft_cs = 0 ;
+DigitalOut *pse530_en = 0 ;
+DigitalOut *color_en = 0 ;
+
+static int error_tolerance = 100 ;
+static int loop_interval = 100 ; // 1000 ;
+static int accel_interval = 10 ;
+int edge_mgr_status = EDGE_MGR_INIT ;
+char *reset_reason_str = 0 ;
+int display_mode = 1 ;
+bool reboot_requested = false ;
+
+/* following two functions are for test power on/off of color sensor */
+void enable_color_sensor(void)
+{
+ if (color_en == 0) {
+ printf("Color Enable Pin is not initiated\n") ;
+ } else {
+ *color_en = 0 ;
+ }
+}
+
+void disable_color_sensor(void)
+{
+ if (color_en == 0) {
+ printf("Color Enable Pin is not initiated\n") ;
+ } else {
+ *color_en = 1 ;
+ }
+}
+
+void init_display(void)
+{
+reset_watch_dog() ;
+ printf("TFT Initializing\n") ;
+ tft_reset = new DigitalOut(PIN_RESET_TFT, 1) ;
+ tft_backlight = new DigitalOut(PIN_BL_TFT, 0) ;
+ tft_cs = new DigitalOut(PIN_CS_TFT, 1) ;
+
+reset_watch_dog() ;
+ display = new ILI9341(SPI_8, 10000000,
+ PIN_MOSI, PIN_MISO, PIN_SCK,
+ PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "LaSuno") ;
+
+reset_watch_dog() ;
+ display->BusEnable(true) ;
+ display->set_orientation(1) ;
+
+reset_watch_dog() ;
+ display->cls() ;
+ *tft_backlight = 1 ;
+ display->BusEnable(false) ;
+ printf("TFT Initialized\n") ;
+}
+
+void edge_splash(void)
+{
+ printf("Sensor loop started!\n") ;
+ if (display) {
+ reset_watch_dog() ;
+ display->BusEnable(true) ;
+ display->cls() ;
+ display->foreground(Green) ;
+ display->locate(40, 20) ;
+ display->printf("Sensor Loop") ;
+ display->locate(40, 60) ;
+ display->printf(" Started!") ;
+ display->BusEnable(false) ;
+ reset_watch_dog() ;
+ }
+}
+
+int init_edge_attribute(void)
+{
+ static int sensor_index = 0 ;
+ static int attr_index = 0 ;
+ static int error_count = 0 ;
+ int return_value = 1 ;
+ int result ;
+
+ reset_watch_dog() ;
+
+ if (reset_reason_str) {
+ result = afero->setAttribute(ATTR_MCU_RESET_REASON, reset_reason_str) ;
+ if (result == afSUCCESS) {
+ error_count = 0 ;
+ reset_reason_str = 0 ;
+ } else {
+ error_count++ ;
+ }
+ reset_watch_dog() ;
+ }
+ if (sensor_index < NUM_MAX_SENSOR) {// for each sensor send presence
+// printf("Setting sensor[%d] presence\n", sensor_index) ;
+ if (sensor_index == 3) { /* for temp lm75b0 is used */
+ result = afero->setAttributeBool(attr_to_set[sensor_index], lm75b0) ;
+ } else {
+ result = afero->setAttributeBool(attr_to_set[sensor_index], sensor[sensor_index]) ;
+ }
+ if (result == afSUCCESS) {
+ error_count = 0 ;
+ sensor_index++ ;
+ } else {
+ error_count++ ;
+ }
+ reset_watch_dog() ;
+ } else { // all sensor presence sent, now get attributes
+ if (attr_to_get[attr_index] != 0) {
+// printf("getting attribute [%d]\n", attr_index) ;
+ result = afero->getAttribute(attr_to_get[attr_index]) ;
+ if (result == afSUCCESS) {
+ error_count = 0 ;
+ attr_index++ ;
+ } else {
+ error_count++ ;
+ }
+ }
+ reset_watch_dog() ;
+ }
+
+ if (error_count > error_tolerance) { // too many fails, trying reset
+ reset_watch_dog() ;
+ reboot_edge() ;
+ }
+
+ if ((sensor_index >= NUM_MAX_SENSOR)&&(attr_to_get[attr_index] == 0)) { /* all sensors attributes done */
+ sensor_index = 0 ;
+ attr_index = 0 ;
+ return_value = 0 ;
+ }
+ return(return_value) ;
+}
+
+void edge_loop(uint32_t count_robin)
+{
+ static int sensor_index = 0 ;
+ int result ;
+
+ reset_watch_dog() ;
+
+ if ((count_robin % accel_interval) == 0) {
+ if (accel) {
+ accel->accum() ; /* get and accum accel data */
+ }
+ reset_watch_dog() ;
+ }
+
+ if ((count_robin % loop_interval) == 0) {
+ reset_watch_dog() ;
+ loop_interval = 10 ;
+ if ((sensor[sensor_index])&&(sensor[sensor_index]->isEnabled())) {
+ switch(sensor_index) {
+ case SENSOR_ID_COLOR1: /* color0 */
+ if (((edge_color*)sensor[sensor_index])->calibration_requested()) {
+ ((edge_color*)sensor[sensor_index])->calibrate(color0_target, color0_pwm, 10) ;
+ reset_watch_dog() ;
+ while((result = afero->setAttribute32(ATTR_COLOR0_PWM_R, color0_pwm[0])) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ while((result = afero->setAttribute32(ATTR_COLOR0_PWM_G, color0_pwm[1])) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ while((result = afero->setAttribute32(ATTR_COLOR0_PWM_B, color0_pwm[2])) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ while((afero->setAttributeBool(ATTR_COLOR0_CALIBRATE, false)) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ } else {
+ sensor[sensor_index]->runStateMachine() ;
+ }
+ break ;
+ case SENSOR_ID_COLOR2: /* color1 */
+ if (((edge_color*)sensor[sensor_index])->calibration_requested()) {
+ ((edge_color*)sensor[sensor_index])->calibrate(color1_target, color1_pwm, 10) ;
+ reset_watch_dog() ;
+ if ((result = afero->setAttribute32(ATTR_COLOR1_PWM_R, color1_pwm[0])) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ if ((result = afero->setAttribute32(ATTR_COLOR1_PWM_G, color1_pwm[1])) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ reset_watch_dog() ;
+ if ((result = afero->setAttribute32(ATTR_COLOR1_PWM_B, color1_pwm[2])) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ while((afero->setAttributeBool(ATTR_COLOR1_CALIBRATE, false)) != afSUCCESS) {
+ reset_watch_dog() ;
+ print_af_error(result) ;
+ wait_ms(10) ;
+ }
+ } else {
+ sensor[sensor_index]->runStateMachine() ;
+ }
+ break ;
+ default:
+ sensor[sensor_index]->runStateMachine() ;
+ break ;
+ }
+ }
+ sensor_index = (sensor_index + 1) % NUM_MAX_SENSOR ;
+ }
+ reset_watch_dog() ;
+}
+
+int is_present(I2C *i2c, int address)
+{
+ char t[1] = { 0 } ;
+ char data[2] = { 0, 0 } ;
+ int result ;
+ address <<= 1 ;
+ result = i2c->write(address, t, 1, true) ;
+ if (result == 0) {
+ result = i2c->read(address, data, 2) ;
+ }
+ return((result == 0)) ;
+}
+
+/**
+ * check_i2c_pins
+ * To avoid I2C dead-lock condition,
+ * check status of SDA and SCL.
+ * As they are supposed to be HIGH
+ * in case one of them is/are LOW,
+ * change SCL pin to a digital out pin and
+ * generate forced clock for a several cycles.
+ * and when SDA come back to High returns
+ * or I2C_UNLOCK_TRIAL_CYCLE exceeds, give up.
+ */
+#define I2C_UNLOCK_TRIAL_CYCLE 50
+
+void check_i2c_pins(PinName sda_pin, PinName scl_pin, int number)
+{
+ DigitalIn *sda_in = 0 ;
+ DigitalIn *scl_in = 0 ;
+ DigitalOut *scl_out = 0 ;
+ int count = 0 ;
+ sda_in = new DigitalIn(sda_pin, PullUp) ;
+ scl_in = new DigitalIn(scl_pin, PullUp) ;
+ printf("I2C%d pin ", number) ;
+ if ((*sda_in == 0) || (*scl_in == 0)) { /* bus hang! */
+ printf("hang detected, trying to clear ... ") ;
+ delete scl_in ;
+ scl_in = 0 ;
+ scl_out = new DigitalOut(scl_pin) ;
+ while((*sda_in == 0)&&(count++ > I2C_UNLOCK_TRIAL_CYCLE)) {
+ *scl_out = 0 ;
+ wait(0.01) ;
+ *scl_out = 1 ;
+ wait(0.01) ;
+ }
+ if (*sda_in != 0) {
+ printf("Cleared!\n") ;
+ } else {
+ printf("Failed to Clear, proceeding\n") ;
+ }
+ } else {
+ printf("condition OK\n") ;
+ }
+ if (sda_in) { delete sda_in ; }
+ if (scl_in) { delete scl_in ; }
+ if (scl_out) { delete scl_out ; }
+}
+
+void init_sensors(void)
+{
+ printf("=== Initializing Sensor(s) ===\n") ;
+#if 0
+ color_en = new DigitalOut(PIN_COLOR_EN, 0) ;
+ *color_en = 0 ; /* enable */
+ *color_en = 1 ; /* disable */
+ wait_ms(100) ;
+ *color_en = 0 ; /* enable */
+ wait_ms(10) ;
+#endif
+
+ check_i2c_pins(PIN_I2C0_SDA, PIN_I2C0_SCL, 0) ;
+ edge_i2c0 = new I2C(PIN_I2C0_SDA, PIN_I2C0_SCL) ;
+
+ check_i2c_pins(PIN_I2C1_SDA, PIN_I2C1_SCL, 1) ;
+ edge_i2c1 = new I2C(PIN_I2C1_SDA, PIN_I2C1_SCL) ;
+
+ if (display) {
+reset_watch_dog() ;
+printf("printing inital string to TFT\n") ;
+ display->BusEnable(true) ;
+
+
+ display->background(Black) ;
+ display->foreground(White) ;
+reset_watch_dog() ;
+ display->cls() ;
+reset_watch_dog() ;
+ display->set_font((unsigned char*) Arial24x23);
+ display->foreground(Green) ;
+ display->locate(70, 5) ;
+ display->printf("Suntory") ;
+ display->locate(30, 30) ;
+ display->printf("Server Monitor") ;
+ display->set_font((unsigned char*) Arial28x28);
+ display->foreground(White) ;
+ display->locate(30, 60) ;
+ display->printf("La Suno") ;
+ display->locate(30, 100) ;
+ display->foreground(Red) ;
+ display->printf("Preparing...") ;
+ display->BusEnable(true) ;
+ printf("Done\n") ;
+ wait(0.1) ;
+reset_watch_dog() ;
+ display->cls() ;
+ display->foreground(Yellow) ;
+ display->locate(40, 5) ;
+ display->printf("Probing sensors...") ;
+ display->foreground(Green) ;
+ display->BusEnable(false) ;
+ }
+reset_watch_dog() ;
+ if (is_present(edge_i2c1, MMA8451Q_I2C_ADDRESS)) {
+ printf("MMA8451Q on I2C1 is present\n") ;
+ if (display) {
+ display->BusEnable(true) ;
+ display->locate(30, num_sensor * 30 + 40) ;
+ display->printf("ACCEL is present") ;
+ display->BusEnable(false) ;
+ }
+ mma8451q = new MMA8451Q(edge_i2c1, MMA8451Q_I2C_ADDRESS) ;
+ accel = new edge_accel(mma8451q) ;
+ sensor[SENSOR_ID_ACCEL] = accel ;
+ sensor[SENSOR_ID_ACCEL]->setId(SENSOR_ID_ACCEL) ;
+ num_sensor++ ;
+ } else {
+ sensor[SENSOR_ID_ACCEL] = 0 ;
+ printf("MMA8451Q is absent\n") ;
+ }
+reset_watch_dog() ;
+ if (is_present(edge_i2c1, VEML6040_I2C_ADDRESS)) {
+ printf("VEML6040 on I2C1 is present\n") ;
+ if (display) {
+ display->BusEnable(true) ;
+ display->locate(30, num_sensor * 30 + 40) ;
+ display->printf("COLOR1 is present") ;
+ display->BusEnable(false) ;
+ }
+ veml6040[0] = new VEML6040(edge_i2c1, VEML6040_I2C_ADDRESS) ;
+ led[0] = new PwmOut(PIN_LED_R) ;
+ led[1] = new PwmOut(PIN_LED_G) ;
+ led[2] = new PwmOut(PIN_LED_B) ;
+ color[0] = new edge_color(veml6040[0], led, pwm) ;
+ sensor[SENSOR_ID_COLOR1] = color[0] ;
+ sensor[SENSOR_ID_COLOR1]->setId(SENSOR_ID_COLOR1) ;
+ num_sensor++ ;
+ } else {
+ sensor[SENSOR_ID_COLOR1] = 0 ;
+ printf("VEML6040 on I2C1 is absent\n") ;
+ }
+reset_watch_dog() ;
+ if (is_present(edge_i2c0, VEML6040_I2C_ADDRESS)) {
+ printf("VEML6040 on I2C0 is present\n") ;
+ if (display) {
+ display->BusEnable(true) ;
+ display->locate(30, num_sensor * 30 + 40) ;
+ display->printf("COLOR2 is present") ;
+ display->BusEnable(false) ;
+ }
+ veml6040[1] = new VEML6040(edge_i2c0, VEML6040_I2C_ADDRESS) ;
+ if (led[0] == 0) {
+ led[0] = new PwmOut(PIN_LED_R) ;
+ led[1] = new PwmOut(PIN_LED_G) ;
+ led[2] = new PwmOut(PIN_LED_B) ;
+ }
+ color[1] = new edge_color(veml6040[1], led, pwm) ;
+ sensor[SENSOR_ID_COLOR2] = color[1] ;
+ sensor[SENSOR_ID_COLOR2]->setId(SENSOR_ID_COLOR2) ;
+ num_sensor++ ;
+ } else {
+ sensor[SENSOR_ID_COLOR2] = 0 ;
+ printf("VEML6040 on I2C0 is absent\n") ;
+ }
+reset_watch_dog() ;
+ if (is_present(edge_i2c1, LM75B_I2C_ADDRESS)) {
+ printf("LM75B on I2C1 is present\n") ;
+ if (display) {
+ display->BusEnable(true) ;
+ display->locate(30, num_sensor * 30 + 40) ;
+ display->printf("TEMP1 is present") ;
+ display->BusEnable(false) ;
+ }
+ lm75b0 = new LM75B(edge_i2c1, LM75B_I2C_ADDRESS) ;
+ } else {
+ printf("LM75B on I2C1 is absent\n") ;
+ }
+#if 0
+ if (is_present(edge_i2c0, LM75B_I2C_ADDRESS)) {
+ printf("LM75B on I2C0 is present\n") ;
+ lm75b1 = new LM75B(edge_i2c0, LM75B_I2C_ADDRESS) ;
+ } else {
+ printf("LM75B on I2C0 is absent\n") ;
+ }
+#endif
+ if (display) { /* press is present anyway */
+ display->BusEnable(true) ;
+ if (lm75b0) {
+ display->locate(30, (num_sensor+1) * 30 + 40) ;
+ } else {
+ display->locate(30, num_sensor * 30 + 40) ;
+ }
+ display->printf("PRESS is present") ;
+ display->BusEnable(false) ;
+ }
+reset_watch_dog() ;
+ an0 = new AnalogIn(PIN_AN0) ;
+ smtc502at0 = new SMTC502AT(an0) ;
+ an1 = new AnalogIn(PIN_AN1) ;
+ smtc502at1 = new SMTC502AT(an1) ;
+ temp = new edge_temp(lm75b0, smtc502at0, smtc502at1, lm75b1) ;
+ sensor[SENSOR_ID_TEMP] = temp ;
+ sensor[SENSOR_ID_TEMP]->setId(SENSOR_ID_TEMP) ;
+ num_sensor++ ;
+
+
+reset_watch_dog() ;
+ an2 = new AnalogIn(PIN_AN2) ;
+ pse530_en = new DigitalOut(PIN_PRESS_EN, 0) ;
+ pse530 = new PSE530(an2) ;
+ pressure = new edge_pressure(pse530, pse530_en) ;
+ sensor[SENSOR_ID_PRESS] = pressure ;
+ sensor[SENSOR_ID_PRESS]->setId(SENSOR_ID_PRESS) ;
+ num_sensor++ ;
+
+reset_watch_dog() ;
+ if (num_sensor > 0) {
+ printf("%d edge_sensor(s) registered\n", num_sensor) ;
+ printf("Edge is waiting for ASR to link\n") ;
+ if (display) {
+ display->BusEnable(true) ;
+ display->foreground(White) ;
+ display->locate(40, 200) ;
+ display->printf("Waiting for ASR") ;
+ display->BusEnable(false) ;
+ }
+ }
+reset_watch_dog() ;
+}
+
+void enable_sensors(void)
+{
+ int i ;
+ for (i = 0 ; i < NUM_MAX_SENSOR ; i++ ) {
+ if (sensor[i]) {
+ sensor[i]->enable() ;
+ }
+ }
+}
+
+void disable_sensors(void)
+{
+ int i ;
+ for (i = 0 ; i < NUM_MAX_SENSOR ; i++ ) {
+ if (sensor[i]) {
+ sensor[i]->disable() ;
+ }
+ }
+}
+
+void reboot_edge(void)
+{
+ int i ;
+ reset_watch_dog() ;
+ disable_sensors() ;
+ reset_watch_dog() ;
+ if (display) {
+ delete display ;
+ display = 0 ;
+ }
+ for (i = 0 ; i < NUM_MAX_SENSOR ; i++ ) {
+ if (sensor[i]) {
+ reset_watch_dog() ;
+ delete sensor[i] ;
+ sensor[i] = 0 ;
+ }
+ }
+ reset_watch_dog() ;
+ software_reset() ;
+}
\ No newline at end of file
La Suno