/*
* Convince Them Its Clean
*
* An Arduino, display, and accelerometer are attached to a cleaning bottle.
* The display shows the number of minutes since it was last moved.
*
* For full instructions and the accompanying circuit, see the
* project entitled "Convince Them It's Clean" on hackster.io by amamitof7.
*
*
*
*
* Copyright (C) 2020 Andrea Mitofsky
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A copy of the GNU General Public License is available at <https://www.gnu.org/licenses></https:>.
*
*
*/
#include<Wire.h>
//Define Pin Names
#define cathodeE_pin 9
#define cathodeD_pin 8
#define cathodeC_pin 7
#define cathodeG_pin 6
#define anode4_pin 5
#define cathodeB_pin 4
#define anode3_pin 2
#define anode2_pin 3
#define cathodeF_pin 12
#define cathodeA_pin 11
#define anode1_pin 10
//Define Global Variables
//Tol represents the tolerance of the accelerometer. If the numbers reset when they should not, try raising tol.
//If the numbers do not reset unless the accelerometer moves significantly, try lowering tol.
int tol=800;
//timeMax represents the minutes until the message "USE ME" is displayed.
int timeMax=480;
//timeDiff represents the milliseconds needed to increment the display. To inccrement each minute, set this to 60000.
unsigned long timeDiff=60000;
const int MPU6050_addr=0x68;
unsigned long zeroTime=0;
unsigned long updateTime=0;
unsigned long msgTime=0;
int minSinceUse=0;
int16_t origX, origY, origZ;
int msg=1; //0=use and 1=me
/*The setup function sets up the output pins and accelerometer.*/
void setup() {
// Set up the IO pins
pinMode(cathodeA_pin, OUTPUT);
pinMode(cathodeB_pin, OUTPUT);
pinMode(cathodeC_pin, OUTPUT);
pinMode(cathodeD_pin, OUTPUT);
pinMode(cathodeE_pin, OUTPUT);
pinMode(cathodeF_pin, OUTPUT);
pinMode(cathodeG_pin, OUTPUT);
pinMode(anode1_pin,OUTPUT);
pinMode(anode2_pin, OUTPUT);
pinMode(anode3_pin,OUTPUT);
pinMode(anode4_pin, OUTPUT);
//Set up the accelerometer
Wire.begin();
Wire.beginTransmission(MPU6050_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
//Set up variables for timing and for the accelerometer
zeroTime=millis();
updateTime=zeroTime;
minSinceUse=0;
Wire.beginTransmission(MPU6050_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU6050_addr,14,true);
origX=Wire.read()<<8|Wire.read();
origY=Wire.read()<<8|Wire.read();
origZ=Wire.read()<<8|Wire.read();
}
/* The function Loop runs repeatedly.*/
void loop() {
unsigned long currentTime;
//Check the accelerometer, and reset time if needed.
hasItMoved();
//Check the time, and update the display.
currentTime=millis();
if((currentTime-updateTime)>timeDiff)
{
minSinceUse++;
updateTime=currentTime;
}
displayNumber(minSinceUse);
}
/* The function displayNumber accepts an integer, picks off the digits, and calls the displayDigit function
* to display it. If the number is bigger than timeMax, "USE ME" is displayed.
*/
void displayNumber(int inNum)
{
int dig1, dig2, dig3, dig4;
if((inNum>timeMax)||(inNum<0))
{
useMe();
}
else
{
//Pick off each digit and display it
dig4=inNum%10;
dig3=((inNum-dig4)%100)/10;
dig2=((inNum-dig3-dig4)%1000)/100;
dig1=((inNum-dig2-dig3-dig4)%10000)/1000;
//Display the digits
displayDigit(dig1);
digitalWrite(anode1_pin,HIGH);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
delay(5);
displayDigit(dig2);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, HIGH);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
delay(5);
displayDigit(dig3);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, HIGH);
digitalWrite(anode4_pin, LOW);
delay(5);
displayDigit(dig4);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, HIGH);
delay(5);
}
}
/* The function hasItMoved checks the accelerometer. If it has moved, the variable minSinceUse is reset and other variables are set.
* The following site was used as a reference for code for the accelerometer:
* https://www.electronicshub.org/getting-started-arduino-mpu6050/
*
*/
int hasItMoved()
{
int16_t AccX,AccY,AccZ;
//Check the accelerometer
Wire.beginTransmission(MPU6050_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU6050_addr,14,true);
AccX=Wire.read()<<8|Wire.read();
AccY=Wire.read()<<8|Wire.read();
AccZ=Wire.read()<<8|Wire.read();
//If the device moved, reset time to zero
if((abs(AccX-origX)>tol)||(abs(AccY-origY)>tol)||(abs(AccZ-origZ)>tol))
{
minSinceUse=0;
zeroTime=millis();
updateTime=zeroTime;
}
return 0;
}
/* The function useMe displays the message "USE ME".*/
void useMe()
{
unsigned long myTime;
myTime=millis();
if(abs(myTime-msgTime)>3000)
{
msgTime=myTime;
//switch the message
if(msg==0)
{msg=1;}
else
{msg=0;}
}
if(msg==0)
{
//Display U
digitalWrite(cathodeA_pin, HIGH);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, HIGH);
digitalWrite(anode1_pin, HIGH);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
delay(5);
//Display S
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, HIGH);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, HIGH);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
delay(5);
//Display E
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, HIGH);
digitalWrite(cathodeC_pin, HIGH);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, HIGH);
digitalWrite(anode4_pin, LOW);
delay(5);
//Last letter Blank
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
delay(5);
}
else
{
//Display Half of M
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, HIGH);
digitalWrite(cathodeD_pin, HIGH);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, HIGH);
digitalWrite(anode1_pin, HIGH);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
delay(5);
//Display Half of M
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, HIGH);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, HIGH);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, HIGH);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
delay(5);
//Display E
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, HIGH);
digitalWrite(cathodeC_pin, HIGH);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, HIGH);
digitalWrite(anode4_pin, LOW);
delay(5);
//Last letter Blank
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
digitalWrite(anode1_pin, LOW);
digitalWrite(anode2_pin, LOW);
digitalWrite(anode3_pin, LOW);
digitalWrite(anode4_pin, LOW);
}
}
/* The function displayDigit takes a digit as an input and lights up the corresponding pins of the display. */
void displayDigit(int inDigit)
{
switch(inDigit)
{
case 1:
{
digitalWrite(cathodeA_pin, HIGH);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin,HIGH);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, HIGH);
digitalWrite(cathodeG_pin, HIGH);
break;
}
case 2:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, HIGH);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, HIGH);
digitalWrite(cathodeG_pin, LOW);
break;
}
case 3:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, HIGH);
digitalWrite(cathodeG_pin, LOW);
break;
}
case 4:
{
digitalWrite(cathodeA_pin, HIGH);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, HIGH);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
break;
}
case 5:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, HIGH);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
break;
}
case 6:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, HIGH);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
break;
}
case 7:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, HIGH);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, HIGH);
digitalWrite(cathodeG_pin, HIGH);
break;
}
case 8:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
break;
}
case 9:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, HIGH);
digitalWrite(cathodeE_pin, HIGH);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, LOW);
break;
}
case 0:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeB_pin, LOW);
digitalWrite(cathodeC_pin, LOW);
digitalWrite(cathodeD_pin, LOW);
digitalWrite(cathodeE_pin, LOW);
digitalWrite(cathodeF_pin, LOW);
digitalWrite(cathodeG_pin, HIGH);
break;
}
default:
{
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeA_pin, LOW);
digitalWrite(cathodeA_pin, HIGH);
break;
}
}
}
Comments