Assignment 1

My goal with this code was to make something that would measure temperature and light using a thermistor sensor and a photo sensor. I then coded in a servo motor whose rotational speed would vary based on light/temperature. I was thinking of this as a sort of electric fan that varies in speed based on the conditions of the room it is placed in. I used the code we went over in class, with adjustments, to “accomplish” this. My issue is that it’s not actually accomplished.

The code compiles, and it “uploads” to my board via my computer, but the sensors don’t respond and I keep getting error messages from my computer ex.  (every time I upload)

and  which I’ve never seen before,

and apparently the internet is as confused as I am.

I then tried taking the servo code out, and just running for the two sensors using the on-board neopixel as an output, with the same results. And apparently my computer has the same problem with the code we went over in class. Seeing as the deadline is about 15 min. away, and I’m not sure if my code or my wiring is wrong or if my computer is just being weird, I figured I’d upload the code and the wiring and re-upload past the deadline when I figure out what went wrong.

 

The servo one (with diagram):     photo_servo

The neo pixel one: photo_therm

 

Assignment 1

Circuit: The circuit in two modes i.e. photoresistor and thermistor mode. The wires can be interchanged or the pins can be changed in the code to alter the input sensor. After calibration, I use a library(https://playground.arduino.cc/Main/QuickStats) to find the median which assigns the value to the output pin via analogWrite. The library also gives access to other stats.

CODE: https://drive.google.com/open?id=1tP_MSYRrJdPCSbaLjyjgEVYBWCxyLu0I

/* basic stats with analogRead()
*
* intputs
* A0 photoresitor / A3 thermistor
*
* output
* D13 LED (Debugging)
* A9 LED (Output)
* Serial stats output
*
* Auto caliberates in the first 5 seconds (press/cover the sensor)
*
*/
// using library from https://playground.arduino.cc/Main/QuickStats
#include "QuickStats.h"
int NUMSAMPLES=10; // number of samples to take for data smoothing
float measurements[10];
const int analogInPin = A0; // Analog input A0 for photoresistor and A1 for thermistor
const int analogOutPin = 9; // Analog output pin that the LED is attached to

int sensorValue = 0; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)

QuickStats stats; //initialize an instance of this class

// Min and Max sensor values

int sensorMin = 1023; // minimum sensor value
int sensorMax = 0; // maximum sensor value
float sensorMinF = 0.1;
float sensorMaxF = 0.0;
float smoothed = 0.0;

void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
caliberate();

}

// concept borrowed from https://www.arduino.cc/en/Tutorial/Calibration
void caliberate()
{
Serial.println("Caliberating ");
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

while (millis() < 5000) { sensorValue = analogRead(analogInPin); // record the maximum sensor value if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}

// record the minimum sensor value
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}

sensorMin-= 10;
sensorMax+=10;

// volts * 10 for the thermistor to work

sensorMinF = (50.0*(float)sensorMin/1023.0);
sensorMaxF = (50.0*(float)sensorMax/1023.0);
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

}

void printStats()
{
Serial.println("Descriptive Statistics");
Serial.print("Mean : ");
Serial.println(stats.average(measurements,NUMSAMPLES));
Serial.print("Minimum: ");
Serial.println(stats.minimum(measurements,NUMSAMPLES));
Serial.print("Maximum: ");
Serial.println(stats.maximum(measurements,NUMSAMPLES));
Serial.print("Standard Deviation: ");
Serial.println(stats.stdev(measurements,NUMSAMPLES));
Serial.print("Standard Error: ");
Serial.println(stats.stderror(measurements,NUMSAMPLES));
Serial.print("Coefficient of Variation (%): ");
Serial.println(stats.CV(measurements,NUMSAMPLES));
Serial.print("Median: ");
Serial.println(stats.median(measurements,NUMSAMPLES));
Serial.print("Mode: ");
Serial.println(stats.mode(measurements,NUMSAMPLES,0.00001));
}

