Ejemplo n.º 1
0
/**
 * \brief Main entry of example application
 */
int main(void)
{
	/* The sensor_platform_init() function will initialize the system
	 * clock and sensor bus support in addition to configuring the
	 * XMEGA-A3BU and Sensor Xplained boards.
	 *
	 * Use gfx_mono_init() to initialize the monochrome graphical system
	 * API then write a splash screen after enabling the LCD display
	 * backlight and setting the contrast.
	 */
	sensor_platform_init();
	gfx_mono_init();

	gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
	st7565r_set_contrast(ST7565R_DISPLAY_CONTRAST_MIN);

	gfx_mono_draw_string(
			"Atmel\r\nSensors Xplained\r\nInertial Sensor Demo",
			0, 0, &sysfont);

	delay_ms(2000);

	clear_screen();

	gfx_mono_draw_string("Press button SW1", 1, 5, &sysfont);
	gfx_mono_draw_string("to change sensor", 1, 13, &sysfont);

	delay_ms(1000);

	screen_border();

	/* Attach descriptors to sensors on an Xplained add-on board. */
	sensor_t accelerometer;
	sensor_attach(&accelerometer, SENSOR_TYPE_ACCELEROMETER, 0, 0);

	sensor_t gyroscope;
	sensor_attach(&gyroscope, SENSOR_TYPE_GYROSCOPE, 0, 0);

	sensor_t compass;
	sensor_attach(&compass, SENSOR_TYPE_COMPASS, 0, 0);

	/* Configure operational parameters for select sensors. */
	sensor_set_range(&accelerometer, 2000 /* milli-g */);
	sensor_set_bandwidth(&accelerometer, 25 /* Hertz */);

	while (true) {
		/* Initialize a sensor data descriptor for scaled data. */
		static sensor_data_t sensor_data = {.scaled = true};

		do {
			/* Measure & show acceleration until button SW1 is
			 * pushed. */
			sensor_read(&accelerometer, SENSOR_READ_ACCELERATION, &sensor_data);
			draw_formatted_data(acceleration_format, &sensor_data);
		} while (!switch_pressed(SW1));

		do {
			/* Measure & show rotation until button SW1 is pushed. */
			sensor_read(&gyroscope, SENSOR_READ_ROTATION, &sensor_data);
			draw_formatted_data(rotation_format, &sensor_data);
		} while (!switch_pressed(SW1));

		static gfx_coord_t const ring_center_x = 112;
		static gfx_coord_t const ring_center_y = 16;
		static gfx_coord_t const ring_radius   = 15;

		/* Compass needle point x- and y-coordinate. */
		gfx_coord_t needle_x = ring_center_x;
		gfx_coord_t needle_y = ring_center_y;

		/* Draw the compass ring. */
		gfx_mono_draw_circle(ring_center_x, ring_center_y, ring_radius,
				GFX_PIXEL_SET, GFX_WHOLE);

		do {
			/* Measure & show magnetic heading until button SW1 is
			 * pushed.
			 */
			sensor_read(&compass, SENSOR_READ_HEADING, &sensor_data);

			/* Calculate compass needle coordinates on the display
			 * by using sin() & cos() to find the x- and y-coordinate of the
			 * needle point. Note that the 'direction' value is in degrees
			 * and must be converted to radians for the C-library math
			 * functions.
			 */
			int const needle_length = ring_radius - 3;
			double const direction  = radians(sensor_data.heading.direction);

			/* Erase the old compass needle. */
			gfx_mono_draw_line(ring_center_x, ring_center_y,
					needle_x, needle_y, GFX_PIXEL_CLR);

			needle_x = ring_center_x +
					(needle_length * sin(direction + M_PI));
			needle_y = ring_center_y +
					(needle_length * cos(direction + M_PI));

			/* Draw the new compass needle. */
			gfx_mono_draw_line(ring_center_x, ring_center_y,
					needle_x, needle_y, GFX_PIXEL_SET);

			draw_formatted_data(heading_format, &sensor_data);
		} while (!switch_pressed(SW1));

		/* Clear last compass needle and compass ring. */
		gfx_mono_draw_line(ring_center_x, ring_center_y,
				needle_x, needle_y, GFX_PIXEL_CLR);

		gfx_mono_draw_circle(ring_center_x, ring_center_y, ring_radius,
				GFX_PIXEL_CLR, GFX_WHOLE);

		screen_border();

		do {
			/* Measure & show temperature until button SW1 is pushed. */
			sensor_read(&gyroscope, SENSOR_READ_TEMPERATURE, &sensor_data);

			/* Arrange temperature data values in array with
			 * Fahrenheit and Celsius formats.
			 */
			int32_t const temp_deg_c = sensor_data.temperature.value;
			int32_t const temp_deg_f = CELSIUS_TO_FAHRENHEIT(temp_deg_c);

			sensor_data.value[0] = temp_deg_f;
			sensor_data.value[1] = temp_deg_c;

			draw_formatted_data(temperature_format, &sensor_data);
		} while (!switch_pressed(SW1));
	}
}
Ejemplo n.º 2
0
/**
 * \brief Example application entry routine
 */
