Project 1: A Double Transducer: Position to Brightness
Peter Heo, John Hewitt, Evangeline Mensah-Agyekum
Gallery
Progress Images
Discussion
In terms of difficulty, the brainstorming was one of the more easier parts, as we were able to quickly come up with what we wanted for our middle step to be. However, what was more difficult were the more specific mechanics of the middle step, as we were initially unsure of how to convert slide position into pressure. We started with a couple of ideas but we were able to narrow it down to an arm that would press down on the sensor. Peter tried to come up with a piston that would press and lift a weight onto the round FSR, and a sort of linear actuator that would press against a vertically placed FSR sensor, but both of these proved to be unwieldy and unreliable. We eventually settled on using a straw attached to a lever (servo arm) with enough flexibility to bend when pressed against the FSR.
There were also a couple of challenges along the way, as the code proved to be one source of difficulty. The motor would jitter and stutter periodically, making the servo arm unreliable in pressing down on the FSR sensor. The initial approach to this problem was try to smooth out the values, as we thought it was the potentiometer sending jumpy values, but we learned that it was actually timer collisions between the servo motor and the Neopixel LED ring causing the servo motor to jitter. From this, we learned that sometimes it is not the main user code that is unreliable, but the type of libraries and mechanical components we use.
It was also interesting to calibrate the sensors to not only work with each other, but fit into a 1-100 range on the lcd. It took some finessing, but as we messed around with the values it began to feel more intuitive.
Both Evangeline and Peter experienced a specific wiring issue with the potentiometer, where they switched up input with ground/5V wiring, causing a short circuit. However, after learning that the wiring was fixed, this problem was easily addressed. Soldering also proved an interesting step for Peter, as he was unfamiliar with it, and learning how to solder was something he enjoyed learning, albeit a bit nervously. John preemptively soldered up the different parts of the project without realizing the wires were not long enough to reach the opposite ends of the board, and had to re-solder things. John also snapped a round FSR when trying to reposition it, it was interesting to use such a delicate piece. John also learned to what a heatsink was, and would have probably damaged the FSR if he hadn’t been warned ahead of time.
This project also made us think more spatially, as organization and how components would be physically laid out on the board were also part of the project near the end of putting the whole thing together. However, the straightforwardness of the setup and its processes made it easier to assemble.
Block Diagram and Schematic
Code
//Project: Double Transducer (Position to Brightness) //Peter Heo //John Hewitt //Evangeline Mensah-Agyekum //The code below allows for the user to control a slide potentiometer, which then controls a servo motor. //The slide potentiometer readings are converted to a servo motor angle. //Said servo motor exerts pressure onto a round FSR through the use a physical arm. //The round FSR readings are then converted to a certain degree of brightness for an Neopixel LED ring. //All the input and output values of the mechanisms aforementioned are displayed onto an LCD screen... //...all mapped to a range of 0-99. //Pins Mode Description //A0 Input Slide potentiometer readings //A3 Input Round FSR readings //6 Output LED Ring //10 Output Servo motor //Library and implementation for the Neopixel servo motor object: //https://learn.adafruit.com/neopixels-and-servos/the-ticoservo-library #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <Adafruit_TiCoServo.h> #include <Adafruit_NeoPixel.h> //Intitialize pin for LED ring and the number of lights on said LED ring, as well as the LED object. #define PIN 6 #define NUMPIXELS 16 Adafruit_NeoPixel light = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); //Initialize pins for the slide potentiometer, the round FSR, and the servo motor, as well as the LCD screen object. LiquidCrystal_I2C screen(0x27, 16, 2); const int SLIDEPIN = A0; const int PRESSUREPIN = A3; const int SERVOPIN = 10; //Initialize the time between display updates, and the timer itself. const int LCDUPDATETIME = 250; long prevDisplayTime = 0; Adafruit_TiCoServo servoMotor; void setup() { //Set up pins for inputs and outputs: //Slide potentiometer... //...Servo motor... //...and Round FSR sensor. pinMode(SLIDEPIN, INPUT); servoMotor.attach(SERVOPIN); pinMode(PRESSUREPIN, INPUT); //Set up LCD display. screen.init(); screen.backlight(); screen.display(); //Set up light. light.begin(); light.setBrightness(0); light.show(); //Open the serial communication port to talk back to the computer. Serial.begin(9600); } void loop() { //Look at current time. long currentTime = millis(); //Initialize slide potentiometer value. int slideVal = analogRead(SLIDEPIN); //Range should be about 11 degrees. //Set servo motor angle proportional to slide pot value. int servoVal = map(slideVal, 0, 1023, 142, 156); servoMotor.write(servoVal); //Read pressure value from FSR sensor. int pressureVal = analogRead(PRESSUREPIN); //Set brightness of LED ring proportional to pressure value. int brightnessVal = map(pressureVal, 0, 410, 0, 255); light.setBrightness(brightnessVal); //Set color of all LEDs on the LED ring to green. for (int i = 0; i < NUMPIXELS; i++) { //Set color of all LEDs on the LED ring to green. light.setPixelColor(i, light.Color(128, 150, 128)); } light.show(); //Update LCD display every 250 milliseconds. if (currentTime - prevDisplayTime >= LCDUPDATETIME) { screen.clear(); //Print slide values on a range of 0-99 on LCD display. int slideDisplayVal = map(slideVal, 1023, 0, 0, 99); screen.home(); screen.print("i:"); screen.print(slideDisplayVal); //Print servo motor value on a range of 0-99 on LCD display. int servoDisplayVal = map(servoVal, 142, 156, 99, 0); screen.setCursor(6, 0); screen.print("m:"); screen.print(servoDisplayVal); //Print pressure values on a range of 0-99 on LCD display. int pressureDisplayVal = map(pressureVal, 0, 410, 0, 99); screen.setCursor(8, 1); screen.print(pressureDisplayVal); //Print brightness values on a range of 0-99 on LCD display. int brightnessDisplayVal = map(brightnessVal, 0, 255, 0, 99); screen.setCursor(12, 1); screen.print("o:"); screen.print(brightnessDisplayVal); prevDisplayTime = currentTime; } }