Overall Photos:

Aerial photo of the entire transducer setup. (Mimi)

Top View of the Project -Daniel

Description:

This double transducer converts a temperature input into a color output. The transducer measures the ambient temperature. That measurement is then converted to movement on a servo motor. The servo motor moves in the range of 0 to 180 degrees. The higher the temperature reading is the closer the motor movement will be to 180 degrees and vise versa for lower temperatures. A magnet is attached to the arm of the servo motor, so the magnet rotates as the servo arm rotates. As the magnet rotates it changes its distance from the magnetic sensor that is located nearby. The magnet is the closest to the sensor at when the servo motor is at 0 degrees and the farthest when the servo motor is at 180 degrees. The reading from the magnetic sensor is then converted to a color that is outputted on the neoPixel ring.

Final Working Videos:

(Mimi)

(Daniel)-Not worked properly

I changed the temp value in the code to show that the light changes its color depending on the temperature.

TinkerCad Simulation:

 

Detail Photos:

Wires and Arduino we used for this project.-Daniel

The magnet is taped to the servo motor arm. When the servo arm rotates the magnet rotates as well. (Mimi)

GY 271 sensor(magnetic sensor) we used for this project.-Daniel

The NeoPixel Ring is the final output of our transducer. It outputs a color based on the magnetic field detected. (Mimi)

Process Images:

Thermistor, Magnetic sensor, and Servo Motor are wired to Arduino and working. (Mimi)

The LCD and NeoPixel ring have been added and are working. The neoPixel ring only changes shades of blue and the magnetic sensor is not reading correct values yet. (Mimi)

Starting to connect each component together on the breadboard. (Started with plugging in the LCD)-Daniel

Fully assembling the components from top to operate the system. Except, the LCD and the LED did not turn at this point because the 5V and GND circuit in the breadboard was not connected correctly.-Daniel

 

 

Discussion: 

Since this project was processed remotely, the easiest part of the project was to work in Tinkercad to demonstrate the project theoretically works. When we started the Tinkercad, we faced some problems with connecting LCD and finding the neo pixel code library. However, we passed this problem smoothly by referring back to various examples provided by the web and professor. Therefore, there was no actual hardship for working this project remotely.

However, the actual hardship came up from physical construction. Mimi had a problem with not having a consistent returning value from the magnetic sensor. Daniel had a problem with connecting his LCD and magnetic sensor to his project. We both solved this problem by asking a professor or referring back to the web explanations, but it took several tries to fix our mistakes. Also, we had a problem with choosing our materials. Mimi used a thermistor to measure the temperature, while Daniel used a temperature and humidity sensor to measure the temperature. This created little difference in coding since the temperature and humidity sensor requires its specific library to work properly.

If we had worked this project by meeting physically instead of remotely, it would have been much easier to fix our mistakes since we both had a problem with different parts. We could have fixed our mistakes by talking to each other and could have prepared the complete set of the project during our presentation. If we have the next team project time, we should find a better communication method between the working team members during the physical assembly work step to reduce differences between each project.

 

Schematic:

Schematic of the actual project

 

Code Submission:

/*
* Double Transducer: Temperature to Color
* Mimi Marino (mmarino) Daniel Moon (seonghym)
*
*
* Description: The temperature sensor reads the temperature.
    That value is then converted to a value that will
    correspond to the angle that the servo motor is moved. 
    A magnet is attached to the servo motor. As the servo
    moves the azimuth angle of the magnet with respect to 
    the magnetic sensor changes. The magnetic senesor reads
    that azimuth angle and that value is converted to an RGB 
    value. The neoPixel ring outputs this RGB color. 
*
*Credit: 
*   -HSV to RGB convertor functions 
*   https://gist.github.com/postspectacular/2a4a8db092011c6743a7 
*   
*   -Figuring out how to wire up the thermistor 
*   https://www.circuitbasics.com/arduino-thermistor-temperature-sensor-tutorial/
    
*
* Pin mapping:
*
* pin   | mode   | description
* ------|--------|------------
  6      output   Servo
  5      output   neoPixel
  A0     input    Temp Sensor
  A4     I2C      Magnet Sensor
  A5     I2C      Magnet Sensor
  3      ouput    LCD rs
  4      output   LCD enable
  10     output   LCD d4
  11     output   LCD d5
  12     output   LCD d6
  10     output   LCD d7
*/

