/* PUSH UP COUNTER
An ultrasonic sensor measures the distance between you and your head, if the distance is larger than 20 cm a rgb-led will shine red,
if the distance is between 10 and 20 cm, it turns yellow
and if it is less than 10 cm it turns green, and a point appears on a lcd screen.
Every ten pushups it makes a sound.
You can reset the score with the push of a button.
*/
#include <LiquidCrystal_I2C.h> // include LCD library
#define F_CPU 1000000UL
#define BLUE 12 // define RGB-led pins
#define RED 10
void Delay_oneMs();
void Delay_oneS();
void Delay_Ms(int n);
const int trigPin = 8; //set pins for the ultrasonic sensor, button and buzzer
const int echoPin = 9;
int buttonPin = A0;
const int b = 13;
long duration; // set integers
int distance;
int i;
int buttonState = 0;
int x = 1;
int y = 1;
LiquidCrystal_I2C lcd(0x27, 16, 2); // set lcd pins
void Delay_oneMs() {
TCNT1H = 0xFC; // Load initial value for 16-bit timer
TCNT1L = 0x3B; // Adjust the initial value as needed
TCCR1A = 0x00; // Normal mode
TCCR1B = 0x03; // Normal mode, prescaler 64
while ((TIFR1 & (0x1 << TOV1)) == 0);
TCCR1B = 0x00; // Stop the timer
TIFR1 = 0x1 << TOV1; // Clear the overflow flag
}
void Delay_Ms(int n) {
for (int i = 0; i <= n; i++)
Delay_oneMs();
}
void Delay_oneS() {
TCNT1H = 0xFF; // Load initial value for 16-bit timer
TCNT1L = 0xC2; // Adjust the initial value as needed
TCCR1A = 0x00; // Normal mode
TCCR1B = 0x05; // Normal mode, prescaler 1024
while ((TIFR1 & (0x1 << TOV1)) == 0);
TCCR1B = 0x00; // Stop the timer
TIFR1 = 0x1 << TOV1; // Clear the overflow flag
}
void setup() {
DDRD &= ~(1 << 2); //Set button pin to be input with pullup
PORTD |= (1 << 2);
EICRA |= (1 << ISC01); //falling edge of INT0
EICRA &= ~(1 << ISC00);
EIMSK |= (1 << INT0); //Enable interrupts for INT0
sei();//Enable globa; interrupt
Serial.begin(9600); // begin in 9600 baud
DDRD |= (1 << 1); //Set pins to be input
DDRD &= ~((1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 0)); //Set pins to be output
// pinMode(trigPin, OUTPUT); //set pin modes
// pinMode(echoPin, INPUT);
// pinMode(buttonPin, INPUT);
// pinMode(b, OUTPUT);
// pinMode(RED, OUTPUT);
// pinMode(BLUE, OUTPUT);
lcd.begin(16, 2); // begin lcd, define scale of lcd (16 places in a row, 2 rows)
lcd.print("Push Ups:");
}
void loop() {
digitalWrite(trigPin, HIGH); // send out an ultra sonic sound for 10 microseconds and measure the time it took for the sound to go from the trigpin to the echo pin
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2; //convert the time the signal took to travel to distance in cm
if (distance >= 20) {
PORTD |= (1 << 2); /*&digitalWrite(RED, HIGH);*/ //configure RGB-led to burn red, magenta or blue depending on distance
PORTD &= ~(1 << 4);/*digitalWrite(BLUE, LOW);*/
}
if (distance <= 20) {
PORTD |= (1 << 4);/*digitalWrite(BLUE, HIGH);*/
}
if (distance <= 10) {
PORTD &= ~(1 << 2);/*digitalWrite(RED, LOW);*/
}
if (i == (10 * y) && x == (1 * y)) { //this if statement plays a sound every ten pushups
tone(b, 146.8);
Delay_Ms(50);
//delay(50);
noTone(b);
delay(100);
tone(b, 146.8);
Delay_Ms(50);
//delay(50);
noTone(b);
Delay_Ms(50);
//delay(50);
tone(b, 293.7);
Delay_Ms(100);
//delay(100);
noTone(b);
x ++;
y ++;
}
else if (distance <= 10) {
Delay_Ms(350); //delay(350); //this if else statement makes sure that the time between pushup-readings always stay the same
}
//buttonState = digitalRead(buttonPin); //these lines of code resets every integer and the lcd to the original state by the press of a button
if (buttonPin = 1) { //(buttonState == HIGH)
i = 0;
x = 1;
y = 1;
lcd.setCursor(0, 1);
lcd.print("0 ");
buttonPin = 0;
}
lcd.setCursor(0, 1); // set cursor on the second row
if (distance <= 10 ) {
i ++; //print a point if a pushup has been done
}
lcd.print(i, DEC);
while (distance <= 10) { //if the distance stays smaller then ten for a while, this piece of code makes sure that only one point is given for one pushup
PORTD |= (1 << 0); // digitalWrite(trigPin, HIGH);
Delay_Ms(10);// delayMicroseconds(10);
PORTD &= ~(1 << 0); // digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
Delay_Ms(100);
} //delay(100);
}
ISR(INT0_vect) {
buttonPin = 1;
}