Notifications
Clear all

Clearing garbage characters on OLED display  

Page 1 / 2

DaveMorris
(@davemorris)
Eminent Member
Joined: 2 months ago
Posts: 23
Topic starter  

I have another issue on the same project that I am working on with the temp sensors.  This involves a voltage monitor display. I am using a divider to monitor the voltage in my vehicle. I followed Bill's video on setting up a divider network to read voltage and it works great. However, when I display it on my oled, the characters do not clear as the reading changes.  It seems like I am just writing new numbers over old numbers.  In Bill's video the oled display numbers just change as the values change.  His code doesn't contain any lines to clear it out each time it is updated.  What am I missing here? I am using a Waveshare 128x128 display and using the Adafruit SSD1351 library.

Here is the part of the code in the void loop for the voltage reading:

display.setTextColor(WHITE,BLACK);
display.setCursor(82,20);
display.setTextColor(WHITE);
//display.print(" ");
display.print(in_voltage, 2);
delay(1000);

I have lines in the void setup to display the blue and red text, which doesn't change, as shown in the photo. How can I clear just the values that I am getting back on the voltage?  I would assume I will have the same problem when I try to display the temp values the same way.  This project is really getting me frustrated, but I know I can learn by working through it, with help from those that know way more than I.

IMG 0807

Quote
noweare
(@noweare)
Estimable Member
Joined: 1 year ago
Posts: 108
 

I have always had to clear the space before writing to my display. I normally use the 2x16 lcd displays. You don't have to clear space if your new value takes up the same amount of space as the old value. That will save you from having to clear the locations on your display. You can just format your values to take up the same amount of space.


ReplyQuote
MadMisha
(@madmisha)
Estimable Member
Joined: 1 year ago
Posts: 240
 

@davemorris

I offer a couple of solutions you can play around with.

If you know the max number of characters it would be, then print a "   " with the correct number of spaces to fill and then print your values right after(over the top of it).

If you know the max number you can display, you can put your values in a string and run a while loop with the len function and add a " " to the end every loop until the characters are enough.(If you have the space, then you could just adding a string of "        " to the end every time would work too. That would be in place of the while loop.)

You could also use the round function if you have a float with too many digits.

 

Otherwise, consider using a clear function and redrawing the whole screen. Your set characters could be moved into a function and called whenever needed. I see that library uses fillscreen and a color to accomplish this.

 

If you want examples, just let me know.

 

Edit: I will also note that if you want to keep a few decimal places and use the round function then just do this:

newVar = (round((oldVar * 100))/100); //Add as many 0's as needed

LydaRA liked
ReplyQuote
LydaRA
(@lydara)
Trusted Member
Joined: 2 months ago
Posts: 95
 

@madmisha  "Localized clearing," nice & efficient!


ReplyQuote
DaveMorris
(@davemorris)
Eminent Member
Joined: 2 months ago
Posts: 23
Topic starter  
Posted by: @madmisha

@davemorris

I offer a couple of solutions you can play around with.

If you know the max number of characters it would be, then print a "   " with the correct number of spaces to fill and then print your values right after(over the top of it).

If you know the max number you can display, you can put your values in a string and run a while loop with the len function and add a " " to the end every loop until the characters are enough.(If you have the space, then you could just adding a string of "        " to the end every time would work too. That would be in place of the while loop.)

Thanks for the info.  I tried doing a display.print("   ") but it didn't work. This project is going in a vehicle so the spaces I need would be 2 spaces, decimal point, 2 spaces.  Maybe my syntax is off somewhere. Here is my coding that I have so far.  This doesn't include the top part showing the include library lines and a few of the other parameters.

//analog input pin
#define ANALOG_IN_PIN A0

//floats for ADC voltage & input voltage
float adc_voltage = 0.0;
float in_voltage = 0.0;

//floats for resistor values in divider
float R1 = 30000.0;
float R2 = 7500.0;

//float for reference voltage
float ref_voltage = 5.0;

//integer for ADC value
int adc_value = 0;

Adafruit_SSD1351 display=Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);

void setup() {
// put your setup code here, to run once:
display.begin();
display.fillScreen(BLACK);
display.setTextColor(ORANGE);
display.setTextSize(1.5);
display.setCursor(25,0);
display.print("SYSTEM STATUS");
display.setTextSize(1);
display.setCursor(0,20);
display.setTextColor(BLUE);
display.print("INPUT VOLTAGE:");
display.setCursor(0,33);
display.setTextColor(BLUE);
display.print("VXi TEMP RIGHT:");
display.setCursor(88,33);
display.setTextColor(WHITE);
display.print(" 120 F");
display.setCursor(0,46);
display.setTextColor(BLUE);
display.print("VXi TEMP LEFT:");
display.setCursor(88,46);
display.setTextColor(WHITE);
display.print(" 122 F");
display.setCursor(0,100);
display.setTextColor(BLUE);
display.print("LED STATUS:");
display.setCursor(63,100);
display.setTextColor(WHITE);
display.print(" ON");

}

