void SensorsTask(void) { // Array storing the status of each physical sensor. // If a sensor fails to initialize, or fails 3 sensor reads in a row, // it will be disabled here until the next system reboot // 0 = tmp0 // 1 = tmp1 // 2 = tmp3 // 3 = humidity / air temp // 4 = pressure // 5 = accelerometer uint8_t enabledSensors[7] = {3, 3, 3, 3, 3, 3, 3}; uint8_t i; I2C_Status retVal = I2C_OK; INFO("(SENSORS_TASK) I2C Sensor failed to initialize\r\n"); for(i = 0; i < 3; i++) { // If the temperature sensor initialized, set its enabled value to 3 (so it has 3 chances to respond to a read request) // Else, disable the sensor if(InitTempSensor(i) != I2C_OK) { I2C_Reset(SLB_I2C); enabledSensors[i] = 0; WARN("(SENSORS_TASK) I2C Sensor failed to initialize\r\n"); } } if(InitHumiditySensor() != I2C_OK) { I2C_Reset(ALB_I2C); enabledSensors[3] = 0; WARN("(SENSORS_TASK) Humidity sensor failed to initialize\r\n"); } if(InitPressureSensor() != I2C_OK) { I2C_Reset(ALB_I2C); enabledSensors[4] = 0; WARN("(SENSORS_TASK) Pressure sensor failed to initialize\r\n"); } if(InitAccelerometer() != I2C_OK) { I2C_Reset(ALB_I2C); enabledSensors[5] = 0; WARN("(SENSORS_TASK) Accelerometer failed to initialize\r\n"); } // Let other tasks in the system warmup before entering the sensor polling loop osDelay(2000); // TODO: re-initialize the sensors once a day to check for failures and for sensors that have come back online // TODO: report to the base station when a sensor fails while(1) { for(i = 0; i < 3; i++) { if(enabledSensors[i] > 0) { switch(i) { case 0: retVal = ReadTempSensor(0, &sensorData.temp0); break; case 1: retVal = ReadTempSensor(1, &sensorData.temp1); break; case 2: retVal = ReadTempSensor(2, &sensorData.temp2); break; default: retVal = ReadTempSensor(0, &sensorData.temp0); break; } // If the sensor read failed, indicate that the sensor has one less chance to respond correctly before being disabled if(retVal != I2C_OK) { I2C_Reset(SLB_I2C); enabledSensors[i]--; WARN("(SENSORS_TASK) Temp sensor read failed\r\n"); } // The sensor is still alive! Restore it to a full 3 chances to respond else if(enabledSensors[i] != 3) { enabledSensors[i] = 3; DEBUG("(SENSORS_TASK) Temp sensor connection restored\r\n"); } } } if(enabledSensors[3] > 0) { do { if(ReadHumiditySensor(&sensorData.humid) != I2C_OK) { I2C_Reset(ALB_I2C); enabledSensors[3]--; WARN("(SENSORS_TASK) Humidity sensor read failed\r\n"); break; } else if(enabledSensors[3] != 3) { enabledSensors[3] = 3; DEBUG("(SENSORS_TASK) Humidity sensor connection restored\r\n"); } if(ReadAirTempSensor(&sensorData.tempAir) != I2C_OK) { I2C_Reset(ALB_I2C); enabledSensors[3]--; WARN("(SENSORS_TASK) Air temp sensor read failed\r\n"); } else if(enabledSensors[3] != 3) { enabledSensors[3] = 3; DEBUG("(SENSORS_TASK) Air temp sensor connection restored\r\n"); } } while(0); } if(enabledSensors[4] > 0) { if(ReadPressureSensor(&sensorData.alt) != I2C_OK) { I2C_Reset(ALB_I2C); enabledSensors[4]--; WARN("(SENSORS_TASK) Altimeter sensor read failed\r\n"); } } if(enabledSensors[5] > 0) { uint16_t x, y, z; if(ReadAccelerometer(&x, &y, &z) != I2C_OK) { I2C_Reset(ALB_I2C); enabledSensors[5]--; WARN("(SENSORS_TASK) Accelerometer sensor read failed\r\n"); } DEBUG("X: %d, Y: %d, Z: %d", x, y, z); } ReadSoilMoisture(&sensorData.moist0, &sensorData.moist1, &sensorData.moist2); // Send sensor Data to the base station SendSensorData(); osDelay(pollingRate); } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { int i = 0; uint16_t temp_humid_sensor; float rel_humidity, dew_point; char buffer_humid[10]; // char buffer_voltage[10]; // char light_level[10]; /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ TRACE_ProfilerSetup(); /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ; /* Disable usart0 clock, it is enabled by default in gecko series mcu's. */ CMU_ClockEnable(cmuClock_USART0, false); /* Infinite blink loop with main state machine */ state = RESET; while (1) { // state machine switch(state){ case RESET: // RESET state check for vital HW functions if(1){ // todo all checks i = 0; state = INIT; } else state = RESET; break; case INIT: // INIT state initialize all necessary peripherials if(1){ i = i + 1; /* Enable clocks. */ CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_I2C0, true); /* Configure PB9, PB10 pin interrupt on falling edge do not enable yet. */ GPIO_PinModeSet(gpioPortB, 9, gpioModeInput, 0); GPIO_PinModeSet(gpioPortB, 10, gpioModeInput, 0); GPIO_IntConfig(gpioPortB, 9, false, true, true); GPIO_IntConfig(gpioPortB, 10, false, true, true); HumiditySensorInit(); LED_Init(); /* Initialize LED driver */ LED_Set(0); /* Enable LCD without voltage boost */ SegmentLCD_Init(false); /* Init LCD driver */ SegmentLCD_Write("ST: INIT"); Delay(500); SegmentLCD_Number(i); Delay(500); state = IDLE; } else state = INIT; break; case IDLE: if(1){ i = i + 1; SegmentLCD_Write("ST: IDLE"); Delay(500); SegmentLCD_Number(i); Delay(500); // while idle check humidity and temp paramters rel_humidity = ReadHumiditySensor(); dew_point = getDewPoint(); /* Get temperature from humidity sensor, notice that both pressure sensor and */ /* humidity sensor has built in temperature sensors, since dewpoint and pressure */ /* is dependent on the temperature close to the sensor it gives the most accurate */ /* results to use the built in temperature sensor in each device. */ temp_humid_sensor = getTemperatureHumidSensor(); state = RX_STATE; } else state = IDLE; break; case RX_STATE : if(1){ i = i + 1; SegmentLCD_Write("ST: Rx"); Delay(500); SegmentLCD_Number(i); Delay(500); SegmentLCD_Symbol(LCD_SYMBOL_ANT, 1); state = TX_STATE; } else state = RX_STATE; break; case TX_STATE: if(1){ i = i + 1; SegmentLCD_Write("ST: TX"); Delay(500); SegmentLCD_Number(i); Delay(500); SegmentLCD_Symbol(LCD_SYMBOL_ANT, 1); state = ERROR; } else state = TX_STATE; break; case ERROR: if(1){ i = i + 1; SegmentLCD_Write("ST: ERR"); Delay(500); SegmentLCD_Number(i); Delay(500); state = IDLE; } else state = ERROR; break; } LED_Toggle(0); LED_Toggle(1); Delay(1000); } }