A smart hydrate reminder that reminds you to drink water.
I myself find it hard to reach the daily water intake. I can go on without water for hours when sitting behind my desk. For this purpose, I wanna create a coaster that reminds me to take a drink after a certain amount of time.
Softwares:
For creating the 3d model
For slicing the 3D model
For writing the code
Materials and Tools:
- Arduino Nano.
- IEFSR sensor.
- Neopixel ring.
- Buzzer.
- Bread board.
- Adapter 9v.
- On/Off switch.
- Jumper wires.
- PLA.
Machines:
- PRUSA i3 MK2 3D Printer.
Design:
My design is a cylinder will contain the components. my challenge wasn’t in the form but how to make each component fit easily and fixed accurately in the base of the enclosure to make the cylinder small as much as possible and to be sure that nothing will move or hinder action of any component. So I started with testing, wiring and coding to know how will the components arranged and fixed together and the total diameter and height of the enclosure.
1- started with testing the Neopixel ring by downloading Adafruit Neopixel library and test different examples.
2- testing the IEFSR sensor and trying to know how it works. what makes its sensitivity more accurate. so I searched for the wiring and test different resistors to enhance the sensor sensitivity.
3- tried different codes for the Neopixel then choose a simplified one that match my function and make the same with the IEFSR sensor and the buzzer.
4- Divide and concer by writing a code for each function/component separately then integrate them in one code .
For the 3d model:
- I started by measuring my components ( Arduino- Breadboard ) by digital caliper to get accurate dimensions and make a clearance that make them fit well and fixed.
- arrange them in the smallest circle that can contain them.
- measure the components height too to know the coaster height and make walls around them to fix them well it their places. also leave a good space to the wires.
- modeling the components ( Arduino- Breadboard - Neopixel ring ) to imagine the space well and make an accurate clearance.
- make a sketch for the walls rounding the components and extrude it.
- make the edge sketch by a good thickness to make a screw in and revolve it so I have the base part now.
- make the cap sketch by making a space for the Neopixel ring to be fixed in.
- make a screw in the the cap that can fit the base’s screw so I can get a closed cylinder to be my coaster containing the components.
- open slots for the on/off switch and the adapter socket by measuring them and make sketches and extrude them in 2 sides till meet the surface of the cylinder.
So after the design I realized that attaching the IEFSR sensor in the bottom of the cap which is fixed in the base by the screw affect the sensitivity of the sensor and make it doesn't work sometimes because any load on the cap will be distributed to the edges as long as the cap is fixed to the base. So the cap should be free and based only on the sensor to sense all the load.
So I had to edit the design to meet the purpose as fellow:
- cancel the screw and reduce the thickness of the cylinder.
- make a cylinder in the middle of the base between the Arduino and Breadboard with the same height of the base edges so it can meet the bottom of the cap and attach the sensor on it to sense all the load from the cap.
- make the sensor area start with a rectangle from the base for not taking up too much space between components until exceeding the components height then complete as a cylinder with the sensor diameter by Loft feature.
- make the walls around the components with less height.
- make the cap smaller than the base diameter with four chamfered parts attached to the edges to protect it from tilting when under pressure.
3d printing preparations :
- I open the STL files in Cura for Slicing and estimate the printing time and the PLA weight needed at first.
- Open every part and adjust the settings as fellow:
- Layer height (.3) ( extra fast).
- Infill (10%).
- Support (None).
- Build plate adhesion (Prim).
- Nozzle temp (215) Bed temp (60).
For 3d printer operating :
I transferred the Gcode file into the SD card and operate the machine as follow :
insert the SD card into the printer.
Choose the unloaded option to change the filament.
- White for the base.
- transparent for the cap so the light would be seen.
Using a flush trip pliers to cut the new color filament into a sharp end so the extruder can take it easily.
Choose loading the new filament.
After confirming the filament is clean I start printing.
Choose print from SD card.
7. Choose my file and started printing.
I started to build my circuit on Tinker CAD which is composed of:
Brain:
Arduino Nano.
Input Components:
FSR sensor.
Action Components:
Neopixel RGB Ring.
Buzzer.
Power Management:
5v Adaptor is suitable for the Neopixel ring and buzzer.
Connections:
The Neopixel ring goes to Pin 6.
The Buzzer goes to Pin 3.
FSR goes to Pin A0.
Common Negative (from the Breadboard) can go to any of the GND (Ground) pins.
Common Positive (from the Breadboard) can go to the 5V pin.
I have 4 components need power in my project:
1- Arduino needs 5 volt and from its 5V pin.
2- FSR sensor needs 5 volt.
3- Buzzer needs 5 volt.
4- Neopixel ring needs 5 volt.
I used a 5 volt adaptor and it was fine with the Neopixel and FSR sensor.
As FSR and Neopixel ring are new components to me and this is the first time I use so I started to search how each component work.
I started with the Neopixel and use a simplified code to build up on it.
-Install the Adafruit Neopixel library.
-define pin 6 connected to the Neopixel ring.
-define the number of Neopixel led.
-adjust the values of RGB to each color.
- run the code and test.
Search how FSR sensor work and get a code and try to understand how it work and test it multiple times as the sensitivity was so weak at first till I discovered that it needs a big resistance to work well by connecting the sensor with different potentiometers to know the suitable resistance value that was 50 Ohm or more.
Integrate the sensor code with the Neopixel ring code to control the colors of the ring according to the sensitivity of the FSR sensor to water weight as fellow:
-defining the variables.
-defining the output and input pins.
-connect between sensor readings and the ring colors by If conditions.
Now I want a buzzer to alarm me every hour to drink so I found a function that called Millis that work as an alarm in Arduino so I get a simplified code for blinking a led with Millis functions and understand how it works so I ca apply on the buzzer. So I build up on the code of the FSR with the Neopixel ring by adding the buzzer code to get my final code.
So the final code will work as fellow:
-include the Neopixel library.
-define the Neopixel and buzzer pins as outputs.
-define the RGB variables of the colors I want.
-define the FSR reading.
So the overall function of the code will described in If conditions as fellow:
- If the FSR reading was between 875 and 1023 then make the Neopixel Red.
- If the FSR reading was between 790 and 875 then make the Neopixel Yellow.
- If the FSR reading was between 700 and 790 then make the Neopixel Green.
- If the FSR reading was between 600 and 700 then make the Neopixel Blue.
- If the FSR reading was between 0 and 600 then make the Neopixel White.
And the buzzer is working according to the Millis function that calculate the time once the code run and preserve it in Millis variable to be added to the rememberTime variable which =0 to be compared with the onDuration variable and offDuration variables which I define them with the periods I want for turning the buzzer on and off. So the buzzer will alarm me every hour by ringing for 3 seconds but in the code I make it ring every minute for the demo.
#include <Adafruit_NeoPixel.h>
defining the variables
#define PIN 6
#define NUM_LIGHTS 16
int fsrPin = A0;
int fsrReading;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LIGHTS, PIN, NEO_GRB + NEO_KHZ800);
uint32_t NOLIGHT = strip.Color(0, 0, 0);
uint32_t RED = strip.Color(255, 0, 0);
uint32_t YELLOW = strip.Color(255, 255, 0);
uint32_t GREEN = strip.Color(0, 255, 0);
uint32_t BLUE = strip.Color(0, 0, 255);
uint32_t WHITE = strip.Color(255, 255, 255);
const int BUZZERpin = 3;
const long onDuration = 2000;//
const long offDuration = 60000;//
int BUZZERState =LOW;// initial state of BUZZER
long rememberTime=0;// this is used by the code
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
pinMode(BUZZERpin,OUTPUT);// define LEDpin as output
digitalWrite(BUZZERpin,BUZZERState);// set initial state
Serial.begin(9600);
}
void loop() {
delay(500);
fsrReading = analogRead(fsrPin);
Serial.println("Analog reading = ");
Serial.println(fsrReading);
Serial.println(millis());
comparing the FSR sensor readings with the values of RGB leds
if ((fsrReading > 875) && (fsrReading <= 1023)) {
for( int i = 0; i<NUM_LIGHTS; i++){
strip.setPixelColor(i, RED);
strip.show(); }
}
else if ((fsrReading > 790) && (fsrReading <= 875)) {
for( int i = 0; i<NUM_LIGHTS; i++){
strip.setPixelColor(i, YELLOW);
strip.show(); }
}
else if ((fsrReading > 700) && (fsrReading <= 790)) {
for( int i = 0; i<NUM_LIGHTS; i++){
strip.setPixelColor(i, GREEN);
strip.show(); }
}
else if ((fsrReading > 600) && (fsrReading <= 700)) {
for( int i = 0; i<NUM_LIGHTS; i++){
strip.setPixelColor(i, BLUE);
strip.show(); }
}
else if ((fsrReading > 200) && (fsrReading <= 600)) {
for( int i = 0; i<NUM_LIGHTS; i++){
strip.setPixelColor(i, WHITE);
strip.show(); }
}
if( BUZZERState ==HIGH )
{
if( (millis()- rememberTime) >= onDuration){
BUZZERState = LOW;// change the state of LED
rememberTime=millis();// remember Current millis() time
}
}
else
{
if( (millis()- rememberTime) >= offDuration){
BUZZERState =HIGH;// change the state of LED
rememberTime=millis();// remember Current millis() time
}
}
digitalWrite(BUZZERpin,BUZZERState);// turn the LED ON or OFF
}
As my parts were 3d printed so they don’t need any finishing or assembling so just put every component on its place as fellow.
Assembly of the enclosure parts together
Test the circuit and the FSR sensitivity by hand pressure to se the Neopixel ring output colors according to the different pressure and sreial monitor values.
Testing with a bottle full of water to see the Neopixel Color changing to red according to the high value of the FSR reading on serial monitor. So this is the range for red color.
Taking the bottle off the coaster to see the ring’s color changing from red to white that indicate the lowest load applied on the FSR sensor. Sometimes it blinks between blue and white as the transition between their values is in a small range.
Neopixel gives the blue color with a lowest level of water.
Neopixel gives the yellow color with a different level of water.
Neopixel gives the green color with a medium level of water.
I have suggestions to make print this cap in white PLA so it will reduce the reduce the exposure.
-printing failure in the cap and reprint it again.
-soo many times stuck in trials to understand the FSR sensor, testing, wiring and enhancing the sensitivity.
-After finishing the design on fusion 360 then discovered that it isn’t suitable for the sensor efficiency so I had to make a new design as fellow:
I realized that attaching the IEFSR sensor in the bottom of the cap which is fixed in the base by the screw affect the sensitivity of the sensor and make it doesn't work sometimes because any load on the cap will be distributed to the edges as long as the cap is fixed to the base. So the cap should be free and based only on the sensor to sense all the load.
So I had to edit the design to meet the purpose as fellow:
- cancel the screw and reduce the thickness of the cylinder.
- make a cylinder in the middle of the base between the Arduino and Breadboard with the same height of the base edges so it can meet the bottom of the cap and attach the sensor on it to sense all the load from the cap.
- make the sensor area start with a rectangle from the base for not taking up too much space between components until exceeding the components height then complete as a cylinder with the sensor diameter by Loft feature.
- make 2 gussets with the middle cylinder for supporting and strengthening.
- make the walls around the components with less height.
- make the cap smaller than the base diameter with four chamfered parts attached to the edges to protect it from tilting when under pressure.
Printing failure in the cap and reprint it again.
Other problem was wire jam in the enclosure and I found that the pins has no space to get out from the Arduino as it is rubbing in the edges So I detache the Arduino from its base connector as I has pins I can connect jumpers directly to.
They attached and detached like that
So it saves a nice space for wires and to make sure that the jumpers won’t get out of pins I use heat shrink to fix them
-I will try a different ways for more simplified wiring without breadboard maybe or making a path for it.