/** \brief Inertial sensor data visualizer demo application entry
 *
 * This application uses a serial connection to transmit sensor data.  The
 * data is formatted for use by the Atmel Data Visualizer application
 * running on a remote host.
 *
 * Upon entry, the hardware (including processor and sensor board) are
 * initialized, and the sensor interfaces are established.  The application
 * then transmits a series of special data stream configuration packets,
 * which tell the remote application the number, type, and labels for
 * data streams that will subsequently be used.
 *
 * After this initialization, the application enters a continuous loop
 * in which it periodically samples the sensors that are defined and
 * sends the obtained data values to the remote host in stream data packets.
 * Each type of sensor measurement uses an interval counter to determine
 * how often the measurement should be performed and transmitted.
 */
int main(void)
{
	int led_index = 0;
	int loop_count = 0;

	sensor_t accel_dev;             /* Accelerometer device */
	sensor_t compass_dev;           /* Compass/magnetometer device */
	sensor_t gyro_dev;              /* Gyroscope device */

	sensor_data_t accel_data;       /* Accelerometer data */
	sensor_data_t compass_data;     /* Compass data */
	sensor_data_t gyro_data;        /* Gyroscope data */
	sensor_data_t temp_data;        /* Temperature data */

	/* Initialize the board (Xplained UC3 or XMEGA & Xplained Sensor boards)
	 * I/O pin mappings and any other configurable resources selected in
	 * the build configuration.
	 */
	sensor_platform_init();

	LED_On(ALL_LEDS);

	/* Attach descriptors to the defined sensor devices. */
	sensor_attach(&accel_dev, SENSOR_TYPE_ACCELEROMETER, 0, 0);
	sensor_attach(&gyro_dev, SENSOR_TYPE_GYROSCOPE, 0, 0);
	sensor_attach(&compass_dev, SENSOR_TYPE_COMPASS, 0, 0);

	if (accel_dev.err || gyro_dev.err || compass_dev.err) {
		while (true) {
			/* Error occurred, loop forever */
		}
	}

	/* Set sensor data output formats */
	accel_data.scaled   = true;
	gyro_data.scaled    = true;
	compass_data.scaled = true;
	temp_data.scaled    = true;

	/* Wait for user to push button before continuing */
	LED_Off(ALL_LEDS);
	
	do {
		/* Just blink LED until button is pushed */
		LED_Toggle(PROMPT_LED);

		delay_ms(500);
	} while (!SWITCH_PRESSED);

	LED_Off(PROMPT_LED);

	/* Enable output streams for Atmel Data Visualizer (ADV) */
	visual_stream_init();

	while (true) {
		/* Change LED display */
		LED_Toggle(led_array [led_index++]);
		if (led_index >= NUM_BLINK_LEDS) {
			led_index = 0;
		}

		/* Accelerometer data */
		if ((loop_count % ACCEL_INTERVAL) == 0) {
			sensor_get_acceleration(&accel_dev, &accel_data);

			adv_data_send_3(ACCEL_STREAM_NUM, accel_data.timestamp,
					accel_data.axis.x, accel_data.axis.y,
					accel_data.axis.z);
		}

		/* Gyroscope data */
		if ((loop_count % GYRO_INTERVAL) == 0) {
			sensor_get_rotation(&gyro_dev, &gyro_data);

			adv_data_send_3(GYRO_STREAM_NUM, gyro_data.timestamp,
					gyro_data.axis.x, gyro_data.axis.y,
					gyro_data.axis.z);
		}

		/* Compass/magnetometer data */
		if ((loop_count % COMPASS_INTERVAL) == 0) {
			sensor_get_heading(&compass_dev, &compass_data);

			adv_data_send_3(COMPASS_STREAM_NUM,
					compass_data.timestamp,
					compass_data.heading.direction,
					compass_data.heading.inclination,
					compass_data.heading.strength);
		}

		/* Temperature data */
		if ((loop_count % TEMP_INTERVAL) == 0) {
			sensor_get_temperature(&gyro_dev, &temp_data);

			adv_data_send_1(TEMP_STREAM_NUM, temp_data.timestamp,
					temp_data.temperature.value);
		}

		/* Re-send stream initialization if switch pressed */
		if (SWITCH_PRESSED) {
			LED_Off(ALL_LEDS);
			LED_On(PROMPT_LED);
			
			/* Re-send init info */
			visual_stream_init();

			while (SWITCH_PRESSED) {
				/* wait until button is released */
			}

			LED_Off(PROMPT_LED);
			led_index = 0;
		}

		loop_count++;
	}

	return 0;
}
Beispiel #2
0
/** Unit test to check that the gyroscope works correctly on the Inertial
 *  One board using the Sensor Platform library.
 *
 *  \param test  Pointer to the unit test case instance
 */
