I'm trying to move a meter around a screen using #define X_POS 0 and #define Y_POS 0
and then adding +X_POS and +Y_POS to the parts of the code that "I think" need it
I've done most of it but having trouble moving the needle parts to the correct position(see attached image)
in the image I've moved it down screen using #define Y_POS 200
I think I've messed up the centre point too somehow
hoping someone can point me in the right direction
// #########################################################################
// Draw the analogue meter on the screen
// #########################################################################
void analogMeter()
{
// Meter outline
tft.fillRect(X_POS+2, Y_POS+0, M_SIZE*239, M_SIZE*126, TFT_GREY);
tft.fillRect(X_POS+5, Y_POS+3, M_SIZE*230, M_SIZE*119, TFT_WHITE);
tft.setTextColor(TFT_BLACK); // Text colour
// Draw ticks every 5 degrees from -50 to +50 degrees (100 deg. FSD swing)
for (int i = -50; i < 51; i += 5) {
// Long scale tick length
int tl = 15;
// Coodinates of tick to draw
float sx = cos((i - 90) * 0.0174532925);
float sy = sin((i - 90) * 0.0174532925);
uint16_t x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
uint16_t y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
uint16_t x1 = sx * M_SIZE*100 + M_SIZE*120;
uint16_t y1 = sy * M_SIZE*100 + M_SIZE*140;
// Coordinates of next tick for zone fill
float sx2 = cos((i + 5 - 90) * 0.0174532925);
float sy2 = sin((i + 5 - 90) * 0.0174532925);
int x2 = sx2 * (M_SIZE*100 + tl) + M_SIZE*120;
int y2 = sy2 * (M_SIZE*100 + tl) + M_SIZE*140;
int x3 = sx2 * M_SIZE*100 + M_SIZE*120;
int y3 = sy2 * M_SIZE*100 + M_SIZE*140;
// Meter Zones (angles +/- 50 Degrees from centre).
// Blue zone limits
if (i >= -50 && i < 0) {
tft.fillTriangle(x0+X_POS, y0+Y_POS, x1+X_POS, y1+Y_POS, x2+X_POS, y2+Y_POS, TFT_BLUE);
tft.fillTriangle(x1+X_POS, y1+Y_POS, x2+X_POS, y2+Y_POS, x3+X_POS, y3+Y_POS, TFT_BLUE);
}
// Green zone limits
if (i >= 0 && i < 25) {
tft.fillTriangle(x0+X_POS, y0+Y_POS, x1+X_POS, y1+Y_POS, x2+X_POS, y2+Y_POS, TFT_GREEN);
tft.fillTriangle(x1+X_POS, y1+Y_POS, x2+X_POS, y2+Y_POS, x3+X_POS, y3+Y_POS, TFT_GREEN);
}
// Orange zone limits
if (i >= 25 && i < 50) {
tft.fillTriangle(x0+X_POS, y0+Y_POS, x1+X_POS, y1+Y_POS, x2+X_POS, y2+Y_POS, TFT_ORANGE);
tft.fillTriangle(x1+X_POS, y1+Y_POS, x2+X_POS, y2+Y_POS, x3+X_POS, y3+Y_POS, TFT_ORANGE);
}
// Short scale tick length
if (i % 25 != 0) tl = 8;
// Recalculate coords incase tick lenght changed
x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
y0 = sy * (M_SIZE*100 + tl) + M_SIZE*140;
x1 = sx * M_SIZE*100 + M_SIZE*120;
y1 = sy * M_SIZE*100 + M_SIZE*140;
// Draw tick
tft.drawLine(x0+X_POS, y0+Y_POS, x1+X_POS, y1+Y_POS, TFT_BLACK);
// Check if labels should be drawn, with position tweaks
if (i % 25 == 0) {
// Calculate label positions
switch (i / 25) {
// Set left and right labels
case -2: tft.setCursor(M_SIZE*16+X_POS,M_SIZE*16+Y_POS);tft.print("0");break;
case 2: tft.setCursor(M_SIZE*190+X_POS,M_SIZE*16+Y_POS);tft.print("100");break;
}
}
// Now draw the arc of the scale
sx = cos((i + 5 - 90) * 0.0174532925);
sy = sin((i + 5 - 90) * 0.0174532925);
x0 = sx * M_SIZE*100 + M_SIZE*120;
y0 = sy * M_SIZE*100 + M_SIZE*140;
// Draw scale arc, don't draw the last part
if (i < 50) tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
}
tft.drawRect(X_POS+5, Y_POS+3, M_SIZE*230, M_SIZE*119, TFT_BLACK); // Draw bezel line
plotNeedle(0, 0); // Put meter needle at centre (0,0)
}
// #########################################################################
// Update needle position
// This function is blocking while needle moves, time depends on ms_delay
// 10ms minimises needle flicker if text is drawn within needle sweep area
// Smaller values OK if text not in sweep area, zero for instant movement but
// does not look realistic... (note: 100 increments for full scale deflection)
// #########################################################################
void plotNeedle(int value, byte ms_delay)
{
tft.setTextColor(TFT_BLACK, TFT_WHITE);
char buf[8]; dtostrf(value, 4, 0, buf);
tft.setCursor(M_SIZE*40+X_POS, M_SIZE*(119 - 20+Y_POS));
tft.print(buf);
//FIXME: tft.drawRightString(buf, M_SIZE*40, M_SIZE*(119 - 20), 2);
if (value < -10) value = -10; // Limit value to emulate needle end stops
if (value > 110) value = 110;
// Move the needle until new value reached
while (!(value == old_analog)) {
if (old_analog < value) old_analog++;
else old_analog--;
if (ms_delay == 0) old_analog = value; // Update immediately if delay is 0
float sdeg = map(old_analog, -10, 110, -150, -30); // Map value to angle
// Calcualte tip of needle coords
float sx = cos(sdeg * 0.0174532925);
float sy = sin(sdeg * 0.0174532925);
// Calculate x delta of needle start (does not start at pivot point)
float tx = tan((sdeg + 90) * 0.0174532925);
// Erase old needle image
tft.drawLine(M_SIZE*(120 + 20+X_POS * ltx - 1), M_SIZE*(140 - 20+Y_POS), osx - 1, osy, TFT_WHITE);
tft.drawLine(M_SIZE*(120 + 20+X_POS * ltx), M_SIZE*(140 - 20+Y_POS), osx, osy, TFT_WHITE);
tft.drawLine(M_SIZE*(120 + 20+X_POS * ltx + 1), M_SIZE*(140 - 20+Y_POS), osx + 1, osy, TFT_WHITE);
// Re-plot text under needle
tft.setTextColor(TFT_BLACK);
tft.setCursor(M_SIZE*120+X_POS, M_SIZE*80+Y_POS);
tft.print("%");
// FIXME: tft.drawCentreString("%RH", M_SIZE*120, M_SIZE*70, 4); // // Comment out to avoid font 4
// Store new needle end coords for next erase
ltx = tx;
osx = M_SIZE*(sx * 98 + 120+X_POS);
osy = M_SIZE*(sy * 98 + 140+Y_POS);
// Draw the needle in the new postion, magenta makes needle a bit bolder
// draws 3 lines to thicken needle
tft.drawLine(M_SIZE*(120 + 20+X_POS * ltx - 1), M_SIZE*(140 - 20+Y_POS), osx - 1, osy, TFT_ORANGE);
tft.drawLine(M_SIZE*(120 + 20+X_POS * ltx), M_SIZE*(140 - 20+Y_POS), osx, osy, TFT_MAGENTA);
tft.drawLine(M_SIZE*(120 + 20+X_POS * ltx + 1), M_SIZE*(140 - 20+Y_POS), osx + 1, osy, TFT_ORANGE);
// Slow needle down slightly as it approaches new postion
if (abs(old_analog - value) < 10) ms_delay += ms_delay / 5;
// Wait before next update
delay(ms_delay);
}
}