Final Model of the double transducer(temperature to magnetic field). In this model, when the thermistor heats up, the LED becomes brighter. The stronger light signal causes the servo motor to push the magnet closer to the other team’s sensor, increasing the magnetic field they detect. As the thermistor cools, the LED dims, the sensor receives less light, and the servo moves the magnet back, reducing the field strength.
There is a square brown board with a small breadboard on the top side with a thermistor wired, positioned on top of a LEGO cube. In the middle, there is an Arduino Uno with a cable connected to it, next to a medium white breadboard with multiple wires on it, including a tactile button switch. To the right is a small protoboard. On the bottom is a LEGO and wooden popsicle stick contraption with a servo motor and a magnet. On the right is an LCD screen displaying data. Each part is labeled in marker with the names and short descriptions of each component.
Final image of the temperature to magnetic field double transducer
As the thermistor heats up, the LED becomes brighter. As the LED becomes brighter, the photoresistor reads the brightness of the LED and drives a servo motor with a magnet attached, pushing the magnet closer to the edge. As the thermistor cools, the LED becomes dimmer, the photoresistor reads less light, and the servo motor retracts further from the edge.
There is a square brown board with a small breadboard on the left side with a thermistor wired, positioned on top of a LEGO cube. In the middle, there is an Arduino Uno with a cable connected to it, next to a medium white breadboard with multiple wires on it, including a tactile button switch. Below that is a small protoboard with black electrical tape covering it. On the right is a LEGO and wooden popsicle stick contraption with a servo motor and a magnet. Above that is an LCD screen displaying data. Each part is labeled in marker with the names and short descriptions of each component.
Start of process : Thermistor on a small breadboard which senses the temperature
Picture of a medium white breadboard with wires, a resistor, and a thermistor wired up.
LCD display : scale from 0-99
i = temperature
m = LED
photoresistor
o = servo motor
Picture of a LCD display showing data.
Servo motor with magnet attached on a stick : the servo motor depending on the value of the photoresistor it will push or retract the magnet
A picture of a servo motor contraption with LEGOS and popsicles sticks.
Soldered photoresistor and LED on a protoboard. The tape on top covers them to maximize the accuracy and also remove any distracting lights that might interfere.
A picture of a soldered protoboard with resistors, LED, wires, and photoresistor.
Russell: When temperature rises the LED light will brighten, the photoresistor sensing light will then turn the servo motor to push the magnet.
Silvia: As the thermistor heats up, the LED becomes brighter. As the LED becomes brighter, the photoresistor reads the brightness of the LED and drives a servo motor with a magnet attached, pushing the magnet closer to the edge. As the thermistor cools, the LED becomes dimmer, the photoresistor reads less light, and the servo motor retracts further from the edge.
On the board there are four main parts. The thermistor feels hot and cold, and it makes the LED light shine brighter when it’s hot or dimmer when it’s cold. The photoresistor looks at the LED’s light and tells the servo motor to move. The servo motor has a little stick on it that pushes the magnet forward and then pulls it back.
Russell : First prototype of the servo motor connect to a stick! As the servo motor turns it will change the angle of stick connected to it, eventually causing the magnet to be extended.
An image of a hand holding a servo motor with two popsicle sticks attached that are screwed together, showing a mechanism.
Russell : Wired thermistor that worked for the first time! Experimenting with wiring and location of the thermistor and a working thermistor was the first sensor to work properly.
A close up of a wiring setup for a thermistor on a medium sized breadboard with wires, resistor, and photoresistor.
Silvia: Snapped a picture of the setup on the breadboard before soldering the LED and photoresistor and moving the thermistor so that I could reference the wiring.
An image of an Arduino Uno on the left and a white medium breadboard on the right with various wires and resistors, yellow LED, photoresistor, and tactile button switch.
Silvia: Process picture of attempt 1 of soldering the protoboard with the middle step of the double transducer.
A small protoboard with power and GND rails standing upright, with resistors, a white LED, a photoresistor, and red, blue, green, and black wires.
Russell :
Starting was the biggest challenge for our team. We were unsure where to begin, whether to start wiring or writing code, since we had never worked with four different inputs and outputs at once. We decided to begin with the thermistor, and once we successfully wired it and got the code running, that became the turning point. It gave us the momentum and confidence to move forward with the other components. A particularly interesting challenge was creating a push and pull mechanism with the servo motor. Since the servo naturally moves in a swinging motion, we had to rethink how to make it push in one direction and pull in the other, which encouraged us to be more creative in our design.
Through this process, we became more technically confident with wiring basic inputs and outputs and setting up the LCD display to show sensor values. Coding was the most difficult part, as fixing one error often caused another, but this taught us patience and persistence. In retrospect, even a small tweak such as restructuring the code or approaching the wiring differently could have shifted the project in an entirely new direction. Overall, this project gave us a stronger foundation in Arduino and made us more confident in tackling future projects with both technical skill and creative problem solving.
Silvia:
The most challenging part of the process for me was wiring up the components in a neat way that aligned with the arrangement I wanted, as well as soldering. Wiring up the first draft was pretty simple, as I referenced resources like the ioref and block diagram/electrical schematic, but figuring out how to prepare the setup for the final was more difficult because I had to think more specifically about how I wanted the components to flow while being physically able to be in certain positions. I think moving the thermistor to its own separate breadboard was a good move in establishing this flow and clearing up the middle, as well as soldering the middle step to the protoboard. Soldering was challenging because it was one of my first times doing so, and I did have to redo the proto board, but it was really great practice in terms of technical skills and came to be one of the most rewarding aspects of the project (aside from getting it all to work in the end, of course). I think Russell came up with a great idea for the servo motor contraption, and in retrospect, it was what we needed to pull off the machine due to the simplicity and neatness of it, which was able to drive the magnet pretty smoothly.
We also struggled a bit with the code at first, especially with getting the thermistor to work in influencing the middle step and having a big enough impact to get through to the end. The code bits and resources, including ioref, as well as the asynchronous videos, were very helpful in getting the pieces we needed to put the code together. Coding is still a challenge for me, but I learned a lot in this project in terms of the common technical terms and setup you see in Arduino code, and I would love to explore more of it in future projects and opportunities. Something I would love to play with in the future are those rainbow LED lights that we saw some other groups using, because the lights were a lot more vivid than I imagined, and I'm interested in the different ways you could program them.
In the future, I would love to approach soldering again, as my favorite part was arranging the components and wires as neatly as possible. Trimming off the ends of the wires after finishing was super satisfying. I would also love to play around with different creative methods of building these machines, such as more use of LEGO blocks or popsicle sticks. I felt intrigued by the toy wheels and have my eyes on that for future ideas.
Russell Sang, Silvia Shin
Project: Double Transducer (Thermistor → LED, Photoresistor → Servo, Button = bypass)
60-223 Intro to Physical Computing
A thermistor reads temperature (heat) and controls the LED brightness (PWM).
A photoresistor reads light level and controls the servo motor position.
When the pushbutton is pressed, the thermistor value is used instead to control the servo,
bypassing the photoresistor. The LCD shows the sensor readings and actuator states.
Pin mapping:
Arduino pin | role | description
----------------------------------------
A0 input thermistor
A1 input photoresistor
7 input pushbutton
11 output LED (PWM brightness)
2 output servo motor
I2C (0x27) output LCD display
* Input values (sensor readings)
thermRaw → raw analog value from thermistor (0–1023)
ldrRaw → raw analog value from photoresistor (0–1023)
buttonState → digital input from button (HIGH = not pressed, LOW = pressed)
* Computed sensor percentages
heatPercent → temperature level from thermistor, mapped into 0–100%
lightPercent → light level from photoresistor, mapped into 0–100%
drivePercent → selected percentage that drives the servo (from lightPercent or heatPercent depending on button state)
* Actuator control values
ledPWM → PWM value (0–255) that controls LED brightness based on thermistor
servoPos → servo motor position in degrees, mapped from drivePercent
* Display values (scaled to 0–99 for LCD)
i_val → input reading (thermistor) shown on LC
s_val → sensor reading (photoresistor) shown on LCD
m_val → mapped LED brightness (0–99) shown on LCD
o_val → output servo position (0–99) shown on LCD
*_Raw = raw sensor input
*_Percent = mapped to percentage
ledPWM / servoPos = actuator control signals
*_val = values formatted for LCD display
*/
// libaries
#include <Servo.h>
#include <LiquidCrystal_I2C.h>
// create objects
Servo magneticServo;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// pin assignments
const int THERM_PIN = A0;
const int LDR_PIN = A1;
const int BTN_PIN = 7;
const int LED_PIN = 11;
const int SERVO_PIN = 2;
// calibration constants
const int THERM_COLD_RAW = 506;
const int THERM_HOT_RAW = 568;
// servo limits
const int SERVO_RETRACT = 55;
const int SERVO_EXTEND = 110;
void setup() {
// initialize pins
pinMode(LED_PIN, OUTPUT);
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(THERM_PIN, INPUT);
pinMode(LDR_PIN, INPUT);
// attach servo
magneticServo.attach(SERVO_PIN);
// set up LCD
lcd.init();
lcd.backlight();
lcd.clear();
}
void loop() {
// ---------------------------------------------------------
// 1. read inputs
// ---------------------------------------------------------
int thermRaw = analogRead(THERM_PIN); // raw thermistor value
int ldrRaw = analogRead(LDR_PIN); // raw photoresistor value
int buttonState = digitalRead(BTN_PIN); // button state (LOW = pressed)
// ---------------------------------------------------------
// 2. Compute and make decisions
// ---------------------------------------------------------
// map thermistor value to a percentage (0–100%)
int heatPercent = map(thermRaw, THERM_COLD_RAW, THERM_HOT_RAW, 0, 100);
if (heatPercent < 0) heatPercent = 0;
if (heatPercent > 100) heatPercent = 100;
// map light value to a percentage (0–100%)
int lightPercent = map(ldrRaw, 0, 1023, 0, 100);
if (lightPercent < 0) lightPercent = 0;
if (lightPercent > 100) lightPercent = 100;
// percent value to use based on button state
int drivePercent;
if (buttonState == LOW) {
drivePercent = heatPercent; // button pressed
} else {
drivePercent = lightPercent; // button not pressed
}
// ---------------------------------------------------------
// 3. Actuate actuators (drive outputs)
// ---------------------------------------------------------
// LED brightness depends on heat, unless button is pressed
int ledPWM;
if (buttonState == LOW) {
ledPWM = 0; // button pressed → LED off
} else {
ledPWM = map(heatPercent, 0, 100, 0, 255);
}
analogWrite(LED_PIN, ledPWM);
// servo position depends on chosen drivePercent
int servoPos = map(drivePercent, 0, 100, SERVO_RETRACT, SERVO_EXTEND);
if (servoPos < SERVO_RETRACT) servoPos = SERVO_RETRACT;
if (servoPos > SERVO_EXTEND) servoPos = SERVO_EXTEND;
magneticServo.write(servoPos);
// ---------------------------------------------------------
// 4. Report to LCD
// ---------------------------------------------------------
int i_val = map(thermRaw, 0, 1023, 0, 99); // input display value
int s_val = map(ldrRaw, 0, 1023, 0, 99); // sensor (LDR) display value
int m_val = map(ledPWM, 0, 255, 0, 99); // LED PWM display value
int o_val = map(servoPos, SERVO_RETRACT, SERVO_EXTEND, 0, 99); // output display value
// first row
lcd.setCursor(0, 0); lcd.print("i:");
if (i_val < 10) lcd.print('0'); lcd.print(i_val);
lcd.setCursor(6, 0); lcd.print("m:");
if (m_val < 10) lcd.print('0'); lcd.print(m_val);
// second row
lcd.setCursor(7, 1);
if (s_val < 10) lcd.print('0'); lcd.print(s_val);
lcd.setCursor(12, 1); lcd.print("o:");
if (o_val < 10) lcd.print('0'); lcd.print(o_val);
// short delay for readability
delay(200);
}