Difference between revisions of "SparkFun: ITG-3200,Triple-Axis Gyro"

From eLinux.org
Jump to: navigation, search
(Sample C Code)
Line 29: Line 29:
  
 
<pre>
 
<pre>
/***************************************
+
/*
#* adxl335.c
+
* MiniProject02.c
#*  
+
*
#* This file demonstrates the usage of the ADXL335 accelerometer.
+
* Created on: Sep 20, 2012
#*
+
*     Author: Ruffin White
#* With the proper accelerometer axis inputs defined below,  
+
*/
#* this application will output and constantly update the readings
+
#* from the accelerometer
+
#*
+
***************************************/
+
  
 +
#include "Header.h"
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <stdlib.h>
 +
#include <string.h>
 +
#include <unistd.h>
 +
#include <fcntl.h>
 +
#include <poll.h>
 
#include <signal.h>
 
#include <signal.h>
#include <sys/time.h>
+
#include "ITG-3200.h"
  
#define ANINX 7
+
int loop=1;
#define ANINY 3
+
#define ANINZ 1
+
  
int keepGoing = 1;
 
  
 
void signal_handler(int sig)
 
void signal_handler(int sig)
 
{
 
{
 
printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
 
printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
keepGoing = 0;
+
loop = 0;
 
}
 
}
  
/*
+
int main(int argc, char** argv){
* int read_anin(char * fileName)
+
*
+
* The argument is the fileName instead of the integer because this will be called a lot for only 3 filenames,
+
* so we want to save ourselves the work of constructing the filename each time.
+
*
+
*/
+
int read_anin(char * fileName){
+
FILE *fp;
+
char readValue[5];
+
  
if ((fp = fopen(fileName, "r")) == NULL) {
+
//variable declarations
printf("Cannot open anin file: %s.\n", fileName);
+
struct pollfd fdset[1];
exit(1);
+
int nfds = 1;
 +
int timeout = 100;
 +
int rc;
 +
char* buf[MAX_BUF];
 +
int gpio1, gpio2;
 +
int gpio1_fd, gpio2_fd;
 +
int gpio2_value = 0;
 +
int pattern =0;
 +
int value =0;
 +
 
 +
int freq = 10;
 +
int duty = 25;
 +
 
 +
int gyroID, gyroTemp, gyroX, gyroY, gyroZ;
 +
 
 +
// I2C Variables
 +
char *end;
 +
int res, i2cbus, address, size, file;
 +
int daddress;
 +
 
 +
//check that at least two arguments are passed in
 +
if(argc < 4){
 +
printf("Usage: %s <input-gpio> <output-gpio> <i2c-bus>\n", argv[0]);
 +
printf("polls input-gpio, and writes value to output-gpio\n");
 +
fflush(stdout);
 +
return 1;
 
}
 
}
  
//Set pointer to begining of the file
 
rewind(fp);
 
//Write our value of "out" to the file
 
fread(readValue, sizeof(char), 10, fp);
 
readValue[4] = '\0'; //for some reason when reading 4 digit numbers you get weird garbage after the value
 
fclose(fp);
 
  
return atoi(readValue);
+
//set signal handler for Ctrl + C
}
+
if (signal(SIGINT, signal_handler) == SIG_ERR)
 +
printf("\ncan't catch SIGINT\n");
  
