Go Down

Topic: Stop Watch (solved) (Read 232 times) previous topic - next topic

mrteach

Jul 08, 2018, 08:13 pm Last Edit: Jul 12, 2018, 11:36 pm by mrteach
So using various sources I've been making a stop watch device.

One issue I'm having is that I'm trying to make my colon more centred and everytime I try to adjust

Code is the one with colon centered but ruins all the other numbers

Code: [Select]

// include the library
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// initialize the interface pins
LiquidCrystal_I2C lcd(0x3f,16,2); // 0x20 is adresss for LCC 16x2

// the 8 arrays that form each segment of the custom numbers
byte bar1[8] =
{
        B11100,
        B11110,
        B11110,
        B11110,
        B11110,
        B11110,
        B11110,
        B11100
};
byte bar2[8] =
{
        B00111,
        B01111,
        B01111,
        B01111,
        B01111,
        B01111,
        B01111,
        B00111
};
byte bar3[8] =
{
        B11111,
        B11111,
        B00000,
        B00000,
        B00000,
        B00000,
        B11111,
        B11111
};
byte bar4[8] =
{
        B11110,
        B11100,
        B00000,
        B00000,
        B00000,
        B00000,
        B11000,
        B11100
};
byte bar5[8] =
{
        B01111,
        B00111,
        B00000,
        B00000,
        B00000,
        B00000,
        B00011,
        B00111
};
byte bar6[8] =
{
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B11111,
        B11111
};
byte bar7[8] =
{
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00111,
        B01111
};
byte bar8[8] =
{
        B11111,
        B11111,
        B11111,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000
};
byte bar9[8] =
{
        B00000,
        B00000,
        B11111,
        B11111,
        B11111,
        B11111,
        B00000,
        B00000
};


// variables will change:
int value = 0;

//Timing
const byte interruptPin1 = 2;
const byte interruptPin2 = 3;
int state = LOW;
int led = 10;

//Backlight Brightness
int backlightPin = 6;
int brightness = 50;

void setup()
{
  lcd.begin();
  // assignes each segment a write number
  lcd.createChar(1,bar1);
  lcd.createChar(2,bar2);
  lcd.createChar(3,bar3);
  lcd.createChar(4,bar4);
  lcd.createChar(5,bar5);
  lcd.createChar(6,bar6);
  lcd.createChar(7,bar7);
  lcd.createChar(8,bar8);
  lcd.createChar(9,bar9);
 lcd.backlight(); //backlight is now ON
 
 // initialize the pushbutton pin as an input:
  pinMode(interruptPin1, INPUT_PULLUP);
  pinMode(interruptPin2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), resetvalue, CHANGE);
  attachInterrupt(digitalPinToInterrupt(interruptPin2), startstop, CHANGE);

  pinMode(led, OUTPUT);
  pinMode(backlightPin, OUTPUT);
  state = LOW;
  digitalWrite(led, LOW);
  analogWrite(backlightPin, brightness);
}

void customcol(int col)
{ // uses segments to build the colon
  lcd.setCursor(col, 0);
  lcd.write(9);
  lcd.setCursor(col,1);
  lcd.write(9);
}


void custom0(int col)
{ // uses segments to build the number 0
  lcd.setCursor(col, 0);
  lcd.write(2); 
  lcd.write(8);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(2); 
  lcd.write(6); 
  lcd.write(1);
}