#include <LiquidCrystal.h>
#include <Adafruit_NeoPixel.h>
#include <Servo.h>
#include <QMC5883LCompass.h>

const int SERVO_PIN = 6;
const int PIXEL_PIN = 5;
const int TEMP_PIN = A0;
const int NUMPIXELS = 12;
const int MAG_PIN = A4;
const int MAG_PIN1 = A5;
const int TEMP_LOW = 650;
const int TEMP_HIGH = 1023;

unsigned long timer = 0;
int temp;
int magnetMap;
int a;

QMC5883LCompass compass;
Servo doorMotor;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
//LiquidCrystal(rs, enable, d4, d5, d6, d7) 
LiquidCrystal lcd(3, 4, 10, 11, 12, 13);

void setup()
{
   Serial.begin(9600);
   //Sets OUPUT and INPUT pins
   pinMode(SERVO_PIN, OUTPUT);
   pinMode(PIXEL_PIN, OUTPUT);
   pinMode(TEMP_PIN, INPUT);
   doorMotor.attach(SERVO_PIN);
   
   //Sets LCD
   lcd.begin(16, 2);
   
   //Sets Neo pixel Strip
   pixels.begin();
  
   //initilizes the magnetic sensor
   compass.init();
}

void loop()
{
  // only executes every 200ms
  //updates the LCD, checks the temp sensor, 
  //updates and reads the motor position,
  //reads the magnetic sensor and outputs a color
  if ((millis() -timer >= 200)){
    
  //Read the temperature sensor 
  temp = analogRead(TEMP_PIN);
  
  //Change temp sensor input into values 0-180
  //650 -1023 corresponds to the varabilty of the 
  //sensor in my room w/o applied heat
  int tempMap = map(temp,TEMP_LOW, TEMP_HIGH, 0, 180);
  doorMotor.write(tempMap);  

  //magnetic senor outputs the azimuth angle
  compass.read();
  a = compass.getAzimuth();

  //48 corresponds to the servo at 0 degrees
  //338 corresponds to the servo at 180 degrees
  magnetMap = map(a, 48, 338, 0, 99);
  
  //makes magnetMap into value from 0.0-0.99 for 
  //hsv input
  float h = magnetMap / 100.0;
  float rgb[3];
  // converts magnetic value 0.0-0.99 to RGB value
  hsv2rgb (h, 1, .5, rgb);
  
  //Changes the color of NeoPixel Strip
  for (int i=0; i < NUMPIXELS; i++) {
      pixels.setPixelColor(i,rgb[0]*255,rgb[1]*255,rgb[2]*255);
      pixels.show();
     }    
  
  // maps current values to 0 to 99 for display
  int disTemp= map(temp, TEMP_LOW, TEMP_HIGH, 0, 99);
  int disMotor = map (doorMotor.read(), 0, 180, 0, 99);
  
  // updates the LCD with corresponding values 
  // in correct places
  lcd.clear();
  lcd.setCursor(0,0); 
  lcd.print((String)"i:" + disTemp);
  lcd.setCursor(6,0);
  lcd.print((String)"m:" + disMotor);
  lcd.setCursor(8,1);
  lcd.print(magnetMap);
  lcd.setCursor(12,1);
  //technically the color output but we map the magent
  //sensor 0-99 and use that directly to compute the RGB value
  //so the math would be the inverse so it make sense to just 
  //display the magnet map value becayse the inverse math functions 
  //would produce the same value
  lcd.print((String)"o:" + magnetMap);
  
  // updates the timer
  timer = millis();
  }
} 

// from https://gist.github.com/postspectacular/2a4a8db092011c6743a7
// expects hsv channels defined in 0.0-1.0 interval
//helps to convert HSV values to RBG values for the neopixel strip
float fract(float x) { return x - int(x); }
float mix(float a, float b, float t) { return a + (b - a) * t; }
float* hsv2rgb(float h, float s, float b, float* RBG) {
  RBG[0] = b * mix(1.0, constrain(abs(fract(h + 1.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s);
  RBG[1] = b * mix(1.0, constrain(abs(fract(h + 0.6666666) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s);
  RBG[2] = b * mix(1.0, constrain(abs(fract(h + 0.3333333) * 6.0 - 3.0) - 1.0, 0.0, 1.0), s);
  return RBG;
}