static void run_sensor_gyro_test(const struct test_case *test)
{
	sensor_t gyro;
	sensor_data_t gyro_data = { .scaled = true };
	
	configure_sensor_platform();
	
	sensor_attach(&gyro, SENSOR_TYPE_GYROSCOPE, 0, 0);	
	test_assert_false(test, gyro.err, "Error attaching to gyroscope");
	
	delay_ms(50);
	
	for (uint8_t i = 0; i < 10; i++) {	
		test_assert_true(test, sensor_get_rotation(&gyro, &gyro_data),
				"Gyroscope read failed");
		test_assert_false(test, gyro.err,
				"Gyroscope internal error");
				
		delay_ms(2);
	}	
}

/** Unit test to check that the accelerometer works correctly on the Inertial
 *  One board using the Sensor Platform library.
 *
 *  \param test  Pointer to the unit test case instance
 */
static void run_sensor_accel_test(const struct test_case *test)
{
	sensor_t accel;
	sensor_data_t accel_data = { .scaled = true };
	
	configure_sensor_platform();
	
	sensor_attach(&accel, SENSOR_TYPE_ACCELEROMETER, 0, 0);
	test_assert_false(test, accel.err, "Error attaching to accelerometer");
	
	delay_ms(50);
	
	for (uint8_t i = 0; i < 10; i++) {
		vector3_t accel_data_vect;
		
		test_assert_true(test, sensor_get_acceleration(&accel, &accel_data),
				"Accelerometer read failed");
		test_assert_false(test, accel.err,
				"Accelerometer internal error");
		
		accel_data_vect.x = accel_data.axis.x;
		accel_data_vect.y = accel_data.axis.y;
		accel_data_vect.z = accel_data.axis.z;
		
		scalar_t accel_mag = vector3_magnitude(&accel_data_vect);
		
		test_assert_true(test,
				(accel_mag > (1000 - 300)) && (accel_mag < (1000 + 300)),
				"Accelerometer returned value not close to 1000 milli-g: %i",
				(uint16_t)accel_mag);
				
		delay_ms(2);
	}	
}

/** Unit test to check that the compass works correctly on the Inertial
 *  One board using the Sensor Platform library.
 *
 *  \param test  Pointer to the unit test case instance
 */
static void run_sensor_compass_test(const struct test_case *test)
{
	sensor_t compass;
	sensor_data_t compass_data = { .scaled = true };
	
	configure_sensor_platform();
	
	sensor_attach(&compass, SENSOR_TYPE_COMPASS, 0, 0);
	test_assert_false(test, compass.err, "Error attaching to magnetometer");
	
	delay_ms(50);
	
	for (uint8_t i = 0; i < 10; i++) {
		vector3_t compass_data_vect;
		
		test_assert_true(test, sensor_get_heading(&compass, &compass_data),
				"Compass read failed");
		test_assert_false(test, compass.err,
				"Compass internal error");
		
		compass_data_vect.x = compass_data.heading.direction;
		compass_data_vect.y = compass_data.heading.inclination;
		compass_data_vect.z = compass_data.heading.strength;
		
		scalar_t compass_mag = vector3_magnitude(&compass_data_vect);
		
		test_assert_false(test, (compass_mag == 0),
				"Compass returned zero data");		
		
		delay_ms(2);
	}	
}

