Devin's Final Double Transducer Board
Zixin's final Double Transducer Board, In this model, when the photoreister (光检测) detect the bright light, the heating pad begin to increace temperature, and after the 热检测 detect the rasing temperature, the servo motor will push the the block by 5cm.
Devin's heating pad wrapping around the thermistor like a blanket
Devin's motor and slide crank mechanism
Devin's LCD display panel
Leaf's Photoresistor and connections. It is the start of the transducer, photoresistor with resistor on a small bread board which detect the brightness of light.
Leaf's Heating Pad and connections. The Heating pad is folded and in order to help the themoister detect the temperature. The heat intensity responding to photoresistor brightness values.
Leaf's LCD Arduino and Bread Board Connections
Leaf's LCD display panel. In the screen, i is the temperature, m is the LED, o is the servo motor.
Devin's Final Double Transducer Video. Shows the system working normally and then shows the system working with the skip the middle button.
Leaf's Final Double Transducer Video. The system working normally and then the system working with the skip the middle button.
Everything is powered by 5 volts from the Arduino through the big white breadboard. A small sensor on the black breadboard reads brightness and tells the Arduiono it's readings. Arduino Uno yellow heat pad the brightness: heat up more when bright, and heat up less when dim. The little sensor wrapped by the heat pad tells the Arduino how hot the heat pad is. Arduino sees hot hot the heat pad is and tells the small blue motor to turn: turn clockwise and push wall forward when hot, turn counter-clockwise to pull back wall when less hot. Arduino takes all values read by all sensors and displays them on the screen.
Testing if Photoresistor is reading brightness and displaying on monitor
Testing if Thermistor is reading heat and displaying values on monitor
Testing LCD Display and Slide Crank Mechanism
Testing if skip the middle button skips middle step
Soldering the middle steps (the heating pad connections)
Testing the Heating pad after soldering process
The beginning of our project went very smooth. We sped through the electrical and software for the input sensors: photoresistor and thermistor. We tested both and both gave back smooth values.
In plan we decided that heat would be a very cool middle step for our double transducer. However, as we tested it we realized that the change in temperature of the heatpad is very minuscule as it takes a long time for the heatpad to cool down even at lower heating intensities. This problem made us think that the motor was unresponsive to thermistor values when in reality it did. When we took out the thermistor from the heating pad to expedite the cooling process we discovered that it did work just very slowly in the heating pad.
Towards the end phase of the project when eveything was built we encountered persistent jitter with the servo motor. First we analyzed the serial monitor where it is spiking constantly. Initially we thought it was a problem with the servo motor, but after switching out 5 servo motor the problem still occured. Then we tried switching the power from the arduino 5V pin to an external 5V source. It helped smooth it out the beginning but the jittering still came back. We then discussed how the servo motor is creating too much electrical noise interfering with the other components and creating a negative feedback loop for itself so it should be powered completely seperately from every other component. It ended up still not working. I think this taught us that signal integrity and noise suppression are very critical in electronics and that our electronics are far from calipered well as they are cheap.
/*
Group 1 Double Transducer Project by Devin and Leaf
Our double transducer uses a photoresistor and a thermistor to control a resistive heat pad and a servo motor.
A tactile push button lets the user skip the middle step to move the motor directly from the photoresistor
- The photoresistor (A0) measures ambient light. Its value is mapped to:
• brightness percentage (for display)
• heat pad intensity (PWM output)
• optional servo position override when the button is pressed
- The thermistor (A1) measures temperature. Its value is mapped to:
• temperature percentage (for display)
• servo motor position (default behavior)
- The tactile switch (pin 8) is a digital input. When held down, it causes the servo to
respond to brightness instead of temperature.
- The heat pad (pin 3) is a PWM output, driven by brightness.
- The servo motor (pin 5) rotates based on temperature (or brightness if the button is held).
- An LCD displays brightness, temperature, heat output, and motor position as percentages.
Arduino pin | role | description
-------------------------------------
A0 input Photoresistor
A1 input Thermistor
3 input Heat Pad
5 output Servo Motor
8 output Tactile Switch Button
SDA & SCL output LCD Display
*/
#include <Wire.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>
// Pin assignments
const int PHOTO_PIN = A0;
const int TEMP_PIN = A1;
const int HEATPAD_PIN = 3;
const int SERVO_PIN = 5;
const int BUTTON_PIN = 8;
// LCD setup
LiquidCrystal_I2C screen(0x27, 16, 2);
// Servo object
Servo gaugeMotor;
// Sensor and control variables
int photoVal, tempVal, buttonState;
int heatOutput, motorPosSkip, motorPos;
int brightnessPct, tempPct, heatPct, motorPct;
unsigned long quarterTimer = 0;
void setup() {
pinMode(HEATPAD_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT);
gaugeMotor.attach(SERVO_PIN);
Wire.begin();
screen.init();
screen.backlight();
Serial.begin(9600); // Start serial communication for debugging
}
// Main loop: read sensors, compute outputs, update display, and control devices
void loop() {
readInputs();
computeMappedValues();
controlOutputs();
lcdDisplay();
reportBack();
delay(100);
}
// Read sensor and button values
void readInputs() {
buttonState = digitalRead(BUTTON_PIN);
photoVal = analogRead(PHOTO_PIN);
tempVal = analogRead(TEMP_PIN);
}
// Map raw sensor values to usable control ranges
void computeMappedValues() {
brightnessPct = map(photoVal, 200, 1023, 0, 99);
brightnessPct = constrain(brightnessPct, 0, 99);
tempPct = map(tempVal, 500, 900, 0, 99);
tempPct = constrain(tempPct, 0, 99);
heatOutput = map(brightnessPct, 0, 99, 0, 255);
heatOutput = constrain(heatOutput, 0, 255);
motorPosSkip = map(photoVal, 0, 1023, 0, 90);
motorPos = map(tempVal, 400, 900, 10, 170);
motorPct = map(motorPos, 10, 170, 0, 99);
motorPct = constrain(motorPct, 0, 99);
}
// Drive outputs based on current state
void controlOutputs() {
analogWrite(HEATPAD_PIN, heatOutput); // PWM control for heat pad
if (buttonState == HIGH) {
gaugeMotor.write(motorPosSkip); // Override: servo follows brightness
} else {
gaugeMotor.write(motorPos); // Default: servo follows temperature
}
}
// Display sensor percentages on LCD
void lcdDisplay() {
if ((millis() - quarterTimer) >= 250) {
screen.clear();
screen.home();
screen.print("i:");
screen.print(brightnessPct);
screen.setCursor(6, 0);
screen.print("m:");
screen.print(map(heatOutput, 0, 255, 0, 99));
screen.setCursor(0, 1);
screen.print("#:");
screen.print(tempPct);
screen.setCursor(10, 1);
screen.print("o:");
screen.print(motorPct);
quarterTimer = millis();
}
}
// Print debug info to Serial Monitor
void reportBack() {
Serial.print("photoVal = ");
Serial.print(photoVal);
Serial.print(", tempVal = ");
Serial.print(tempVal);
Serial.print(", buttonState = ");
Serial.println(buttonState);
}