void loop() {
// put your main code here, to run repeatedly:
//Read analog voltage input
adc_value = analogRead(ANALOG_IN_PIN);

//Determine voltage at ADC input
adc_voltage = (adc_value * ref_voltage)/1024.0;

//Calculate voltage at divider input
in_voltage = adc_voltage / (R2/(R1+R2));

//Send results to display
display.setTextColor(WHITE,BLACK);
display.setCursor(82,20);
display.setTextColor(WHITE);
display.print(" ");
display.print(in_voltage, 2);
delay(1000);

}

 

One more note, the display I am using is the Waveshare 1.5", 128x128 display.  Is it possible that I am using the wrong library? (Adafruit SSD1351) It seems to work fine, other than the numbers not staying clean.  Ultimately I will be doing the same thing with the two temp readings.  They will be coming from two MLX90614 IR temp sensors.  (I have another post about that issue)  I am guessing that once the temp sensors are running I will have the same issue printing that to screen.  None of these readings need to respond faster or more often than every second or so.  It is a little overwhelming and frustrating since I know this should be easy.


ReplyQuote
MadMisha
(@madmisha)
Estimable Member
Joined: 1 year ago
Posts: 240
 

@davemorris

You are using the library exactly how I would expect. But you are only printing one space to clear it? The way the screen works is that when you set the cursor, that is where you start out. So if it is on character 60(I know your not doing it by character but that's just a good example), then that first character it prints will be there and the cursor will move to 61. The " " will only replace that one space. Try adding more spaces. If you are looking to clear 5 characters then "     "(or more might be better here). Then you need to reset your cursor back to where it was and print your actual data.

 

You might also try printing to serial monitor to see exactly how it looks. Or try converting it to a string before you print it.


LydaRA liked
ReplyQuote
MadMisha
(@madmisha)
Estimable Member
Joined: 1 year ago
Posts: 240
 
Posted by: @davemorris

display.setTextColor(WHITE,BLACK);

This does concern me though.  I have never seen two colors listed. I can't say it's wrong or that it would be causing your problem, but it seems off. You also change it right after without writing anything.

 

Try:

//Send results to display
display.setCursor(82,20);
display.setTextColor(WHITE);
display.print(" ");
display.setCursor(82,20);
display.print(" ");
display.print(in_voltage, 2);
delay(1000);

 


ReplyQuote
MadMisha
(@madmisha)
Estimable Member
Joined: 1 year ago
Posts: 240
 
Posted by: @davemorris

display.print(in_voltage, 2);

Why is that 2 there? I ignored it until I could do a search because I was not sure what it was for, but I might see the problem. I could be missing something obvious or just it's just over my head but I did find in the example test that it printed from a variable and had a 6. It didn't print out 6 characters but it did print out 6 decimal places so I have to assume that is the purpose. Your variable adc_value is an int. Try changing it to float and see what happens. If you were using it as an integer to truncate it, consider using round instead as I described above.


ReplyQuote
DaveMorris
(@davemorris)
Eminent Member
Joined: 2 months ago
Posts: 23
Topic starter  
Posted by: @madmisha
Posted by: @davemorris

display.setTextColor(WHITE,BLACK);

This does concern me though.  I have never seen two colors listed. I can't say it's wrong or that it would be causing your problem, but it seems off. You also change it right after without writing anything.

 

Try:

//Send results to display
display.setCursor(82,20);
display.setTextColor(WHITE);
display.print(" ");
display.setCursor(82,20);
display.print(" ");
display.print(in_voltage, 2);
delay(1000);

 

I saw in a video regarding that driver that the two colors are (Text color, Background color).  I also put the 2 in the parentheses to limit the number to two decimal places.


ReplyQuote
DaveMorris
(@davemorris)
Eminent Member
Joined: 2 months ago
Posts: 23
Topic starter  
Posted by: @madmisha

Try:

//Send results to display
display.setCursor(82,20);
display.setTextColor(WHITE);
display.print(" ");
display.setCursor(82,20);
display.print(" ");
display.print(in_voltage, 2);
delay(1000);

 

I am going to try this code.  Thank you for the assistance.


ReplyQuote
DaveMorris
(@davemorris)
Eminent Member
Joined: 2 months ago
Posts: 23
Topic starter  

Wow, I am really getting frustrated here. Even with the code supplied above by madmisha, this still shows the same result. I see no reason why this would not work.  I'm going to dig around on the Waveshare sight again to see if I am missing something but even with me being very much a newbie to the programming, I still think this should not be this hard to have a clean display that updates every second or so.


ReplyQuote
MadMisha
(@madmisha)
Estimable Member
Joined: 1 year ago
Posts: 240
 

@davemorris

Posted by: @davemorris

int adc_value = 0;

Did you change this to a float too? Because the print statement is expecting 2 decimal places and the value you are referring to does not have any. When mixing data types you can get unexpected results. You could also try being implicate with all your math function and make them floats.

Or you could try this to see what happens:

//Send results to display
display.setCursor(82,20);
display.setTextColor(WHITE);
display.print(" ");
display.setCursor(82,20);
display.print(" ");
display.print(in_voltage);
delay(1000);

If one of those works, I have some possible solutions to get it to conform to what you want.

 

You could also try converting it to a string first(there are a few options to go with). It is expecting a string and it may play nicer that way.

Here is one to try that will print all values to the serial monitor and maybe you can see where the error is. It also conforms all the values to the same data type.

//analog input pin
#define ANALOG_IN_PIN A0

//floats for ADC voltage & input voltage
float adc_voltage = 0.0;
float in_voltage = 0.0;

//floats for resistor values in divider
float R1 = 30000.0;
float R2 = 7500.0;

//float for reference voltage
float ref_voltage = 5.0;

//integer for ADC value
float adc_value = 0;

Adafruit_SSD1351 display=Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
display.begin();
display.fillScreen(BLACK);
display.setTextColor(ORANGE);
display.setTextSize(1.5);
display.setCursor(25,0);
display.print("SYSTEM STATUS");
display.setTextSize(1);
display.setCursor(0,20);
display.setTextColor(BLUE);
display.print("INPUT VOLTAGE:");
display.setCursor(0,33);
display.setTextColor(BLUE);
display.print("VXi TEMP RIGHT:");
display.setCursor(88,33);
display.setTextColor(WHITE);
display.print(" 120 F");
display.setCursor(0,46);
display.setTextColor(BLUE);
display.print("VXi TEMP LEFT:");
display.setCursor(88,46);
display.setTextColor(WHITE);
display.print(" 122 F");
display.setCursor(0,100);
display.setTextColor(BLUE);
display.print("LED STATUS:");
display.setCursor(63,100);
display.setTextColor(WHITE);
display.print(" ON");

}

