Assignment 6 Update

With the wires back on the fan motor, I confirmed that code works in two ways: 1) when the humidity sensor detects that the average humidity is less than 50% the fan turns on, and 2) when the average humidity is less than 50% the fan turns off. Next, with condition 2 as the base conditions, I needed to test if the fan will turn on when the humidity sensor detects that the average humidity has increased to above 50%.

With my first version of the code, the fan was not responding the way I wanted to the humidity sensor readings.

This second version of the code using millis() was successful:

#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 2        // sensor DHT22 data connected to Arduino pin 2
#define DHTTYPE DHT22  // using sensor DHT22
DHT dht(DHTPIN, DHTTYPE);  //dht library
int chk;
int humid; //stores humidity


//data smoothing
const int numReadings = 5;
int humReadings [numReadings];
int humReadIndex = 0;
int humTotal = 0;
int humAverage = 0;
int inputPin = 2; //put dht 222 sensor pin here
//detecting sensor change
int last;
//response to sensor change


//for fan and motor
int speedPin = 5;
int dir1 = 4;
int dir2 = 3;
int mSpeed = 0;
unsigned long lastReadTime = 0;

void setup() {
  // put your setup code here, to run once:
  //pins for fan and motot
  pinMode(speedPin, OUTPUT);
  pinMode(dir1, OUTPUT);
  pinMode(dir2, OUTPUT);


  //dht sensor
  dht.begin();

//data smoothing for humidity
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    //tempReadings[thisReading] = 0;
    humReadings[thisReading] = 0;
  }
  Serial.begin(9600);

  lastReadTime = millis();
}

void loop() {
  //delay(1000);

  if ((millis() - lastReadTime) >= 10000UL) {
    //Serial.println(lastReadTime); //used to check millis 
    //Serial.println(millis());//used to check millis
    lastReadTime = millis();
    humid = dht.readHumidity();
    Serial.println(humid); //prints the current sensor reading
    humTotal = humTotal - humReadings[humReadIndex];
    humReadings[humReadIndex] = humid;
    humTotal = humTotal + humReadings [humReadIndex];
    humReadIndex = humReadIndex + 1;
    if (humReadIndex >= numReadings) {
      humReadIndex = 0;
    }
    humAverage = humTotal / numReadings;
    Serial.println(humAverage);

  }


  if (humAverage > 50)
  {
    digitalWrite(dir1, HIGH);
    digitalWrite(dir2, LOW);
    analogWrite(speedPin, 225);
  }else
  {
    digitalWrite(dir1,HIGH);
    digitalWrite(dir2,LOW);
    analogWrite(speedPin, 0);
  }
}

I started in a room with humidity readings less than 50 (no fan motion). I turned on hot water in the bathroom, and after a few minutes, moved the sensor and fan into that room. As the sensor’s humidity reading rose, so did the average humidity reading. Once the average humidity reading rose above 50, the fan began to turn. Then I moved the sensor and fan back into the original room, and waited for the average humidity to fall. When the average humidity fell below 50 again, the fan motor turned off.

Note on power and troubleshooting:

I originally had both the fan and the humidity sensor connected to the rail. This worked the first time I tried it, but the sensor began to send back 0 readings after a few test runs. I had to connect the DHT22 sensor to the arduino and the fan to the rail (with 5V power supply connected to 9V battery) for both the sensor and the fan to work properly. My clue was that the LED light on the power supply started bright and dimmed as the code started running.

Class Notes, 22 Feb 22

(mostly me talking today)

How to read a data sheet using L293 vs. tutorials

How would you do your project differently using a bridge?  Is coasting a useful feature?

How do interrupts work with motion?

How do state machines work with interrupts and motion?

Using chips to simply interrupts

Let’s say you have to interrupts, and you only care if both of them happen at the same time.   You could feed both inputs to an AND chip that we have in A10 and feed the output to a single input interrupt.  Likewise, if you have two inputs and you care if either one go off and will do the same thing for each, use an OR chip.

Use state variables to change solenoid / motor based on an interrupt

Talk about crits and elevator pitches.

Simple assignment

  • Verify that your Teensy boards are working and that you can download sketches.
  • Skim the Teensy 4.1 page and think about things you can do in future projects / crits.  Update Looking Out if you find something interesting using the Teensy chips in ixd projects.

 

Assignment 6 – Jud

Description:

