Goal / Habit / Medication Tracker Using ATTINY85

by glenzac in Circuits > Arduino

769 Views, 4 Favorites, 0 Comments

Goal / Habit / Medication Tracker Using ATTINY85

Goal_tracker_2018-Aug-21_06-00-42PM-000_CustomizedView31543827901_png.png
Goal_tracker_2018-Aug-21_08-26-08PM-000_CustomizedView17692731216_png.png
Goal_tracker_2018-Aug-21_06-40-02PM-000_CustomizedView34833863956_png.png
Goal_tracker_2018-Aug-21_08-23-57PM-000_CustomizedView23316504619_png.png
Goal_tracker_2018-Aug-21_08-25-07PM-000_CustomizedView1879998196_png.png

People tend to forget if they had that day's medication or not and this often leads to an overdose or totally skipping it. Both are dangerous in most cases.
This was the problem I was aiming to solve, but as I made it, I realised that I could use it also to track my daily habits or goals.

It will be a small device with 7 LED's that signify the 7 days of the week. The LED's turn on one after the other when a button is pressed. With the help of the potentiometer, one can track more than one goal. Just turn the pot to the required range and the LED's light up to show the count of that particular goal.

After completing the day's said task, one has to press the button and an additional LED lights up. Then turn the potentiometer to another goal (the LED's count changes ) and when that task's done, update it by pressing the button again. As mentioned above, this can also be used to track medicines one takes at different times of the day.

Getting Things Ready

Parts list:

  1. ATTINY85
  2. 74HC595 (Shift Register 8-Bit)
  3. Pushbutton
  4. Potentiometer 10K
  5. LED (7)
  6. 0.1 uF capacitor (3)
  7. 10uF capacitor
  8. 1K resistor (2)
  9. 10K resistor
  10. Perforated board
  11. 8 pin IC socket

Apart from this, you'll need a programmer to program the ATTINY85, wires, solder, Hot glue (not mandatory) and power source.

Note: Please do check out the 'Going Further' step for other design improvements and parts.

ATTINY85 programmer

You can either buy programmers like these or make one on your own if you have an Arduino lying around. Follow this guide here .

I made my own shield sort of programmer using the above guide, which I will be using here.

A Bit of Theory

shot.png

I recommend you read the following instructable to get a good picture of what we are trying to do.

https://www.instructables.com/id/Getting-more-IO-pins-on-ATTiny-with-Shift-Register/

With the shift register, one can control 7 LED's (or more using cascading) using just 3 pins. If you don't want to use another IC then try Charlieplexing but you'll only be able to control 6 LEDs (you can take a day off work :P) using the 3 pins.

I've simplified the circuit and the code as much as possible. I've added decoupling capacitors (for each IC) and a debouncing circuit for the pushbutton - They are very essential and should not be avoided.

Downloads

Making It

WP_20180807_18_44_30_Pro.jpg
WP_20180807_18_44_47_Pro.jpg
WP_20180807_18_44_53_Pro.jpg
WP_20180807_19_02_43_Pro.jpg
WP_20180807_19_03_11_Pro.jpg
WP_20180807_19_03_39_Pro.jpg
WP_20180807_19_04_02_Pro.jpg
WP_20180807_19_04_16_Pro.jpg
WP_20180807_19_08_51_Pro.jpg
WP_20180807_19_09_06_Pro.jpg
WP_20180807_19_50_50_Pro.jpg
WP_20180807_19_09_15_Pro.jpg
WP_20180807_19_50_41_Pro.jpg
WP_20180822_03_22_52_Pro.jpg
WP_20180822_03_23_47_Pro.jpg
WP_20180822_03_21_51_Pro.jpg
WP_20180822_03_23_43_Pro.jpg
WP_20180822_03_25_30_Pro.jpg
WP_20180822_03_25_37_Pro.jpg
WP_20180822_03_25_45_Pro.jpg
WP_20180822_03_26_04_Pro.jpg
WP_20180822_03_35_07_Pro.jpg
WP_20180822_03_35_13_Pro.jpg
Testing it
Moving lights
  • Put the LED's in and place the components at the required positions on the board (I've left space at the bottom of the perforated board for future upgrades).
  • In order to ensure that the part stays in place when we turn it face down (for soldering), I used some hot glue to do that. I find this easier than bending all the leads.
  • Solder the components onto the board.
  • Now make connections using solder and wires.
  • Verify all connections with a multimeter
  • Remove the hot glue
  • Program the ATTINY85 with the code given below
    • Board: ATtiny25/45/85
    • Processor: ATtiny85
    • Clock: Internal 8Mhz
    • Programmer: Arduino as ISP
  • Test it

POSSIBLE USES :

  • Daily goal tracker
  • Habits tracker
  • Medication tracking
  • Days left tracker (invert LED sequence in code)
  • Timer (alter the code to use the button for starting an internal timer)
  • Temperature intensity meter (using the inbuilt temperature sensor in the ATtiny85 - check this )

-------------------------------------------------------------------------------------------------------------------------------------------------

CODE

