• If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

View

# Lab 4 - HJ

last edited by 7 years, 1 month ago

Part A.  Writing to the Serial Monitor

a. Based on the readings from the serial monitor, what is the range of the analog values being read?

0 - 1023

b. How many bits of resolution does the analog to digital converter (ADC) on the Atmega32U4 have (hint: where might you look to find this sort of thing)? How many are you using with the range of values you're seeing?

10 bits (found in data sheet at http://www.atmel.com/Images/7766s.pdf)

10 bits corresponds to a max value of 2^10 = 1024, and the range of values is 0 – 1023, so all values are being used.

Part B. Voltage Varying Sensors

1. IR Distance Sensor

a. Describe the voltage change over the sensing range of the sensor. A sketch of voltage vs. distance would work also. Does it match up with what you expect from the datasheet?

When something is close to the sensor, the output voltage is very high. If the object is put even closer to the sensor, the voltage drops rapidly. As the object is moved further away, the voltage drops off quickly as well. When nothing is in range of the sensor, the output voltage jumps around low values. This behavior is as expected from the datasheet graph.

2. Accelerometer

/* This program prints the readings from the X, Y, and Z

values of an accelerometer to a 16x2 LCD display.

The circuit:

* LCD RS pin to digital pin 12

* LCD Enable pin to digital pin 11

* LCD D4 pin to digital pin 5

* LCD D5 pin to digital pin 4

* LCD D6 pin to digital pin 3

* LCD D7 pin to digital pin 2

* LCD R/W pin to ground

* 10K resistor:

* ends to +5V and ground

* wiper to LCD VO pin (pin 3)

*Accelerometer with...

*G to ground

*Vin to 3V

*X0 to A3     //analog 3 = x-axis

*Y0 to A2     //analog 2 = y-axis

*Z0 to A1     //analog 1 = z-axis

*/

// include the library code:

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int xPin = A3;

const int yPin = A2;

const int zPin = A3;

//ints to store the x, y, and z values

int x;

int y;

int z;

void setup() {

// set up the LCD's number of columns and rows:

lcd.begin(16, 2);

}

void loop() {

//set axis values

lcd.display(); //turn on display

lcd.setCursor(0,0);

lcd.print("X:");

lcd.print(x);

lcd.setCursor(6,0);

lcd.print("Y:");

lcd.print(y);

lcd.setCursor(0,1);

lcd.print("Z:");

lcd.print(z);

delay(500);

}

Part C. Count/Time-Based Sensors

1. Rotary Encoder Part D. Logging values to the EEPROM and reading them back

a. Turn in a copy of your final state diagram. 2. Reading and writing values to the EEPROM

a. How many byte-sized data samples can you store on the Atmega32U4?

1 K bytes (http://www.atmel.com/Images/7766s.pdf)

b. How would you get your analog data from the ADC to be byte-sized?

To become byte-sized, the analog data must be changed in range from 10 bits to 8 bits, meaning the values from 0 – 1023 (2^10 = 1024) should correspond to values from 0 – 255 (2^8 = 256). We could do this by dividing the data from the ADC by 4.

/*

* Allows input from a rotary encoder to be stored in EEPROM.

* Each value from the rotary encoder corresponds to one of

* 6 LEDs to be lit up.

* The stored values can be used to play back even after

* the board is turned off, as well.

* Record and play are each determined by a button.

*/

#include <EEPROM.h>

//rotary encoder pins

#define ENC_A 0 //digital input pins

#define ENC_B 1

// the current address in the EEPROM (i.e. which byte

// we're going to write to next)

int yLedPin1 = 10;

int yLedPin2 = 6;

int gLedPin1 = 9;

int gLedPin2 = 13;

int rLedPin1 = 8;

int rLedPin2 = 7;

int writeButtonPin = A0;

int playbackButtonPin = A1;

boolean writeButtonPushed = false;

boolean playButtonPushed = false;

void setup()

{

/* Setup encoder pins as inputs */

pinMode(ENC_A, INPUT_PULLUP);

pinMode(ENC_B, INPUT_PULLUP);

pinMode(yLedPin1, OUTPUT);

pinMode(yLedPin2, OUTPUT);

pinMode(gLedPin1, OUTPUT);

pinMode(gLedPin2, OUTPUT);

pinMode(rLedPin2, OUTPUT);

pinMode(rLedPin2, OUTPUT);

}

void loop()

{

//if write button is pushed

writeButtonPushed = true;

int counter = getCount(); //Rotary Encoder returns anything from 0 to 16383

int value = counter/65; //need a number < 255, and 16383/65 with integer math = 255

delay(500);

}

//if playButton pushed

playLightPattern(readValue); //counter/65 gives a value between 0 and 252 (needed< 255)

delay(500);

}

}

int getCount(){

static unsigned int counter4x = 0; //the SparkFun encoders jump by 4 states from detent to detent

static unsigned int counter = 0;

static unsigned int prevCounter = 0;

int tmpdata;

if( tmpdata) {

counter4x += tmpdata;

counter = counter4x/4;

return counter;

}

}

/* returns change in encoder state (-1,0,1) */

static int enc_states[] = {

0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0  };

static byte ABab = 0;

ABab *= 4;                   //shift the old values over 2 bits

ABab = ABab%16;      //keeps only bits 0-3

return ( enc_states[ABab]);

}

void playLightPattern(int remainder){

if(remainder >= 0 && remainder <= 41){

digitalWrite(yLedPin1, HIGH);

pause(500);

digitalWrite(yLedPin1, LOW);

}

else if(remainder >= 42 && remainder <= 83){

digitalWrite(gLedPin1, HIGH);

pause(500);

digitalWrite(gLedPin1, LOW);

}

else if(remainder >= 84 &&  remainder <= 125){

digitalWrite(rLedPin1, HIGH);

pause(500);

digitalWrite(rLedPin1, LOW);

}

else if(remainder >=126 && remainder <= 167){

digitalWrite(rLedPin2, HIGH);

pause(500);

digitalWrite(rLedPin2, LOW);

}

else if(remainder >= 168 && remainder <= 209){

digitalWrite(yLedPin2, HIGH);

pause(500);

digitalWrite(yLedPin2, LOW);

}

else if(remainder >= 210 && remainder <= 252){

digitalWrite(gLedPin2, HIGH);

pause(500);

digitalWrite(gLedPin2, LOW);

}

}