Crit 1: Motion – The Plant Rotater

The automatic plant rotater helps indoor plant owners ensure that their plant gets even exposure to sunlight, even when the source of sunlight is one directional. This reduces the amount that a plant will grow to one side, which can result in an undesirable aesthetic, and in extreme cases, a plant that needs additional weights and staking to stay up. A common solution is for the caretaker to rotate the pot regularly, but this can be a difficult task to keep track of. See the picture below for extreme case of succulents trying to seek out the light (and an owner irregularly rotating the pot for correction)!

The hormone auxin is commonly responsible for triggering a plant to grow towards the light. Unless a plant is irregularly shaded in its environment, this hormonal response usually encourages plant to grow upward. 

A light sensor is placed near the plant, on the side exposed to the most amount of light. It measures the light exposure at regular intervals, and when it has detected the “preferred total exposure” it will rotate the plant by a quarter turn. Since sunlight will vary throughout the day, the plant rotates based on exposure instead of based on a timer. If desired, the owner can press a button to rotate the plant before the “preferred total exposure” is reached, which allows for greater control.

When connected to p5js, each time the plant turns, information about the latest total light sum (light exposure since the last turn), the preferred total exposure, and the total number of turns is sent through the Serial Port to p5js. The P5js sketch below does several tasks:

  1. Lists the array of numbers sent from the Arduino
  2. Calculates “percent complete” which is a percentage of Total Light Exposure Since Last Turn/Preferred Total Exposure. For turns triggered by the sensor, we would expect this number to be about 100% while it could be anything lowered when the turn is triggered by a button press.  If the plant is exposed to a significant amount of light at once, the number could be over 100%.
  3. Illustrates the Total Light Exposure adjacent to the Preferred Total Exposure to provide a user with a visual.
  4. If the Percent Complete value falls within a defined range (ex: 60-125%), there will be a smiley face on the screen. If the value falls outside of this range, a frowny face will appear instead. The visualization provides a quick reference for the user to understand what is going on without having to interpret the numbers flashing on the screen.

Arduino Sketch:

//motor and light sensor

#define lightPin A0 //Ambient light sensor reading 
#include <Stepper.h>

//data smoothing and light sensor
const int numReadings = 100;
float ligReadings [numReadings];
int ligReadIndex = 0;
float ligTotal = 0;
int inputPin = lightPin; //put sensor pin here
float ligPer=0;
float light_percent=0;
int prefLigExp=150;

//stepper motor
int stepsPerRevolution = 2048; //see motor spec sheet
int motSpeed = 10;
int dt = 500;
Stepper stepmot(stepsPerRevolution, 8, 10, 9, 11); //see motor and driver specs

//for millis
unsigned long lastReadTime = 0;

//for button
const int buttonPin = 2;
int buttonValue = 0;

//p5jsturncount
int numberOfTurns = 0;

void setup() {
  pinMode(lightPin, INPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    ligReadings[thisReading] = 0;
  }

  Serial.begin(9600);
  lastReadTime = millis();
  stepmot.setSpeed(motSpeed);

}


void loop() {
  //millis and light sensor
  if ((millis() - lastReadTime) >= 5000UL) {
    //Serial.println(lastReadTime);
    //Serial.println(millis());
    lastReadTime = millis();
    //light sensor read
    float light = analogRead(lightPin);
    float light_ratio = light / 1023.0;
    float light_percent = light_ratio * 100;

    ligTotal = ligTotal - ligReadings[ligReadIndex];
    ligReadings[ligReadIndex] = light_percent;
    ligTotal = ligTotal + ligReadings [ligReadIndex];
    ligReadIndex = ligReadIndex + 1;


  }

  buttonValue = digitalRead(buttonPin);


  if (buttonValue == LOW) {
    stepmot.step(stepsPerRevolution / 4);
    numberOfTurns=numberOfTurns+1;
    Serial.print(ligTotal);
    Serial.print(",");
    Serial.print(prefLigExp);
    Serial.print(",");
    Serial.println(numberOfTurns);
    ligTotal = 0;
  }


  if (ligTotal >= prefLigExp) {
    stepmot.step(stepsPerRevolution / 4);
    numberOfTurns=numberOfTurns+1;
    delay(3000);
    Serial.print(ligTotal);
    Serial.print(",");
    Serial.print(prefLigExp);
    Serial.print(",");
    Serial.println(numberOfTurns);
    //make step stop rotating
    ligTotal = 0;
    //ligReadIndex=0;
  }

  else {
    stepmot.step(0);
  }


}

 

 

p5js Sketch:

