Double Transducer: Water Level to Rotational Speed

Top view of project cardboard and components. Includes colorful wires, tape to hold elements in place, and a grey gear motor at the bottom middle.

Overall Photo

Isometric view of project on cardboard. Includes a red and white stripped tower which the ultrasonic sensor sit on top of. LCD screen is at the bottom middle, with the arduino and wires above it. Also includes a grey cube with wires leading into it. On the right hand side sits a grey gear motor and a square of cardboard attached to the front of the motor.

Overall Photo 

Isometric View of finalized project. Includes a pink flower attached to the gear motor, colorful wiring connecting the arduino to breadboards, the LCD screen, and the ultrasonic sensor. White labels describing each component of the creation.

General axonometric view of the project

Side view of finalized project. Includes a pink flower next to a metal rail that sits on the bottom of the brown cardboard sheet. The LCD screen is at the bottom left of the image and blue tape throughout holding the components of the project to the board.

Roational speed device (DC motor)

Green solder breadboard with three wires, black, blue and red, attached. A photoresistor and resistor have also been soldered to the board.

Photoresistor on solder board

Image of the LCD screen with a blue background and white text outputting the contents "i=3, m=3, m=72, o=73".

LCD screen displaying data

IMG_5504.MOV

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. 

Arduino and breadboard connected with many wires sitting on top of a brown cardboard sheet.

Process Photo: Connecting all elements together 

Breadboard with colorful wires connected to it. Sits on top of a brown cardboard sheets. Top View.

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();

 }

}