コード例 #1
0
/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {
//	For calibrating internal oscillator
//	OSCCAL = eeprom_read_byte(0);
	Timebase_Init();
	Serial_Init();

#if MCP_CS_BIT != PB2
	/* If slave select is not set as output it might change SPI hw to slave
	 * See ch 18.3.2 (18.3 SS Pin Functionality) in ATmega48/88/168-datasheet */
	DDRB |= (1<<PB2);
#endif
#if USE_STDCAN == 0
	Can_Init();
#else
	StdCan_Init(0);
#endif	
	
	DDRC |= 1<<PC1 | 1<<PC0;
	PORTC |= (1<<PC1) | (1<<PC0);
	
	sei();
	
#if SENDTIMESTAMP == 1
#if USE_STDCAN == 0
	Can_Message_t timeMsg;
#else
	StdCan_Msg_t timeMsg;
#endif	
	uint32_t time = Timebase_CurrentTime();
	uint32_t time1 = time;
	uint32_t unixtime = 0;
#endif
	uint16_t rxByte;
	uint8_t i = 0;
	
#if SENDTIMESTAMP == 1
#if USE_STDCAN == 0
	timeMsg.ExtendedFlag = 1;
	timeMsg.RemoteFlag = 0;
	timeMsg.DataLength = 8;
#else
	/* Jag orkar inte fixa in datan i paketen, sätter längd till 0 sålänge */
	timeMsg.Length = 0;
#endif
	timeMsg.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_TIME << CAN_SHIFT_NMT_TYPE);
	//timeMsg.Id = 0; //Same thing, and lib's can.h is not updated.
#endif
	
#if USE_STDCAN == 1
	StdCan_Msg_t rxMsg;
