Sketch seems to be skipping data

I'm building a bench top power supply with a TFT display. When text updates, it just writes over the old text, so the solution is to first have it place a rectangle the same color as the background, then write the text, which leads to flicker. I'm trying to write a sketch that will have three separate rectangles, since I have three decimal places, and only fill the rectangle of a digit if it changes.

I have the sketch below as a test, and it's breaking down the digits OK, but it's skipping one set. If I start with a value of 24.5, it's supposed to write to the serial monitor the whole value (24.5) then the next line the 2, next line the 4, next line the 5, then a line with a space, then the next set of numbers (24.4, etc).

What I'm getting back is as follows:

24.5
2
4
5

24.4
2
4
4

24.3
2
4
2

24.2
2
4
1

etc. The first two sets of numbers are correct, but then is writes 243. but never has a 2,4, and a 3. It skips to 2,4,2.

Even stranger is I plugged this into my TFT sketch to test it out and align the rectangles, and what that does is it displays the numbers correctly from 24.5 to 24.0, then at 23.9, it writes the 3 over the 4, but the tenths place displays correctly. Then when it gets to 23.0, it shows all three digits correctly, then writes a 2 over the 3, etc.

Below is my sketch:

float Volts;
int TenthsA;
int TenthsB;
int Tenths;
int VoltsA;
int OnesA;
int OnesConv;
int OnesConvB;
int Ones;
int Tens;
static float PresentVolts;

void setup() {
Serial.begin (9600);
//Test Data
Volts=25.0;

}

void loop() {

// Convert Tenths
PresentVolts = Volts;
TenthsA = PresentVolts;
TenthsB = TenthsA * 10;
Tenths = (PresentVolts * 10)-TenthsB;

// Convert Ones
VoltsA = PresentVolts;
OnesConv = VoltsA/10;
OnesConvB = OnesConv*10;
Ones = VoltsA-OnesConvB;

//Convert Tens

Tens=PresentVolts/10;

Serial.println (Volts,1);
Serial.println(Tens);
Serial.println (Ones); 
Serial.println (Tenths); 
Serial.println ("  ");
delay (250);
Serial.println("  ");

Volts = Volts - .1;
if (Volts<0) {
  Volts=25;
}
}

Please format your source code properly.

I'm building a bench top power supply, with a TFT screen, which will be Arduino based. I'm looking at a max voltage output of 30 volts, but it will display one decimal place (30.0 volts).

TFT screens have the issue of flicker when updating text, and I know that the common thing is to draw a rectangle over the text, then redsiplay. I'm trying to figure out if there's any way to tell it to do an if statement based on a change in only one column - the tens column, ones column, or the tenths column. In other words, if it goes from 24.0 to 25.0, that's a change in the ones column.

My thinking is that I would have it display the voltage, and have a float called oldVoltage, which in each loop, oldVotls=Volts. After it reads the voltage, If volts doesn't equal oldVolts then in this case where the ones column changed, put the rectangle over the 4, then re display the voltage value. Since the rest of the text is unchanged, it would be writing the same thing over itself, and won't appear to flicker.

I would have to have three if statements, one for each column.

It will be a fools errand to leave the numbers in floating point. Do not follow that path.

Hopefully this will give you some motivation...


void setup(void) {}

static float get_current_voltage()
{
  return 3.14;
}

static unsigned previous_value;

void loop(void)
{
  unsigned current_value = (unsigned) (get_current_voltage() * 10.0 + 0.5);

  // If either value is greater than 999 we have trouble!

  // Something changed?
  if (current_value != previous_value)
  {
    // Use temporary / local storage to preserve current_value and previous_value
    unsigned cv = current_value;
    unsigned pv = previous_value;

    // Always three digits
    for (int i=0; i < 3; ++i)
    {
      // Isolate the right most digits
      byte cd = cv % 10;
      byte pd = pv % 10;

      // Changed?
      if (cd != pd) 
      {
        // Output cd.  i indicates the position.
      }

      // One less digit to worry about
      cv = cv / 10;
      pv = pv / 10;
    }
  }
  previous_value = current_value;
}
static byte previousTens = 0;
byte currentTens = unknownFloat/10;
if (previousTens!=currentTens) 
  unknownDisplay.deleteTensAndPrintNewTens(currentTens);
//...
previousTens = currentTens;