int main(void)
{
	/* The sensor_platform_init() function will initialize the system
	 * clock and sensor bus support in addition to configuring the
	 * XMEGA-A3BU and Sensor Xplained boards.
	 *
	 * Use gfx_mono_init() to initialize the monochrome graphical system
	 * API then write a splash screen after enabling the LCD display
	 * backlight and setting the contrast.
	 *
	 * The MCU is going to be put in a sleep mode, so initialize the
	 * sleep manager API with a call to the sleepmgr_init() routine.
	 */
	sensor_platform_init();
	gfx_mono_init();
	sleepmgr_init();

	gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
	st7565r_set_contrast(ST7565R_DISPLAY_CONTRAST_MIN);

	/* Attach an accelerometer on a Sensors Xplained board. */
	sensor_t accelerometer;
	sensor_attach(&accelerometer, SENSOR_TYPE_ACCELEROMETER, 0, 0);

	/* Enable the accelerometer low-g (free fall) event. */
	sensor_enable_event(&accelerometer, SENSOR_EVENT_LOW_G);

	/* Set the free fall threshold (low-g event), bandwidth and range. */
	sensor_set_threshold(&accelerometer, SENSOR_THRESHOLD_LOW_G,
			LOW_G_THRESHOLD);
	sensor_set_bandwidth(&accelerometer, BANDWIDTH);
	sensor_set_range(&accelerometer, RANGE);

	while (true) {
		/* Put the accelerometer into a low-power mode (if available). */
		sensor_set_state(&accelerometer, SENSOR_STATE_LOW_POWER);

		LED_Off(ACCEL_LED);

		clear_screen();

		/* Display the "armed" message and put the MCU in sleep mode. */
		gfx_mono_draw_string("ATMEL Drop Demo\r\nXMEGA Powered Down\r\n"
				"g Sensor Armed", 1, 5, &sysfont);

		sleepmgr_lock_mode(SLEEP_MODE);
		sleepmgr_enter_sleep();

		/* The following runs after the MCU has been woken by an
		 * external low-g interrupt from the accelerometer.
		 *
		 * Turn on the red LED while falling and put the accelerometer
		 * into a high-power mode (if available) to sample date points.
		 */
		LED_On(ACCEL_LED);

		sensor_set_state(&accelerometer, SENSOR_STATE_HIGHEST_POWER);

		static scalar_t acceleration_waveform[DATA_SAMPLE_COUNT];
		scalar_t acceleration_max = 0;

		for (int data_count = 0; data_count < DATA_SAMPLE_COUNT;
				++data_count) {
			acceleration_waveform[data_count] = 0;

			for (int i = 0; i < SAMPLE_AVG_COUNT; ++i) {
				/* Calculate the gravity vector magnitude. */
				vector3_t gvec;
				sensor_get_vector(&accelerometer, &gvec);

				scalar_t const acceleration_magnitude
					= vector3_magnitude(&gvec);

				/* Store the maximum g magnitude for this
				 * sub-group. */
				if (acceleration_magnitude >
						acceleration_waveform[data_count]) {
					acceleration_waveform[data_count]
						= acceleration_magnitude;
				}

				/* Store the maximum g magnitude for the whole
				 * data set. */
				if (acceleration_magnitude > acceleration_max) {
					acceleration_max = acceleration_magnitude;
				}
			}
		}

		clear_screen();

		/* Turn the max acceleration into a string and convert to g. */
		static char max_g_string[20];

		if (acceleration_max > LOW_G_SATURATION) {
			sprintf(max_g_string, "g Sensor Saturated");
		} else {
			sprintf(max_g_string, "Peak = %02.2f g",
					acceleration_max / 1000);
		}

		/* Print the max g on the monochrome display. */
		gfx_mono_draw_string("Drop Detected", 1, 5, &sysfont);
		gfx_mono_draw_string(max_g_string, 1, 13, &sysfont);
		gfx_mono_draw_string("Press SW1 for chart", 1, 21, &sysfont);

		do {
			LED_Toggle(ACCEL_LED);
			delay_ms(100);
		} while (!switch_pressed(SW1));

		/* Plot the collected data points to create the waveform chart. */
		clear_screen();
		screen_border();

		for (int data_count = 0; data_count < DATA_SAMPLE_COUNT; ++data_count) {
			gfx_mono_draw_filled_circle(data_count,
					32 -
					(acceleration_waveform[data_count] / 500), 1,
					GFX_PIXEL_SET, GFX_WHOLE);
		}

		do {
			LED_Toggle(PROMPT_LED);
			delay_ms(100);
		} while (!switch_pressed(SW1));

		LED_Off(PROMPT_LED);
	}
}