Lab 4 - HJ


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

a. Include your accelerometer read-out code in your write-up.

 /* 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

  x = analogRead(xPin);

  y = analogRead(yPin);

  z = analogRead(zPin);

 

  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

a. Upload a picture of your rotary encoder in action!


 

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.

 

3. Create your data logger!

/*

 * 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 addr = 0;

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;

 

byte readValue;

 

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

  if(analogRead(writeButtonPin) == 0){ 

    address = 0;

    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

    EEPROM.write(address, val);

    //go to next address

    address += 1;

    if(address == 1000) break;

    delay(500);

  }

 

  //if playButton pushed 

  if(analogRead(playbackButtonPin) == 0){  

    address = 0;

    readValue = EEPROM.read(address);

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

    address += 1;

    if(address == 1000) break;

    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;

  tmpdata = read_encoder();

  if( tmpdata) {

    counter4x += tmpdata;

    counter = counter4x/4;

    return counter;

  }

}

 

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

int read_encoder(){

  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

  ABab += 2*digitalRead(ENC_A)+digitalRead(ENC_B); //adds enc_a and enc_b values to bits 1 and 0

  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);

    }

 

}