#endif	
	
	/* main loop */
	while (1) {
		/* any new CAN messages received? */
#if USE_STDCAN == 0
		if (rxMsgFull) {
#else
		if (StdCan_Get(&rxMsg) == StdCan_Ret_OK) {
#endif
			// Toggle activity LED
			PORTC ^= (1<<PC1);
			/* send message to CanWatcher */
			uart_putc(UART_START_BYTE);
			uart_putc((uint8_t)rxMsg.Id);
			uart_putc((uint8_t)(rxMsg.Id>>8));
			uart_putc((uint8_t)(rxMsg.Id>>16));
			uart_putc((uint8_t)(rxMsg.Id>>24));
#if USE_STDCAN == 0
			uart_putc(rxMsg.ExtendedFlag);
			uart_putc(rxMsg.RemoteFlag);
			uart_putc(rxMsg.DataLength);
			for (i=0; i<8; i++) {
				uart_putc(rxMsg.Data.bytes[i]);
			}
#else
			uart_putc(1);
			uart_putc(0);
			uart_putc(rxMsg.Length);
			for (i=0; i<8; i++) {
				uart_putc(rxMsg.Data[i]);
			}
#endif
			uart_putc(UART_END_BYTE);
			
#if USE_STDCAN == 0
			rxMsgFull = 0;
#endif
		}
		
		/* any UART bytes received? */
		rxByte = uart_getc();
		while (rxByte != UART_NO_DATA) {
			/* parse byte! */
			UartParseByte((uint8_t)(rxByte & 0x00FF));
			/* receive next */
			rxByte = uart_getc();
		}
		
#if SENDTIMESTAMP == 1
		time1 = Timebase_CurrentTime();
		if ((time1 - time) > 1000) {
			time = time1;
#if USE_STDCAN == 0
			timeMsg.Data.dwords[0] = ++unixtime;
			IncTime();
			timeMsg.Data.dwords[1] = date.packed;
			Can_Send(&timeMsg);
#else
			/* Jag orkar inte fixa in datan i paketen, sätter längd till 0 sålänge */
			StdCan_Put(&timeMsg);
#endif
		}
#endif
	}
	
	return 0;
}
コード例 #2
0
/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {
	Mcu_Init();
	Timebase_Init();
	sei();
#if defined(UART_OUTPUT)
	Serial_Init();

	printf("\n------------------------------------------------------------\n");
	printf(  "   CAN Test:\n");
	printf(  "   Periodic Transmission on CAN\n");
	printf(  "   CAN Dump\n");
	printf(  "   CAN Echo\n");
	printf(  "------------------------------------------------------------\n");
	
	printf("CanInit...");
	if (Can_Init() != CAN_OK) {
		printf("FAILED!\n");
		printf("Check wires between AVR and MCP2515 and the MCP speed (xtal).");
	}
	else {
		printf("OK!\n");
		printf("MCP2515 working fine\n");
	}
#elif defined(LED_OUTPUT)
	Can_Init();
#else
	Can_Init();
#endif
	
	uint32_t timeStamp = 0;
	
	Can_Message_t txMsg;
	Can_Message_t rxMsg;
	txMsg.RemoteFlag = 0;
	txMsg.ExtendedFlag = 1;
	txMsg.Id = SENDING_ID;
	txMsg.DataLength = 2;
	txMsg.Data.bytes[0] = 0x12;
	txMsg.Data.bytes[1] = 0x34;

	/* main loop */
	while (1) {
		/* service the CAN routines */
		Can_Service();
		
		/* send CAN message and check for CAN errors once every second */
		if (Timebase_PassedTimeMillis(timeStamp) >= 1000) {
			timeStamp = Timebase_CurrentTime();
			/* send txMsg */
			txMsg.Id = SENDING_ID;
			Can_Send(&txMsg);
		}
		
		/* check if any messages have been received */
		while (Can_Receive(&rxMsg) == CAN_OK) {
#if defined(UART_OUTPUT)
			/* Dump message data on uart */
			printf("\nPKT %#lx %u %u", rxMsg.Id, (uint16_t)(rxMsg.ExtendedFlag), (uint16_t)(rxMsg.RemoteFlag));
			for (uint8_t i=0; i<rxMsg.DataLength; i++) {
				printf(" %#x", rxMsg.Data.bytes[i]);
			}
#endif
			/* Echo function */
			if(rxMsg.Id == ECHO_RECEIVE_ID){
#if defined(UART_OUTPUT)
				printf("\n\"ping\" received");
				txMsg.Id = ECHO_SENDING_ID;
				/* Send reply */
				Can_Send(&txMsg);
				printf("\nreply sent");
#else
				txMsg.Id = ECHO_SENDING_ID;
				/* Send reply */
				Can_Send(&txMsg);
#endif
			}
		}
	}
	
	return 0;
}
コード例 #3
0
/**
 * Parses an incoming UART byte by maintaining a state machine. The UART
 * bytes will build up a CAN message according to the protocol described here:
 * 
 * http://www.arune.se/projekt/doku.php?id=homeautomation:pc-mjukvara
 * 
 * @param c
 * 		The received UART byte.
 */
