Overall Photos:
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:
Process Images:
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:
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; }