Balázs Simon
Published © GPL3+

Medicine Packaging Powered by Amazon DRS

My vision of IoT medicine packaging.

IntermediateWork in progress5 hours1,554
Medicine Packaging Powered by Amazon DRS

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
Or any other microcontroller with network connection
×1
Resistor 10k ohm
Resistor 10k ohm
×10
Resistor 100k ohm
Resistor 100k ohm
SMD
×11
Conductive ink/glue
×1
Vitamin/Medicine in bubble package
×1
Wires
×1

Software apps and online services

AWS SNS
Amazon Web Services AWS SNS
Amazon Web Services Amazon Dash Replenishment
Blynk
Blynk

Story

Read more

Schematics

Design 1-2 schematics

The switches are representing the wires that will break when you release the pill

Design 1 - the package

Design 2 - the package

Design 3 schematics

Design 3 the package

Code

Sketch for design 1 and 2

Arduino
As design 1 and 2 are basically the same, this code will work with both of them
/**************************************************************
 * 
 * Medicine packaging powered by Amazon DRS sketch for design 1 and 2
 * More info:
 * https://www.hackster.io/Abysmal/medicine-packaging-powered-by-amazon-drs-2dda73
 *  
 * This project is made for "Amazon DRS Developer Challenge"
 * contest on hackster.io. More info:
 * https://www.hackster.io/contests/DRS
 * 
 * author: Balázs Simon
 *
 **************************************************************/


#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

#define DAY_IN_MILLIS 86400000  //25 hours in millis

char auth[] = "your auth";
char ssid[] = "your ssid";
char password[] = "your password";
SimpleTimer timer;