int latchPin = 2;	//Pin connected to pin 12 (RCK) of 74HC595<br>int clockPin = 0;	//Pin connected to pin 11 (SCK) of 74HC595
int dataPin = 1;	//Pin connected to pin 14 (SER) of 74HC595
int buttonPin=4; 	// for the pushbutton
int potPin=3;   	// for the potentiometer
int val=0;       	// to store the state of the button
int analog=0;    	// to store the value from ADC

//holders for infromation you're going to pass to shifting function
byte data;
byte dataArray[10];

void setup() {
 
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(buttonPin,INPUT);
  pinMode(potPin,INPUT);

  //predefined array to store the different LED configurations 
  //   => 0 = LED ON
  //   => 1 = LED OFF
  // IGNORE MSB VALUE AS WE ONLY HAVE 7 LED'S 
  dataArray[0] = 0xFF; //0b11111111 => All off
  dataArray[1] = 0xBF; //0b10111111
  dataArray[2] = 0x9F; //0b10011111
  dataArray[3] = 0x8F; //0b10001111
  dataArray[4] = 0x87; //0b10000111
  dataArray[5] = 0x83; //0b10000011
  dataArray[6] = 0x81; //0b10000001
  dataArray[7] = 0x80; //0b10000000 => All on

  // THIS PART LIGHTS UP ALL THE LEDS IN A SEQUENCE AT STARTUP
  for (int j = 0; j < 8; j++) {
    data = dataArray[j];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, data);
    digitalWrite(latchPin, 1);
    delay(50); // adjust as needed
  }
}

void loop() 
{

  val = digitalRead(buttonPin); // read button state
  analog=analogRead(potPin);    // read potentiometer value

  // Variable to store the count of the different tasks 
  //(can be increased as needed provided the potentiometer divisions are also increased )
  static int count1=0; // Task1
  static int count2=0; // Task2
  static int count3=0; // Task3

  // Potentiometer divisions:  [0-100 |  100-600 | 600-1023 ] => 3 divisions => 3 tasks   
  // TASK1
  if (analog <= 100)
  {
     if (count1 < 8) 
     {
    //load the LED sequence you want from array
    data = dataArray[count1];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, data);
    //return the latch pin high at the end of transmission
    digitalWrite(latchPin, 1);
    //adjust delay to adjust switch response 
    delay(50);
     }
     else
    {
      count1=0;  // reset count when the all 7 LEDs are lit
    }
  
  if(val == 0){
    count1++;  // increment count when switch becomes low (or is pressed :- since its pulled up )
   }
  }
  
  // TASK2
    if (analog > 100 && analog <= 600 )
  {
     if (count2 < 8) {
    //load the LED sequence you want from array
    data = dataArray[count2];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, data);
    //return the latch pin high at the end of transmission
    digitalWrite(latchPin, 1);
    //adjust delay to adjust switch response 
    delay(50);
   }
       else
    {
      count2=0;  // reset count when the all 7 LEDs are lit
    }
  if(val == 0){
    count2++;    // increment count when switch becomes low (or is pressed :- since its pulled up )
   }
  }

  //TASK3
   if (analog > 600)
  {
   if (count3 < 8) {
    //load the LED sequence you want from array
    data = dataArray[count3];
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, data);
    //return the latch pin high at the end of transmission
    digitalWrite(latchPin, 1);
    //adjust delay to adjust switch response 
    delay(50);
   }
   else
    {
      count3=0;  // reset count when the all 7 LEDs are lit
    }
  if(val == 0){
    count3++;   // increment count when switch becomes low (or is pressed :- since its pulled up )
   }
}
}

//--------------------------------------------------------------------------------------------------------

// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first,
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut�
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights.
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) )="" {=""      ="" pinstate="1;"    ="" }="" else="" }<="" p=""></i)>

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

   //stop shifting
  digitalWrite(myClockPin, 0);
}

Downloads

Going Further

Goal tracker v2.png

Design Improvements

  1. LEDs should have been soldered a little higher so that it sticks out of the surface when put in an enclosure.
  2. I observed that different LEDs had different brightness even though they were all identical in make. Then I came across this . Hence its advisable to use resistors in series with each LED.
  3. Use bigger buttons

Going Further

  1. 3D print the enclosure - the enclosure can be 3D printed as shown in the image and the engraved text can be filled with paint.
  2. Powering it from a Li-ion battery - I've tested and it works fine with a Li-ion battery since the ATtiny can work from 2.7V to 5.5V and the SN74HC595 works from 2V to 6V. I also plan to add a Li-ion charging circuit later and make it a standalone device.
  3. Putting the device to sleep - It would be great if the device could be put to sleep after a period of inactivity and made to wake up when there is a button press. This would also help improve the battery life by a great margin.
  4. Keeping data safe - By writing the count values to the inbuilt EEPROM the data can be kept safe and retrieved even after power down. Data can also be logged to later check monthly stats.[the only limitation here is the 10,000 write/erase cycles of the EEPROM ]

Do post your questions and suggestions in the comments section and I will be more than happy to help you out!