//smiley sketch: https://medium.com/spidernitt/introduction-to-digital-art-with-p5-js-d8ba63080b77
//serial, sensors, arrays, and p5js: https://www.youtube.com/watch?v=feL_-clJQMs

let serial; 
let sensors = [256,256,0];
let newData = "waiting for data";
let px, py;
let rad1;
let rad2;
let rad3;
let potDiameter;

function setup() {
  createCanvas(windowWidth, windowHeight);
  stroke(255);
  let radius = min(width,height)/2;
  let rad1=radius*0.7;
  let rad2= radius*.5;
  let rad3= radius*.25
  px= width/2;
  py = height/2;
  potDiameter = radius*1.5
  serial = new p5.SerialPort();
  serial.list();
  serial.open('COM5');
  serial.on('connected', serverConnected);
  serial.on('list',gotList);
  serial.on('data',gotData);
  serial.on('error',gotError);
  serial.on('open',gotOpen);
  
}

function serverConnected() {
  print("Connected to Server");
}

function gotList(thelist) {
  print("List of Serial Ports:");
  
  for (let i=0; i < thelist.length; i++) {
    print(i + " " + thelist[i]);
    
  }
}

function gotOpen() {
  print("Serial Port is Open");
}

function gotClose() {
  print("Serial Port is Closed");
  newData = "Serial Port is Closed";
}

function gotError(theerror) {
  print(theerror);
}

function gotData() {
  let currentString = serial.readLine();
  trim(currentString);
  if (!currentString) return;
  sensors=split(currentString, ',');
  console.log(sensors);
  newData = currentString;
}





function draw() {
  background(255,255,255);
  fill(50,25,0);
  strokeWeight();
  text(newData,10,10);
  
  //numTurns=newData
  //text(numTurns,px,py)
  
  totExp=sensors[0];
  prefExp=sensors[1];
  numTurns=sensors[2];
  //strokeWeight(.5);
  text("Turn:"+ numTurns,px,py+75);
  perc = (totExp)/(prefExp)*100;
  text("Percent Complete:"+ perc,px,py+90);

  text("Preferred",px+60,py+20);
  noStroke();
  fill(200, 150, 0);
  rect(px+55,py, 55,-sensors[1]);
  
  strokeWeight(1);
  fill(50,25,0);
  text("Received",px,py+20);
  
  noStroke();
  fill(200, 200, 0);
  rect(px,py,55,-sensors[0]);
  
  if (perc >=60 || perc <=125) {
    smiley(px, py-10, 30);
  }
  if (perc <60 || perc >125) {
    frowny(px,py-10,30);
  }
  
  
function smiley(x, y, diameter) {
  // Face
  fill(255, 255, 0);                  //fills the face with yellow color
  stroke(0);                          //outline in black color 
  strokeWeight(2);                    //outline weight set to 2
  ellipse(x, y, diameter, diameter);  //creates the outer circle

  // Smile
  var startAngle = 0.1 * PI;          //start angle of the arc
  var endAngle = 0.9 * PI;            //end angle
  var smilediameter = 0.5 * diameter;  
  arc(x, y, smilediameter, smilediameter, startAngle, endAngle);

  // Eyes
  var offset = 0.15 * diameter;
  var eyediameter = 0.05 * diameter;
  fill(0);
  ellipse(x - offset, y - offset, eyediameter, eyediameter);
  ellipse(x + offset, y - offset, eyediameter, eyediameter);
}

  function frowny(x, y, diameter) {
  // Face
  fill(255, 150, 0);                  //fills the face with yellow color
  stroke(0);                          //outline in black color 
  strokeWeight(2);                    //outline weight set to 2
  ellipse(x, y, diameter, diameter);  //creates the outer circle

  var startAngle = 1.2 * PI;          //start angle of the arc
  var endAngle = -0.2 * PI;            //end angle
  var smilediameter = 0.5 * diameter;  
  arc(x, y+8, smilediameter, smilediameter, startAngle, endAngle);

  // Eyes
  var offset = 0.15 * diameter;
  var eyediameter = 0.05 * diameter;
  fill(0);
  ellipse(x - offset, y - offset, eyediameter, eyediameter);
  ellipse(x + offset, y - offset, eyediameter, eyediameter);
}


  
}

 

Crit1 Development: Stepper Motor Progress

I have 2 alternatives to power the turning plant- a DC motor or a stepper motor. I have run through a test of a DC motor (attached to a fan) and 2 tests for a stepper motor. I was inclined to try to use the stepper motor, but neither of the stepper motor tests have worked. It appears that the power supply module I’m using (which is supposed to be compatible with the driver and stepper motor I’m using) is failing to provide power to the driver and the stepper motor. Not clear yet where the failure is happening, although the dim LED light on the power supply module suggests that the 9V battery power supply I am using is not adequate. I will need to test another power supply to see if I can get the stepper motor to work. Since the DC motor with fan seemed to have varying success depending on the speed, I tried two stepper motor tests just in case a difference in the speed would make the stepper motor move.

