Converting `millis()` to decimal seconds?
Dividing an integer by an integer (1000) yields an integer, regardless of what you cast that result to.

Instead you need to divide the integer by a float, or cast the integer to a float first. The simplest way is:

Serial.println(millis() / 1000.0, 3);


The 3 as the second parameter tells Serial.println() how many decimal places to print. The .0 at the end of 1000.0 forces the compiler to see 1000 as a float value (you can also use 1000f if you prefer).

Since floating point can be quite expensive it's possible to emulate it using integer division and modulus (although they are still quite expensive):

uint32_t now = millis();
uint32_t secs = now / 1000;
uint32_t ms = now % 1000;

Serial.print(now / 1000);
Serial.print(".");
if (ms &lt; 100) Serial.print("0");
if (ms &lt; 10) Serial.print("0");
Serial.println(ms); 


You could replace the % with a x1000 and a subtraction too if you like:

uint32_t now = millis();
uint32_t secs = now / 1000;
uint32_t ms = now - (secs * 1000);

Serial.print(now / 1000);
Serial.print(".");
if (ms &lt; 100) Serial.print("0");
if (ms &lt; 10) Serial.print("0");
Serial.println(ms); 


A further method would be to first "print" the milliseconds to a string, then split it into two chunks. Print the first chunk, then a decimal point, and finally the second chunk. This avoids the use of any division or multiplication, but does use expensive string operations:

char num[10];
snprintf(num, 10, "%lu", millis());
uint8_t nlen = strlen(num);

for (uint8_t i = 0; i &lt; nlen - 3; i++) {
    Serial.write(num[i]);
}
Serial.write('.');
for (uint8_t i = nlen-3; i &lt; nlen; i++) {
    Serial.write(num[i]);
}
Serial.println();


So really there is no "perfect" method for converting milliseconds into seconds that uses hardly any CPU cycles. All base 10 operations tend to be a bit expensive on a small microcontroller without hardware support for integer MUL/DIV instructions, or a Floating Point Unit.