Arduino

From FourMs

Jump to: navigation, search

Contents

About

Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments. In this tutorial I will only focus on communication with Max.


Needs to be updated

Serial Line Internet Protocol (SLIP)

Serial communication with Max, however, may not the best solution for communication with micro-controllers. To prevent flaws in the transmission of sensor data from the micro-controller, the Slip protocol can be used for efficient serial communication. As the serial hardware–software communication is very simple and does not impose any kind of ”packet structure” on data, it is the responsibility of the transmitting program, inside the micro-controller, to let the receiver know where a chunk of data begins and where it ends. The Slip protocol applies two characters at the beginning and at the end of the sensor values in the array, and these are being serially transmitted into Max. This is done by applying a delimiter-character between each value in the sensor data array, and an escape character after the last value of the array.

Inter-Integrated Circuit (I²C)

Philips Semiconductors (now NXP Semiconductors) developed a simple bidirectional 2-wire bus for efficient inter-IC control. This bus is called the Inter-IC or I2C-bus. Only two bus lines are required: a serial data line (SDA) and a serial clock line (SCL).

Serial Peripheral Interface (SPI)

For a project, I needed to use 6 FSR's, which occupied all the analog inputs of an Arduino Pro Mini, however, I also wanted to use a 3D accelerometer. In order to do so, I ended up with a digital accelerometer.

SPI interfacing requires more complex programming than the ease of use Wire library, which can be used in I2C interfacing. Since I wanted to use all the analog inputs for the FSR's, the SPI was the only solution.

A diagram of SPI interfacing with the LIS3LV02DQ digital acelerometer and the Arduino Pro Mini can be seen here:


Image:Sheet.jpg


#define DATAOUT 11//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss for /LIS3LV02DQ, active low

//define values for slip coding
int escapeChar = 101;
int delimiterChar = 100;

byte clr;
int t;
int ledPin = 9;
int ledStatus = 0;
unsigned long then = 0;
unsigned long now = 0;
int timeout = 1000;

char spi_transfer(volatile char data) {
	//Writing to the SPDR register begins an SPI transaction
	SPDR = data;

	/*Loop right here until the transaction is complete. the SPIF bit is 
	the SPI Interrupt Flag. When interrupts are enabled, and the 
	SPIE bit is set enabling SPI interrupts, this bit will set when
	the transaction is finished. */
	while (!(SPSR & (1<<SPIF))) {};

// received data appears in the SPDR register
return SPDR;                    
}

void setup() {
	char in_byte;
	clr = 0;
	in_byte = clr;
	Serial.begin(115200);

	//define pin modes
	pinMode(ledPin, OUTPUT);
	// set direction of pins
	pinMode(DATAOUT, OUTPUT);
	pinMode(DATAIN, INPUT);
	pinMode(SPICLOCK,OUTPUT);
	pinMode(SLAVESELECT,OUTPUT);

	digitalWrite(SLAVESELECT,HIGH); //disable device

	// SPCR = 01010000
	// Set the SPCR register to 01010000
	//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
	//sample on leading edge of clk,system clock/4 rate
	SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA);
	clr=SPSR;
	clr=SPDR;

	// query the WHO_AM_I register of the LIS3LV02DQ
	// this should return 0x3A, a factory setting
	in_byte = read_register(15);

	// start up the device
	// this essentially activates the device, powers it on, enables all axes, and turn off the self test
	// CTRL_REG1 set to 10000111
	write_register(0x20, 135);

	// query the WHO_AM_I register of the LIS3LV02DQ
	// this should return 0x3A, a factory setting
	in_byte = read_register(15);

	//delay(250);    
}

// reads a register
char read_register(char register_name) {
	char in_byte;

	// need to set bit 7 to indicate a read
	register_name |= 128;

	// SS is active low
	digitalWrite(SLAVESELECT, LOW);

	// send the address of the register we want to read first
	spi_transfer(register_name);

	// send nothing, but here's when the device sends back the register's value as an 8 bit byte
	in_byte = spi_transfer(0);

	// deselect the device
	digitalWrite(SLAVESELECT, HIGH); 
	return in_byte;
}

// write to a register
void write_register(char register_name, byte data) {
	// clear bit 7 to indicate we're doing a write
	register_name &= 127;

	// SS is active low
	digitalWrite(SLAVESELECT, LOW);

	// send the address of the register we want to write
	spi_transfer(register_name);

	// send the data we're writing
	spi_transfer(data);
	digitalWrite(SLAVESELECT, HIGH);
}

void loop() {
	char message = Serial.read();
	if (message=='r') {

		
		// read digital values from register
		slipOut(read_register(0x28)); //Read X LSB
		slipOut(read_register(0x29)); //Read X MSB

		slipOut(read_register(0x2A)); //Read Y LSB
		slipOut(read_register(0x2B)); //Read Y MSB

		slipOut(read_register(0x2C)); //Read Z LSB
		slipOut(read_register(0x2D)); //Read Z MSB

		// read analog values
		readAnalog();

		Serial.print(delimiterChar, BYTE);

		ledBlink();
		then = millis();

	}
	else {
		now = millis();
		if ((now - then) > timeout) {
			ledBlink();
			then = now;
		}
		else if (then > now)
			then = 0;
	}
}


void ledBlink() {
	ledStatus = (ledStatus + 1) % 2;
	digitalWrite(ledPin, ledStatus);
}


// read 6 analog values
void readAnalog() {
	for (t=0; t<6; t++) {
		slipOutInt(analogRead(t));
	}
}

void slipOut(byte output) {
	if ((output==escapeChar)||(output==delimiterChar)) Serial.print(escapeChar, BYTE);
	Serial.print(output, BYTE);
}

void slipOutInt(int output) {
	slipOut( byte(output & 0xff)); // explicitly mask the LSB using bitwise
	slipOut( byte(output >> 8)); // right-shift for MSB
}

Conclusion

To do

Personal tools