int main(int argc, char **argv, char **envp){
+
//assign gpio values
int i;
+
gpio1 = atoi(argv[1]);
 +
gpio2 = atoi(argv[2]);
  
char fileNameX[50], fileNameY[50], fileNameZ[50];
 
sprintf(fileNameX, "/sys/devices/platform/omap/tsc/ain%d", ANINX);
 
sprintf(fileNameY, "/sys/devices/platform/omap/tsc/ain%d", ANINY);
 
sprintf(fileNameZ, "/sys/devices/platform/omap/tsc/ain%d", ANINZ);
 
 
signal(SIGINT, signal_handler);
 
  
while(keepGoing){
+
//assign I2C values
printf("X: %d | Y: %d | Z: %d\r", read_anin(fileNameX), read_anin(fileNameY), read_anin(fileNameZ));
+
i2cbus  = atoi(argv[3]);
usleep(10000);
+
address  = ITG3200_I2C_ADDRESS;
}
+
file = initialize(i2cbus, address);
+
 
+
 
 +
 
 +
//argument 1 will be input
 +
export_gpio(gpio1);
 +
set_gpio_direction(gpio1, "in");
 +
set_gpio_edge(gpio1, "falling");
 +
gpio1_fd = gpio_fd_open(gpio1);
 +
 
 +
//argument 2 will be output
 +
export_gpio(gpio2);
 +
set_gpio_direction(gpio2, "out");
 +
set_gpio_value(gpio2, gpio2_value);
 +
gpio2_fd = gpio_fd_open(gpio2);
 +
 
 +
set_mux_value("gpmc_a2",6);
 +
 
 +
 
 +
while(loop){
 +
memset((void*)fdset, 0, sizeof(fdset));
 +
 
 +
fdset[0].fd = gpio1_fd;
 +
fdset[0].events = POLLPRI;
 +
 
 +
rc = poll(fdset, nfds, timeout);
 +
 
 +
if (rc < 0){
 +
printf("\npoll() failed!\n");
 +
}
 +
 
 +
if (rc == 0){
 +
printf(".");
 +
}
 +
 
 +
if((fdset[0].revents & POLLPRI) == POLLPRI) {
 +
read(fdset[0].fd, buf, MAX_BUF);
 +
printf("interrupt value=%c\n", buf[0]);
 +
pattern++;
 +
if(pattern == 4){
 +
pattern = 0;
 +
}
 +
}
 +
 
 +
switch(pattern){
 +
 
 +
// blink led
 +
case 0:
 +
printf("Case 0\n");
 +
value = read_ain("ain6");
 +
printf("Voltage: %d\n",value);
 +
set_pwm("ehrpwm.1:0",10,25);
 +
if(gpio2_value){
 +
gpio2_value = 0;
 +
}
 +
else{
 +
gpio2_value = 1;
 +
}
 +
set_gpio_value(gpio2, gpio2_value);
 +
break;
 +
 
 +
//PWM output
 +
case 1:
 +
 
 +
gyroID = readWhoAmI(file);
 +
 
 +
printf("gyroID: 0x%02x (%d)\n", gyroID, gyroID);
 +
break;
 +
 
 +
//Read Gyro Temperature
 +
case 2:
 +
printf("Case 2\n");
 +
 
 +
gyroTemp = readTemp(file);
 +
 
 +
printf("gyroTemp: 0x%02x (%d)\n", gyroTemp, gyroTemp);
 +
break;
 +
 
 +
//Read Gyro XYZ
 +
case 3:
 +
printf("Case 3\n");
 +
 
 +
gyroX = readX(file);
 +
gyroY = readY(file);
 +
gyroZ = readZ(file);
 +
 
 +
printf("gyroX: 0x%02x (%d)\n", gyroX, gyroX);
 +
printf("gyroY: 0x%02x (%d)\n", gyroY, gyroY);
 +
printf("gyroZ: 0x%02x (%d)\n", gyroZ, gyroZ);
 +
break;
 +
 
 +
default:
 +
break;
 +
}
 +
}
 +
close(file);
 +
gpio_fd_close(gpio1_fd);
 +
gpio_fd_close(gpio2_fd);
 +
unexport_gpio(gpio1);
 +
unexport_gpio(gpio2);
 +
fflush(stdout);
 +
return 0;
 
}
 
}
 +
 
</pre>
 
</pre>
  
 
This code can be compiled with the command ''gcc adxl335.c -o adxl335''
 
This code can be compiled with the command ''gcc adxl335.c -o adxl335''
 
  
 
== Features ==
 
== Features ==

Revision as of 15:53, 25 September 2012


Overview

The ADXL335 is a three-axis accelerometer that can be purchased from SparkFun. The datasheet describes it:

The ITG-3200 is the world’s first single-chip, digital-output, 3-axis MEMS gyro IC optimized for gaming, 3D mice, and 3D remote control applications. The part features enhanced bias and sensitivity temperature stability, reducing the need for user calibration. Low frequency noise is lower than previous generation devices, simplifying application development and making for more-responsive remote controls.

Inputs and Outputs

The ITG-3200 takes a supply voltage (Vs) of 1.8-3.6 V. The analog outputs are scaled proportionally to the supply voltage; at Vs = 3.6 V, the output will change by 2x for the same acceleration as compared to Vs = 1.8 V. Although the output sensitivity is scaled proportionally to the input voltage, noise is not, so higher supply voltages are advisable to reduce the impact of noise.

At all supply voltages, 0 g acceleration corresponds to an output voltage of Vs/2. At Vs = 3.6 V, the datasheet specs the typical sensitivity at 360 mV / g, with g as standard gravitational acceleration.

Bone Usage

Because the ITG-3200 has and I2C port, data can be read into the Bone via the I2C buss pins. One sets of I2C buss pins are required, for the X, Y, Z, and temperature outputs on the gyro. Here we will use the ITG300.h (This header also imports the i2c-dev.h and errno.h automatically, these are necessary to poll the device later on). See the picture on the right for an example wiring configuration.

"
File:ABone.jpg
Wiring example for ITG-3200 on a Bone
"

Note: There are two unpopulated resistors on the I2C lines, these can be added later by the customer if desired..

Sample C Code

The code shown below is sample code to demonstrate reading analog output from the ADXL335.

/*
 * MiniProject02.c
 *
 *  Created on: Sep 20, 2012
 *      Author: Ruffin White
 */