UPDATE 2/28: With a new power supply (wall plug), the stepper motor code is working. Next step is to make a sketch that combines the stepper motor and the light sensor TEMT6000.

Stepper Motor Test 1 Sketch:

#include <Stepper.h>
int stepsPerRevolution=2048; //see motor spec sheet
int motSpeed=10;
int dt=500;
Stepper stepmot(stepsPerRevolution, 8,10,9,11);//see motor and driver specs

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  stepmot.setSpeed(motSpeed);

}

void loop() {
  // put your main code here, to run repeatedly:
  stepmot.step(stepsPerRevolution);
  delay(dt);
  stepmot.step(-stepsPerRevolution);
  delay(dt);


}

Stepper Motor Test 2 Sketch:

#include <Stepper.h>
const float STEPS_PER_REV=32; //see motor spec sheet
const float GEAR_RED = 64;
const float STEPS_PER_OUT_REV = STEPS_PER_REV * GEAR_RED;
int stepsReq;
int motSpeed=10;
int dt=500;
 
Stepper steppermotor(STEPS_PER_REV, 8,10,9,11);//see motor and driver specs

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


}

void loop() {
  // put your main code here, to run repeatedly:
  steppermotor.setSpeed(1);
  stepsReq=4;
  steppermotor.step(stepsReq);
  delay(2000);

  stepsReq = STEPS_PER_OUT_REV / 2;
  steppermotor.setSpeed(100);
  steppermotor.step(stepsReq);
  delay(1000);


}

 

Crit1 Development: Experiment with Fan Motor and Light Sensor TEMT6000

With the TEMT6000 light sensor, I can turn on a motor based on input to the light sensor, similar to the one I had with the DHT-22.

With the TEMT6000, I used an analog write (instead of the digital write with the DHT-22) and the data arrives in float form. Several lines of code convert the reading into a percent. Data smoothing and millis () set up are the same as previous DHT-22 code.

#define lightPin A0 //Ambient light sensor reading 

//data smoothing
const int numReadings = 5;
float ligReadings [numReadings];
int ligReadIndex = 0;
float ligTotal = 0;
float ligAverage = 0;
int inputPin = lightPin; //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;
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);
  pinMode(lightPin, INPUT);

  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    ligReadings[thisReading] = 0;
  }
  Serial.begin(9600);
  lastReadTime = millis();
}

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

  if ((millis() - lastReadTime) >= 5000UL) {
    Serial.println(lastReadTime);
    Serial.println(millis());
    lastReadTime = millis();
    //light sensor read
    float light = analogRead(lightPin);
    float light_ratio = light / 1023.0;
    float light_percent = light_ratio * 100;

    ligTotal = ligTotal - ligReadings[ligReadIndex];
    ligReadings[ligReadIndex] = light_percent;
    ligTotal = ligTotal + ligReadings [ligReadIndex];
    ligReadIndex = ligReadIndex + 1;
    if (ligReadIndex >= numReadings) {
      ligReadIndex = 0;
    }
    ligAverage = ligTotal / numReadings;
    Serial.println(light_percent);
    Serial.println(ligAverage);

  }



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

Next, I plan to use the sensor to turn another motor (the stepper motor, which I think is a better fit for turning the plant turntable).

Crit1 Development: Experiment with Button and p5js

I ran into challenges with the previous DHT22 sensor to p5js assignment. I performed another test run using input from a button. With this, I was able to connect the p5.js web editor to the arduino, and have an image on the screen of the web editor change when the button input changed.

Arduino sketch below:

const int buttonPin = 2;
int buttonValue = 0; 

void setup() {
  // put your setup code here, to run once:
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  buttonValue = digitalRead(buttonPin);
  Serial.println(buttonValue);
  delay(10);

}

p5js sketch:

let serial; 
let newData = "waiting for data";

function setup() {
  createCanvas(windowWidth, windowHeight);
  serial = new p5.SerialPort();
  serial.list();
  serial.open('COM5');
  serial.on('connected', serverConnected);
  serial.on('list',gotList);
  serial.on('data',gotData);
  serial.on('error',gotError);
  serial.on('open',gotOpen);
  
}

function serverConnected() {
  print("Connected to Server");
}

