Stopwatch and temperature sensors Moto Racing

Hello everyone.

I take this opportunity to introduce myself. I am new to Arduino, although I was always struck by the curiosity of these systems powerfully, I have never launched for a simple reason; I don't know what is said to program (bungling code yes, but to program .....)

But due to various circumstances, the idea of ​​a project that I wanted to develop came up and I finally launched Arduino. I am learning step by step and pulling a lot of Google and forums to progress ..... but I have reached a point that after trying it for several days, I can definitely say that I am "stuck". For many it will be a trifle or an easy solution to my problem, but I cannot implement it well.

Without further delay I expose you:

I am trying to make a display for my racing bike (endurance racing) that shows me the following; exhaust temperature sensor, cylinder temperature sensor and countdown timer with a push button to restart the stopwatch.

I bought an Arduino Uno, an ILI9341 tft display, thermocouple sensors, MAX6675 modules, and a bi-directional 5v to 3v converters for the display. I programmed and adapted all my code to my needs and so far everything was fine. But now my problems come;

I get the screen and sensors to work and I put the positions where I want everything to be shown, so far so good, but with the stopwatch I have problems. I can't get it to work with any accuracy.

At first I used a delay 1000 command to make it count down seconds, but it actually discounts badly. In a stopwatch minute, actually 1 minute is 12 real seconds. Searching for forums something similar, I see that they use the command of milis () but I don't know how to implement it well, nor that the code works.
On the other hand, I do not know how to implement the push button so that once it is switched it launches the stopwatch sequence again. (whether the account is finished or not)

This is my "clean" code for lack of integrating the discount command and the stopwatch start button.

#include <gfxfont.h>

#include "Fonts/FreeSans9pt7b.h"
#include <TFT_ILI9341.h>


#include <max6675.h>


#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <SPI.h>



#define TFT_DC 9
#define TFT_CS 10



//termocouple 1 - escape
int soPin = 5;
int cs1Pin = 6;
int sckPin = 7;
//termocouple 2 - cilindro
int cs2Pin = 4;


Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

MAX6675 thermocouple1(sckPin, cs1Pin, soPin);
MAX6675 thermocouple2(sckPin, cs2Pin, soPin);

int S = 59; // cuenta segundos
int M = 59; // cuenta minutos
int H = 00; // cuenta horas






void setup() {
 
  tft.fillScreen (ILI9341_BLACK);
  tft.setTextColor (ILI9341_WHITE, ILI9341_BLACK);
  tft.setFont (&FreeSans9pt7b);

  tft.setCursor (40,50);
  tft.print ("escape (C)");
  tft.setCursor (200,50);
  tft.print ("cilindro (C)");
 
  tft.drawLine (160,30,160,110, ILI9341_WHITE);  //linea vertical pantalla
  tft.drawLine (0,110,320,110, ILI9341_WHITE);  //linea horizontal superior pantalla
  tft.drawLine (0,30,320,30, ILI9341_WHITE);     //linea horizontal inferior pantalla
 
  tft.setCursor (100,130);
  tft.print ("tiempo STINT");

  tft.setTextColor (ILI9341_WHITE, ILI9341_BLACK);  //punteros cronometro
  tft.setFont ();
  tft.setTextSize (4);
  tft.setCursor(93, 180);
  tft.print (":");
  tft.setCursor(203, 180);
  tft.print (":");


 

}


