converting total seconds to hours, minutes and seconds...

Status
Not open for further replies.
make TL_hours and TL_mins uint32_t (get away from int on mega/uno since it's only 16bits) that will make this computation 32-bit

remainingSeconds = ((TL_hours * 60) * 60) + (TL_mins * 60);
 
make TL_hours and TL_mins uint32_t (get away from int on mega/uno since it's only 16bits) that will make this computation 32-bit

remainingSeconds = ((TL_hours * 60) * 60) + (TL_mins * 60);

BINGO!!!!! THAT DID IT!!! ;) I'm punching in countdown times of 60 hours and its working!! dialled it up to 100 hours.. the max.. and its counting down perfectly!

Thats one big LEARN! Thanks so much, Manitou.. and thanks to everyone who helped me nail down this problem. Relieved it wasnt a display library problem, wasnt looking forward to changing to a different library at this point!

Here's the code once again, with manitou's suggested change..

Code:
/*


  List of fonts: https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts






  If you have the 128x64 version, you need to edit the file called Adafruit_SSD1306.h that is on the
  Adafruit_SSD1306-master folder. The library comes by default set to use the 128x32 display.
  For this reason you need to define the correct resolution like this:
  Quote:
   #define SSD1306_128_64
  //   #define SSD1306_128_32
  //   #define SSD1306_96_16
  Unquote.
  Notes the "//" before each line to comment the other resolutions that we are not going to use.




*/






#include <Adafruit_GFX.h>  // Include core graphics library for the display
#include <Adafruit_SSD1306.h>  // Include Adafruit_SSD1306 library to drive the display
#include <Metro.h>
#include <Encoder.h>
#include <Bounce2.h>
#include <Fonts/FreeSans9pt7b.h>  // Add a custom font


Adafruit_SSD1306 display;  // Create display




int Variable1;  // Create a variable to have something dynamic to show on the display


//                                        Time variables


long unsigned int TotalSeconds = 0;
uint32_t remainingSeconds = 0;
uint32_t h   = 0;
uint32_t m   = 0;
uint32_t s   = 0;
uint32_t rem = 0;
uint32_t TL_hours = 0;
uint32_t TL_mins = 0;


//                                          Menu Variables
boolean hlight = 0;
int menuMax = 5;
int menuMode = 0;
int menuDelay = 500;
Metro blinkon = Metro(1000);
Metro blinkoff = Metro(1000);
Metro debounce = Metro(10);


//                                          Keyframe Variables


char StartingKey;
char EndingKey;


//                                          Encoder Variables


Encoder myEnc(2, 3);
int encState;
int encRead;                              //current encoder read
int encOld;                               //previous encoder read


const int EncButton = 4;                  //Pin # to which SW line is connected
byte oldButtonState = HIGH;               // set previous buttonestate to HIGH because of pull-up resistor
const unsigned long debounceTime = 10;    // milliseconds
unsigned long buttonPressTime;            // when the switch last changed state
boolean buttonPressed = 0;                // a flag variable




//                                          Graphic variables
int progress = 0;


//                                          Mode variables


// timelapse






#define SMLFONT FreeSans9pt7b




Metro nextfunc = Metro(4000);


class FlashBox
{
    int OnTime;
    int OffTime;
    int x;
    int y;
    int w;
    int h;
    int highlight;
    unsigned long previousMillis;


    // constructor
  public:
    FlashBox(int xx, int yy, int width, int height, int on, int off)
    {
      x = xx;
      y = yy;
      w = width;
      h = height;
      OnTime = on;
      OffTime = off;
      highlight = 0;
      previousMillis = 0;
      blinkon.interval(OnTime);
      blinkon.reset();
      blinkoff.interval(OffTime);
      blinkoff.reset();
    }


    void Flasher()
    {
      unsigned long currentMillis = millis();


      //        if ((blinkon.check())  && (highlight == 0))
      if ((currentMillis - previousMillis >= OnTime)  && (highlight == 0))
      {


        display.drawRect(x, y, w, h, WHITE);
        display.display();
        highlight = 1;
        previousMillis = currentMillis;


        //delay (1000);
      }
      //          else if ((blinkoff.check()) && (highlight == 1))
      else if ((currentMillis - previousMillis >= OffTime) && (highlight == 1))
      {


        display.drawRect(x, y, w, h, BLACK);
        display.display();
        highlight = 0;
        previousMillis = currentMillis;
        //delay(1000);
      }


    }
};




void setup()  // Start of setup
{
  // Encoder setup
  pinMode(EncButton, INPUT);
  digitalWrite(EncButton, HIGH); // Pull-Up resistor for switch


  // Display Setup
  delay(100);  // This delay is needed to let the display to initialize
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Initialize display with the I2C address of 0x3C
  display.clearDisplay();  // Clear the buffer
  display.setTextColor(WHITE);  // Set color of the text
  display.setRotation(0);  // Set orientation. Goes from 0, 1, 2 or 3
  display.setTextWrap(false);  // By default, long lines of text are set to automatically “wrap” back to the leftmost column.
  // To override this behavior (so text will run off the right side of the display - useful for
  // scrolling marquee effects), use setTextWrap(false). The normal wrapping behavior is restored
  // with setTextWrap(true).


  display.dim(0);  //Set brightness (0 is maximun and 1 is a little dim)


}  // End of setup




void loop()  // Start of loop
{


  getMenuMode();   // 0: Run Mode A 1: Run Mode B 2: Live Mode




}  // End of loop


void getMenuMode() {
  int mode = 1;
  display.clearDisplay();  // Clear the display so we can refresh
  display.setFont(&SMLFONT);  // Set a custom font
  display.setTextSize(1);  // Set text size. We are using a custom font so you should always use the text size of 0
  display.setTextColor(WHITE);


  do {
    encRead = myEnc.read() >> 2; // bitwise divide by 4


    if (encRead < encOld)
    {
      mode--;
      if (mode < 1) mode = 1;
      encOld = encRead;
    }




    if (encRead > encOld)
    {
      mode++;
      if (mode > menuMax) mode = menuMax;
      encOld = encRead;
    }






    switch (mode) {
      case 1:
        display.clearDisplay();  // Clear the display so we can refresh
        //drawgrid();
        display.drawRoundRect(0, 0, 128, 64, 8, WHITE);
        display.setCursor(48, 12);  // (x,y)
        display.setFont();
        display.print("SELECT");
        //display.print(mode);
        display.setFont(&SMLFONT);
        display.setCursor(20, 38);  // (x,y)
        display.println("REALTIME");
        display.setCursor(44, 55);  // (x,y)
        display.println("Mode");
        display.display();
        //            RunMode('A','B');
        break;


      case 2:
        display.clearDisplay();  //            RecordMode()
        //drawgrid();
        display.drawRoundRect(0, 0, 128, 64, 8, WHITE);
        display.setCursor(48, 12);  // (x,y)
        display.setFont();
        display.print("SELECT");
        //display.print(mode);
        display.setFont(&SMLFONT);
        display.setCursor(27, 38);  // (x,y)
        display.println("RECORD");
        display.setCursor(44, 55);  // (x,y)
        display.println("Mode");
        display.display();


        break;


      case 3:
        display.clearDisplay();  // Clear the display so we can refresh
        //drawgrid();
        display.drawRoundRect(0, 0, 128, 64, 8, WHITE);
        display.setCursor(48, 12);  // (x,y)
        display.setFont();
        display.print("SELECT");
        //display.print(mode);
        display.setFont(&SMLFONT);
        display.setCursor(47, 38);  // (x,y)
        display.println("LIVE");
        display.setCursor(44, 55);  // (x,y)
        display.println("Mode");
        display.display();
        //            LiveMode();
        break;


      case 4:
        display.clearDisplay();  //           SET TimeLapse  menuMode = 4
        //drawgrid();
        display.drawRoundRect(0, 0, 128, 64, 8, WHITE);
        display.setCursor(48, 12);  // (x,y)
        display.setFont();
        display.print("SELECT");
        //display.print(mode);
        display.setFont(&SMLFONT);
        display.setCursor(48, 38);  // (x,y)
        display.println("SET");
        display.setCursor(22, 55);  // (x,y)
        display.println("Timelapse");
        display.display();
        checkSwitch();
        if (buttonPressed) {
          buttonPressed = 0;
          display.drawRect(0, 0, 128, 64, WHITE);
          display.display();
          delay(menuDelay);
          menuMode = 4;
          LapseModeSet();
        }
        break;


      case 5:
        display.clearDisplay();  //            RUN Timelapse  MenuMode = 5
        //drawgrid();
        display.drawRoundRect(0, 0, 128, 64, 8, WHITE);
        display.setCursor(48, 12);  // (x,y)
        display.setFont();
        display.print("SELECT");
        //display.print(mode);
        display.setFont(&SMLFONT);
        display.setCursor(46, 38);  // (x,y)
        display.println("RUN");
        display.setCursor(22, 55);  // (x,y)
        display.println("Timelapse");
        display.display();
        checkSwitch();
        if (buttonPressed) {
          buttonPressed = 0;
          display.drawRect(0, 0, 128, 64, WHITE);
          display.display();
          delay(menuDelay);
          menuMode = 5;
          LapseModeRun();
        }
        break;


    }
  } while (menuMode == 0);
}


void TimeCalc( uint32_t seconds ) {
  uint32_t t = seconds;


  h =  (uint32_t)t / (uint32_t)3600L;
  rem =  (uint32_t)t %  (uint32_t)3600L;
  m = rem / 60;
  s = rem % 60;


//
//  h = t / 3600;
//  rem = t % 3600;
//  m = rem / 60;
//  s = rem % 60;
}


void RunMode ( char startKF, char endKF ) {
  nextfunc.reset();
  TotalSeconds = 740;
  do {
    Variable1++;  // Increase variable by 1
    if (Variable1 > 150) // If Variable1 is greater than 150
    {
      Variable1 = 0;  // Set Variable1 to 0
    }


    display.clearDisplay();  // Clear the display so we can refresh




    display.setFont(&SMLFONT);  // Set a custom font
    display.setTextSize(1);  // Set text size. We are using a custom font so you should always use the text size of 0
    display.setTextColor(WHITE);




    // Print text:
    display.setCursor(0, 12);  // (x,y)
    display.print("Running "); display.print(startKF); display.print("<->"); display.print(endKF);  // print start and end keyframes
    display.setFont();
    display.setCursor(0, 30);  // (x,y)
    //        display.println("TIME REMAINING");  // Text or value to print
    display.setCursor(0, 29);
    display.println(" HOURS   MIN.    SEC.");
    display.drawLine(0, 43, 128, 43, WHITE);  // Draw Horizontal line
    display.drawLine(42, 43, 42, 64, WHITE);  // Draw Vertictal line
    display.drawLine(84, 43, 84, 64, WHITE);  // Draw Vertictal line
    display.setFont(&SMLFONT);
    TimeCalc(TotalSeconds);
    display.setCursor(5, 62);
    display.println(h);    // Hours
    display.setCursor(54, 62);
    display.println(m);      // Minutes
    display.setCursor(97, 62);
    display.println(s);      // Seconds
    --TotalSeconds;




    // Draw Progress Bar rectangle:
    display.drawRect(0, 22, 128, 1, WHITE);  // Draw rectangle (x,y,width,height,color)
    display.fillRect(0, 21, progress, 3, WHITE);  // It draws from the location to down-right
    progress++;
    if (progress > 127) {
      progress = 0;
    }


    //display.setFont(&FreeMonoBold12pt7b);  // Set a custom font


    // Print variable with left alignment:
    display.setFont();




    display.display();  // Print everything we set previously
    checkSwitch();      // check encoder switch
    if (buttonPressed) {
      Variable1 = 0;
      progress = 0;
      display.clearDisplay();
      display.display();
      return;
    }
  } while (Variable1 < 128);




}


void LiveMode() {
  // display.fillRect(0, 0, 128, 64, WHITE);
  display.setFont(&SMLFONT);
  display.setTextSize(0);
  display.clearDisplay();
  display.setCursor(10, 20);  // (x,y)
  display.setTextColor(WHITE);
  while (!buttonPressed) {
    display.println("Live Mode");
    display.display();
  }
  return;
}


void RecordMode() {
  // display.fillRect(0, 0, 128, 64, WHITE);
  display.setFont(&SMLFONT);
  display.setTextSize(0);
  display.clearDisplay();
  display.setCursor(10, 20);  // (x,y)
  display.setTextColor(WHITE);
  while (!buttonPressed) {
    display.println("Recording..");
    display.display();
  }
  return;
}


void LapseModeSet() {


  screen_Lapse();


  FlashBox hours(1, 36, 63, 27, 200, 200); // Construct flashing box (Hours)
  FlashBox mins(65, 36, 62, 27, 200, 200); // Construct flashing box (Minutes)
  FlashBox TL_set(0, 0, 128, 64, 300, 300); // Construct TL Done flashing box
  int mode = 0;  // 0 = hours selected   1 = minutes selected
  int valuechange = 0;


  encOld = 0;
  buttonPressed = 0;
  myEnc.write(0);
  do {




    do {


      encRead = myEnc.read() >> 2; // bitwise divide by 4
      if (encRead < encOld)
      {
        mode--;
        if (mode < 0) mode = 0;
        encOld = encRead;
        screen_Lapse();
      }
      if (encRead > encOld)
      {
        mode++;
        if (mode > 2) mode = 2;
        encOld = encRead;
        screen_Lapse();
      }




      switch (mode)
      {
        case 0:
          hours.Flasher();    // flash Hours Box
          break;
        case 1:
          mins.Flasher();     // flash Minutes Box
          break;
        case 2:
          TL_set.Flasher();   // flash whole screen Box
          break;
      }


      checkSwitch();
      if (buttonPressed)
      {
        buttonPressed = 0;
        valuechange = 1;
        if (mode == 0) myEnc.write(TL_hours);
        if (mode == 1) myEnc.write(TL_mins);
        screen_Lapse();
      }


    } while (!valuechange);






    do {
      if (mode == 0)   // Adjust Hours
      {
        display.drawRect(1, 36, 63, 27, WHITE);
        encRead = myEnc.read() >> 2; // bitwise divide by 4
        TL_hours = constrain(encRead, 0, 100);
        screen_Lapse();
        checkSwitch();
        if (buttonPressed)
        {
          valuechange = 0;
          buttonPressed = 0;
        }
      }


      if (mode == 1)   // Adjust Minutes
      {
        display.drawRect(65, 36, 62, 27, WHITE);
        encRead = myEnc.read() >> 2; // bitwise divide by 4
        TL_mins = constrain(encRead, 0, 59);
        screen_Lapse();
        checkSwitch();
        if (buttonPressed)
        {
          valuechange = 0;
          buttonPressed = 0;
        }
      }


      if (mode == 2)   // Quit to Main Menu
      {


        valuechange = 0;
        buttonPressed = 0;
        menuMode = 0;
        remainingSeconds = ((TL_hours * 60) * 60) + (TL_mins * 60);


      }


    } while (valuechange);










  } while (menuMode == 4);


}


void LapseModeRun() {
  //  Serial.begin(9600);
  TotalSeconds = remainingSeconds;
  int percent = 0;


  do {






    display.clearDisplay();  // Clear the display so we can refresh
    display.setFont(&SMLFONT);  // Set a custom font
    display.setTextSize(1);  // Set text size. We are using a custom font so you should always use the text size of 0
    display.setTextColor(WHITE);
    display.setCursor(0, 12);  // (x,y)
    display.print("Running ");
    display.setFont();
    display.setCursor(0, 30);  // (x,y)
    //        display.println("TIME REMAINING");  // Text or value to print
    display.setCursor(0, 29);
    display.println(" HOURS   MIN.    SEC.");
    display.drawLine(0, 43, 128, 43, WHITE);  // Draw Horizontal line
    display.drawLine(42, 43, 42, 64, WHITE);  // Draw Vertictal line
    display.drawLine(84, 43, 84, 64, WHITE);  // Draw Vertictal line
    display.setFont(&SMLFONT);
    TimeCalc(remainingSeconds);
    //Serial.print(h); Serial.print(" ");Serial.print(m); Serial.print(" ");Serial.println(s);
    display.setCursor(5, 62);
    display.println(h);    // Hours
    display.setCursor(54, 62);
    display.println(m);      // Minutes
    display.setCursor(97, 62);
    display.println(s);      // Seconds




    // Draw Progress Bar rectangle:
    progress = abs((((float)remainingSeconds / (float)TotalSeconds) * 128) - 128);
    percent = ((float)progress / 128) * 100;
    display.drawRect(0, 22, 128, 1, WHITE);  // Draw rectangle (x,y,width,height,color)
    display.fillRect(0, 21, progress, 3, WHITE);  // It draws from the location to down-right




    //display.setFont(&FreeMonoBold12pt7b);  // Set a custom font


    // Print variable with left alignment:
    display.setFont();
    display.setCursor(100, 5);
    display.print(percent);
    display.println("%");
    //    display.setCursor(80, 5);
    //    display.print(remainingSeconds);


    display.display();  // Print everything we set previously


    if (remainingSeconds == 0)
    {
      //display.getTextBounds("Running ",0,12,int x, int y, int ww, int hh);
      display.fillRect(0, 0, 70, 20, BLACK);
      display.setFont(&SMLFONT);
      display.setCursor(0, 12);  // (x,y)
      display.print("DONE ");
      display.display();
      delay(50000);
      menuMode = 0;
    }




    remainingSeconds--;             //          TICK!










    checkSwitch();      // check encoder switch
    if (buttonPressed) {
      buttonPressed = 0;
      menuMode = 0;
      display.clearDisplay();
      display.display();
      return;
    }
  } while (menuMode == 5);




}


void checkSwitch() {
  // Check Encoder Switch


  byte buttonState = digitalRead(EncButton);
  if (buttonState != oldButtonState)
  {
    if (millis () - buttonPressTime >= debounceTime)
    { // debounce
      buttonPressTime = millis ();                      // when we closed the switch
      oldButtonState =  buttonState;                    // remember for next time
      if (buttonState == LOW)
      {
        //        Serial.println ("Button pressed");               // DEBUGGING: print that button has been closed
        buttonPressed = 1;
      }
      else
      {
        //        Serial.println ("Button released");               // DEBUGGING: print that button has been opened
        buttonPressed = 0;
      }
    }  // end if debounce time up
  } // end of state change
}


void screen_Lapse() {
  display.setFont(&SMLFONT);
  display.setTextSize(0);
  display.clearDisplay();
  display.drawRect(0, 0, 128, 64, WHITE);  // Draw Border
  display.setCursor(4, 15);  // (x,y)
  display.setTextColor(WHITE);
  display.println("Set Timelapse");
  display.setFont();
  display.setCursor(0, 25);
  display.println("   HOURS     MINUTES");
  display.drawLine(0, 35, 128, 35, WHITE);  // Draw Horizontal line
  display.drawLine(64, 35, 64, 64, WHITE);  // Draw Vertictal line
  display.setFont(&SMLFONT);
  display.setCursor(17, 55);
  display.println(TL_hours);
  display.setCursor(85, 55);
  display.println(TL_mins);
  display.display();


}


void drawgrid() {
  display.drawRect(0, 0, 128, 64, WHITE);
  display.drawLine(64, 0, 64, 128, WHITE);
  display.drawLine(0, 32, 128, 32, WHITE);
}




// Adafruit Graphic library code references




// Draw triangle:
// display.drawTriangle(40,40,   50,20,   60,40, WHITE);  // Draw triangle. X, Y coordinates for three corner points defining the triangle, followed by a color


// Draw filled triangle:
//display.fillTriangle(0,35,   15,45,   30,63, WHITE);  // Draw filled triangle. X, Y coordinates for three corner points defining the triangle, followed by a color


// Draw line:
//  display.drawLine(0, 18, 128, 18, WHITE);  // Draw line (x0,y0,x1,y1,color)


// Draw circle:
// display.drawCircle(47, 36, 20, WHITE);  //  Draw circle (x,y,radius,color). X and Y are the coordinates for the center point


// Draw a filled circle:
// display.fillCircle(12, 27, 10, WHITE);  // Draw filled circle (x,y,radius,color). X and Y are the coordinates for the center point


// Draw rectangle:
// display.drawRect(58, 0, 18, 18, WHITE);  // Draw rectangle (x,y,width,height,color)
// It draws from the location to down-right


// Draw rounded rectangle and fill:
// display.fillRoundRect(58, 0, 18, 18, 5, WHITE);  // Draw filled rounded rectangle (x,y,width,height,color)
// It draws from the location to down-right
// Draw rounded rectangle:
//display.drawRoundRect(79, 37, 49, 27, 8, WHITE);  // Draw rounded rectangle (x,y,width,height,radius,color)
// It draws from the location to down-right


// Print variable with right alignment:
//  display.setCursor(83, 60);  // (x,y)
//  display.println(string);  // Text or value to print




//


//  // Convert Variable1 into a string, so we can change the text alignment to the right:
//  // It can be also used to add or remove decimal numbers.
//  char string[10];  // Create a character array of 10 characters
//  // Convert float to a string:
//  dtostrf(Variable1, 3, 0, string);  // (<variable>,<amount of digits we are going to use>,<amount of decimal digits>,<string name>)
 
I think you need to take a pass through your code and look for everywhere that these values are set and used. Maybe check every place you use uint16_t and try changing to uint32_t. Try looking at other data types as well. Look at everywhere you are using constants and see if you need to make sure that they are with the L suffix for long values.

Probably with each case like this you should maybe add some debug print out statements. Example with the mode set after you calculate the remainingSeconds, try printing out this value to debug terminal... If you had you would have seen that the value had wrapped around.
 
Kurt, I'll take that pass through, but I should only need uint32_t types for really large numbers, no? For this application, only the total seconds would ever get that large.. cant imagine even the number of steps for the motors getting that big. I take your point though..

As I said at the outset, I'm new to coding... I learned BASIC in high school on a Commodore PET, then a TRS-80 at home, dabbled in C and Swift, but at the end of the day.. I'm a filmmaker trying to make a tool I need. Learned alot in this thread.

Question.. should I be setting that TotalSeconds to uint32_t too? Suspect I should. Its confusing, I thought LONG UNSIGNED INT would have been good enough for all this.. the Arduino reference says: "Unsigned long variables are extended size variables for number storage, and store 32 bits (4 bytes). Unlike standard longs unsigned longs won’t store negative numbers, making their range from 0 to 4,294,967,295 (2^32 - 1)."

Why then did I even need uint32_t?? The Arduino reference doesnt even mention it.
 
The problem is that when you specify data types like: char, int, long, ... the actual size of these change depending on what platform you are compiling your code for.
So for example I don't know what size long unsigned int compiles to? ...

So they developed a set of standardized defines for data types:
So if you define a variable as uint16_t, it will be 16 bits and unsigned on every platform you compile your code on. likewise int32_t will be a signed 32 bit value on all platforms. It just makes it easier to be sure your code will work OK, especially when you may be working on different platforms like Arduino where some chips are 8 bit processors (AVR) and some others are 32 bits...
 
based on what you're saying, I had to see if LONG UNSIGNED INT would have worked. It does.. right up to 100 hours..

Code:
long unsigned int TotalSeconds = 0;
long unsigned int remainingSeconds = 0;
long unsigned int h   = 0;
long unsigned int m   = 0;
long unsigned int s   = 0;
long unsigned int rem = 0;
long unsigned int TL_hours = 0;
long unsigned int TL_mins = 0;

So apparently, the issue was not having TL_hours and TL_mins set to 32 bit.. whether uint32_t or LONG UNSIGNED INT. But you're saying the former is safer for cross-platform.. so I'll stick with it.

Great learning experience.
 
Like I said in my comment, the variables containing the total number of seconds must also be of sufficient size.

You call TimeCalc() in two places; one is TimeCalc(TotalSeconds) and the other is TimeCalc(remainingSeconds). However, you have
Code:
  long unsigned int  TotalSeconds = 0;
  uint16_t  remainingSeconds = 0;
TotalSeconds is probably of sufficient size, but remainingSeconds can only represent values between 0 and 65535, inclusive (18 hours, 12 minutes, and 15 seconds) -- and if you use int constants to calculate the limits, only half that (due to int being a signed integer type).

It is not sufficient to make sure the target variable is large enough; you also need to ensure the calculations are done at sufficiently high precision. In your case, on line
Code:
        remainingSeconds = ((TL_hours * 60) * 60) + (TL_mins * 60);
the calculation on the right side of the = is only done at int precision. To ensure that it is done at uint32_t precision, you need to change it for example into
Code:
        remainingSeconds = 60 * 60 * (uint32_t)TL_hours + 60 * (uint32_t)TL_mins;
The (uint32_t) before a number or a variable is called a cast: it converts the value to the type. With these casts, you can use uint8_t TL_hours, TL_mins; and still get correct results.

(Arithmetic operations like addition, subtraction, and multiplication is done at the highest precision and range between the arguments; if you have multiple terms multiplied together, only one of them needs to be cast to ensure the entire product is calculated at that range and precision. Above, we have two products, and we want both of them to be calculated at uint32_t precision and range. When the products are summed, both of the sum terms are already of that type.)

So, the actual reason for the problems was twofold: First, wrong type for remainingSeconds ; both should have been uint32_t. Second, the calculation of remainingSeconds was done at only int precision and range, without telling the compiler that you want it to be done at uint32_t range and precision.
 
Completely understood, Nominal.. now, that is... painfully obvious in hindsight... Thanks again for your assistance.
 
Status
Not open for further replies.
Back
Top