#include "Header.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include "ITG-3200.h"

int loop=1;


void signal_handler(int sig)
{
	printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
	loop = 0;
}

int main(int argc, char** argv){

	//variable declarations
	struct pollfd fdset[1];
	int nfds = 1;
	int timeout = 100;
	int rc;
	char* buf[MAX_BUF];
	int gpio1, gpio2;
	int gpio1_fd, gpio2_fd;
	int gpio2_value = 0;
	int pattern =0;
	int value =0;

	int freq = 10;
	int duty = 25;

	int gyroID, gyroTemp, gyroX, gyroY, gyroZ;

	// I2C Variables
	char *end;
	int res, i2cbus, address, size, file;
	int daddress;

	//check that at least two arguments are passed in
	if(argc < 4){
		printf("Usage: %s <input-gpio> <output-gpio> <i2c-bus>\n", argv[0]);
		printf("polls input-gpio, and writes value to output-gpio\n");
		fflush(stdout);
		return 1;
	}


	//set signal handler for Ctrl + C
	if (signal(SIGINT, signal_handler) == SIG_ERR)
		printf("\ncan't catch SIGINT\n");

	//assign gpio values
	gpio1 = atoi(argv[1]);
	gpio2 = atoi(argv[2]);


	//assign I2C values
	i2cbus   = atoi(argv[3]);
	address  = ITG3200_I2C_ADDRESS;
	file = initialize(i2cbus, address);



	//argument 1 will be input
	export_gpio(gpio1);
	set_gpio_direction(gpio1, "in");
	set_gpio_edge(gpio1, "falling");
	gpio1_fd = gpio_fd_open(gpio1);

	//argument 2 will be output
	export_gpio(gpio2);
	set_gpio_direction(gpio2, "out");
	set_gpio_value(gpio2, gpio2_value);
	gpio2_fd = gpio_fd_open(gpio2);

	set_mux_value("gpmc_a2",6);


	while(loop){
		memset((void*)fdset, 0, sizeof(fdset));

		fdset[0].fd = gpio1_fd;
		fdset[0].events = POLLPRI;

		rc = poll(fdset, nfds, timeout);

		if (rc < 0){
			printf("\npoll() failed!\n");
		}

		if (rc == 0){
			printf(".");
		}

		if((fdset[0].revents & POLLPRI) == POLLPRI) {
			read(fdset[0].fd, buf, MAX_BUF);
			printf("interrupt value=%c\n", buf[0]);
			pattern++;
		if(pattern == 4){
		pattern = 0;
		}
		}

		switch(pattern){

			// blink led
			case 0:
				printf("Case 0\n");
				value = read_ain("ain6");
				printf("Voltage: %d\n",value);
				set_pwm("ehrpwm.1:0",10,25);
				if(gpio2_value){
					gpio2_value = 0;
				}
				else{
					gpio2_value = 1;
				}
				set_gpio_value(gpio2, gpio2_value);
				break;

			//PWM output
			case 1:

				gyroID = readWhoAmI(file);

				printf("gyroID: 0x%02x (%d)\n", gyroID, gyroID);
				break;

			//Read Gyro Temperature
			case 2:
				printf("Case 2\n");

				gyroTemp = readTemp(file);

				printf("gyroTemp: 0x%02x (%d)\n", gyroTemp, gyroTemp);
				break;

			//Read Gyro XYZ
			case 3:
				printf("Case 3\n");

				gyroX = readX(file);
				gyroY = readY(file);
				gyroZ = readZ(file);

				printf("gyroX: 0x%02x (%d)\n", gyroX, gyroX);
				printf("gyroY: 0x%02x (%d)\n", gyroY, gyroY);
				printf("gyroZ: 0x%02x (%d)\n", gyroZ, gyroZ);
				break;

			default:
				break;
			}
		}
	close(file);
	gpio_fd_close(gpio1_fd);
	gpio_fd_close(gpio2_fd);
	unexport_gpio(gpio1);
	unexport_gpio(gpio2);
	fflush(stdout);
	return 0;
}

This code can be compiled with the command gcc adxl335.c -o adxl335

Features

Digital-output X-, Y-, and Z-Axis angular rate sensors (gyros) on one integrated circuit Digitally-programmable low-pass filter Low 6.5mA operating current consumption for long battery life Wide VDD supply voltage range of 2.1V to 3.6V Standby current: 5μA Digital-output temperature sensor Fast Mode I2C (400kHz) serial interface Optional external clock inputs of 32.768kHz or 19.2MHz to synchronize with system clock Pins broken out to a breadboard friendly 7-pin 0.1" pitch header

Dimensions

0.70 x 0.55" (17.78 x 13.97mm)

Documents

Schematic

Eagle Files

Quickstart Guide

ITG-3200 Datasheet

Code (ATmega328)

Example