void loop(void) {



                                      //sensor ESCAPE:
                                     
 if((thermocouple1.readCelsius())<30){

  tft.setTextColor (ILI9341_GREEN, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (10,70);
  tft.print(thermocouple1.readCelsius());
 
 }
else{
 tft.setTextColor (ILI9341_RED, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (10,70);
  tft.print(thermocouple1.readCelsius());
 
}

                                          //sensor CILINDRO:
                                         
  if((thermocouple2.readCelsius())<30){

  tft.setTextColor (ILI9341_GREEN, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (190,70);
  tft.print(thermocouple2.readCelsius());

 }
else{
 tft.setTextColor (ILI9341_RED, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (190,70);
  tft.print(thermocouple2.readCelsius());
 
}
 



  //////cronometro//////

 
  S--;

 tft.setTextColor (ILI9341_WHITE, ILI9341_BLACK);
 tft.setTextSize (7);
 if(S<0)
 {
   M--;
   S=59;
 }
 if(M<0)
 {
   H--;
   M=59;
 }
 if(H<0) { H=00; M=00; S=00; }
 
 if(M>9)
 {
   tft.setCursor(120,170);
   tft.print(M);
 }
 else
 {
   tft.setCursor(120,170);
   tft.print("0");
   tft.setCursor(160,170);
   tft.print(M);
 }
 
 if(S>9)
 {
   tft.setCursor(230,170);
   tft.print(S);
 }
 else
 {
   tft.setCursor(230,170);
   tft.print("0");
   tft.setCursor(270,170);
   tft.print(S);
 }
 
 if(H>9)
 {
   tft.setCursor(10,170);
   tft.print (H);
 }
 else
 {
   tft.setCursor(10,170);
   tft.print("0");
   tft.setCursor(50,170);
   tft.print(H);
 }
}

You'll probably need a real time clock to get any accuracy. Adafruit has them Here, for example.

delay() is not very accurate at all.

-jim lee

consider

#define ONE_SEC     1000
#define ONE_HOUR    (60*60)

unsigned long timeSec = 10;

void
chrono (void)
{
    static unsigned int msecLst = 0;
           unsigned int msec    = millis ();

    if (msec - msecLst > ONE_SEC)  {
        msecLst = msec;

        timeSec--;

        int min = timeSec / 60;
        int sec = timeSec % 60;

        char s [20];
        sprintf (s, "%2d:%02d", min, sec);
        Serial.println (s);

        if (0 >= timeSec)
            timeSec = ONE_HOUR;
    }
}


void
loop (void)
{
    chrono ();
}

void
setup (void)
{
    Serial.begin (115200);

}

Thank you all for your responses. :grinning:

I'm going to try how you tell me.
I will let you know of my progress :wink:

Hi.
Finally I have changed the code as suggested. It was hard for me because I don´t undestand the function millis() very well but it seems work.

This is my new code. Do you see it correct?

include"Wire.h"
#include <gfxfont.h>

#include "Fonts/FreeSansBold9pt7b.h"
#include "Fonts/FreeSans9pt7b.h"
#include <TFT_ILI9341.h>


#include <max6675.h>


#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <SPI.h>


#define start 3
#define LED_ROJO 2
#define TFT_DC 9
#define TFT_CS 10

#define ONE_SEC     1000
#define ONE_HOUR    (60*60)

unsigned long timeSec = 3600; //time seconds

//termocouple 1 - exhaust
int soPin = 5;
int cs1Pin = 6;
int sckPin = 7;
//termocouple 2 - cht
int cs2Pin = 4;


Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

MAX6675 thermocouple1(sckPin, cs1Pin, soPin);
MAX6675 thermocouple2(sckPin, cs2Pin, soPin);


void setup() {

  pinMode(LED_ROJO, OUTPUT);
  pinMode(start,INPUT_PULLUP);
 

  tft.begin();
  tft.setRotation(3);
  tft.fillScreen (ILI9341_WHITE);
 
  tft.fillScreen (ILI9341_BLACK);
  tft.setFont (&FreeSans9pt7b);
  tft.setTextColor (ILI9341_GREEN, ILI9341_BLACK);
  tft.setCursor (5,20);
  tft.print("ok");
  tft.setTextColor (ILI9341_WHITE, ILI9341_BLACK);
  tft.setCursor (40,50);
  tft.print ("escape (C)");
  tft.setCursor (200,50);
  tft.print ("cilindro (C)");
 
  tft.drawLine (160,30,160,110, ILI9341_WHITE);  //linea vertical pantalla
  tft.drawLine (0,110,320,110, ILI9341_WHITE);  //linea horizontal superior pantalla
  tft.drawLine (0,30,320,30, ILI9341_WHITE);
 
  tft.setCursor (100,130);
  tft.print ("tiempo STINT");

}
 
void loop() {


                                      //sensor EGT:
                                     
 if((thermocouple1.readCelsius())<30){
  digitalWrite(LED_ROJO, LOW);
  tft.setTextColor (ILI9341_GREEN, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (10,70);
  tft.print(thermocouple1.readCelsius());
 
 }
else{
  digitalWrite(LED_ROJO, HIGH);
  tft.setTextColor (ILI9341_RED, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (10,70);
  tft.print(thermocouple1.readCelsius());
 
}
                                         //sensor CHT:
                                         
  if((thermocouple2.readCelsius())<30){
  digitalWrite(LED_ROJO, LOW);
  tft.setTextColor (ILI9341_GREEN, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (170,70);
  tft.print(thermocouple2.readCelsius());

 }
else{
  digitalWrite(LED_ROJO, HIGH);
  tft.setTextColor (ILI9341_RED, ILI9341_BLACK);
  tft.setTextSize (4);
  tft.setCursor (170,70);
  tft.print(thermocouple2.readCelsius());
 
}

{
    chrono ();
}
}

void
chrono (void)
{
    static unsigned int msecLst = 0;
           unsigned int msec    = millis ();

    if (msec - msecLst > ONE_SEC)  {
        msecLst = msec;

        timeSec--;

        int min = timeSec / 60;
        int sec = timeSec % 60;

        char s [20];
        sprintf (s, "%2d:%02d", min, sec);
        tft.setTextSize (9);
        tft.setTextColor (ILI9341_WHITE, ILI9341_BLACK);
        tft.setCursor(30,170);
        tft.println (s);

        if (0 >= timeSec)\
           timeSec = ONE_HOUR;
   

}
}

Now two questions;
when the counter reaches "0" it does not stop and starts again.
Any suggestions on how to leave it at "0" when the countdown ends? (While () function did not work properly).
How can I make the "start" button restart the chrono whenever I want?

Thank you