A lab report by Zwee Dao.
Include your responses to the bold questions on your own fork of this lab report template. Include snippets of code that explain what you did. Deliverables are due next Tuesday. Post your lab reports as README.md pages on your GitHub, and post a link to that on your main class hub page.
For this lab, we will be experimenting with a variety of sensors, sending the data to the Arduino serial monitor, writing data to the EEPROM of the Arduino, and then playing the data back.
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 Arduino have? 10 bits
How might you use this with only the parts in your kit? Show us your solution. Just simply connect the 4 legs of RGB LED with proper ports. RGB led video
a. What voltage values do you see from your force sensor? 4.5V
b. What kind of relationship does the voltage have as a function of the force applied? (e.g., linear?) The graph looks kind of linear. The more force I apply, the more voltage value.
c. Can you change the LED fading code values so that you get the full range of output voltages from the LED when using your FSR?
I normalize the FSR values to be in the same range as LED values: brightness = analogRead(A0)\*255/1024;
FSR controlling LED video
int led = 9; // the PWM pin the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
void setup() {
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
// initialize the serial communication:
Serial.begin(9600);
}
void loop() {
Serial.println(analogRead(A0));
// change the brightness for next time through the loop:
brightness = analogRead(A0)\*255/1024;
analogWrite(led, brightness);
delay(30);
}
d. What resistance do you need to have in series to get a reasonable range of voltages from each sensor? A 27k ohm resitance seems to produce a reasonable range.
e. What kind of relationship does the resistance have as a function of stimulus? (e.g., linear?) It seems to be linear.
a. LED: Include your accelerometer read-out code in your write-up.
// Basic demo for accelerometer readings from Adafruit LIS3DH
#include
#include
#include
#include
#include
// initialize the LCD with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Used for software SPI
#define LIS3DH_CLK 13
#define LIS3DH_MISO 12
#define LIS3DH_MOSI 11
// Used for hardware & software SPI
#define LIS3DH_CS 10
// software SPI
//Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS, LIS3DH_MOSI, LIS3DH_MISO, LIS3DH_CLK);
// hardware SPI
//Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS);
// I2C
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
void setup(void) {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("Hello Zwee");
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
Serial.println("LIS3DH test!");
if (! lis.begin(0x18)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
Serial.print("Range = "); Serial.print(2 << lis.getRange());
Serial.println("G");
}
void loop() {
lis.read(); // get X Y and Z data at once
// Then print out the raw data
Serial.print("X: "); Serial.print(lis.x);
Serial.print(" \tY: "); Serial.print(lis.y);
Serial.print(" \tZ: "); Serial.print(lis.z);
/* Or....get a new sensor event, normalized */
sensors_event_t event;
lis.getEvent(&event);
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
Serial.print(" \tY: "); Serial.print(event.acceleration.y);
Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
Serial.println(" m/s^2 ");
Serial.println();
print_lcd("X Y Z",String(lis.x)+' '+String(lis.y)+' '+String(lis.z));
delay(200);
}
void print_lcd(char line_1[], String line_2)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line_1);
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print counter value
lcd.print(line_2);
}
a. OLED: Include your accelerometer read-out code in your write-up.
#include
#include
#include
#include
#include
#include
// Used for software SPI
#define LIS3DH_CLK 13
#define LIS3DH_MISO 12
#define LIS3DH_MOSI 11
// Used for hardware & software SPI
#define LIS3DH_CS 10
// software SPI
//Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS, LIS3DH_MOSI, LIS3DH_MISO, LIS3DH_CLK);
// hardware SPI
//Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS);
// I2C
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define NUMFLAKES 10 // Number of snowflakes in the animation example
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000 };
void setup() {
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
Serial.println("LIS3DH test!");
if (! lis.begin(0x18)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
Serial.print("Range = "); Serial.print(2 << lis.getRange());
Serial.println("G");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
// Show the display buffer on the screen. You MUST call display() after
// drawing commands to make them visible on screen!
// display.display() is NOT necessary after every single drawing command,
// unless that's what you want...rather, you can batch up a bunch of
// drawing operations and then update the screen all at once by calling
// display.display(). These examples demonstrate both approaches...
display.display();
delay(2000); // Pause for 2 seconds
}
void loop() {
// Read accelormeter
lis.read(); // get X Y and Z data at once
// Then print out the raw data
Serial.print("X: "); Serial.print(lis.x);
Serial.print(" \tY: "); Serial.print(lis.y);
Serial.print(" \tZ: "); Serial.print(lis.z);
/* Or....get a new sensor event, normalized */
sensors_event_t event;
lis.getEvent(&event);
//Print text
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(WHITE); // Draw white text
display.setCursor(0,0); // Start at top-left corner
//display.println(F("Hello, world!"));
display.println(String(lis.x)+' '+String(lis.y)+' '+String(lis.z));
display.display();
delay(200);
}
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?
b. Upload your merged code to your lab report repository and link to it here.
Take a picture of your screen working insert it here!
a. Does it matter what actions are assigned to which state? Why? Yes, the sequence of states matter. Because the potential metter will turn in certain direction.
b. Why is the code here all in the setup() functions and not in the loop() functions? We don't need to constantly loop, just need to set it once.
c. How many byte-sized data samples can you store on the Atmega328? 512 bytes
d. How would you get analog data from the Arduino analog pins to be byte-sized? How about analog data from the I2C devices? Divides the reading by 4.
e. Alternately, how would we store the data if it were bigger than a byte? (hint: take a look at the EEPROMPut example) Move storage address to the next byte after float 'f':
eeAddress += sizeof(float);
Upload your modified code that takes in analog values from your sensors and prints them back out to the Arduino Serial Monitor.
/*
basic state machine 2
Modified to switch between states to write, read and clear EEPROM
Demonstrates how to use a case statement to create a simple state machine.
This code uses a potentiometer knob to select between 3 states.
The circuit:
* pot from analog in 0 to +5V
* 10K resistor from analog in 0 to ground
created 13 Apr 2010
by Wendy Ju
modified from switchCase by Tom Igoe
12 Sep 2018
Modified to switch between states to write, read and clear EEPROM
*/
#include
const int numStates = 3;
const int sensorMin =0;
const int sensorMax = 1024;
const int EEPROMSIZE=1024;
int sensorPin = A3; // select the input pin for the potentiometer
int ledPin = LED_BUILTIN;
int state,lastState = -1;
void setup() {
// initialize serial communication:
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
// map the pot range to number of states :
state = map(analogRead(sensorPin), sensorMin, sensorMax, 0, numStates);
// do something different depending on the
// range value:
switch (state) {
case 0:
doState0();
break;
case 1:
doState1();
break;
case 2:
doState2();
break;
}
lastState = state;
}
a. Insert here a copy of your final state diagram. State diagram
a. Record and upload a short demo video of your logger in action. Data logger video