The IR proximity sensor measures when something is near, allowing us to use the timing to calculate rotational speed.

Faster rotational speed makes the LED brighter. The photoresistor detects the brightness to change the output.

The servo motor powered by the external battery moves a magnet, changing magnetic field strength.



The IR proximity sensor reads the distance of a specific point of the rotating disk. If it takes less time to get closer to the sensor, the rotational speed is faster. When rotational speed is faster, the LED gets brighter. The photoresistor senses the brightness of the light. The brighter the light, the servo motor moves the magnet further away, which creates a stronger magnetic field.


First, we used a potentiometer to test how the middle step, the LED and photoresistor, would affect the rotation of the servo motor.

We switched to a smaller IR proximity sensor that detected more specific distances, because the larger one was meant for further distances. This was an important change in our project.

We attached an external battery to the servo motor to decrease electrical noise that affected the LED. This helped us reduce the flickering of the LED and the twitching of the motor.



Something that was difficult to figure out was how to use the IR proximity sensor to read rotational speed. We needed it to measure difference in the time when the stick got close to it at first and then close to it again. We wrote software to have the sensor read the time only the first time it gets approached, before spinning away and back again.

Another thing that was difficult was getting the servo motor to stop being really jittery. At first, we noticed that the LED light was flickering, which affected the motor, which in turn made the light flicker. We use an external power to power the servo motor to give it a steady supply of electricity, which stopped the LED from flickering.

We then realized that the noisy data that the photoresistor was picking up was causing the problem. We figured out through testing the range of the LED with analog write that there was a consistent pattern of spiking. We solved this problem by using moving average filter code from the course website. This tweak got rid of the majority of the twitching of the servo motor.



   Project 1: Double Transducer: Rotation Speed to Magnetic Field Strength
   Varsha Shankar and Suzanne Nie (varshas)+(suzannen)

   Description: The double trasnducer takes in rotational speed through the IR proximity sensor and outputs 
   that as a LED brightness. Then a photoresistor reads the LED brightness and outputs that to a servo motor 
   that moves a magnet towards the front as the LED gets brighter and opposite and LED gets dimmer.
   This changes the magnetic field.

   Pin mapping:

   pin   | mode   | description
   5      output     LED
   A2     input    photoresistor
   A3     input    potentiometer[testing]
   A1     input    IR sensor 
   3      output   servo

   Libraries Used:
   LiquidCrystal Arduino library for I2C LCD displays


#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//used to make the data coming in less noisy
float filtered_val = 0;  
const float PREV_WEIGHT = 0.8; 
const float CUR_WEIGHT = 1 - PREV_WEIGHT;

LiquidCrystal_I2C screen(0x27, 16, 2);

int LED_brightness;
const int LEDPIN = 5;

const int PHOTOPIN = A2;
int photopinval;

Servo servo;
const int servopin = 3;
int servopos;

//Testing purpose
//const int potpin = A3;
//int oldpotval;
//int newpotval;
//int potval;

int IRval;
int IRPin = A1;

//used to measure the time difference between each rotation
unsigned long timer;
unsigned long oldtime;
unsigned long newtime;
unsigned long timediff;

//used to take only one measurement each rotation
bool far;

void setup() {
  pinMode(LEDPIN, OUTPUT);
  //can use this to test
  //pinMode(potpin, INPUT);
  pinMode(IRPin, INPUT);

  timer = millis();
  oldtime = 0;
  newtime = 0;
  timediff = 0;


void loop() {
  timer = millis();

  photopinval = 925 - analogRead(PHOTOPIN);
  //checks to see if an object is close enough starting and ending a rotation
  IRval = analogRead(IRPin);
  if (IRval > 450 and far == false) {
    far = true;
    newtime = timer;
    if ((newtime - oldtime) > timediff) {

    timediff = newtime - oldtime;
    oldtime = newtime;
  if (IRval < 450 and far == true) {
    far = false;

  LED_brightness = map(timediff, 0, 750, 0, 255);
  if (LED_brightness > 255) {
    LED_brightness = 255;
  else if (LED_brightness < 0) {
    LED_brightness = 0;
  analogWrite(LEDPIN, 255 - LED_brightness);
  filtered_val = filtered_val * PREV_WEIGHT + photopinval * CUR_WEIGHT;
  servopos = map(filtered_val, 29, 750, 0, 180);

  screen.setCursor(12, 1);
  screen.setCursor(6, 0);
  if (timer % 50 == 0) {

    screen.setCursor(2, 0);
    if (timediff <= 0) {
      timediff = 0;
    if (timediff > 750){
      timediff = 750;
    screen.print(99 - map(timediff, 0, 750, 0, 99));
    screen.setCursor(14, 1);
    screen.print(map(servopos, 0, 180, 0, 99));
    screen.setCursor(8, 0);
    screen.print(99 - map(LED_brightness, 0, 255, 0, 99));
    screen.setCursor(8, 1);
    if (filtered_val < 29) {
      filtered_val = 29;
    if (filtered_val > 750) {
      filtered_val = 750;
    screen.print(map(filtered_val, 29, 750, 0, 99));