First, let me apologize for the length of the post. There is a TL;DR at the bottom.
I consider myself the world's second worst programmer so please assume I know less than you think and use small words.
I'm trying to develop my own bike computer because I figure I can do it half as well and for twice the price
of buying one. I'm using this module from Waveshare: https://www.waveshare.com/esp32-s3-touch-lcd-1.28.htm
For software, Attempt 1 was with the "animated dial" project under Examples > TFT_eSPI > Sprite. I had some measure of success but I was having a real hard time understanding the code so I started again with a simpler one. That seems to be going better, but I'm still struggling. Attempt 2 is from Examples > TFT_eSPI >
Smooth Graphics > Smooth Arc.
Explanation: The outer ring is just an image and I'm happy with that.
The inner arc (CYAN), is supposed to move clockwise about the inner circumference with speed. 0 mph is at 60 degrees (0 deg. is at the 6 o'clock position). 30mph (the max) or higher values is supposed to peg at 300 deg. See picture 1 it is sort of what I'm looking for. (problem 1)
In the middle, in large numbers is the speed with one decimal place accuracy. (problem 2). The "MPH" label under it is fine. In the 120 degree gap in the arc at the bottom I have placed other info. In this case it's the total miles traveled. I'm happy with the "TOTAL MILES" label, but the numeric value is also a problem. (problem 3).
I am not getting any warnings. The code compiles fine.
(Problem 4) = documentation.
PROBLEM 1: In my code the random number generated will not be used. The data will come from elsewhere, but because it's messing up, I need to know if it's the arc that's the problem or if the number I'm generating is out of range. The arc works like this: If the speed is increasing, I just draw more arc, but if the speed is decreasing, I "erase" the excess arc by creating a black arc from the new value to the previous end value. I never draw the black arc into the out-of-bounds area, so when the cyan arc goes there, it never goes away. I started by running random (min,max); with 60 and 301 as the arguments, so I figured this would keep the arc
between those values. When that didn't work, I inserted the if (a < 60) a = 60; and if (a > 300) a = 300; statements. That didn't work either. See picture 2.
PROBLEM 2: I'm happy with the look and placement of the numbers indicating speed. I'd like one decimal place accuracy so I used a float. I know there are problems with floats and I can change it later if it is too slow.
But the problem here, as with the odometer number below it, is that when I write a new number, it goes over the old number. This was not a problem with Attempt 1, probably because it used Sprites, which I don't understand. I don't really know how to get rid of the old value when the new one writes on top of it. I don't want to use
a black box, because I don't seem to be able to get it to cover the number at the correct rate (either the number never shows up, just a black box or a horrible flicker with both numbers briefly showing). Also, the numbers are close to the arc and a box might cut a chunk out of it. See picture 4.
PROBLEM 3: I can't seem to make the odometer number font size smaller than the speed font size. I thought if I loaded the font IN the command, it would take precedence over the tft.loadFont(AA_FONT_LARGE); command. I just want a more normal font, like the MPH and TOTAL MILES labels, but a little bit bigger, not the
NotoSansBold72 font. Even picture 3 is a little too big.
PROBLEM 4: Documentation. I think I struggle a lot because I can't seem to find a complete definition for a lot of topics (e.g. Sprites.) The arduino site defining the syntax of many of the basic commands is good. And this site TFT_eSPI::drawFloat - TFT_eSPI library is super helpful. I would like
more sites like it. For instance I found it by searching for a command. I think it was tft.drawNumber, but when I search tft.pushSprite, I can find specific examples from users on forums and stuff, but there has to be a place with all of the commands for, well, everything doesn't there? I mean, someone developed this stuff.
TL;DR
Look at code.
Problem 1. The arc I'm drawing seems to go into the out-of-bounds area between 60 and 300 degrees. Why?
Problem 2. How do I "delete" a number on the screen when I update it so new values don't appear over old ones?
Problem 3. How do I get two font sizes on one display? Using tft.loadFont seems to set it for everything.
Problem 4. Can you lead me to a "dictionary" or "dictionaries" of every command (or as many as possible)?
Thank you in advance. Now I have to hope I can properly post all of this info.
/ 11-29-24 Bike computer interface with smooth arc instead of sprite with no erase.
#include "outer_ring_test_gradiant_pink_blue_glow3.h"
#include <TFT_eSPI.h>
uint16_t x = 120; // Position of centre of arc, round screen is 240 x 240 with corners chopped off.
uint16_t y = 120;
uint16_t fg_color = TFT_CYAN; // Foreground and background colour used for smoothing (anti-aliasing)
uint16_t bg_color = TFT_BLACK;
uint8_t radius = 100; // Outer arc radius
uint8_t thickness = 15; // Thickness or arc
uint8_t inner_radius = radius - thickness; // Calculate inner radius (can be 0 for circle segment)
const unsigned long refresh_rate = 1000; //interval to update speed/screen (millis)
unsigned long previousTime = 0; //longs are needed because millis can get big fast
float speed;
static int16_t old_end_angle = 60; //start old_end_angle for program.
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
#include "NotoSansBold72.h"
#define AA_FONT_LARGE NotoSansBold72
long a;
//SETUP *********************************************************************************************************
void setup(void)
{
Serial.begin(115200);
tft.init();
tft.setRotation(0); //Rotate display to appropriate angle. 0 degrees is at 6 o'clock position
tft.fillScreen(TFT_BLACK);
tft.pushImage(0, 0, 240, 240, outer_ring_test_gradiant_pink_blue_glow3);
tft.setTextDatum(MC_DATUM);
tft.drawString("MPH", x, y + 35, 2);
tft.drawString("TOTAL MILES",x, y + 90, 2);
}
//MAIN LOOP********************************************************************************************************
void loop()
{
unsigned long currentTime = millis();
if (currentTime - previousTime >= refresh_rate)
{
a = random(60,301);
if (a < 60) a = 60;
if (a > 300) a = 300;
speed = 27.7;
uint16_t start_angle = 60; // Start angle must be in range 0 to 360. Arcs are drawn clockwise from start_angle to end_angle
uint16_t end_angle = a; // End angle must be in range 0 to 360
while (end_angle != old_end_angle)
{
tft.drawSmoothArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color);
if (end_angle < old_end_angle)
{
tft.drawSmoothArc(x, y, radius, inner_radius, end_angle, old_end_angle, TFT_BLACK, bg_color);
}
float distance = 400.3;
//tft.fillRect(x, y + 70, 80, 12, TFT_BLACK);
tft.setTextSize(2);
tft.setTextFont(4);
tft.drawFloat(distance, 1, x, y + 65);
tft.loadFont(AA_FONT_LARGE);
tft.drawFloat(speed, 1, x , y ); //x and y are the upper left corner of the speed text, apparently
old_end_angle = end_angle;
}
previousTime = currentTime;
}
}type or paste code here







