Temporary Connector Reversed Version
Dependencies: UniGraphic mbed vt100
afero_poc15_180403R , J1 のピン配置を反転させたヴァージョンです。
Color2系を使用するためには以下のピンをジャンパで接続してください。
J1-D7 <-> J1-D0
J1-D6 <-> J1-D1
(調査中) また、こちらでテストした範囲では、
FRDM-KL25Z の V3.3 を、Modulo2 の VCC_3V3 ピンに接続してやる必要がありました。
尚、J1-D1, D0 を使用するために UART を無効にしているため
ログは表示されません。
TFTモジュールについて
aitendoのTFTモジュールはデフォルトでは8bit bus モードになっています。
半田のジャンパを変えて、SPIの設定にしてください。
サーミスタについて
POC1.5 では サーミスタは 25℃の時に抵抗値が 50.0kΩになる502AT-11 が
4.95kΩのプルアップ(実際は10kΩx2の並列)で使用されていました。
今回の試作では抵抗値が 10.0kΩの 103AT-11 が
5.1kΩのプルアップで使用されていますので、係数を合わせるために
SMTC502AT-11 のコンストラクタを
R0 = 10.0
R1 = 5.1
B = 3435
T0 = 298.15
で呼ぶように変更しました。
Diff: edge_utils/edge_mgr.cpp
- Revision:
- 0:0b6732b53bf4
- Child:
- 1:6c54dc8acf96
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edge_utils/edge_mgr.cpp Tue Apr 24 08:58:33 2018 +0000 @@ -0,0 +1,569 @@ +#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 ; + +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 ; + +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") ; + 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