function gotList(thelist) {
  print("List of Serial Ports:");
  
  for (let i=0; i < thelist.length; i++) {
    print(i + " " + thelist[i]);
    
  }
}

function gotOpen() {
  print("Serial Port is Open");
}

function gotClose() {
  print("Serial Port is Closed");
  newData = "Serial Port is Closed";
}

function gotError(theerror) {
  print(theerror);
}

function gotData() {
  let currentString = serial.readLine();
  trim(currentString);
  if (!currentString) return;
  console.log(currentString);
  newData = currentString;
}

function draw() {
  background(245,245,245);
  fill(50,50,200);
  text(newData,10,10);
  
  
  if (newData == 0) {
    rectMode(CENTER);
    rect(width/2,height/2,100,100);
  } else {
    ellipse(width/2,height/2,200,200);
    
  }
  
}

Next, for the Crit1 project, I want to be able to record or represent the actions of the plant turntable with p5js.

Resources and Demos:

 

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.

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: 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.

Motion-Sensor(?) Split Flap

I was staying at this hotel for work and I was convinced this was a motion-sensor split flap, since it never seemed to turn on until I rounded the corner into the elevator bank. The flaps make a very satisfying noise- a homage to the train station boards.  There is a link to a video that I took below. According to the article posted below, it’s on a timer, not a motion sensor, but at the time, I thought it was a cool use of a motion sensor.

 

The Ritz-Carlton

 

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 4: DHT 22 Temperature Sensor and LED

Before adding p5js to the operation, I set up a first iteration of input and output in Arduino.

The intention of the project is to measure environmental conditions and cue an alert when environmental conditions exceed a desired limit (too hot or too cold). This could have applications as a monitoring device during excessive heat waves. Based on temperature input from the sensor, the arduino  turns on a blinking warming light at a set temperature limit. For those seeking to use air-conditioning to a bare minimum (and save $), this system could act as a gauge that advises on serious conditions. Especially if someone is reliant on a window unit A/C instead of central air-conditions, it may encourage someone to seek a cooler environment and avoid risk of heat stroke.

I used the sensor to capture temperature data in warm and cold spots in my apartment. At the time measured, there was about a 7 degree F difference between the kitchen (~72 degrees F) and the bedroom (~65 degrees F). Since this was the temperature differential currently present in my apartment, I used tempF>= 70 to test the code, moving between rooms. In the kitchen, the LED light blinked, indicating the temperature was equal to or greater than 70 degrees F (I also used the Arduino serial monitor to check readings as I moved around).

 

^DHT 22 Temperature and Humidity Sensor and LED

//

#include "DHT.h"   //adafruit dht library 
#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;
float humid; //stores humidity
float tempC; //stores temperature
float tempF; //stores temp in F
int blueled=10;


void setup() {
  pinMode(blueled, OUTPUT);
  Serial.begin(9600);
  dht.begin();


}

void loop() {
  //read dht22 data and store to variables humid and temp
  if (isnan(humid) || isnan(tempC) ||isnan(tempF)){
    Serial.println(F("Failed to read from DHT sensor"));
    delay(10000);
    return;
  }
// troubleshooting issues with getting nan reading from dht22
  humid=dht.readHumidity();
  tempC=dht.readTemperature();
//converting to fahrenheit
  tempF=(tempC*1.8)+32;
//printing temp and humid values to serial monitor
  Serial.print("Humidity: ");
  Serial.print(humid);
  Serial.print(" %, Temp: ");
  Serial.print(tempF);
  Serial.println("Fahrenheit");
  delay(2000);
  if (tempF >= 70){
    digitalWrite(blueled,HIGH);
    delay(150);
    digitalWrite(blueled,LOW);
    delay(75);
  }
 delay(2000); 


}

Arduino was a success. The LED light blinked on and off when temperature was above 70, and stayed off when temperature was less than 70.

When I connected the p5.serial control, the console was printing out the serial print that had been set up on the arduino:

^first, I thought I would break out the second part of the arduino code (the control of the LED light) as data sent to arduino via p5. serial control. The library for DHT22 is all C++ and not clear to me initially how to modify. So as a first step, I tried to print sensor data on p5js.