int pins[] = {16, 5, 4, 0, 2, 14, 12, 13, 15, 1};
int pills[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

WidgetLED pillsLEDs[10] = {
  WidgetLED(V1), 
  WidgetLED(V2), 
  WidgetLED(V3), 
  WidgetLED(V4), 
  WidgetLED(V5), 
  WidgetLED(V6), 
  WidgetLED(V7), 
  WidgetLED(V8), 
  WidgetLED(V9), 
  WidgetLED(V10)
};
WidgetLED thresholdReachedLED(V14);

int test = 0;
int remainingPills = 10;
int notified = 0;
int threshold = 2;
int autoReorder = 1;
int snooze = 3000;
int totalSnoozeTime = 0;

long millisAtLastPill = 0L;

void checkPills() {
  lookForPills();
  updateWLEDs();
  pillsTaken();
}

void setup() {
  
  for (int i = 0; i < 10; i++) {
    pinMode(pins[i], INPUT);
  }
  
  Blynk.begin(auth, ssid, password);
  timer.setInterval(1000, checkPills);
  
  thresholdReachedLED.off();
}

void loop() {
  Blynk.run();
  timer.run();
}

void lookForPills(){
  int temp = 0;  
  for(int i = 0; i < 10; i++){
    pills[i] = digitalRead(pins[i]) == 0 ? 1 : 0;
    temp += pills[i];
  }
  if(remainingPills != temp || temp == 10){
    millisAtLastPill = millis();
    remainingPills = temp;
  }
}

void updateWLEDs(){
  
  for(int i = 0; i < 10; i++){
    if(pills[i]){
      pillsLEDs[i].on();
    }
    else{
      pillsLEDs[i].off();
    }
    
    if(threshold >= remainingPills){
      thresholdReachedLED.on();
      if(!notified){
        if(autoReorder){
          Blynk.notify("You're about to run out of Vitamin C, but don't worry I ordered new ones from Amazon");
        }
        else{
          Blynk.notify("Attention! DRS is disabled for this device and you're about to run out of Vitamin C");
        }
        notified = 1;
      }
    }
  }
}

void pillsTaken(){
  if(remainingPills < 10 && remainingPills > 0 && millis() - millisAtLastPill > DAY_IN_MILLIS + totalSnoozeTime){
    Blynk.notify("You forgot to take your daily Vitamin C pill");
    totalSnoozeTime += snooze;
  }

  if(millis() - millisAtLastPill < DAY_IN_MILLIS){
    totalSnoozeTime = 0;
  }
}

BLYNK_WRITE(V0)
{
  threshold = param.asInt();
}

BLYNK_WRITE(V11)
{
  autoReorder = param.asInt();
}

BLYNK_WRITE(V12)
{
  notified = 1;
  Blynk.notify("I ordered new Vitamin C from Amazon");
}

BLYNK_WRITE(V15)
{
  snooze = 60 * param.asInt() * 1000;
}

Sketch for design 3 and IoT Post-IT

Arduino
This code is the modified version of version 1's code. It will work with design 3 and IoT Post-IT. The main difference is how the lookForPills() function works
/**************************************************************
 * 
 * Medicine packaging powered by Amazon DRS sketch for design 3 and IoT Post-IT
 * More info:
 * https://www.hackster.io/Abysmal/medicine-packaging-powered-by-amazon-drs-2dda73
 *  
 * This project is made for "Amazon DRS Developer Challenge"
 * contest on hackster.io. More info:
 * https://www.hackster.io/contests/DRS
 * 
 * author: Balázs Simon
 *
 **************************************************************/

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

#define DAY_IN_MILLIS 86400000  //24 hours in millis

char auth[] = "your auth";
char ssid[] = "your SSID";
char password[] = "your password";
SimpleTimer timer;

//int pins[] = {16, 5, 4, 0, 2, 14, 12, 13, 15, 1};
int pills[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
int analogInPin = A0;

WidgetLED pillsLEDs[10] = {
  WidgetLED(V1), 
  WidgetLED(V2), 
  WidgetLED(V3), 
  WidgetLED(V4), 
  WidgetLED(V5), 
  WidgetLED(V6), 
  WidgetLED(V7), 
  WidgetLED(V8), 
  WidgetLED(V9), 
  WidgetLED(V10)
};
WidgetLED thresholdReachedLED(V14);

int test = 0;
int remainingPills = 10;
int previousRemainingPills = 10;
int notified = 0;
int threshold = 2;
int autoReorder = 1;
int snooze = 3000;
int totalSnoozeTime = 0;

long millisAtLastPill = 0L;

void checkPills() {
  lookForPills();
  updateWLEDs();
  pillsTaken();
}

void setup() {

  Serial.begin(9600);
  Blynk.begin(auth, ssid, password);
  timer.setInterval(1000, checkPills);
  
  thresholdReachedLED.off();
}

void loop() {
  Blynk.run();
  timer.run();
}

void lookForPills(){

  int reading = analogRead(analogInPin);

  if(reading < 264){
    remainingPills = 0;
    pills[0] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 395){
    remainingPills = 1;
    pills[1] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 499){
    remainingPills = 2;
    pills[2] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 582){
    remainingPills = 3;
    pills[3] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 651){
    remainingPills = 4;
    pills[4] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 711){
    remainingPills = 5;
    pills[5] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 761){
    remainingPills = 6;
    pills[6] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 805){
    remainingPills = 7;
    pills[7] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 843){
    remainingPills = 8;
    pills[8] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  else if(reading < 877){
    remainingPills = 9;
    pills[9] = 0;
    if(previousRemainingPills != remainingPills){
      previousRemainingPills = remainingPills;
      millisAtLastPill = millis();
    }
  }
  Serial.println(millisAtLastPill);
  Serial.println(reading);
  Serial.println();
}

void updateWLEDs(){
  
  for(int i = 0; i < 10; i++){
    if(pills[i]){
      pillsLEDs[i].on();
    }
    else{
      pillsLEDs[i].off();
    }
    
    if(threshold >= remainingPills){
      thresholdReachedLED.on();
      if(!notified){
        if(autoReorder){
          Blynk.notify("You're about to run out of Vitamin C, but don't worry I ordered new ones from Amazon");
        }
        else{
          Blynk.notify("Attention! DRS is disabled for this device and you're about to run out of Vitamin C");
        }
        notified = 1;
      }
    }
  }
}

void pillsTaken(){
  if(remainingPills < 10 && remainingPills > 0 && millis() - millisAtLastPill > DAY_IN_MILLIS + totalSnoozeTime){
    Blynk.notify("You forgot to take your daily Vitamin C pill");
    totalSnoozeTime += snooze;
  }

  if(millis() - millisAtLastPill < DAY_IN_MILLIS){
    totalSnoozeTime = 0;
  }
}

BLYNK_WRITE(V0)
{
  threshold = param.asInt();
}

BLYNK_WRITE(V11)
{
  autoReorder = param.asInt();
}

BLYNK_WRITE(V12)
{
  notified = 1;
  Blynk.notify("I ordered new Vitamin C from Amazon");
}

BLYNK_WRITE(V15)
{
  snooze = 60 * param.asInt() * 1000;
}

Credits

Balázs Simon

Balázs Simon

12 projects • 85 followers

Comments