/** Unit test to check that the gyroscope internal temperature sensor works 
 *  correctly on the Inertial One board using the Sensor Platform library.
 *
 *  \param test  Pointer to the unit test case instance
 */
static void run_sensor_temp_test(const struct test_case *test)
{
	sensor_t gyro;
	sensor_data_t temp_data = { .scaled = true };
	
	configure_sensor_platform();
	
	sensor_attach(&gyro, SENSOR_TYPE_GYROSCOPE, 0, 0);
	test_assert_false(test, gyro.err, "Error attaching to gyroscope");
	
	delay_ms(50);
	
	for (uint8_t i = 0; i < 10; i++) {	
		test_assert_true(test, sensor_get_temperature(&gyro, &temp_data),
				"Gyroscope temperature read failed");
		test_assert_false(test, gyro.err,
				"Gyroscope internal error");
		
		test_assert_false(test, ((int16_t)temp_data.temperature.value == 0),
				"Gyroscope returned zero temperature data");

		test_assert_false(test, ((int16_t)temp_data.temperature.value > 40),
				"Gyroscope returned too high temperature data: %d",
				(int16_t)temp_data.temperature.value);

		delay_ms(2);
	}
}

int main(void)
{
	// Initialize the board and all the peripheral required
	sysclk_init();
	board_init();
	stdio_serial_init(CONF_TEST_USART, &usart_serial_options);

#if XMEGA
	pmic_init();
	sleepmgr_init();
#endif

	DEFINE_TEST_CASE(sensor_init_test, NULL, run_sensor_init_test,
			NULL, "Test sensor initialization");

	DEFINE_TEST_CASE(sensor_gyro_test, NULL, run_sensor_gyro_test,
			NULL, "Test gyroscope read");

	DEFINE_TEST_CASE(sensor_accel_test, NULL, run_sensor_accel_test,
			NULL, "Test accelerometer read");
	
	DEFINE_TEST_CASE(sensor_compass_test, NULL, run_sensor_compass_test,
			NULL, "Test compass read");

	DEFINE_TEST_CASE(sensor_temp_test, NULL, run_sensor_temp_test,
			NULL, "Test temperature read");
				
	DEFINE_TEST_ARRAY(sensor_tests) = {
		&sensor_init_test,
		&sensor_gyro_test,
		&sensor_accel_test,
		&sensor_compass_test,
		&sensor_temp_test
	};

	DEFINE_TEST_SUITE(sensor_suite,
			sensor_tests, "Common sensor plarform test suite");

	test_suite_run(&sensor_suite);

	while (1) {
		/* Intentionally left blank */
	}
}
Beispiel #3
0
/** \brief Inertial sensor demo application entry
 *
 * After initializing the Xplained platform and sensor boards, this application
 * attaches descriptors to the accelerometer, gyroscope, and compass devices on
 * an Xplained inertial sensor board.  The sensor data, which is formatted and
 * printed via printf() after being read, can be viewed with a serial terminal
 * application on a machine attached to the USB interface on the Xplained
 * board.
 */
