Basic LED display error, two digits interchange and are not shown together

I am using the basic LED display (5261BS) together with the basic LEDDisplay.h and want to show actual temperature on it (from DHT11). I managed to parse the result from the sensor into an array with two members, each member is one digit from the actual temperature (example 37 degrees > "3" and "7").

I've tested the code with serial output and it works OK, but there is an issue when this goes to the LED display. I presume the error is simple, but after 4-5 hours of troubleshooting, I really needed to register here to ask you guys for some help.

Here is the code I currently use:

void loop()
{

int result = DHT11.acquireAndWait();
int ninja = DHT11.getCelsius();
char array[2];
sprintf(array, "%i", ninja);
int value1 = array[0] - '0';
int value2 = array[1] - '0';

    led->displayNumber(value1, 1);
    led->displayNumber(value2, 0);

}

The issue with the above code is that the 2-digit LED display shows the first digit for a milisecond (or so) and stays showing just the second digit - in this case when the temperature is 37 it just hangs on " 7" instead "37".

When I add some delay between both printouts (for both digits) it shows flickering 3 and 7, never at the same time, just very quickly interchanging.

The code for this is:

void loop()
{

int result = DHT11.acquireAndWait();
int ninja = DHT11.getCelsius();
char array[2];
sprintf(array, "%i", ninja);
int value1 = array[0] - '0';
int value2 = array[1] - '0';

    led->displayNumber(value1, 1);
    delay(100);
    led->displayNumber(value2, 0);
    delay(100);
}

I really tried everything and I really can't see how the LED display can show both digits at the same time. Any help is much appreciated. Thanks guys/gals!

I really can't see how the LED display can show both digits at the same time.

It can't, but what it can do is to show one digit then the other digit in such quick succession that they appear to be on at the same time.

I am not familiar with the DHT11 and LEDDisplay libraries but from the function name acquireAndWait() it looks like there is a delay being introduced so what happens is that the first digit is displayed and the second one is turned off, then immediately afterwards the second digit is displayed and the first one is turned off. The net result is that you predominately see only the second digit whilst the temperature data is acquired.

How long does it take for the data to be acquired from the sensor ?

Do you have to read it each time through loop() or could you read it less frequently and display the 2 digits quickly one after the other in the meantime ? After all, how quickly do you expect the temperature to change ?

Hi,
Welcome to the forum.

Can you post your complete code please?

Thanks.. Tom.. :slight_smile:

Hi,
Have you seen this, after googling LED display (5261BS)

http://arduvino.com/arduino-project-03-reading-temperature-using-the-lm35-sensor-and-displaying-it-on-a-7-segment-led-display-5261bs/

Hope it helps...Tom. :slight_smile:

bennyk:

void loop()

{

int result = DHT11.acquireAndWait();
int ninja = DHT11.getCelsius();
char array[2];
sprintf(array, "%i", ninja);
int value1 = array[0] - '0';
int value2 = array[1] - '0';

led->displayNumber(value1, 1);
    delay(100);
    led->displayNumber(value2, 0);
    delay(100);
}

About this line:

char array[2];

Don't do that. You are asking for trouble, because for two characters you need three array elements (google "null terminated string").

char array[3]; // now you have enough room

If it were me, though, I would use a different approach entirely.

void loop()
{
  int result = DHT11.acquireAndWait();
  int ninja = DHT11.getCelsius();
  int tens = ninja / 10; // division by 10
  int ones = ninja % 10; // remainder from division by 10
  led->displayNumber(tens, 1);
  delay(100);
  led->displayNumber(ones, 0);
  delay(100);
}

I know, I know... that doesn't get rid of the flicker. Maybe this will help:

void loop()
{
  int result = DHT11.acquireAndWait();
  int ninja = DHT11.getCelsius();
  int tens = ninja / 10; // division by 10
  int ones = ninja % 10; // remainder from division by 10
  led->displayNumber(tens, 1);
  delay(50); // shorter delay
  led->displayNumber(ones, 0);
  delay(50); // the same, shorter delay
}

Or this:

void loop()
{
  int result = DHT11.acquireAndWait();
  int ninja = DHT11.getCelsius();
  int tens = ninja / 10; // division by 10
  int ones = ninja % 10; // remainder from division by 10
  led->displayNumber(tens, 1);
  delay(20); // even shorter delay
  led->displayNumber(ones, 0);
  delay(20); // ditto
}

UKHeliBob:
It can't, but what it can do is to show one digit then the other digit in such quick succession that they appear to be on at the same time.

