Assignment 5 – Jud

The idea for this sensor reading is to read the noise level in a room and detect whether it would be damaging to someone’s hearing. For the average human ear, a sustained noise level over 70dB or a burst of sound over 120dB can cause harm to the human ear. In order to counteract this, I used a speaker sensor connected to an Arduino to read the noise level in a room and decide whether either of these conditions have been met. If they have then an LED would turn on. So far I have gotten the speaker to read data but I haven’t been able to translate this data into decibels at the moment. The sensor I am currently using measures the noise level in its output by varying the signal to a degree relative to the amount of noise being detected. So if there is a high noise level, the sensor gives data that looks like the following:

If there is a low noise output, the data looks more uniform like a straight line.

I attempted to write a script that would look at the change in this data and use a filter to smooth the delta calculation but this didn’t work very well when I tried it out. My next idea would be to take a moving average of the data over time and then take the max and min of that range as the magnitude of the noise level. With this magnitude, it could then be converted into decibels through tuning of an equation.

//Define Accelerometer Variables for pins
#define MICROPHONE   A0

double speakerLevel = 0;
double prevSpeakerLevel = 0;
double delta = 0;
double prevDelta = 0;

double alpha = 0.8;


void setup() {
  //Setup pins as inputs

  pinMode(MICROPHONE, INPUT);
  
  Serial.begin(9600);

}

void loop() {

  speakerLevel = analogRead(MICROPHONE);
  delta = abs(speakerLevel - prevSpeakerLevel);

  speakerLevel = alpha*speakerLevel + (1-alpha)*prevSpeakerLevel;

  delta = alpha*delta + (1-alpha)*prevDelta;

  prevDelta = delta;
  
  Serial.println(speakerLevel);
//  Serial.println(delta);
  
}

 

 

Assignment 5: Smoothing Sensor Data

For assignment 5, I sampled temperature and humidity data points from the DHT22 sensor to create average temperature and humidity values. I used the serial monitor within Arduino IDE to follow changes in values and added characters to distinguish visually between temperature, temperature average, humidity, and humidity averages within the serial monitor.

Then I used the values from the average temperature (with an average of 10 data points) to calculate a temperature change over a period of values.  If the temperature change was greater than 3 degrees within the specified sampling period, the ‘alarm’ (an LED light) would turn on. It would turn off again when the temperature change fell below 3 degrees.

The limitations of this method are that slow and steady change in one direction to an average may not be detected. The data smoothing is desirable to avoid ‘blips’ from occurring, but it may be preferable for environmental alarms (temperature, smoke, etc) to compare their average sampling to a constant value that reflects the preferred conditions – not only a rapid change in values. As observed in the paragraph above, when using this technique, the ‘alarm’ turns off if the temperature change falls back below the threshold of acceptable change. This may or may not be desirable, depending on the response needed.

Final Code:

#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
//based on https://docs.arduino.cc/built-in-examples/analog/Smoothing 
//include dht library 
//note this tutorial is for analog sensors not digital like the dht22

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

//const char tNow="Temperature: ";
//const char tAvg="Average Temperature: "; 

//4 lines below only print T, A, H, and v
const char*tempNow="Temperature: ";
const char*tempAvg="Average Temperature: ";
const char *huNow="Humidity: ";
const char *huAvg="verage Humidity: ";

//detecting sensor change
int last; 

//response to sensor change
int blueled=10;

void setup() {

  // put your setup code here, to run once:
  Serial.begin(9600);
  dht.begin(); 

  //for response to sensor change
  pinMode(blueled,OUTPUT);

  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    tempReadings[thisReading]= 0;
    humReadings[thisReading]=0;
    //placing humreadings below temp readings does not appear to work
    //humReadings[thisReading]=0;
  //for (int hThisReading = 0; hThisReading < numReadings; hThisReading++) {
    //humReadings[hThisReading]= 0;

  }

}

void loop() {
  // put your main code here, to run repeatedly:

humid=dht.readHumidity();
tempC=dht.readTemperature();
//tempF=(tempC*1.8)+32;
//Serial.write(tempC);
delay(2000);
//delay needed for p5js to recieve 2 values separately
//Serial.write(humid);
//delay(1000);

  tempTotal = tempTotal - tempReadings[tempReadIndex];
  //need 2 reads start with one use temp
  tempReadings[tempReadIndex] = tempC;
  tempTotal = tempTotal + tempReadings [tempReadIndex];
  tempReadIndex = tempReadIndex + 1; 

  if (tempReadIndex >= numReadings) {
    tempReadIndex = 0; 
   
  }

  tempAverage = tempTotal / numReadings;

  humTotal = humTotal - humReadings[humReadIndex];
  humReadings[humReadIndex] = humid;
  humTotal = humTotal + humReadings [humReadIndex];
  humReadIndex = humReadIndex + 1;


  if (humReadIndex >= numReadings) {
    humReadIndex=0;
  }

  humAverage = humTotal / numReadings;


//printing to serial monitor

  //const char* pNowTemp = tNow + tempC;
  //const char* pAvgTemp = tAvg + tempAverage;
  //setDisplayToString(pNowTemp);
  //tempAverage.setDisplayToString(pAvgTemp);
  //Serial.print(f'Avg: ');
  
  //one line below printed just A
  Serial.print(*tempAvg);
  Serial.println(tempAverage);
 
  //Serial.print(F('Average temperature {tempAverage}'));
  //Serial.print(F('Average temperature:'));
  //Serial.println(tempAverage);

  //Serial.println(pNowTemp);
  delay(5);

  //two lines below printed just T 
  Serial.print(*tempNow);
  Serial.println(tempC);

  //Serial.println(pAvgTemp);

  delay(5);

  Serial.print(*huAvg);
  Serial.println(humAverage);

  Serial.print(*huNow);
  Serial.println(humid);

  delay(5);

//measuring change in temperature average
  int t = tempAverage;
  int tdiff = t-last;
  int thresh = 1;
  Serial.println(tdiff);
  //this statement could be simplified, need to do it for all tdiff values 
  if(tdiff>thresh||tdiff<=thresh){
    Serial.println(t);
    last=t;



//led response to rate of change in temperature average
 if (tdiff>=3)
  {
    digitalWrite(blueled,HIGH);

  }
if(tdiff<3)
  {
  digitalWrite(blueled,LOW);
 }
  }


  
  

}

Process Notes:

Identifying Change in Average Temperature Value

Printing Change in Average Temperature Value

LED on/off with Changes in Average Temperature Value

 

LED doesn’t turn off when Change in Average Temperature = 0

Solution: Turning Off LED when Change = 0

 

 

Assignment 5: smooth and parse data then display a result

Take physical input over time from sensor(s), smooth and parse the data in way to make it usable/accessible.

You can “fake” sensors for safety.  If you want to make a “smoke detector” detect the relative humidity and note significant changes (like from taking a shower) as if they were dangerous levels of smoke.

Interaction has emotional meaning.  Can you create an emotional data feed?  An emotional output?

Due by midnight, Monday, 14 Feb, 2022