Reviewed two arduino/potentiometer/P5js tutorials (https://medium.com/@yyyyyyyuan/tutorial-serial-communication-with-arduino-and-p5-js-cd39b3ac10ce, https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-serial-input-to-the-p5-js-ide/#Draw_a_Graph_With_the_Sensor_Values). I thought it would be interesting to use the information from the sensor to draw a graph, which would highlight changes in temperature or humidity. There was a lot that needed to be done to set up serial port, not sure if this is where everything went wrong, and my final result was undefined. I am wondering if this has to do with the DHT22 library being all C++ or if DHT 22 values need to be mapped to 0 to 255 before this information is read by P5 serial.

 

let serial; // variable to hold an instance of the serialport library
let inData;
 
function setup() {
  serial = new p5.SerialPort(); // make a new instance of the serialport library
  serial.on('list', printList); // set a callback function for the serialport list event
 
  serial.list(); // list the serial ports
}
 
// get the list of ports:
function printList(portList) {
  // portList is an array of serial port names
  for (var i = 0; i < portList.length; i++) {
    // Display the list the console:
    console.log(i + portList[i]);
  }
}


let portName = 'COM5';  // fill in your serial port name here
 
function setup() {
  serial = new p5.SerialPort();       // make a new instance of the serialport library
  serial.on('list', printList);  // set a callback function for the serialport list event
  serial.on('connected', serverConnected); // callback for connecting to the server
  serial.on('open', portOpen);        // callback for the port opening
  serial.on('data', serialEvent);     // callback for when new data arrives
  serial.on('error', serialError);    // callback for errors
  serial.on('close', portClose);      // callback for the port closing
 
  serial.list();                      // list the serial ports
  serial.open(portName);              // open a serial port
}

function serverConnected() {
  console.log('connected to server.');
}
 
function portOpen() {
  console.log('the serial port opened.')
}
 
function serialEvent() {
  inData=Number(serial.read());
 
}
 
function serialError(err) {
  console.log('Something went wrong with the serial port. ' + err);
}
 
function portClose() {
  console.log('The serial port closed.');
}

function setup() {
  createCanvas(400, 400);
}


function draw() {
  background(0);
  fill(255);
  text("data:"+ inData, 30, 50)
}

 

My references include:

https://www.arduino.cc/reference/en/libraries/dht-sensor-library/

https://stackoverflow.com/questions/40874880/getting-nan-readings-from-dht-11-sensor

https://create.arduino.cc/projecthub/mafzal/temperature-monitoring-with-dht22-arduino-15b013

https://www.instructables.com/How-to-use-DHT-22-sensor-Arduino-Tutorial/

https://itp.nyu.edu/physcomp/videos/videos-serial-communication/#Serial_to_p5js_in_binary

How to Set Up the DHT11 Humidity Sensor on an Arduino

Notes-

When looking for DHT22 and p5js, this project came up: https://github.com/TTurbo0824/pcom_final/blob/master/test_led_hum_serial.ino

^has a note for incorporating p5js but this just looks like what got uploaded to arduino, not additional p5js data sent

 

** 2/08/2022 Update:

Serial port appears now to be connected to P5JS. I was able to use the test sketch from last week to check that the values for temperature (in C) came through, then both values for temperature and for humidity.

HOWEVER, while running the sketch in the browser editor, the data from the serial port is not registering.

New P5JS sketch:

let serial; // variable to hold an instance of the serialport library
let portName = 'COM5'
let inData;
 
function setup() {
  createCanvas(400,300);
  background('rgba(0,255,0, 0.15)');
  

}

  serial = new p5.SerialPort(); // make a new instance of the serialport library
  serial.on('list', printList); // set a callback function for the serialport list event
 
  serial.list(); // list the serial ports

 
// get the list of ports:
function printList(portList) {
  // portList is an array of serial port names
  for (var i = 0; i < portList.length; i++) {
    // Display the list the console:
    console.log(i + portList[i]);
    serial.on('list',printList);
    serial.on('connected', serverConnected); // callback for connecting to the server
  serial.on('open', portOpen);        // callback for the port opening
  serial.on('data', serialEvent);     // callback for when new data arrives
  serial.on('error', serialError);    // callback for errors
  serial.on('close', portClose);      // callback for the port closing
    
    
serial.open(portName);              
    // open a serial port
    
  function serverConnected() {
  console.log('connected to server.');
}
 
function portOpen() {
  console.log('the serial port opened.')
}
 
function serialEvent() {
  inData = Number(serial.read());
 
}
 
function serialError(err) {
  console.log('Something went wrong with the serial port. ' + err);
}
 
function portClose() {
  console.log('The serial port closed.');
}

    
  }
 

  function graphData(newData) {
  var yPos=map(newData,0,255,0,height)
  stroke(0xA8,0xD9,0xA7);
  line(xPos,height,xPos,height - YPos);
  if (xPos>=width) {
    xPos=0;
    background(0x08, 0x16, 0x40);
  } else {
    xPos++;
  }
  }  
 function draw() {
  graphData(inData);
  text("temperature in Celsius:" + inData, 1, 50);
  
} 
  
}