Double Transducer: Water Level to Rotational Speed
Overall Photo
Overall Photo
General axonometric view of the project
Roational speed device (DC motor)
Photoresistor on solder board
LCD screen displaying data
Narrative Description
A lighthouse replicate has a device on top of it which, when water gets closer to the device, lights get brighter. When the lights get brighter a flower gets told to spin faster until it reaches its max speed. Then, when the water gets futher from the device on the lighthouse, the lights get darker and the flower starts to spin slower.
Process Photo: Connecting all elements together
Process Photo: (Attempted) Cable management
Schematic for Project 1
Block Diagram
Reflection
Project 1 marked the beginning of our journey into Arduino-based projects. It was a mix of intriguing and somewhat challenging experiences, primarily because Arduino was a new tool for us and working on both wiring and programming needs a lot of considerations.
At the start, we encountered difficulties with the wiring process due to concerns about the accuracy of our schematics. Our initial sketches lacked specific instructions regarding which wire should be connected to which Arduino pin. We spent a lot of time trying to determine if our wire placements were correct. We gradually solved the problem by deciding to learn programming first and try if we can do wiring as well. We found lots of helpful tutorials for programming these components, often accompanied by clear diagrams. This approach greatly speeded up our progress. We could follow the schematic diagrams to connect the components and simultaneously refer to the programming tutorials.
Step by step, we developed our ability to make each component function, using variables to trigger subsequent actions. For instance, we utilized a variable assigned to the ultrasonic ranger to control the brightness of an LED stick, creating an effect where the light's intensity changed based on the distance from the ultrasonic ranger. The LED stick posed a challenge for some time because it would become very bright instead of dim when we placed our hands too close to the ultrasonic ranger. However, we eventually realized that the ultrasonic ranger worked best when maintained at a certain distance and moved back and forth.
The remaining steps proved relatively straightforward as we discovered helpful wiring schematics. With assistance from Zach, we successfully employed soldering to connect our components, ensuring that our code operated smoothly. Drawing from the experiences gained in Project 1, I believe we are now better equipped to create more engaging and practical interactive devices using Arduino in the future.
//Double Transducer: Water Level to Rotational Speed
/*This code completes the computations needed to successful
migrate from reading the water level from an ultra sonic ranger
to the output speed of a DC motor. The process uses a ranger to
detect the distance to an object, in this case water level,
the distance is then converted into an LED brightness level.
The brightness level is read by a photoresistor and then
converted into a rotational speed level. Each step in the
process requires small calculations made by the arduino, along
with mapping the calculated value to a value that is
implementable by the arduino. */
/* Pin mapping
Input Pins
Ultrasonic Sensor Trigger Pin = 12
Ultrasonic Sensor Echo Pin = 13
Photoresistor Pin = A0
Output Pins
Motor Enable Pin = 4
Motor A Pin = 3
Motor B Pin = 2
Neopixel LED Pin = 8
*/
#include <NewPing.h>
#include <Adafruit_NeoPixel.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int TRIGPIN = 12;
#define ECHOPIN 13
#define MAX_DIST 50
#define NEOPIXEL_PIN 8
//#define NEOPIXEL_PINADD 9 //Extra LED Strip
#define NEOPIXEL_NUM 8
const int PHOTOPIN = A0;
const int MOTOR_ENABLE = 4;
const int MOTORA = 3;
const int MOTORB = 2;
const int PAUSE = 250; //4 Seconds
unsigned long timer = 0;
NewPing sonar(TRIGPIN, ECHOPIN, MAX_DIST);
Adafruit_NeoPixel NeoPixel(NEOPIXEL_NUM, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
//Adafruit_NeoPixel NeoPixelADD(NEOPIXEL_NUM, NEOPIXEL_PINADD, NEO_GRB + NEO_KHZ800); //Extra LED Strip
LiquidCrystal_I2C screen(0x27, 16, 2);
void setup() {
//Photoresistor
pinMode(PHOTOPIN, INPUT);
//DC Motor
pinMode(MOTOR_ENABLE, OUTPUT);
pinMode(MOTORA, OUTPUT);
pinMode(MOTORB, OUTPUT);
//Ranger
Serial.begin(115200);
//LEDs
NeoPixel.begin();
NeoPixel.setBrightness(50);
//Timer
//LCD Display
screen.init();
screen.backlight();
//screen.display();
}
void loop() {
delay(50);
int brightness;
int photoToSpeed;
//First input, ultrasonic ranger distance
int distance = sonar.ping_cm();
Serial.print("Dist ");
Serial.println(distance);
//First output, depending on the distance reading from the ultrasonic sensor
//The NeoPixel LED brightness will be adjusted
if(distance > 12){
brightness = 0;
} else{
int distToBrightness = map(distance, 0, 20, 250, 0);
brightness = constrain(distToBrightness, 0, 255);
}
Serial.print("Brightness: ");
Serial.println(brightness);
for(int i = 0; i < NeoPixel.numPixels(); i++){
NeoPixel.setPixelColor(i, NeoPixel.Color(255, 255, 255));
NeoPixel.setBrightness(brightness);
}
NeoPixel.show();
/*
*/
//Second input, photoresistor lighting level reading
/*Depending on the brightness of the LED output,
/the photoresistor will read a different light level*/
int photoVal = analogRead(PHOTOPIN);
Serial.print("Photo: ");
Serial.println(photoVal);
//Second output, depending on the photoresistor read light level the DC motor will change speed
if(photoVal < 800){
photoToSpeed = 0;
} else {
photoToSpeed = map(photoVal, 900, 930, 80, 200); //80 == 10rpm, 200 == 20rpm
}
Serial.print("Speed: ");
Serial.println(photoToSpeed);
digitalWrite(MOTOR_ENABLE, HIGH);
digitalWrite(MOTORB, LOW);
analogWrite(MOTORA, photoToSpeed);
//For LCD Display
int sensorInput = constrain(map(distance, 0, 20, 0, 99), 0, 99);
int actuatorVal = constrain(map(brightness, 0, 255, 0, 99), 0, 99);
int sensorVal = constrain(map(photoVal, 900, 950, 0, 99), 0, 99);
int actuatorOutput = constrain(map(photoToSpeed, 60, 200, 0, 99), 0, 99);
//Print LCD Screen ever 4 Seconds
if(millis() - timer > PAUSE){
screen.home();
screen.print("i:");
screen.setCursor(2,0);
screen.print(sensorInput);
screen.setCursor(6, 0);
screen.print("m:");
screen.setCursor(8,0);
screen.print(actuatorVal);
screen.setCursor(8,1);
screen.print(sensorVal);
screen.setCursor(12,1);
screen.print("o:");
screen.setCursor(14,1);
screen.print(actuatorOutput);
screen.display();
timer = millis();
}
}