Serial print stops individual 7-segment displays from cycling with PWM and timer

I'm currently making a thermometer with 3 individual 7-segment displays, each connected to a MOSFET to cycle through them.
The problem I'm facing is that whenever I try to serial print something (for example my temperature), only one of the 3 displays is on, in this case the display with the MOSFET connected to D9.
If I don't print anything or disable Serial.begin, then all displays work.

This is the part of my code that displays digits, I'm displaying 9 as a test.
Here I'm not printing anything and all 3 displays are on.

//global variables
const unsigned long interval = 15;
unsigned long previousTime = 0;

void setup() {

  //Serial commands
  Serial.begin(9600);

  //7 segment pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  //MOSFETs
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop(){

  //Timer
  unsigned long currentTime = millis();


  //set digit 9
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(12, HIGH);
  digitalWrite(13, HIGH);

  if ((currentTime - previousTime) >= interval){

    analogWrite(9, 255);
    analogWrite(10,0);
    analogWrite(11,0);

    previousTime = currentTime;
  }
  else if(((currentTime - previousTime) >= 5) && (currentTime - previousTime) < 10){

    analogWrite(9, 0);
    analogWrite(10, 255);
    analogWrite(11, 0);
  }
  else if(((currentTime - previousTime) >= 10) && (currentTime - previousTime) < interval){

    analogWrite(9, 0);
    analogWrite(10, 0);
    analogWrite(11, 255);
  }
}

I suspect something is taking up the full 15 milliseconds so whenever you get back to the start of loop() the elapsed time has already passed 'interval' and you go back to the first digit (Pin 9). The problem is in the part of the sketch you didn't include.

Once the output buffer is full, printing these 13 characters will take about 13 milliseconds. Perhaps changing the baud rate to 115200 will produce better results. Or you could display the temperature once per second instead of hundreds of times per second.

I've changed to code so it prints every second instead by putting the entire temperature measurement part in an If-statement that happens every 1000ms. So far all my displays work but they don't change digits, but i'll try and figure that out. Thanks a lot!

Hello,
Put the code for the leds in the main loop they don't need a restriction in time. The serial print does,
So put that in a if.
like
loop{
do the calculation;
if (millis > lasttime) {printthelot; lasttime=millis+1000;}
manupulate the leds;
}
I hope it is clear,

This seems odd. Why pass 'tempCalculated' to tempCalc() after getting 'tempCalculated' from tempCalc()?

Whoops, don't know why I put that there but I removed it

What do you mean by

leds in the main loop they don't need a restriction in time

You have restricted them with; ```if ((currentTime - previousTime) >= interval){" etc,
there is no need for that. imh.

change it in

`
    setDigit(comma);
    analogWrite(9, 255);
    analogWrite(10,0);
    analogWrite(11,0);
    digitalWrite(2, LOW); //disables comma on display

    setDigit(ones);
    analogWrite(9, 0);
    analogWrite(10, 255);
    analogWrite(11, 0);

    digitalWrite(2, HIGH); //enables comma on display

    setDigit(tens);
    analogWrite(9, 0);
    analogWrite(10, 0);
    analogWrite(11, 255);

    digitalWrite(2, LOW); //disables comma display

I am new so it is for me learning how to write neatly in this forum, so be patient.

Oh so you mean that void loop cycles my mosfets fast enough so the extra timer isn't needed?

Yes, their switching time is faster than that of a transistor, and if the drain from your leds is <20mA you don't need them, only a resistor of about 200k. in the a-f,dp connections.
and btw

analogWrite(11, 255); ```it is anologue for digitalWrite(11,HIGH);?

You could optimize the timing a bit eg:

analogWrite(9, 255);
setDigit(comma);
setDigit(12); //to set all zero Zeroing will keep bleeding to a minimum
digitalWrite(2, LOW); //disables comma on display
analogWrite(9,0);

analogWrite(10,255);
setDigit(ones);
digitalWrite(2, HIGH); //enables comma on display
setDigit(12);
digitalWrite(2, LOW); //disables comma on display
analogWrite(10, 0);

analogWrite(11, 255);
setDigit(tens);
digitalWrite(2, LOW); //disables comma display
setDigit(12);
analogWrite(11, 0);

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.