Programming question please help!

Hello!
I am trying to create a stopwatch which is calculating the distance at the same time depending on the speed. Before starting the stopwatch you have to choose a speed you are going and then when you hit start, the stopwatch shows both the time and the distance accordingly.
I am not that good in programming as of now, but I have managed to create some of the sketch. The biggest problem for me is that I need to get all of the different speeds in under one button, so the system knows that if you press one time it is x speed, two times it is y speed and so forth. After that the system needs to understand that when a speed is choosen, then it is that speed it is going to use for the real time calculations when the timer is started.

Anyone that can help me in this project?
Attaching my uncompleted sketch so you can check it out :wink:

Thanks!

navklokke.ino (6.52 KB)

A few points:

Personally, I do not like using 'while'
I would handle switch pushing in a separate function run every 50 ms and look for the appropriate change in state.
Variables that are set to millis() should be type 'unsigned long'

It's much easier for us if you post your code using code tags. Otherwise, all of us have to download it to examine the code. See Nick Gammon's posts at the top of this Forum.

Thank you for the input :slight_smile: Here is the code embeded.

//Navigational stopwatch
//by Mats



/*********************************************************************
Adafruit library for Monochrome OLEDs based on SSD1306 drivers
https://github.com/adafruit/Adafruit_SSD1306
Adafruit GFX library:
https://github.com/adafruit/Adafruit-GFX-Library  
*********************************************************************/
#include<ButtonV2.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#if (SSD1306_LCDHEIGHT != 64)
//#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };
  
#define numOfButtons 3
ButtonV2 buttonArray[numOfButtons];

#if (SSD1306_LCDHEIGHT != 64)
//#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

//------------------------------------------------------ eo Adafruit header
//define the four timer states.
#define WAITING 0 // waiting to start
#define TIMERONE 1 // timer one running
#define NMDIST 2 // nautical miles traveled
#define FINISHED 3 // timer complete


const long minute = 60000; // 60000 milliseconds in a minute
const long nautical = 10; //10 cabels in one nauicle
const int resetPin = 2; 
const int startPin = 3; 
const int choosePin = 4;
//const int ledPin =  13;      // the number of the LED pin
const byte ButtonPins[numOfButtons] = {2, 3, 4};

long startTime = 0;
long timeOne = 0;
long navdist = 0;
int timer = WAITING; // timer state. Initially waiting for first button press
int reset = 0;  // reset button state
int start = 0; // main button state

long kabler, nm;

void setup()   {    
  pinMode(startPin, INPUT); //init button pin to input
  pinMode(resetPin, INPUT);  //init reset pin to input
  pinMode(choosePin, INPUT); //init choose pin to input
 
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3c
  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(10,0);
  printDigits(0);
    display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();
}


void loop() {
   //-------- main loop -------
 switch ( timer){
   case WAITING: // initial state - waiting for first button press.
     display.clearDisplay();
     display.setCursor(10,00); 
     printDigits(0);
     display.display(); // display screen showing 00:00s
     start = digitalRead(startPin);
     if(start){ // start is pressed.
       timer = TIMERONE; // start the first timer 
       startTime = millis();//read the time the button is pressed.
       while (digitalRead(startPin)){
         //--- wait for button to be released.
       }
     }
   break;
   case TIMERONE: //running first timer
     timeOne = millis();
     start = digitalRead(startPin);
     reset = digitalRead(resetPin);
     display.clearDisplay();
     display.setCursor(10,00);
     printDigits(timeOne - startTime);
     display.display();
     //-----------------------------------
     if(reset){ //reset button was pressed. Clear screeen and start again
       timer = WAITING;
       while (digitalRead(resetPin)){
         //--- wait for reset button to be released.
       }
     }
     //------------------------------------
     if(start){ // start was pressed
         timer = NMDIST;  // start lengde
         distance = natical(); //record the distance from the time of the first timer
         while (digitalRead(startPin)){
           //--- wait for button to be released.
         }
       }
   break;
   case NMDIST: //running first timer
     distance = nautical((18 * (timeOne - startTime))/ 60);
     //distance = (18 * (timeOne - startTime))/ 60; //formula for calculating distance (speed * Time)/ 60
     start = digitalRead(startPin);
     reset = digitalRead(resetPin);
     display.clearDisplay();
     display.setCursor(10,00);
     printDigits(timeOne - startTime); // display the first time
     display.setCursor(10,32);
     printDigits(distance); // display the distance on the second line
     display.display();
     //------------------------------------
     if(reset){ //reset button was pressed. Clear screeen and start again.32w
       timer = WAITING;
       while (digitalRead(resetPin)){
         //--- wait for reset button to be released.
       }
     }
     //------------------------------------
     if(start){ // button was pressed
         timer = FINISHED;  // start the second timer
         while (digitalRead(startPin)){
           //--- wait for button to be released.
         }
       }
     
   break;
    case FINISHED: //running first timer
     reset = digitalRead(resetPin);
     if(reset){ //reset button was pressed. Clear screeen and start again
       display.clearDisplay();
       display.setCursor(10,0);
       printDigits(0);
       display.display();
       timer = WAITING;
       while (digitalRead(resetPin)){
         //--- wait for reset button to be released.
       }
     } 
   break;  
   } // eo switch
  }// eo void loop
  
void printDigits(long timeInMillis){ 
  // convert the time from milliseconds to four digit SS:HH 
  // seconds and hundredths and display at current cursor position
  int seconds;
  int hundredths;
  seconds = timeInMillis /1000;
  seconds = seconds % 60; // seconds never more than 60
  hundredths = (timeInMillis % 1000)/10;
  
  if (seconds <10){ // print leading zero if necessary
    display.print("0");
  }
  display.print(seconds);
  display.print(":");
  if (hundredths <10){ //print leading zero if necessary
  display.print("0");
  
  }
  display.print(hundredths);
  display.print("s");
  //display.display();
}
void printNumbers(long distanceNautical) {
  int nautical;
  int cabel;
  nautical = cabel * 10;
  cabel = cabel % 1; //one cabel can't be bigger than 1, it is allways 0,something example 0,1   0,5  and so forth
}

Anyone who can help?

matskristian:
Anyone who can help?

No me. I don't even understand what this means:

The biggest problem for me is that I need to get all of the different speeds in under one button

WTF does this mean?

const long minute = 60000; // 60000 milliseconds in a minute
const long nautical = 10; //10 cabels in one nauicle

There are 60000UL milliseconds in a minute. I have no idea what a cabel is, or how many of them there are, or are not, in a nauicle (whatever the hell that is).

     display.setCursor(10,00);

Why do you need to use octal notation for the second argument?

SpacesAREusefullittlecritters.Feelfreetoaddsometoyourcode.

       while (digitalRead(startPin)){
         //--- wait for button to be released.
       }

The return type for digitalRead() is NOT a boolean. Do not pretend that it is.

Most of your comments state the obvious. There is nothing that explains WHY the code is written the way that it is.

There is nothing in your first post that explains what the code actually does, or how that differs from what you expect it to do. So, don't expect anyone to help you make what the code actually does match what you expect. We are NOT mind readers here.

If that was my project I would create separate functions to read the buttons and to update the LCD. That should make the logic in the CASE statements easier to see. Something like this

void loop() {
   readButtons();
   updateLCD();
   switch(timerState) {
      case WAITING:
          if(start){ // start is pressed.
             timer = TIMERONE; // start the first timer
             startTime = millis();//read the time the button is pressed.
          }
        break;

...R