void loop() {

for(int i=0;i<NUMSAMPLES;i++){
sensorValue = analogRead(analogInPin);
measurements[i]=(5.0*(float)sensorValue/1023.0); // convert to volts
delay(5); // Change (or remove) this delay value to alter the sampling time span.
}
smoothed=stats.median(measurements,NUMSAMPLES); // Median filter (choose which filter to use)

// caliberating for thermistor (low values)
outputValue = map(smoothed*10, sensorMinF, sensorMaxF, 0, 255);
outputValue = constrain(outputValue, 0, 255);

Serial.println(smoothed,3); // Print smoothed value to serial monitor
Serial.print("min: ");
Serial.print(sensorMinF); // Print min value to serial monitor
Serial.print(", max: ");
Serial.print(sensorMaxF); // Print max value to serial monitor
Serial.print(", ");
Serial.println(sensorValue);
Serial.print("\t output = ");
Serial.println(outputValue);

analogWrite(analogOutPin, outputValue);
printStats();
delay(250); // Change (or remove) this delay to alter the time between readings.
}

Link to picture: https://docs.google.com/document/d/1W2unaggIEvyaNUqzIg3yzXc4pTtWhLolyvhvZdAdMLc/edit

Circuit diagram borrowed from: https://learn.adafruit.com/experimenters-guide-for-metro/circ09-wiring 

Assignment One

Serial “Hot or Cold”

The first code combines the stat code we learned in class with an ultrasonic sensor to play an alternate version of the game “Hot or Cold.” The closer to the sensor, the hotter. The further away, the colder. It prints the results to serial.

VIDEO LINK password: MakingThingsInteractive

//--------NEOPIXEL SETUP --------
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
static const int PIN = 40;
static const int NUMPIXELS = 1;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);

//--------ULTRASONIC PINS--------
static const int trigPin = A0;
static const int echoPin = A1;

//--------SAMPLE ARRAY--------
static const int sampleSize = 30;
int readings[sampleSize];
unsigned int sampleIndex = 0;

//--------TIME--------
unsigned long lastSampleTime = 0;
unsigned long sampleInterval = 100; // in ms
// we need to move these out of the loop() as well

//--------STATS--------
unsigned int median = 0;
unsigned int low = 0;
unsigned int high = 0;
unsigned int mean = 0;

//--------LIGHTS--------
static const int statusLed = 13;
unsigned int lastRedVal = 0;

void setup() {
 Serial.begin(9600);

pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(statusLed, OUTPUT);

pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {

//--------SENDING OUT THE SIGNAL--------
 long duration, distance;
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = duration / 29 / 2 ; //CENTIMETERS

// TODO what happens if you try to set a negative color?
 unsigned int redVal = 0;

// TODO
 // don't read the input on every loop to help stabilize the data
 // sampling over time is also a UI change, you have to actively
 // block light for
 // sampleSize * sampleInterval milliseconds to create a change

unsigned long now = millis();
 if (lastSampleTime + sampleInterval < now) {
 lastSampleTime = now;

// good for debugging:
 // Serial.print(now);
 // Serial.print(" ");
 //
 // Serial.println(distance);

readings[sampleIndex] = distance;
 sampleIndex < (sampleSize - 1) ? sampleIndex++ : sampleIndex = 0;

//digitalWrite(photoPin, HIGH);
 for (int i = 0; i < sampleSize; i++) {
 mean += readings[i];
 if (readings[i] < low) {
 low = readings[i];
 }
 if (readings[i] > high) {
 high = readings[i];
 }
 }

if (distance > 120) {
 Serial.println ("Frozen");
 Serial.println(" ");
 } else if (distance < 120 && distance > 70) {
 Serial.println ("Ice Cold");
 Serial.println(" ");
 } else if (distance < 70 && distance > 40) {
 Serial.println ("Pretty Cold");
 Serial.println(" ");
 } else if (distance < 40 && distance > 20) {
 Serial.println ("Cool...");
 Serial.println(" ");
 } else if (distance < 20 && distance > 15) {
 Serial.println ("Warmer...");
 Serial.println(" ");
 } else if (distance < 15 && distance > 11) {
 Serial.println ("Things are heating up!");
 Serial.println(" ");
 } else if (distance < 11 && distance > 6) {
 Serial.println ("HOT");
 Serial.println(" ");
 } else if (distance < 6 && distance > 2) {
 Serial.println ("On. Fire.");
 Serial.println(" ");
 } else {
 Serial.println (distance);
 Serial.println(" ");
 }

mean = mean / sampleSize;
 bubbleSort();
 median = readings[sampleSize / 2];
 }

redVal = map(median, 2, 150, 0, 200);

int tolerance = 3;

// This looks like it should work, right?
 // what happens if lastRedVal is 0?
 if (
 (redVal > (lastRedVal + tolerance)) || (redVal < (lastRedVal - tolerance))
 ) {

pixels.setPixelColor(0, pixels.Color(redVal, 0, 0));
 pixels.show(); // This sends the updated pixel color to the hardware.
 lastRedVal = redVal;
 }
}


// tigoe's sort for an array
void bubbleSort() {
 int out, in, swapper;
 for (out = 0 ; out < sampleSize; out++) { // outer loop
 for (in = out; in < (sampleSize - 1); in++) { // inner loop
 if ( readings[in] > readings[in + 1] ) { // out of order?
 // swap them:
 swapper = readings[in];
 readings [in] = readings[in + 1];
 readings[in + 1] = swapper;
 }
 }
 }
}

Finding the balance

I wanted to use the values to inform color–both red and blue values. Using mapping to reverse the color values of 0-255, the more light you let in, the LED becomes more red, the less light…blue. However, if you hover in the middle and find the balance between the two values, within 10. This causes the LED to blink.

VIDEO LINK password: MakingThingsInteractive

// -*-c++-*-
/*
 The MIT License (MIT)

Copyright (c) 2014 J. Eric Townsend

Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
*/

/* basic stats with analogRead()

intputs
 A0 photoresitro

output
 D13 LED
 40 NEOPIXEL

*/

#include <Adafruit_NeoPixel.h>

#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 40
#define NUMPIXELS 1
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);