This circuit turns the data that the sound sensor gets into an angle based off of a moving average of the amplitude of the data received. The data from the sensor captures the raw sound waves from the air and sends them to the arduino which has a very spiky and unsmooth nature. In addition, the data transitions for increasing to decreasing very rapidly so a traditional filter or tracking the change in the data does not work well at all. Instead, I have implemented a moving average method where the code tracks a certain number of data points, calculates the max and min of the data, and then uses the difference between these values as the new data. This is then multiplied by some multiplier to increase the variance and translated into an angle for a servo to travel to. The algorithm for calculating the angle works wonders while the servo isn’t connected, however, as depicted in the video, the noise of the servo creates an uncontrollable feedback look that results in the servo moving out of control. Regardless, the system responds to noise in the way that it should translating a noise in the environment into an angle for the servo to move to.

Video:

Code:

#include <Servo.h>

//Define Accelerometer Variables for pins
#define MICROPHONE    A0
#define SERVO_PIN     9

Servo servo;

double servoAngle = 0;

double alpha = 0.9;
double multiplier = 5;

//Array to hold data for moving average calculation
double speakerData[100]; // {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

double speakerLevel = 0;
double prevSpeakerLevel = 0;
double maxSpeakerLevel = 200;
double minSpeakerLevel = 50;


void setup() {
  //Setup pins as inputs
  pinMode(MICROPHONE, INPUT);

  //Create servo object
  servo.attach(SERVO_PIN);
  
}

void loop() {

  //Update moving average array
  for (int i = (sizeof(speakerData)/sizeof(speakerData[0]) - 1); i >= 0; i--) {
    if (i != 0) {
      speakerData[i] = speakerData[i - 1];
    }
    else {
      speakerData[i] = analogRead(MICROPHONE);
    }
  }

  double MIN = findMin();
  double MAX = findMax();

  speakerLevel = MAX - MIN;
  speakerLevel = multiplier*(alpha*speakerLevel + (1 - alpha)*prevSpeakerLevel);  //Filter data

  //Put upper and lower bounds on data
  if (speakerLevel >= maxSpeakerLevel) {
    speakerLevel = maxSpeakerLevel;
  }
  else if (speakerLevel <= minSpeakerLevel) {
    speakerLevel = minSpeakerLevel;
  }

  servoAngle = 180*(speakerLevel - minSpeakerLevel)/(maxSpeakerLevel - minSpeakerLevel);
  servo.write((int) servoAngle);

  prevSpeakerLevel = speakerLevel;
  
}

int findMin() {
  double minimum = 0;
  for (int i = 0; i < sizeof(speakerData)/sizeof(speakerData[0]); i++) {
    if (speakerData[i] < minimum || i == 0) {
      minimum = speakerData[i];
    }
  }
  return minimum;
}

int findMax() {
  double maximum = 0;
  for (int i = 0; i < sizeof(speakerData)/sizeof(speakerData[0]); i++) {
    if (speakerData[i] > maximum) {
      maximum = speakerData[i];
    }
  }
  return maximum;
}

 

thoughts on bearings

I watched the “Bearings” episode of the Secret Life of Components. The history was interesting- it makes sense that wood was used for a long time, but surprising to hear that the hardness plus the oil made tropic hardwoods like Ligum vitae a good choice and used up until the 1960s, even in submarines. He also reviews bearings made of brass, different types of plastic, and steel.

Interesting to learn about oil filled bronze and the process for making it- how did someone come up with that?

His demonstration of different levels of friction and friction reduction with ball races and roller bearings was neat. I had not known how a draw slide worked until I watched this.

Assignment 6 – James Kyle

Daylight Level Indicator:

For this assignment, I have made a theoretical daylight level sensor. The inspiration for this comes from my lab being in the basement of Ansys. We have no windows down there so I can easily get sucked into work and stay there for hours without realizing what time of day it is and/or whether it is time to pack up and call it a day. This daylight level indicator is meant to solve this problem by sensing the amount of daylight coming from outside and physically turning a dial to show the time of day. Theoretically, this dial would take the shape of a circle with night and day images on either side. The servo would turn to the appropriate position to indicate how close the sun is to setting or rising depending on the level of light outside and the time of day.

#include <Servo.h>


int hours = 0;

const int measurementNumber = 20;
int measurementCount = 0;
int lightMeasurements[measurementNumber];
const int lightLevel = A0; //Light level pin (photoresistor pin)

int lightBottomBound = 0;
int lightTopBound = 0;


Servo myServo;
int SERVOPIN = 9;



void setup() {

  pinMode(lightLevel, INPUT);

  myServo.attach(9);

}

