/*----------------------------------------------------------------------------- * Main Program *---------------------------------------------------------------------------*/ int main(void) { uint8_t temp_id, servoid; uint16_t acttype; uint8_t //blindsStatus, /* Position (-128 to 127) */ servoToTurn, turnDirection = BLINDS_TURN_STOP; /* Specifies direction to turn or stopped */ uint32_t boardTemperature = 0; uint32_t timeStamp = 0, timeStampTurn = 0, servoFeed_timeStamp = 0; Can_Message_t txMsg; // Set up callback for CAN messages BIOS_CanCallback = &can_receive; sei(); Timebase_Init(); adcTemperatureInit(); rcServoInit(); #if defined(TWO_BUTTON_MODE) /* * Initialize buttons * It is possible to use ie. sensors instead * but then change this */ /* Set as input and enable pull-up */ DDRD &= ~( (1<<DDD1)|(1<<DDD2) ); PORTD |= (1<<PD1)|(1<<PD2); /* Enable IO-pin interrupt */ PCICR |= (1<<PCIE2); /* Unmask PD1 and SERVO_FEED_PIN */ PCMSK2 |= (1<<PCINT16) | (1<<PCINT17); #endif /* Set output and turn off the servo current feed */ //SERVO_FEED_DDR |= (1<<SERVO_FEED_PIN); //SERVO_FEED_PORT &= ~(1<<SERVO_FEED_PIN); txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID); txMsg.RemoteFlag = 0; txMsg.ExtendedFlag = 1; txMsg.DataLength = 4; txMsg.Data.words[0] = APP_TYPE; txMsg.Data.words[1] = APP_VERSION; BIOS_CanSend(&txMsg); // Send startup message //set up status message txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_STATUS << CAN_SHIFT_SNS_TYPE) | (SNS_ID_SERVO_STATUS << CAN_SHIFT_SNS_ID) | (NODE_ID << CAN_SHIFT_SNS_SID)); // Main loop while (1) { // check if any messages have been received if(rxMsgFull){ if( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT ){ // Actuator package acttype = (uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE); servoid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID); // Check if it is command to control this servo if(acttype == ACT_TYPE_SERVO && (servoid == SERVOID_1 || servoid == SERVOID_2 || servoid == SERVOID_3)){ // This node that control a servo is adressed if(servoid == SERVOID_1){ temp_id = 1; // First servo }else if(servoid == SERVOID_2){ temp_id = 2; // and so on }else if(servoid == SERVOID_3){ temp_id = 3; }else{ temp_id = 0; } if(rxMsg.DataLength == 1 || (rxMsg.DataLength == 2 && rxMsg.Data.bytes[1] == BLINDS_CMD_ABS)){ // Set absolute position to servo setPosition( rxMsg.Data.bytes[0], temp_id ); servoFeed_timeStamp = Timebase_CurrentTime(); }else if(rxMsg.DataLength == 2){ if(rxMsg.Data.bytes[1] == BLINDS_CMD_REL){ // Set relative position to servo alterPosition( rxMsg.Data.bytes[0], temp_id ); servoFeed_timeStamp = Timebase_CurrentTime(); }else if(rxMsg.Data.bytes[1] == BLINDS_CMD_START ){ // Start turning the servo turnDirection = (rxMsg.Data.bytes[0]&0x80)?BLINDS_TURN_CW:BLINDS_TURN_CCW; // FIXME riktning beroende på positivt eller negativt tal? servoToTurn = temp_id; servoFeed_timeStamp = Timebase_CurrentTime(); }else if(rxMsg.Data.bytes[1] == BLINDS_CMD_STOP ){ // Stop turning turnDirection = BLINDS_TURN_STOP; }/*else if(rxMsg.Data.bytes[0] == BLINDS_CMD_STATUS){ // Send blinds status to CAN boardTemperature = getTC1047temperature(); if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){ blindsFailsafe(); }else{ txMsg.Data.bytes[0] = boardTemperature & 0x00FF; txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8; txMsg.Data.bytes[2] = 0x00; txMsg.Data.bytes[3] = getPosition(1); txMsg.Data.bytes[4] = getPosition(2); txMsg.Data.bytes[5] = getPosition(3); txMsg.DataLength = 6; BIOS_CanSend(&txMsg); }*/ } } } rxMsgFull = 0; } if( (Timebase_CurrentTime() - timeStamp) >= STATUS_SEND_PERIOD ){ timeStamp = Timebase_CurrentTime(); // Send blinds status to CAN periodically boardTemperature = getTC1047temperature(); if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){ blindsFailsafe(); }else{ txMsg.Data.bytes[0] = boardTemperature & 0x00FF; txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8; txMsg.Data.bytes[2] = 0x00; txMsg.Data.bytes[3] = getPosition(1); txMsg.Data.bytes[4] = getPosition(2); txMsg.Data.bytes[5] = getPosition(3); txMsg.DataLength = 6; BIOS_CanSend(&txMsg); } } // If start turning servo if( turnDirection ){ if( Timebase_CurrentTime() - timeStampTurn >= TURN_PERIOD ){ timeStampTurn = Timebase_CurrentTime(); // Clockwise or counterclockwise? if( turnDirection == BLINDS_TURN_CCW ){ alterPosition( -STEPS_PER_TURN_PERIOD , servoToTurn); }else if( turnDirection == BLINDS_TURN_CW ){ alterPosition( STEPS_PER_TURN_PERIOD , servoToTurn); } servoFeed_timeStamp = Timebase_CurrentTime(); } } // Turn off the servo current feed after timeout if( Timebase_CurrentTime() - servoFeed_timeStamp >= SERVO_FEED_TIME ){ SERVO_FEED_PORT &= ~(1<<SERVO_FEED_PIN); servoDisable(); }else{ SERVO_FEED_PORT |= (1<<SERVO_FEED_PIN); servoEnable(); } }
/*----------------------------------------------------------------------------- * Main Program *---------------------------------------------------------------------------*/ int main(void) { #if defined(USE_DS18S20) uint8_t nSensors, i; uint8_t subzero, cel, cel_frac_bits; uint32_t timeStamp_DS = 0, timeStamp_DS_del = 0; /* This is to identify and give the sensors correct ID * TODO read ds18s20 serial id and that way give the "can id" */ uint16_t sensor_ds_id[] = {TEMPSENSORID_1, TEMPSENSORID_2, TEMPSENSORID_3, TEMPSENSORID_4}; #endif #if defined(USE_TC1047) uint32_t tcTemperature = 0, timeStamp_TC = 0; adcTemperatureInit(); #endif #if defined(USE_LDR) uint32_t timeStamp_LDR = 0; uint8_t ldr; LDR_SensorInit(); #endif sei(); Timebase_Init(); Can_Message_t txMsg; txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID); txMsg.DataLength = 4; txMsg.RemoteFlag = 0; txMsg.ExtendedFlag = 1; txMsg.Data.words[0] = APP_TYPE; txMsg.Data.words[1] = APP_VERSION; BIOS_CanSend(&txMsg); #if defined(USE_DS18S20) /* Make sure there is no more then 4 DS-sensors. */ nSensors = search_sensors(); #endif txMsg.DataLength = 2; /* main loop */ while (1) { #if defined(USE_DS18S20) /* check temperature and send on CAN */ if( Timebase_PassedTimeMillis(timeStamp_DS) >= DS_SEND_PERIOD ){ timeStamp_DS = Timebase_CurrentTime(); if ( DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ) == DS18X20_OK) { delay_ms(DS18B20_TCONV_12BIT); for ( i=0; i<nSensors; i++ ) { if ( DS18X20_read_meas( &gSensorIDs[i][0], &subzero, &cel, &cel_frac_bits) == DS18X20_OK ) { if (subzero) { txMsg.Data.bytes[0] = -cel-1; txMsg.Data.bytes[1] = ~(cel_frac_bits<<4); }else{ txMsg.Data.bytes[0] = cel; txMsg.Data.bytes[1] = (cel_frac_bits<<4); } } /* Delay */ timeStamp_DS_del = Timebase_CurrentTime(); while(Timebase_PassedTimeMillis(timeStamp_DS_del) < DS_SEND_DELAY){} /* send txMsg */ txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_TEMPERATURE << CAN_SHIFT_SNS_TYPE) | (NODE_ID << CAN_SHIFT_SNS_SID)); txMsg.Id |= ( sensor_ds_id[i] << CAN_SHIFT_SNS_ID); /* Set sensor id */ BIOS_CanSend(&txMsg); } } } #endif #if defined(USE_TC1047) #error tc1047 id is still not correct // FIXME /* check temperature and send on CAN */ if( bios->timebase_get() - timeStamp_TC >= TC_SEND_PERIOD ){ timeStamp_TC = bios->timebase_get(); tcTemperature = getTC1047temperature(); txMsg.Data.bytes[0] = tcTemperature & 0x00FF; txMsg.Data.bytes[1] = (tcTemperature & 0xFF00)>>8; txMsg.DataLength = 2; txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_TEMPERATURE << CAN_SHIFT_SNS_TYPE) | (NODE_ID << CAN_SHIFT_SNS_SID)); txMsg.Id |= (TEMPSENSORID_5 << CAN_SHIFT_SNS_ID); // sätt korrekt sensorid BIOS_CanSend(&txMsg); } #endif #if defined(USE_LDR) /* check light and send on CAN */ if( Timebase_PassedTimeMillis(timeStamp_LDR) >= LDR_SEND_PERIOD ){ timeStamp_LDR = Timebase_CurrentTime(); ldr = (uint8_t)LDR_GetData(0); txMsg.Data.bytes[0] = ldr; txMsg.DataLength = 1; txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_LIGHT << CAN_SHIFT_SNS_TYPE) | (LIGHTSENSORID_1 << CAN_SHIFT_SNS_ID) | (NODE_ID << CAN_SHIFT_SNS_SID)); BIOS_CanSend(&txMsg); } #endif }