static const int photoPin = 0;
static const int sampleSize = 16;
int readings[sampleSize];
int sampleIndex = 0;

static const int statusLed = 13;
int lastRedVal = 0;

void setup() {
 Serial.begin(115200);

pinMode(photoPin, INPUT);

pinMode(statusLed, OUTPUT);

pixels.begin(); // This initializes the NeoPixel library.
}

void loop() {


 int photo = analogRead(photoPin);
 readings[sampleIndex] = photo;
 sampleIndex < (sampleSize - 1) ? sampleIndex++ : sampleIndex = 0;

digitalWrite(photoPin, HIGH);
 // Serial.println(photo);
 int median = 0;
 int low = 1024;
 int high = 0;
 int mean = 0;
 for (int i = 0; i < sampleSize; i++) {
 mean += readings[i];
 if (readings[i] < low) {
 low = readings[i];
 }
 if (readings[i] > high) {
 high = readings[i];
 }
 }
 mean = mean / sampleSize;
 bubbleSort();
 median = readings[sampleSize / 2];

int redVal = map(median, 40, 1023, 0, 100);
 int blueVal = map(median, 40, 1023, 100, 0);

Serial.print ("redVal = ");
 Serial.println (redVal);
 Serial.print ("blueVal = ");
 Serial.println (blueVal);

// use a tolerance to limit to a range
 // by making this not a const we can change it in the code
 // as needed

int tolerance = 3;

// This looks like it should work, right?
 // what happens if lastRedVal is 0?
 if (
 (redVal > (lastRedVal + tolerance))
 || (redVal < (lastRedVal - tolerance))
 ) {

pixels.setPixelColor(0, pixels.Color(redVal, 0, blueVal));
 pixels.show(); // This sends the updated pixel color to the hardware.
 lastRedVal = redVal;
 }

//----Difference code http://forum.arduino.cc/index.php?topic=105383.0 
 int difference = redVal - blueVal;

difference = abs(difference); // 'abs' is the absolute value, the result is always positive.
 Serial.println (difference);
 if (difference < 10) { // it's always higher or equal than zero
 pixels.setPixelColor(0, pixels.Color(redVal, 0, blueVal));
 pixels.show();
 delay(200);
 pixels.setPixelColor(0, 0, 0, 0);
 pixels.show();
 delay(200);
 }
 else {
 pixels.setPixelColor(0, pixels.Color(redVal, 0, blueVal));
 }

}


// tigoe's sort for an array
void bubbleSort() {
 int out, in, swapper;
 for (out = 0 ; out < sampleSize; out++) { // outer loop
 for (in = out; in < (sampleSize - 1); in++) { // inner loop
 if ( readings[in] > readings[in + 1] ) { // out of order?
 // swap them:
 swapper = readings[in];
 readings [in] = readings[in + 1];
 readings[in + 1] = swapper;
 }
 }
 }
}

Assignment Two Zip Files

Assignment 1