void loop() {
// put your main code here, to run repeatedly:
//Read analog voltage input
float adc_value = analogRead(ANALOG_IN_PIN);
Serial.print("ADC Val: ");
Serial.println(adc_value);

//Determine voltage at ADC input
float adc_voltage = (adc_value * ref_voltage)/1024.0;
Serial.print("ADC Volt: ");
Serial.println(adc_voltage);

//Calculate voltage at divider input
float in_voltage = adc_voltage / (R2/(R1+R2));
Serial.print("In Volt: ");
Serial.println(in_voltage);

//Send results to display
display.setTextColor(WHITE,BLACK);
display.setCursor(82,20);
display.setTextColor(WHITE);
display.print(" ");
display.print(String(in_voltage, 2));
delay(1000);

}



ReplyQuote
MadMisha
(@madmisha)
Estimable Member
Joined: 1 year ago
Posts: 240
 

@davemorris

If that does not work, I suggest using the original waveshare library. They do things a little differently in the demo so maybe the Adafruit library just isn't compatible.


ReplyQuote
DaveMorris
(@davemorris)
Eminent Member
Joined: 2 months ago
Posts: 23
Topic starter  
Posted by: @madmisha

Here is one to try that will print all values to the serial monitor and maybe you can see where the error is. It also conforms all the values to the same data type.

This returned correct values to the serial monitor.  Now I just need to figure out how to send it to a specific part of my display and get it to refresh properly. I suspect that my original code was returning correct voltage readings but it isn't refreshing the display in between readings.  I am going to work on it some more and see if something in your code is different than mine.

Thx


ReplyQuote
MadMisha
(@madmisha)
Estimable Member
Joined: 1 year ago
Posts: 240
 

@davemorris

If it was correct on the serial monitor but the screen was still garbage, then I would download the Waveshare library/example I linked above. They do things a little different in their example. Maybe it isn't compatible with the other library. It also included a font.


ReplyQuote
Page 1 / 2