Hi, I need to create a stopwatch with arduino uno 8-segment 4 digit display. It has 3 buttons, the first starts/stops it, the second laps(the time still runs but it displays only the time when the button was pressed), and the third button resets the timer. The problem comes from displaying a float number, I am very confused by multiplexing and display logic in general and I would be very grateful by any guidance or advice, especially for displayNumber(). thank you.
#include "funshield.h"
constexpr int Button1 = button1_pin;
constexpr int Button2 = button2_pin;
constexpr int Button3 = button3_pin;
class Button {
public:
Button() {}
void setup(int pin) {
pinMode(pin, INPUT);
}
bool isPressed(int pin, bool wasDown) {
if(digitalRead(pin) == LOW && wasDown == HIGH){
wasDown = !wasDown;
return true;
}
return false;
}
};
class DisplayNumber {
public:
DisplayNumber() {}
void writeGlyph(byte glyph, byte pos_bitmask) {
digitalWrite(latch_pin, LOW);
shiftOut(data_pin, clock_pin, MSBFIRST, glyph);
shiftOut(data_pin, clock_pin, MSBFIRST, pos_bitmask);
digitalWrite(latch_pin, HIGH);
}
void setup(){
pinMode(latch_pin, OUTPUT);
pinMode(clock_pin, OUTPUT);
pinMode(data_pin, OUTPUT);
}
int countDigits(int num) {
int count = 0;
if (num == 0){
return 1;
}
while (num > 0) {
num /= 10;
count++;
}
return count;
}
void displayNumber(int integerPart, int fractionalPart) {
int integerDigits = countDigits(integerPart);
int i = 0;
for (i; i < integerDigits; i++) {
int digit = integerPart % 10;
writeGlyph(digits[digit], 1 << (integerDigits - 1 - i));
integerPart /= 10;
}
writeGlyph(dot, 0b0010);
writeGlyph(digits[fractionalPart], 0b0001);
}
private:
int dot = 0x7F;
};
Button button1;
Button button2;
Button button3;
DisplayNumber display;
class Time{
public:
float time = 0.0;
void run(){
counter();
display.displayNumber(getInt(time), getFract(time));
}
void stop(){
display.displayNumber(getInt(time), getFract(time));
}
void lap(){
display.displayNumber(getInt(time), getFract(time));
counter();
}
void reset(){
time = 0.0;
display.displayNumber(getInt(time), getFract(time));
}
float getTime(float time){
return time;
}
private:
int duration = 100;
void counter(){
while(time < 1000.0){
time += 0.1;
millisDelay(duration);
}
}
int getInt(float k){
k = (int)k;
return k;
}
int getFract(float k){
k = k - getInt(k);
return k * 10;
}
void millisDelay(int delayTime){
long int start_time = millis();
while ( millis() - start_time < delayTime) ;
}
};
class Control{
public:
Control() : mode("stop") {}
void theController(int button){
switch(button){
case 1:
if (mode == "run"){
time.stop();
mode = "stop";
}
else if(mode == "stop"){
time.run();
mode = "run";
}
break;
case 2:
if(mode == "run"){
time.lap();
mode = "lap";
}
else if(mode == "lap"){
time.run();
mode = "run";
}
break;
case 3:
if(mode == "stop"){
time.reset();
mode = "stop";
}
break;
}
}
private:
Time time;
String mode;
};
Control control;
void setup() {
button1.setup(Button1);
button2.setup(Button2);
button3.setup(Button3);
display.setup();
}
void loop() {
bool wasDown = button1.isPressed(Button1, false);
bool wasDown2 = button2.isPressed(Button2, false);
bool wasDown3 = button3.isPressed(Button3, false);
if(button1.isPressed(Button1, wasDown)) {
control.theController(1);
}
if(button2.isPressed(Button2, wasDown2)) {
control.theController(2);
}
if(button3.isPressed(Button3, wasDown3)){
control.theController(3);
}
}