Thank You both for the replies. I came up with a sketch that seems to separate everything, but it's having an issue of skipping one set of values. I'm posting that in a separate post so that it doesn't get lost here.

Your two topics on the. same subject have been merged. Why did you create the second one ?

Because this one was asking how to make it happen. The other was now that I have it, it's having problems. But someone scrolling by wouldn't see that it was having problems, hence why I stated that in my other post.

I'm trying to format that sketch on here, but I can't seem to figure out how to do so.

Format which sketch ?

Hi, @tpaairman
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

The sketch that I have here. Someone said to format if properly. I was having trouble making that happen, but it's now corrected.

There is another method of removing the old text instead of overwriting with the background-colored rectangle.

When you write the value to the screen, save that value in a variable for future use.
When it is time to write a new value to the screen, write the previous value to the screen with the text color set to the background color (this effectively erases the old text), then reposition the cursor and write the new value to the screen using the actual text color.

You should already be saving the previous value written to the screen, so that you can compare it with the current value and only rewrite the display when the data changes.

I just tried that and it still has the flicker issue.

Please post your complete sketch as it is now

If you are comparing 2 float values to determine whether whether the latest one differs from the previous one then it is very likely that they will differ every time unless you take steps to compare their significant decimal places rather than the complete value down to several decimal places

As previously suggested (post #4) you would almost certainly be better off dealing with integer values and displaying them as a float (or an apparent float) only when required

UKHellBob - This is the complete sketch. I have the other that I used to test with the TFT display, but this is the full sketch to test singling out individual digits. If I can figure out the problem here, there that should lead me down the path to figure out the other one.

As for comparing the float values, I'm not understanding what you are getting at. My first value (VOLTS) is a float, and needs to be. Then PresentVolts, which is a static float, but that's as best I understood from post 4 what I needed to do. Everything else is an integer, and I'm not displaying any of them as a float.

EDIT: I am displaying the original value as a float, but that shouldn't be the issue. I might be wrong, but it seems more that the sketch is not breaking down the numbers.

We really need to see the sketch that you are using with the TFT display in order to understand why the display is blinking. There will always be a bit of blinking because there will be a short interval between erasing the old data and displaying the new data in its place, but that really should not be very noticeable because the digit itself will be changing at the same time.

I don't know why you think you need to break down the numbers. Read the voltage now. Compare it with the voltage read previously. If it is different then display the new value

Work with integer values rather than floats and consider only comparing the new and old values every second (or longer) rather than every time through loop()

The TFT is blinking because you put a rectangle over the old text, then display the new text. It’s that period of time when the rectangle is there but no text. That’s why I’m writing this sketch for it, or should I say adding this one to that. What I’m trying to do is have it only put a smaller rectangle over the individual digit that changed so you won’t have that flicker look since the digit is changing anyway.

But my question here is not about the flicker. It’s about why is this sketch skipping one set of values. If everyone insists, I’ll post that too, but it would be more helpful to figure out what’s going wrong here.

On the subject of using a float, in the actual project, it will read one place to the right of the decimal. Since integers won’t read decimal places, I have to use a float fur that one.

You are running into the problem that 0.1 cannot be exactly represented as a floating point number in binary. When you subtract 0.1 each time through the loop, you are not getting 24.3, but a very slightly smaller number like 24.299999. When printing a float to 1 decimal place, the number gets rounded and will appear as 24.3, but when converting from a float to an integer the decimal part gets truncated, resulting in (24.299999 * 10) being stored as 242 in the int, not 243.

Here is a modified version of your sketch that should give the proper digit breakdown, and avoids the multiple conversions between floats and integers:

float Volts;
int Tenths;
int Ones;
int Tens;
float PresentVolts;

void setup() {
  Serial.begin (9600);
  //Test Data
  Volts = 25.0;
}

void loop() {
  PresentVolts = Volts;
  
  //round and convert to integer
  int intVolts = (PresentVolts + 0.05) * 10;
  Tenths = intVolts % 10;
  Ones = (intVolts / 10) % 10;
  Tens = intVolts / 100;

  Serial.println (Volts, 1);
  Serial.println(Tens);
  Serial.println (Ones);
  Serial.println (Tenths);
  Serial.println ("  ");
  delay (250);
  Serial.println("  ");

  Volts = Volts - .1;
  if (Volts < 0) {
    Volts = 25;
  }
}