void custom1(int col)
{
  lcd.setCursor(col,0);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
  lcd.setCursor(col,1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom2(int col)
{
  lcd.setCursor(col,0);
  lcd.write(5);
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(2);
  lcd.write(6);
  lcd.write(6);
}

void custom3(int col)
{
  lcd.setCursor(col,0);
  lcd.write(5);
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(7);
  lcd.write(6);
  lcd.write(1);
}

void custom4(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(6);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom5(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(3);
  lcd.write(4);
  lcd.setCursor(col, 1);
  lcd.write(7);
  lcd.write(6);
  lcd.write(1);
}

void custom6(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(3);
  lcd.write(4);
  lcd.setCursor(col, 1);
  lcd.write(2);
  lcd.write(6);
  lcd.write(1);
}

void custom7(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(8);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom8(int col)
{
  lcd.setCursor(col, 0);
  lcd.write(2); 
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(2); 
  lcd.write(6); 
  lcd.write(1);
}

void custom9(int col)
{
  lcd.setCursor(col, 0);
  lcd.write(2); 
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(7); 
  lcd.write(6); 
  lcd.write(1);
}

void printNumber(int value, int col) {
  if (value == 0) {
    custom0(col);
  } if (value == 1) {
    custom1(col);
  } if (value == 2) {
    custom2(col);
  } if (value == 3) {
    custom3(col);
  } if (value == 4) {
    custom4(col);
  } if (value == 5) {
    custom5(col);
  } if (value == 6) {
    custom6(col);
  } if (value == 7) {
    custom7(col);
  } if (value == 8) {
    custom8(col);
  } if (value == 9) {
    custom9(col);
  }     


void printRPM(int rpm) {
  int n, m , c, d, u, number;
  number = rpm;
 if (number > 5999) {
    n = (number - (number % 6000)) / 6000;
    number = number % 6000;
  } else {
    n = 0;
  }
  if (number > 599) {
    m = (number - (number % 600)) / 600;
    number = number % 600;
  } else {
    m = 0;
  } 
 
  if (number > 59) {
    c = (number - (number % 60)) / 60;
    number = number % 60;
  } else {
    c = 0;
  } 

  if (number > 9) {
    d = (number - (number % 10)) / 10;
    number = number % 10;
  } else {
    d = 0;
  }
  u = number;
 
  lcd.setCursor(0, 0);
  //printNumber(n, 0);
  printNumber(m, 3);
  printNumber(c, 6);
  customcol (9);
  printNumber(d, 10);
  printNumber(u, 13);
}

void startstop(){
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 200ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 300)
 {
   state = !state;
   digitalWrite(led, !digitalRead(led));
 }
 last_interrupt_time = interrupt_time;
}

void valueup()
{
  delay (1000);
  value=value +1; 
}

void resetvalue(){
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 200ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 300)
 {
   value = 0;
 }
 last_interrupt_time = interrupt_time;
}


void loop(){
printRPM(value);
if (state ==HIGH){
  valueup();
  }
}




mrteach

#1
Jul 08, 2018, 08:59 pm Last Edit: Jul 08, 2018, 09:10 pm by mrteach
Original Code with working colon (but not centred colon)

Code: [Select]

// include the library
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// initialize the interface pins
LiquidCrystal_I2C lcd(0x3f,16,2); // 0x20 is adresss for LCC 16x2

// the 8 arrays that form each segment of the custom numbers
byte bar1[8] =
{
        B11100,
        B11110,
        B11110,
        B11110,
        B11110,
        B11110,
        B11110,
        B11100
};
byte bar2[8] =
{
        B00111,
        B01111,
        B01111,
        B01111,
        B01111,
        B01111,
        B01111,
        B00111
};
byte bar3[8] =
{
        B11111,
        B11111,
        B00000,
        B00000,
        B00000,
        B00000,
        B11111,
        B11111
};
byte bar4[8] =
{
        B11110,
        B11100,
        B00000,
        B00000,
        B00000,
        B00000,
        B11000,
        B11100
};
byte bar5[8] =
{
        B01111,
        B00111,
        B00000,
        B00000,
        B00000,
        B00000,
        B00011,
        B00111
};
byte bar6[8] =
{
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B11111,
        B11111
};
byte bar7[8] =
{
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000,
        B00111,
        B01111
};
byte bar8[8] =
{
        B11111,
        B11111,
        B11111,
        B00000,
        B00000,
        B00000,
        B00000,
        B00000
};
byte bar9[8] =
{
        B00000,
        B00000,
        B11111,
        B11111,
        B11111,
        B11111,
        B00000,
        B00000
};


// variables will change:
int value = 0;

//Timing
const byte interruptPin1 = 2;
const byte interruptPin2 = 3;
int state = LOW;
int led = 10;

//Backlight Brightness
int backlightPin = 6;
int brightness = 50;

void setup()
{
  lcd.begin();
  // assignes each segment a write number
  lcd.createChar(1,bar1);
  lcd.createChar(2,bar2);
  lcd.createChar(3,bar3);
  lcd.createChar(4,bar4);
  lcd.createChar(5,bar5);
  lcd.createChar(6,bar6);
  lcd.createChar(7,bar7);
  lcd.createChar(8,bar8);
  lcd.createChar(9,bar9);
 lcd.backlight(); //backlight is now ON
 
 // initialize the pushbutton pin as an input:
  pinMode(interruptPin1, INPUT_PULLUP);
  pinMode(interruptPin2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), resetvalue, CHANGE);
  attachInterrupt(digitalPinToInterrupt(interruptPin2), startstop, CHANGE);

  pinMode(led, OUTPUT);
  pinMode(backlightPin, OUTPUT);
  state = LOW;
  digitalWrite(led, LOW);
  analogWrite(backlightPin, brightness);
}

void customcol(int col)
{ // uses segments to build the colon
  lcd.setCursor(col, 0);
  lcd.write(9);
  lcd.setCursor(col,1);
  lcd.write(9);
}


void custom0(int col)
{ // uses segments to build the number 0
  lcd.setCursor(col, 0);
  lcd.write(2); 
  lcd.write(8);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(2); 
  lcd.write(6); 
  lcd.write(1);
}

void custom1(int col)
{
  lcd.setCursor(col,0);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
  lcd.setCursor(col,1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom2(int col)
{
  lcd.setCursor(col,0);
  lcd.write(5);
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(2);
  lcd.write(6);
  lcd.write(6);
}

void custom3(int col)
{
  lcd.setCursor(col,0);
  lcd.write(5);
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(7);
  lcd.write(6);
  lcd.write(1);
}

void custom4(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(6);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom5(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(3);
  lcd.write(4);
  lcd.setCursor(col, 1);
  lcd.write(7);
  lcd.write(6);
  lcd.write(1);
}

void custom6(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(3);
  lcd.write(4);
  lcd.setCursor(col, 1);
  lcd.write(2);
  lcd.write(6);
  lcd.write(1);
}

void custom7(int col)
{
  lcd.setCursor(col,0);
  lcd.write(2);
  lcd.write(8);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(32);
  lcd.write(32);
  lcd.write(1);
}

void custom8(int col)
{
  lcd.setCursor(col, 0);
  lcd.write(2); 
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(2); 
  lcd.write(6); 
  lcd.write(1);
}

void custom9(int col)
{
  lcd.setCursor(col, 0);
  lcd.write(2); 
  lcd.write(3);
  lcd.write(1);
  lcd.setCursor(col, 1);
  lcd.write(7); 
  lcd.write(6); 
  lcd.write(1);
}

void printNumber(int value, int col) {
  if (value == 0) {
    custom0(col);
  } if (value == 1) {
    custom1(col);
  } if (value == 2) {
    custom2(col);
  } if (value == 3) {
    custom3(col);
  } if (value == 4) {
    custom4(col);
  } if (value == 5) {
    custom5(col);
  } if (value == 6) {
    custom6(col);
  } if (value == 7) {
    custom7(col);
  } if (value == 8) {
    custom8(col);
  } if (value == 9) {
    custom9(col);
  }     


void printRPM(int rpm) {
  int n, m , c, d, u, number;
  number = rpm;
 if (number > 5999) {
    n = (number - (number % 6000)) / 6000;
    number = number % 6000;
  } else {
    n = 0;
  }
  if (number > 599) {
    m = (number - (number % 600)) / 600;
    number = number % 600;
  } else {
    m = 0;
  } 
 
  if (number > 59) {
    c = (number - (number % 60)) / 60;
    number = number % 60;
  } else {
    c = 0;
  } 

  if (number > 9) {
    d = (number - (number % 10)) / 10;
    number = number % 10;
  } else {
    d = 0;
  }
  u = number;
 
  lcd.setCursor(0, 0);
  //printNumber(n, 0);
  printNumber(m, 3);
  printNumber(c, 6);
  customcol (9);
  printNumber(d, 10);
  printNumber(u, 13);
}

void startstop(){
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 200ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 300)
 {
   state = !state;
   digitalWrite(led, !digitalRead(led));
 }
 last_interrupt_time = interrupt_time;
}

void valueup()
{
  delay (1000);
  value=value +1; 
}

void resetvalue(){
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 200ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 300)
 {
   value = 0;
 }
 last_interrupt_time = interrupt_time;
}


void loop(){
printRPM(value);
if (state ==HIGH){
  valueup();
  }
}

odometer

Code: [Select]

  // assignes each segment a write number
  lcd.createChar(1,bar1);
  lcd.createChar(2,bar2);
  lcd.createChar(3,bar3);
  lcd.createChar(4,bar4);
  lcd.createChar(5,bar5);
  lcd.createChar(6,bar6);
  lcd.createChar(7,bar7);
  lcd.createChar(8,bar8);
  lcd.createChar(9,bar9);

You can only have eight custom characters.

You are trying to have nine custom characters. With this kind of display, that cannot work. What I believe will happen is that character #9 will replace character #1. (Is that what you see happening?)

If you really want your colon, you will need to find another solution.
Here is a datasheet: https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
If you look at pages 17 and 18 of that datasheet, you will see two character sets. I do not know which, if either, your display uses: you will have to experiment to find out. Try displaying characters from whatever character set your display already has.

If all else fails, you could give up on your colon and just display an 'm' after the minutes and an 's' after the seconds.


odometer

Code: [Select]

void valueup()
{
  delay (1000);
  value=value +1; 
}


There is another problem. A stopwatch based on delay() probably will not keep accurate time. (Try testing it against your wristwatch or a smartphone timer.)

marco_c

#4
Jul 12, 2018, 05:29 am Last Edit: Jul 12, 2018, 05:34 am by marco_c
When you define a custom character, the on-display representation changes (updates) to reflect the change - see https://arduinoplusplus.wordpress.com/2018/01/23/lcd-module-pushwheel-animation/ as an example that creates animation.

This open the possibility to just display the characters and then change the definition to update the display. hh:mm:ss uses exactly 7 characters (: is the same character).

Alternatively you can define characters to make the seven segment 'look'. This is explained here https://arduinoplusplus.wordpress.com/2016/07/04/double-height-digits-on-a-character-lcd-module/.

Hopefully this make sense.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

mrteach

You can only have eight custom characters.

You are trying to have nine custom characters. With this kind of display, that cannot work. What I believe will happen is that character #9 will replace character #1. (Is that what you see happening?)

If you really want your colon, you will need to find another solution.
Here is a datasheet: https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
If you look at pages 17 and 18 of that datasheet, you will see two character sets. I do not know which, if either, your display uses: you will have to experiment to find out. Try displaying characters from whatever character set your display already has.

If all else fails, you could give up on your colon and just display an 'm' after the minutes and an 's' after the seconds.


Really..  Ah didn't know there was a limit to custom characters.  I believe that 9 was taking over 1.  Makes perfect sense then.  Thanks.


Code: [Select]

void valueup()
{
  delay (1000);
  value=value +1; 
}


There is another problem. A stopwatch based on delay() probably will not keep accurate time. (Try testing it against your wristwatch or a smartphone timer.)
Yup I did that a while a go and fixed the time (still used delays) and its very close to 99 minutes.



When you define a custom character, the on-display representation changes (updates) to reflect the change - see https://arduinoplusplus.wordpress.com/2018/01/23/lcd-module-pushwheel-animation/ as an example that creates animation.

This open the possibility to just display the characters and then change the definition to update the display. hh:mm:ss uses exactly 7 characters (: is the same character).

Alternatively you can define characters to make the seven segment 'look'. This is explained here https://arduinoplusplus.wordpress.com/2016/07/04/double-height-digits-on-a-character-lcd-module/.

Hopefully this make sense.
I think I understand.  Thanks may try that in the future.

Go Up