void UartParseByte(uint8_t c) {
#if USE_STDCAN == 0
	static Can_Message_t cm;
#else
	static StdCan_Msg_t cm;
#endif
	static uint8_t waitingMessage = 0;
	static uint32_t startTime = 0;
	static int8_t count = 0;
	
	/* 50ms timeout */
	if (waitingMessage && Timebase_PassedTimeMillis(startTime) > 50) {
		waitingMessage = 0;
	}
	
	if (waitingMessage) {
		/* save start time */
		startTime = Timebase_CurrentTime();
		/* UART END */
		if (count >= 15) {
			if (c == UART_END_BYTE) {
				PORTC ^= (1<<PC0);
#if USE_STDCAN == 0
				Can_Send(&cm);
#else
				StdCan_Put(&cm);
#endif
			}
			waitingMessage = 0;
			return;
		}
		/* data */
		else if (count >= 7) {
#if USE_STDCAN == 0
			cm.Data.bytes[count-7] = c;
#else
			cm.Data[count-7] = c;
#endif
			count++;
			return;
		}
		/* data length */
		else if (count >= 6) {
#if USE_STDCAN == 0
			cm.DataLength = c;
#else
			cm.Length = c;
#endif
			count++;
			return;
		}
		/* remote request flag */
		else if (count >= 5) {
#if USE_STDCAN == 0
			cm.RemoteFlag = c;
#endif
			count++;
			return;
		}
		/* extended */
		else if (count >= 4) {
#if USE_STDCAN == 0
			cm.ExtendedFlag = c;
#endif
			count++;
			return;
		}
		/* ident */
		else if (count >= 0) {
			cm.Id += ((uint32_t)c << (count*8));
			count++;
			return;
		}
	}
	
	if (c == UART_START_BYTE && !waitingMessage) {
		waitingMessage = 1;
		startTime = Timebase_CurrentTime();
		count = 0;
		cm.Id = 0;
		return;	
	}
}
コード例 #4
0
/*-----------------------------------------------------------------------------
 * 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();
		}
	}
コード例 #5
0
/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {
    uint32_t timeStamp = 0, timeStampTurn = 0;
    uint8_t buffering = FALSE, gpsMsg_received = FALSE, rxGps_element;
    char buffer[100], rxGps;
    /* GPGGA, Global positioning system fix data */
    char gga_utc[7], gga_latitude[9], gga_latitude_NS, gga_longitude[10], gga_longitude_EW;
    /* GPVTG, Course over ground and speed */
    char vtg_course_true[6], vtg_course_magnetic[6], vtg_speed_kmh[6];
    /* GPZDA, Time & Date */
    char zda_time[7], zda_day[3], zda_month[3], zda_year[5];

    char *pch;

    Timebase_Init();
    Serial_Init();

    sei();
#if DEBUG
    printf("\n------------------------------------------------------------\n");
    printf(  "   CAN: GPS\n");
    printf(  "------------------------------------------------------------\n");

    printf("CanInit...");
    if (Can_Init() != CAN_OK) {
        printf("FAILED!\n");
    }else{
        printf("OK!\n");
    }
#else
    Can_Init();