This is my assignment 1 for Making Things Interactive. The goal was to return statistics from two different analog sensors. My method was creating two separate arrays and averaging the statistics.


// -*-c++-*-
/*
The MIT License (MIT)

Copyright (c) 2014 J. Eric Townsend

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
static const int SENSORPIN = A0;
static const int SENSORPIN2 = A3;
static const int sampleSize = 16;
unsigned int readings[sampleSize];
unsigned int readings2[sampleSize];
unsigned int sampleIndex = 0;

static const int statusLed = 13;

void setup() {
    Serial.begin(115200);

    pinMode(SENSORPIN, INPUT);
   
    pinMode(SENSORPIN2, INPUT);
   
    pinMode(statusLed, OUTPUT);
}

void loop() {

    int photo = analogRead(SENSORPIN);
    int photo2 = analogRead(SENSORPIN2);
    readings[sampleIndex] = photo;
    readings2[sampleIndex] = photo2;

    if (sampleIndex &lt; (sampleSize -1)) {
        sampleIndex++;
    }
    else {
      sampleIndex = 0;
    }

    int median = 0;
    int low = 1024;
    int high = 0;
    int mean = 0;
    for (int i = 0; i &lt; sampleSize; i++) {
        mean += (readings[i] + readings2[i]);
        if (readings[i] &lt; low) {
            low = readings[i];
        }
        if (readings2[i] &lt; low) { low = readings2[i]; } if (readings[i] &gt; high) {
            high = readings[i];
        }
        if (readings2[i] &gt; high) {
            high = readings2[i];
        }
    }
    mean = mean / (sampleSize * 2);
    bubbleSort();
    median = (readings[sampleSize / 2] + readings2[sampleSize / 2] ) / 2;

// Range, mean, and median
    Serial.print("(");
    Serial.print(low);
    Serial.print(",");
    Serial.print(high);
    Serial.print(")");
    Serial.print(",");
    Serial.print(mean);
    Serial.print(",");
    Serial.println(median);

}

// tigoe's sort for an array
void bubbleSort() {
  int out, in, swapper;
  for(out=0 ; out &lt; sampleSize; out++) {  // outer loop
    for(in=out; in&lt;(sampleSize-1); in++) { // inner loop if( readings[in] &gt; readings[in+1] ) {   // out of order?
        // swap them:
        swapper = readings[in];
        readings [in] = readings[in+1];
        readings[in+1] = swapper;
      }
    }
  }
}

 

 

 

 

Assignment 1 – Smoothing

 

 

For the software, my main goal is to modulize the requests or organization for information into separate functions. One function receives the current value from the sensor. A second function calls the initial function, and places the value into an array for the number of times, variable sampleSize. A third function iterates through the array and returns the mean of all values. The different function can be called to view the sample value in an organized table.
Code:

dataSmoothing-jan23

//Ty Van de Zande
//Simple Data Average
static const int sampleSize = 160;
int readings[sampleSize];
int sampleIndex = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
//straightData();
//buildArray();
//printArray();
meanArray();
delay(10);
}
// Averages samples array to output mean
int meanArray(){
int mean = buildArray();
mean = mean / sampleSize;
Serial.print("Mean: ");
Serial.println(mean);
return mean;
}
// Prints readings array in a nice format
void printArray(){
buildArray();
for(int i = 0; i&lt;sampleSize; i++){
Serial.print("||");
Serial.print(readings[i]);
}
Serial.println();
}
// Fills readings array with data from the sensor
int buildArray() {
int sum = 0;
for (int i = 0; i &lt; sampleSize; i++){
readings[i] = straightData();
sum += readings[i];
}
return sum;
}
// Live feed of data from sensor
int straightData(){
int tempIn = analogRead(A6);
//Serial.println(tempIn);
return tempIn;
}

Assignment 1: Basic Stats

Assignment 1: Basic Stats

Post Arduino sketch + Fritzing diagram to the blog by 23:59 Monday, 22 Jan 18.  No video or photos are needed, we’ll look at the sketches during the start of class.

Using two different analog sensors, read values and report on statistics. Do this over time, showing how collecting more analogRead() data in an array allows you to better refine the results for these operations
– mean
– median
– range, min and max values
– outlier (bonus points)
– standard deviation (bonus points)
– change sensor reading rate and sample size to change the interaction
More Bonus points! How can you take these results then modify your sketch to improve the results when it’s moved from one room to another? How can I decide between A10 or my house?