/****************************************************************************************************
 * @fn      I2CCommTask
 *          This tasks primary goal is to serialize the communication request (sensor results) going
 *          over I2C
 *
 * @param   none
 *
 * @return  none
 *
 ***************************************************************************************************/
ASF_TASK void I2CCommTask( ASF_TASK_ARG )
{
    MessageBuffer *rcvMsg = NULLP;

    /* I2C Slave mode initialization */
    I2C_Slave_init();

    /* Init register area for slave */
    SH_Slave_init();

    while(1)
    {
        ASFReceiveMessage(I2CSLAVE_COMM_TASK_ID, &rcvMsg );

        switch (rcvMsg->msgId)
        {
        case MSG_ACC_DATA:
            SendSensorData(AP_PSENSOR_ACCELEROMETER_RAW, &rcvMsg->msg.msgAccelData);
            break;

        case MSG_MAG_DATA:
            SendSensorData(AP_PSENSOR_MAGNETIC_FIELD_RAW, &rcvMsg->msg.msgMagData);
            break;

        case MSG_GYRO_DATA:
            SendSensorData(AP_PSENSOR_GYROSCOPE_RAW, &rcvMsg->msg.msgGyroData);
            break;

        default:
            D1_printf("I2C:!!!UNHANDLED MESSAGE:%d!!!\r\n", rcvMsg->msgId);
            break;
        }
    }
}
Exemplo n.º 2
0
void loop() {
    if(g_bConnected) {
        g_servo.loop();
        
        if(0<Serial.available()) {
            auto readcmd = ReadCommand();
            if(readcmd.m_bValid) {
                HandleCommand(readcmd.m_cmd);
                if(!g_bConnected) return;
            }
        } else if(c_nTIMETODISCONNECT < millis()-g_nLastCommand) {
            OnDisconnection(); 
            return;
        } else if(c_nTIMETOSTOP < millis()-g_nLastCommand) {
            InternalHandleCommand(SRobotCommand::stop());
	    }
        
        for(unsigned int i=0; i<countof(g_amotors); ++i) {
            g_amotors[i].ComputePID(g_apid[i]);
        }

        SendSensorData();
    } else {
        auto readcmd = ReadCommand();
        if(readcmd.m_bValid && readcmd.m_cmd.m_ecmd==ecmdCONNECT) {
            HandleCommand(readcmd.m_cmd);
        }
    }
}
Exemplo n.º 3
0
// This function sends data that has been requested.
void SendPendingMKSerial(void)
{
  // Handle only one request at a time.
  if (tx_request_)
  {
    // A one-time request has higher priority than a periodic "stream" of data.
    if (tx_request_ & MK_TX_VERSION) SendVersion();
  }
  else if (mk_stream_ && TimestampInPast(stream_timer_))
  {
    // A data stream is active and it is time for another transmission.
    switch (mk_stream_)
    {
      case MK_STREAM_CONTROL:
        SendControlData();
        break;
      case MK_STREAM_KALMAN:
        SendKalmanData();
        break;
      case MK_STREAM_MOTOR_SETPOINTS:
        SendMotorSetpoints();
        break;
      case MK_STREAM_SENSORS:
        SendSensorData();
        break;
      default:
        break;
    }
    stream_timer_ += stream_period_;

    // Prevent timer rollover for small periods.
    if (TimestampInPast(stream_timer_)) stream_timer_ = GetTimestamp();

    // Disable the stream if no request has been renewing received in a while.
    if (TimestampInPast(stream_timeout_)) mk_stream_ = MK_STREAM_NONE;
  }
}
Exemplo n.º 4
0
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);
    }
}