void loop() {

  //Update measurement counter
  if (measurementCount < measurementNumber) {
    measurementCount += 1;
  } else {
    measurementCount = 0;
  }


  //Update light level average
  int lightLevelSum = 0;
  for (int i = 1; i < measurementNumber; i++) {
    lightLevelSum += lightMeasurements[i];
  }

  int lightLevelAverage = lightLevelSum / measurementNumber;



  //Update light level measurements
  int currentLightLevel = analogRead(lightLevel);
  lightMeasurements[measurementCount] = currentLightLevel;




  //Change bounds if light level is outside of bounds
  if (lightLevelAverage < lightBottomBound) {
    lightBottomBound = lightLevelAverage;
  }

  if (lightLevelAverage > lightTopBound) {
    lightTopBound = lightLevelAverage;
  }


  //Write to servo
  int servoAngle = map(lightLevelAverage, lightBottomBound, lightTopBound, 0, 180);
  myServo.write(servoAngle);


  delay(1000);

}

 

Assignment 6: Humidity Sensor and Fan

I decided to use smoothed humidity data from the DHT-22 sensor to turn a fan with DC motor on and off.

Code below combines DHT-22 data smoothing and motor response:

#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 2        // sensor DHT22 data connected to Arduino pin 2
#define DHTTYPE DHT22  // using sensor DHT22
DHT dht(DHTPIN, DHTTYPE);  //dht library 
int chk;
int humid; //stores humidity
int tempC; //stores temperature
int tempF; //stores temp in F
//data smoothing
const int numReadings = 10;
int tempReadings [numReadings];
int tempReadIndex = 0;
int tempTotal = 0;
int tempAverage = 0; 
int humReadings [numReadings];
int humReadIndex=0;
int humTotal = 0;
int humAverage = 0; 
int inputPin= 2; //put sensor pin here
//detecting sensor change
int last; 
//response to sensor change


//for fan and motor
int speedPin=5;
int dir1=4;
int dir2=3;
int mSpeed=0;

void setup() {
  // put your setup code here, to run once:
//pins for fan and motot
pinMode(speedPin,OUTPUT);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);


//dht sensor
dht.begin(); 

for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    tempReadings[thisReading]= 0;
    humReadings[thisReading]=0;



Serial.begin(9600);

}
}

void loop() {
  
  humid=dht.readHumidity();
  tempC=dht.readTemperature();
  delay(2000);
  
  humTotal = humTotal - humReadings[humReadIndex];
  humReadings[humReadIndex] = humid;
  humTotal = humTotal + humReadings [humReadIndex];
  humReadIndex = humReadIndex + 1;
  if (humReadIndex >= numReadings) {
    humReadIndex=0;
  }
  humAverage = humTotal / numReadings;
  
  if (humAverage>=50)
{
  digitalWrite(dir1,HIGH);
  digitalWrite(dir2,LOW);
  analogWrite(speedPin,255);
}

if (humAverage<50)
{
  analogWrite(speedPin,0);
}
}

I finished writing the code and set up the sensor and motor. Before I could test, the wire on the motor broke off. I will need to see if I can reattach or replace with materials in the IDEATE room. I will come to office hours tomorrow to review.

Course Notes, 17 Feb, 2022

How can we move things in a helpful, accessible way?

Why do things move?  How can we express emotion?

American Sign Language (ASL) is not English as we speak English, or like they speak in books.  (The wiki entry goes in to deep linguistic details.)

Emotional, artistic expression is done solely through movement.  These examples have audio for people who can’t read ASL:

ASL poetry Sign off Finals – “drop it like its hot”

Cardi B, Bodak Yellow ASL Interpretation

From “Hamilton:  Can you sign as fast as Daveed Diggs can rap? “Guns and Ships“.  “Alexander Hamilton” by a performance group with correct costumes.

ASL in entertainment

Troy Kotsur, a deaf actor, was hired to play a Tusken Raider and create their sign language.

Expression through artistic grammars

Bill Shannon has invented a new vocabulary for dance performed with canes.

Demo Using transistors and diodes

  • rotate a DC motor
  • use a solenoid
  • use a servo

Fritzing sketch, compressed with gzip: arduino-IRLB8721-simple.fzz

Assignment 5 – James Kyle

For this assignment, I tried taking in force readings from a force sensitive resistor (FSR) and displaying them in the Serial Monitor. I split the force readings into 3 groups so that it displays a visual indication of the amount of pressure with words. The data wasn’t very noisy so there was no need for smoothing it. I created a threshold evenly spaced between the highest and lowest values. I then displayed “High”, “Medium”, or “Low” depending on the regime the pressure was in.