int main(void)
{
	sensor_t accel;   /* Accelerometer device descriptor */
	sensor_t compass; /* Magnetic compass device descriptor */
	sensor_t gyro;    /* Gyroscope device descriptor */

	/* Initialize the board (Xplained UC3 or XMEGA & Xplained Sensor boards)
	 * I/O pin mappings and any other configurable resources selected in
	 * the build configuration.
	 */
	sensor_platform_init();

	/* Attach descriptors to the defined sensor devices */
	sensor_attach(&gyro, SENSOR_TYPE_GYROSCOPE, 0, 0);
	sensor_attach(&accel, SENSOR_TYPE_ACCELEROMETER, 0, 0);
	sensor_attach(&compass, SENSOR_TYPE_COMPASS, 0, 0);

	if (gyro.err || accel.err || compass.err) {
		puts("\rSensor initialization error.");

		while (true) {
			/* Error occurred, loop forever */
		}
	}

	/* Print sensor information */
	if (PRINT_BANNER) {
		static const char *const banner_format
			= "%s\r\nID = 0x%02x ver. 0x%02x\r\n"
				"Bandwidth = %d Hz  Range = +/- %d\r\n\n";

		uint32_t id;
		uint8_t version;
		int16_t freq, range;

		sensor_device_id(&gyro, &id, &version);
		sensor_get_bandwidth(&gyro, &freq);
		sensor_get_range(&gyro, &range);

		printf(banner_format, gyro.drv->caps.name,
				(unsigned)id, (unsigned)version, freq, range);

		sensor_device_id(&accel, &id, &version);
		sensor_get_bandwidth(&accel, &freq);
		sensor_get_range(&accel, &range);

		printf(banner_format, accel.drv->caps.name,
				(unsigned)id, (unsigned)version, freq, range);

		sensor_device_id(&compass, &id, &version);
		sensor_get_bandwidth(&compass, &freq);
		sensor_get_range(&compass, &range);

		printf(banner_format, compass.drv->caps.name,
				(unsigned)id, (unsigned)version, freq, range);

		delay_ms(500);
	}

	/* Initialize sensor data descriptors for scaled vs. raw data. */
	static sensor_data_t accel_data   = {.scaled = SCALED_DATA};
	static sensor_data_t compass_data = {.scaled = SCALED_DATA};
	static sensor_data_t gyro_data    = {.scaled = SCALED_DATA};
	static sensor_data_t temp_data    = {.scaled = SCALED_DATA};

	while (true) {
		LED_Toggle(ACTIVITY_LED);

		/* Read sensor values */
		sensor_get_acceleration(&accel, &accel_data);
		sensor_get_rotation(&gyro, &gyro_data);
		sensor_get_temperature(&gyro, &temp_data); /* Get temp from gyro */

		if (SCALED_DATA) {
			/* Get calculated magnetic heading from compass */
			sensor_get_heading(&compass, &compass_data);
		} else {
			/* Get raw magnetic field readings (X,Y,Z) */
			sensor_get_field(&compass, &compass_data);
		}

		/* Print sensor values */
		if (SCALED_DATA) {
			printf("acc = [%5d, %5d, %5d]\r\n",
					(int16_t)accel_data.axis.x,
					(int16_t)accel_data.axis.y,
					(int16_t)accel_data.axis.z);

			printf("rot = [%5d, %5d, %5d]\r\n",
					(int16_t)gyro_data.axis.x,
					(int16_t)gyro_data.axis.y,
					(int16_t)gyro_data.axis.z);

			printf("heading %5d, inclination %5d, strength %5d\r\n",
					(uint16_t)compass_data.heading.direction,
					(int16_t)compass_data.heading.inclination,
					(uint16_t)compass_data.heading.strength);

			printf("T = %d C\r\n\n",
					(int16_t)temp_data.temperature.value);
		} else {
			printf("acc = [%.5x, %.5x, %.5x]\r\n",
					(uint16_t)accel_data.axis.x,
					(uint16_t)accel_data.axis.y,
					(uint16_t)accel_data.axis.z);

			printf("rot = [%.5x, %.5x, %.5x]\r\n",
					(uint16_t)gyro_data.axis.x,
					(uint16_t)gyro_data.axis.y,
					(uint16_t)gyro_data.axis.z);

			printf("field = [%.5x, %.5x, %.5x]\r\n",
					(int16_t)compass_data.axis.x,
					(int16_t)compass_data.axis.y,
					(int16_t)compass_data.axis.z);

			printf("T = %.5x\r\n\n",
					(uint16_t)temp_data.temperature.value);
		}

		delay_ms(500);
	}

	return 0;
}