#endif

    Can_Message_t txMsg;
    Can_Message_t rxMsg;
    txMsg.Id = GPS_CMD_SEND;
    txMsg.RemoteFlag = 0;
    txMsg.ExtendedFlag = 1;
    txMsg.DataLength = 3;

    /* main loop */
    while (1) {
        /* service the CAN routines */
        Can_Service();

        /* check if any messages have been received */
        while (Can_Receive(&rxMsg) == CAN_OK) {
            /* This node that control a servo is adressed */
            if( rxMsg.Id == GPS_CMD_GET ){

            }
        }

        if( Timebase_PassedTimeMillis(timeStamp) >= STATUS_SEND_PERIOD ){
            timeStamp = Timebase_CurrentTime();
            /* Send blinds status to CAN */

        }

        /* Get data from GPS */
        rxGps = uart_getc();
        while( rxGps != UART_NO_DATA ){
            /* '$' indicates start of message, start buffering */
            if( rxGps == '$' ){
                buffering = TRUE;
                rxGps_element = 0;
            }else if( rxGps == CR ){
                /* End of message */
                buffer[rxGps_element]='\0';
                buffering = FALSE;
                gpsMsg_received = TRUE;
            }

            if( buffering ){
                buffer[ rxGps_element ] = rxGps;
                rxGps_element++;
            }
            /* Get next character */
            rxGps = uart_getc();
        }

        if( gpsMsg_received ){
            /* One whole msg is completed, start compare and parse */
            if( !strncmp(buffer, "GPGGA", 5) ){
                /* Standard NMEA message, $GPGGA */
                strtok(buffer, GPS_MSG_DELIMITER); /* Throw away "GPGGA" */

                /* Get UTC */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(gga_utc, pch);

                /* Get latitude */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(gga_latitude, pch);

                /* Get latitude N/S */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(gga_latitude_NS, pch);

                /* Get longitude */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(gga_longitude, pch);

                /* Get longitude E/W */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(gga_longitude_EW, pch);

            }else if( !strncmp(buffer, "GPVTG", 5) ){
                /* Standard NMEA message, $GPVTG */
                strtok(buffer, GPS_MSG_DELIMITER); /* Throw away "GPVTG" */

                /* Get course over ground, true degree */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(vtg_course_true, pch);

                /* Get course over ground, magnetic degree */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(vtg_course_magnetic, pch);

                /* Get speed over ground, km/h */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(vtg_speed_kmh, pch);

            }else if( !strncmp(buffer, "GPZDA", 5) ){
                /* Standard NMEA message, $GPZDA */
                strtok(buffer, GPS_MSG_DELIMITER); /* Throw away "GPZDA" */

                /* Get time */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(zda_time, pch);

                /* Get day, 0-31 */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(zda_day, pch);

                /* Get month, 1-12 */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(zda_month, pch);

                /* Get year */
                pch = strtok(NULL, GPS_MSG_DELIMITER);
                strcpy(zda_year, pch);
            }

            gpsMsg_received = FALSE; /* Get ready for next message */

        }
    }
    return 0;
}
コード例 #6
0
/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {
	uint8_t nSensors, i;
	uint8_t subzero, cel, cel_frac_bits;
	
	Mcu_Init();
	Timebase_Init();
	Serial_Init();
	
	sei();
	
	printf( "\nDS18X20 1-Wire-Reader\n" );
	printf( "-----------------------" );
	nSensors = search_sensors();
	printf( "%i DS18X20 Sensor(s) available:\n", (int) nSensors );
	
	for (i=0; i<nSensors; i++) {
		printf("Sensor# %i is a ", (int) i+1);
		if ( gSensorIDs[i][0] == DS18S20_ID)
			printf("DS18S20/DS1820");
		else printf("DS18B20");
		printf(" which is ");
		if ( DS18X20_get_power_status( &gSensorIDs[i][0] ) ==
			DS18X20_POWER_PARASITE ) 
			printf( "parasite" );
		else printf( "externally" ); 
		printf( " powered\n" );
	}
	
	printf("CanInit...\n");
	if (Can_Init() != CAN_OK) {
		printf("FAILED!\n");
	}
	else {
		printf("OK!\n");
	}
	
	uint32_t timeStamp = 0;
	
	Can_Message_t txMsg;
	Can_Message_t rxMsg;
	
	txMsg.DataLength = 2;
	txMsg.Id = 0;
	txMsg.RemoteFlag = 0;
	txMsg.ExtendedFlag = 1;
	
	/* main loop */
	while (1) {
		/* service the CAN routines */
		Can_Service();

		/* check if any messages have been received */
		while (Can_Receive(&rxMsg) == CAN_OK) {
			
		}

		/* check temperature and send on CAN once every other second */
		if (Timebase_PassedTimeMillis(timeStamp) >= 2000) {
			timeStamp = Timebase_CurrentTime();
			
			if ( DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ) == DS18X20_OK) {
				printf("Measuring temperature... ");
				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 ) {
						
						//txMsg.Data.bytes[0] = subzero;
						if (subzero) {
							txMsg.Data.bytes[i*2] = -cel;
							txMsg.Data.bytes[i*2+1] = ~(cel_frac_bits<<4);
						} else {
							txMsg.Data.bytes[i*2] = cel;
							txMsg.Data.bytes[i*2+1] = (cel_frac_bits<<4);
						}
						
					}
					else printf("CRC Error (lost connection?)\n");
				}
				
				txMsg.DataLength = nSensors*2;
				printf("sending...\n");
				/* send txMsg */
				Can_Send(&txMsg);
			}
			else printf("Start meas. failed (short circuit?)\n");

		}
	}
	
	return 0;
}
コード例 #7
0
/*-----------------------------------------------------------------------------
 * 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
    }