Thanks for the feedback! I can say for sure it can show both digits at the same time - please see my response to TomGeorge below (I didn't answer your other questions as I probably think this feedback of mine could help you pinpoint the issue, will comment if not).

TomGeorge:
Hi,
Have you seen this, after googling LED display (5261BS)

http://arduvino.com/arduino-project-03-reading-temperature-using-the-lm35-sensor-and-displaying-it-on-a-7-segment-led-display-5261bs/

Hi Tom - this link you quoted is actually from my blog where I learn through the sensors and code and upgrade my exisiting projects :slight_smile: But great that you've mentioned it here, as in this example the same LED display works flawlessly (as can be seen from the photos). It prints out the temperature for both digits at the same time. I tried replicating the exact led>DisplayNumbers code, but in this new example it doesn't work.

I will repost the whole code in an hour when I come back to my "devel computer" - maybe comparing the loops in this project and the code I provided in this forum post can help you(us) to identify the issue.

odometer:
Full post redacted

Thanks for the feedback odometer, I will check out your code and see how it works.

Thanks guys!

I can say for sure it can show both digits at the same time

I am not convinced that it can. What you can do is to is to appear to display both digits at the same time. Maybe your later posts will convince me otherwise.

UKHeliBob:
I am not convinced that it can. What you can do is to is to appear to display both digits at the same time. Maybe your later posts will convince me otherwise.

Maybe I am not using the correct technical wording by saying "it can show both digits at the same time", but you can see it in action in another project in this photo. It shows the 19 C temperature on the display.

Sketch for this is over here.

The difference between the code you linked to and your program is that the linked program reads an analogue pin then displays the 2 digits one after another. Reading the analogue port takes about 100 microseconds so both digits of the display are updated about 10,000 times per second so both appear to be on at the same time.

How long does it take to read the DHT11, during which time only the second digit of the display will be active ?

I've just timed it, from the "Upload Done" in the software to the second digit becoming visible it was around 1.48 seconds. The first digit is practically not visible at all at any time (or techically it is, but for a milisecond or so)

As promised earlier, here is the full code I use:

#include <LEDDisplay.h>
#include <idDHT11.h>

LEDDisplay *led;


int idDHT11pin = 2; //Digital pin for comunications
int idDHT11intNumber = 0; //interrupt number, choose the right one from the table below.


// Setting up pins for the display

void dht11_wrapper();

// Lib instantiate
idDHT11 DHT11(idDHT11pin,idDHT11intNumber,dht11_wrapper);


void dht11_wrapper() {
  DHT11.isrCallback();
}


void setup()
{
  int digitFlagPins[] = {11, 12};
  int segmentPins[] = {3, 4, 5, 6 ,7 ,8 ,9, 10};
  int decimalPointPin = 10;
  led = new LEDDisplay(2, digitFlagPins, segmentPins, decimalPointPin);

}

void loop()
{


int result = DHT11.acquireAndWait();

int ninja = DHT11.getCelsius();
char array[2];
sprintf(array, "%i", ninja);
int value1 = array[0] - '0';
int value2 = array[1] - '0';


    led->displayNumber(value1, 1);
    led->displayNumber(value2, 0);
}

As promised earlier, here is the full code I use

It's already been pointed out that your array is too small. Why haven't you fixed that? You are probably writing off the end of the array, so all bets are off as for the rest of the code working properly. You are stepping on something; you have no idea what.

With a direct wiring to your board, you need resistors for each segment, not just the two you presumably have for each digit.

You have to write one digit at a time, and alternate back and forth. No way around that.

You may be getting tripped up with having to switch back and forth between digits for the duration until the next reading. You can set display duration with a for loop of whatever number of repetitions.

Odometer, comments on your pieces of code:

Code #1 - does the same what I managed to do with flickering numbers, but thanks alot for more elegant way of getting two variables from DHT11.getCelsius(); - will use that in the future.

Code #2 - shows the first digit for 1/3 or so of the second, removes it and just shows the second digit indefinitely

Code #3 - something similar like code #2 as it is a short delay.

Thanks for the feedback!

PaulS:
It's already been pointed out that your array is too small. Why haven't you fixed that? You are probably writing off the end of the array, so all bets are off as for the rest of the code working properly. You are stepping on something; you have no idea what.

I tried odometer's code that fixes the array "issue" and the situation was the same.

As regarding "You are stepping on something; you have no idea what." - you are probably true, I thought that I am missing something that would be trivial to fix, but by reading some of the comments, especially the latest by INTP - it seems it is more advanced for me and that I should get back to learn some things to make this happen.

I've just timed it, from the "Upload Done" in the software to the second digit becoming visible it was around 1.48 seconds.

Unless the DHT11 library has a method that allows a reading to be taken without blocking the main code you are not going to be able to have a continuous display of temperature.

Hi,
The display you have at the moment is the cause of your problem, if it hasn't been mentioned before.
This because it is being multipexed by the UNO, it is time critical, if your code has other things to do, you upset the timing of the multiplexing and hence your display suffers.

You need to add an IC to take care of the display job.

It doesn't multiplex but gives you a stable display, as all the UNO does is update the IC that controls the display.

Or you use this display

https://learn.sparkfun.com/tutorials/using-the-serial-7-segment-display/example-3-i2c

This method also saves a lot of wiring.

Hope it helps.. Tom... :slight_smile:

Thanks, will check the links you provided and try to work it out.