Differences between Teensy duino 1.57.2 and 1.58.2

pd0lew

Well-known member
Hi,

1.58.1.jpg1.58.1.jpg

My project compiles perfect with version 1.57.2 but get a lot of errors with version 1.58.1 is here a solution or must I stick on version 1.57.2.

Best regards,
Johan
 
Hard to see if there is a difference between the two images?

What shows is a compiler parameter error that may have been unnoticed by the tool chain in 1.57 that was updated for 1.58. There is another toolchain update in 1.59 currently in Beta.

Would be best to copy text of the console output for better and more complete readability of 'lot of errors'. The visible error indicates a constant single quote literal character parameter is provided where the function prototype tells the compiler to expect a pointer to a character.
 
Those errors I not get in version 1.57.2


In file included from /home/holstein/Desktop/FL2100Z_PWRV1.0/PSWRtft.cpp:28:
/home/holstein/Desktop/FL2100Z_PWRV1.0/PSWRtft.h: In member function 'void PowerMeter::scale(double)':
/home/holstein/Desktop/FL2100Z_PWRV1.0/PSWRtft.h:84:37: warning: invalid conversion from 'char' to 'char*' [-fpermissive]
84 | void scale(double s) { scale(s, '\0'); }// Blank if no scale range string
| ^~~~
| |
| char
/home/holstein/Desktop/FL2100Z_PWRV1.0/PSWRtft.h:83:32: note: initializing argument 2 of 'void PowerMeter::scale(double, char*)'
83 | void scale(double s, char *range); // Scale Erases if required and then draws everything
| ~~~~~~^~~~~
In file included from /home/holstein/Desktop/FL2100Z_PWRV1.0/PSWR_T.h:43,
from /home/holstein/Desktop/FL2100Z_PWRV1.0/FL2100Z_PWRV1.0.ino:113:
/home/holstein/Desktop/FL2100Z_PWRV1.0/PSWRtft.h: In member function 'void PowerMeter::scale(double)':
/home/holstein/Desktop/FL2100Z_PWRV1.0/PSWRtft.h:84:37: warning: invalid conversion from 'char' to 'char*' [-fpermissive]
84 | void scale(double s) { scale(s, '\0'); }// Blank if no scale range string
| ^~~~
| |
| char
/home/holstein/Desktop/FL2100Z_PWRV1.0/PSWRtft.h:83:32: note: initializing argument 2 of 'void PowerMeter::scale(double, char*)'
83 | void scale(double s, char *range); // Scale Erases if required and then draws everything
| ~~~~~~^~~~~

Memory Usage on Teensy 4.0:
FLASH: code:126972, data:912576, headers:9024 free for files:983044
RAM1: variables:339552, code:124840, padding:6232 free for local variables:53664
RAM2: variables:12416 free for malloc/new:511872
Failed uploading: no upload port provided

I included the part of the program where the errors come from.
PSWRtft.cpp and PSWRtft.h

PSWRtft.ccp


Code:
#include "PSWRtft.h"
#include "PSWR_T.h"

extern var_t R; // R.low_power_floor flag/variable used with Modulation Scope
extern RA8875 tft;
//-----------------------------------------------------------------------------------------
// Initialise Dual Power Meter,
// define left x and top y coordinates;
// length x; height y;
// graph, low and high colour
//-----------------------------------------------------------------------------------------

void PowerMeter::init(int16_t xcoord, int16_t ycoord, int16_t xlen, int16_t ylen,
int16_t graphcolour, int16_t lowcolour, int16_t highcolour)
{
x = xcoord;
y = ycoord;
len = xlen;
height = ylen;
GaugeColour = graphcolour;
LowColour = lowcolour;
HighColour = highcolour;
}
void PowerMeter::init(int16_t xcoord, int16_t ycoord, int16_t xlen, int16_t ylen)
{
x = xcoord;
y = ycoord;
len = xlen;
height = ylen;
}

//-----------------------------------------------------------------------------------------
// Draw, Redraw or Erase Power Meter Scale.
// If requested action is same as last time, then nothing is done.
// First input argument is a number from 1.0 and up, divided into 10 or 11 segments
// (11 if (scale*10)%11=0 and if second input is used to indicate unit)
// Second, optional input argument, is an unit indication for the measured level,
// eg "uW", "mW", "W", "kW"
//-----------------------------------------------------------------------------------------

void PowerMeter::scale(double s, char *range)
{
if (erased) // Draw complete Graph if requested and not already drawn
{
drawframe(GaugeColour);
drawscale(s, GaugeColour, range);
printunits(GaugeColour, range);
current_scale = s;
strcpy(current_range, range);
erased = false;
}
else
{
if (current_scale != s) // Replace scale if changed
{
drawscale(current_scale, blnkColour, current_range);
drawscale(s, GaugeColour, range);
current_scale = s;
}
if (strcmp(current_range, range)) // Replace units indication if changed
{
printunits(blnkColour, current_range);
printunits(GaugeColour, range);
strcpy(current_range, range);
}
}
}
void PowerMeter::erase(void)
{
if (!erased)
{
drawframe(blnkColour);
drawscale(current_scale, blnkColour, current_range);
printunits(blnkColour, current_range);
erasegraph();
erased = true;
}
}
void PowerMeter::drawframe(int16_t colour)
{
tft.drawRect(x, y,len+2, height+2, colour); // Draw the Graph Outline
tft.drawFastHLine(x, y + height+2, len+2, colour);// Draw the Scale line below
}
void PowerMeter::printunits(int16_t colour, char *range)
{
tft.setFont(DroidSansMono_16);
tft.setTextColor(colour);
tft.setCursor( x+len - 4*strlen(range), y+height+9);
tft.print(range);
}
void PowerMeter::drawscale(double scale, int16_t colour, char *range)
{
double i, j, k;
uint8_t subdecimal;
int16_t offs = 0;
double divisor; // Divisor of 10 or 11.

// Certain scales are good for 11 segments, if range indication is used
if (((int)(scale*10+.1)%11) == 0) divisor = 11;
else divisor = 10;

tft.setFont(DroidSansMono_16);
tft.setTextColor(colour);
tft.drawFastVLine( x+1, y+height+2, 5, colour); // Draw the Scale
tft.setCursor( x-1, y+height+9); // 1st value
tft.print("0");
// Bars and numbers evenly spread over the full length
for (i=len/divisor, j=scale/divisor; i<=len; i+=len/divisor, j+=scale/divisor)
{
tft.drawFastVLine( x+i, y+height+2, 5, colour);
if ((i>=len-1) && (range[0]!=0)) // Units at end of scale, if used
{
; // If Units (e.g. "mW") used then do nothing here,
// printunits(...) will take care of it
}
else
{
k=j; // Figure out offset for the value to be printed, based on number of digits
offs = 3;
while ((k+.1)>=10)
{
offs += 3;
k /= 10;
}
// Decide whether we have subdecimals or not
if ((modf(j, &k) > 0.05) && (modf(j, &k) < 0.95)) subdecimal = 1;
else subdecimal = 0;
if (subdecimal) offs +=4;
tft.setCursor( x+i - offs, y+height+9);
tft.print(j, subdecimal);
}
}
for (i=len/(2*divisor); i<=len; i+=len/divisor) // Draw additional 10 inbetween midpoints
{
tft.drawFastVLine( x+i, y+height+2, 3, colour);
}
}
//-----------------------------------------------------------------------------------------
// Draw Power Meter Graph in an incremental/decremental manner
// input arguments are low value, high value and full scale value
// Note that high value shown is always same or higher than low value shown
//-----------------------------------------------------------------------------------------

void PowerMeter::graph(double lowlevel, double highlevel, double maxlevel)
{
int16_t low, high;

if (lowlevel > maxlevel) lowlevel = maxlevel; // Prepare max bounds of input values
if (highlevel > maxlevel) highlevel = maxlevel;
if (lowlevel < 0) lowlevel = 0;
if (highlevel < 0) highlevel = 0;

low = len * lowlevel / maxlevel; // Calculate length of lower level
high = len * highlevel / maxlevel; // Calculate length of higher level
if (high < low) high = low; // Higher level is never lower than lower

if (low > lastlow) // Draw an increasing low level
{
tft.fillRect(x+1+lastlow, y+1, low-lastlow, height, LowColour);
if (high > lasthigh) // Draw an increasing high level
{
if (lasthigh > low)
tft.fillRect(x+1+lasthigh, y+1, high-lasthigh, height, HighColour);
else if ((lasthigh < low) && (high != low))
tft.fillRect(x+1+low, y+1, high-low, height, HighColour);
}
else if (high < lasthigh) // Draw a decreasing high level
tft.fillRect(x+1+high, y+1, lasthigh-high, height, blnkColour);
}

else if (low < lastlow) // Draw a decreasing low level
{
if (high <= lastlow) // Adjust high level
{
if (high != low)
tft.fillRect(x+1+low, y+1, high-low, height, HighColour);
if (lasthigh != high)
tft.fillRect(x+1+high, y+1, lasthigh-high, height, blnkColour);
}
else if (high >= lastlow) // Adjust high level
{
tft.fillRect(x+1+low, y+1, lastlow-low, height, HighColour);
if (high < lasthigh)
tft.fillRect(x+1+high, y+1, lasthigh-high, height, blnkColour);
else if (high > lasthigh)
tft.fillRect(x+1+lasthigh, y+1, high-lasthigh, height, HighColour);
}
}

else if (high > lasthigh) // Draw an increasing high level while low level is unchanged
tft.fillRect(x+1+lasthigh, y+1, high-lasthigh, height, HighColour);
else if (high < lasthigh) // Draw a decreasing high level while low level is unchanged
tft.fillRect(x+1+high, y+1, lasthigh-high, height, blnkColour);

lastlow = low;
lasthigh = high;
}
void PowerMeter::erasegraph(void)
{
if (lasthigh > 0)
{
tft.fillRect(x+1, y+1, lasthigh, height, blnkColour);
lastlow = 0;
lasthigh = 0;
lastmax = 0;
}
}
//-----------------------------------------------------------------------------------------
// Initialise SWR Meter,
// define left x and top y coordinates;
// length x; height y;
// graph, lowSWR, midSWR and highSWR colour
//-----------------------------------------------------------------------------------------

void VSWRmeter::init (int16_t xcoord, int16_t ycoord, int16_t xlen, int16_t ylen,
int16_t graphcolour, int16_t lowcolour, int16_t midcolour, int16_t highcolour)
{
x = xcoord;
y = ycoord;
len = xlen;
height = ylen;
GaugeColour = graphcolour;
lSWRcolour = lowcolour;
mSWRcolour = midcolour;
hSWRcolour = highcolour;
}
void VSWRmeter::init (int16_t xcoord, int16_t ycoord, int16_t xlen, int16_t ylen)
{
x = xcoord;
y = ycoord;
len = xlen;
height = ylen;
}
//-----------------------------------------------------------------------------------------
// Draw SWR Meter Scale
// input arguments are starting x&y positions
//-----------------------------------------------------------------------------------------

void VSWRmeter::scale(void)
{
if (erased) // Draw complete Graph if requested and not already drawn
{
drawscale(GaugeColour); // Always the same
erased = false;
}
}
void VSWRmeter::erase(void)
{
if (!erased)
{
graph(2.0, 3.0, 0.0);
drawscale(blnkColour);
midthresh = 0;
highthresh = 0;
erased = true;
}
}
void VSWRmeter::drawscale(int16_t colour)
{
int16_t offs;
bool subdecimal;
double a;
double scalemark[] = { 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10 };
double scaletick[] = { 1.1, 1.2, 1.3, 1.4, 1.6, 1.7, 1.8, 1.9,
2.2, 2.4, 2.6, 2.8, 3.2, 3.4, 3.6, 3.8,
4.5, 5.5, 6.5, 9 };
tft.setFont(DroidSansMono_16);
tft.setTextColor(colour);

// Draw the Graph Outline
tft.drawRect(x, y,len+2, height+2, colour);
// Draw the Scale line below
tft.drawFastHLine(x, y+height+2, len+2, colour);
// Draw the Scale
for (uint8_t i = 0; i < 10; i++) // Draw full size scale ticks and numbers
{
offs = x+1 + len * log10(scalemark);
tft.drawFastVLine(offs, y+height+2, 5, colour);

if ((scalemark < 10) && // Decide whether we have subdecimals or not
(modf(scalemark, &a) > 0.05) &&
(modf(scalemark, &a) < 0.95))
subdecimal = true;
else subdecimal = false;

if (subdecimal) offs -= 6; // Position text and print
else if (scalemark>=10) offs -= 11;
else offs -= 2;
tft.setCursor(offs, y+height+9);
if (scalemark<10) tft.print(scalemark, subdecimal);
else tft.print("10"); // Print indicator at highest mark
}
for (uint8_t i = 0; i < 20; i++) // Draw half size scale ticks
{
offs = x+1 + len * log10(scaletick);
tft.drawFastVLine(offs, y+height+2, 3, colour);
}
}

//-----------------------------------------------------------------------------------------
// Draw SWR Meter Graph
// input arguments are starting x&y positions, swr value, mid and high indications.
// swr, mid and high as values between 1 and infinite. mid and high for colour
// indication above set value, typically 2.0 and 3.0
//-----------------------------------------------------------------------------------------

void VSWRmeter::graph(double mid, double high, double swr)
{
int16_t barlow; // Length of SWR bar on graph
int16_t barmid = 0; // Indicate yellow above this swr level (mid threshold)
int16_t barhigh = 0; // Indicate red above this swr level (high threshold)

// Set sane limits
if (swr < 1.0) swr = 1.0;
if (mid > high) mid = high;

// We need to force a blank slate to redraw everything if scale thresholds have changed
if ((midthresh != mid) || (highthresh != high))
{
swr = 1.0; // Set SWR at 1.0:1 (eq. 0)

// Prepare scale thresholds
scalemid = len * log10(mid); // Recalculate Mid and High threshold in bar lengths
scalehigh = len * log10(high);
lastlow = scalemid; // Set previous value as the highest
lastmid = scalehigh-scalemid; // possible value, to force a redraw
lasthigh = len-scalehigh;
midthresh = mid; // And store threshold values for next comparison
highthresh = high;
}

// Prepare input values
if (swr > 10) swr = 10;
barlow = len * log10(swr); // Determine overall bar length
barhigh = barlow - scalehigh; // Determine length of high bar
if (barhigh < 0) barhigh = 0;
if (barhigh > 0) barmid = scalehigh - scalemid; // Determine length of mid bar
else barmid = barlow - scalemid;
if (barmid < 0) barmid = 0;
if (barlow > scalemid) barlow = scalemid; // Truncate low bar if needed

// Fill the bargraph
if (barlow > lastlow) // Low bar increasing
tft.fillRect(x+1+lastlow, y+1, barlow-lastlow, height, lSWRcolour); // Fill difference between old and new
else if (barlow < lastlow) // Low bar decreasing
tft.fillRect(x+1+barlow, y+1, lastlow-barlow, height, blnkColour); // Empty difference between old and new

if (barmid > lastmid) // Mid bar increasing
tft.fillRect(x+1+lastmid+scalemid, y+1, barmid-lastmid, height, mSWRcolour); // Fill difference between old and new
else if (barmid < lastmid) // Mid bar decreasing
tft.fillRect(x+1+barmid+scalemid, y+1, lastmid-barmid, height, blnkColour); // Empty difference between old and new

if (barhigh > lasthigh) // High bar increasing
tft.fillRect(x+1+lasthigh+scalehigh, y+1, barhigh-lasthigh, height,hSWRcolour); // Fill difference between old and new
else if (barhigh < lasthigh) // High bar decreasing
tft.fillRect(x+1+barhigh+scalehigh, y+1, lasthigh-barhigh, height, blnkColour); // Empty difference between old and new

lastlow = barlow;
lastmid = barmid;
lasthigh= barhigh;
}

//-----------------------------------------------------------------------------------------
// Initialise Modulation Scope,
// define left x and top y coordinates;
// length x; height y;
// border, trace, and peak colour
//-----------------------------------------------------------------------------------------

void ModulationScope::init (int16_t xcoord, int16_t ycoord, int16_t xlen, int16_t ylen,
int16_t bordercolour, int16_t tracecolour, int16_t peakcolour)
{
borderColour= bordercolour;
traceColour = tracecolour;
peakColour = peakcolour;
init(xcoord, ycoord, xlen, ylen);
}
void ModulationScope::init (int16_t xcoord, int16_t ycoord, int16_t xlen, int16_t ylen)
{
x = xcoord;
y = ycoord;
len = xlen;
if (len > SCOPE_BUFSIZE) len = SCOPE_BUFSIZE;
height = ylen;
y_axis0 = y+1 + height/2;
x_axis0 = x+1;
y_max = height/2;
}

//-----------------------------------------------------------------------------------------
// Erase Modulation Scope
//-----------------------------------------------------------------------------------------

void ModulationScope::erase(void)
{
if (!erased)
{
tft.fillRect(x, y,len+2, height+15, blnkColour); // A simple crude draw blank rectangle
for (uint16_t a=0; a<len; a++) olddata[a] = 0; // Erase scope redraw data
in_pos = 0;
out_pos = 0;
erased = true;
drawn = false;
}
}
void ModulationScope::rate(int16_t rate)
{
rateDivisor = rate;
}

//-----------------------------------------------------------------------------------------
// Update the Modulation Scope circulr buffer with one measurement
//-----------------------------------------------------------------------------------------

void ModulationScope::adddata(double level, double fullscale)
{
if (rateCount <= 0) // Only add data every 1/rateDivisor time.
{
rateCount = rateDivisor;

if (fullscale < level) fullscale = level; // Set sane limits

switch (R.low_power_floor) // Set minimum fullscale at 50x selected Low Power Floor
{
case FLOOR_TEN_mW:
if (fullscale<500.0) fullscale = 500.0; // 500 mW
break;
case FLOOR_ONE_mW:
if (fullscale < 50.0) fullscale = 50.0; // 50 mW
break;
case FLOOR_100_uW:
if (fullscale < 5) fullscale = 5; // 5 mW
break;
case FLOOR_TEN_uW:
if (fullscale < 0.5) fullscale = 0.5; // 500 uW
break;
case FLOOR_ONE_uW:
default:
if (fullscale < .05) fullscale = .05; // 50 uW
}

newdata[in_pos++] = level/fullscale*y_max; // Prepare and store incoming level
if (in_pos >= len) in_pos = 0;
}
rateCount--;
}

//-----------------------------------------------------------------------------------------
// Draw (if needed) and Update the TFT with current Modulation Scope data pending in circular buffer
//-----------------------------------------------------------------------------------------

void ModulationScope::draw(void)
{
if (!drawn)
{

tft.setFont(DroidSansMono_16);
tft.drawRect(x, y,len+2, height+3, borderColour); // Draw the Scope Outline
tft.setTextColor(borderColour);
tft.setCursor(x+len - 223, y+height + 5);
//tft.print("Modulation Scope"); // and print title
erased = false;
drawn = true;
}
}

void ModulationScope::update(void)
{
int16_t y_start, y_stop, y_len; // Coordinates to draw
draw(); // Draw scope widget if need be
while (out_pos != in_pos) // Only draw every 1/rateDivisor time.
{

if (newdata[out_pos] > olddata[out_pos]) // Draw/Add Above y0
{
y_start = y_axis0 - newdata[out_pos];
y_stop = y_axis0 - olddata[out_pos];
y_len = y_stop - y_start;
if (y_len>0) tft.drawFastVLine(x_axis0+out_pos, y_start+1, y_len, traceColour);
tft.drawPixel(x_axis0+out_pos,y_start, peakColour);

y_start = y_axis0 + olddata[out_pos]; // Draw/Add Below y0
y_stop = y_axis0 + newdata[out_pos];
y_len = y_stop - y_start;
if (y_len>0) tft.drawFastVLine(x_axis0+out_pos, y_start, y_len, traceColour);

tft.drawPixel(x_axis0+out_pos,y_stop, peakColour);
}
else if (newdata[out_pos] < olddata[out_pos])
{
y_start = y_axis0 - olddata[out_pos]; // Erase Above y0
y_stop = y_axis0 - newdata[out_pos];
y_len = y_stop - y_start;
if (y_len>0) tft.drawFastVLine(x_axis0+out_pos, y_start, y_len, blnkColour);
tft.drawPixel(x_axis0+out_pos,y_stop, peakColour);

y_start = y_axis0 + newdata[out_pos]; // Erase Below y0
y_stop = y_axis0 + olddata[out_pos];
y_len = y_stop - y_start;
if (y_len>0) tft.drawFastVLine(x_axis0+out_pos, y_start+1, y_len, blnkColour);

tft.drawPixel(x_axis0+out_pos,y_start, peakColour);
}
else if (newdata[out_pos] == 0) tft.drawPixel(x_axis0+out_pos,y_axis0, peakColour);

olddata[out_pos] = newdata[out_pos];
out_pos++;
if (out_pos >= len) out_pos = 0;
}
}
//-----------------------------------------------------------------------------------------
// Init size, shape and colour of Text LCD.
// Variables are: columns, rows; upper left corner x, y; Font_name, FG Colour, BG Colour
//-----------------------------------------------------------------------------------------

// NOTE: Max size of character array (columns * rows) is fixed at LCD_TEXTSIZE characters
// variables are columns, rows; upper left corner x, y; Font_name, FG Colour, BG Colour
void TextBox::init(int16_t _col, int16_t _row, int16_t _xoffs, int16_t _yoffs,
const ILI9341_t3_font_t &f, int16_t _fontColour, int16_t _blnkColour)
{
xoffs = _xoffs;
yoffs = _yoffs;
Col = _col;
Row = _row;
font = &f;
fontColour = _fontColour;
blnkColour = _blnkColour;

tft.setFont(*font); // Determine font size
tft.setTextColor(BLACK);
tft.setCursor(0,0);
tft.print("a"); // Print an arbitrary character to determine
fontXsize = tft.getCursorX(); // size of each char, using monospace font
tft.println();
fontYsize = tft.getCursorY();
fontYsize = fontXsize * 2.1;
tft.setCursor(0,0);

}
//-----------------------------------------------------------------------------------------
// Move characters to TFT LCD from virtual LCD
// This function only updates character positions that have changed
//-----------------------------------------------------------------------------------------

void TextBox::transfer(void)
{
uint16_t line, column, character=0;

tft.setFont(*font);
for (line = 0; line < Row; line++)
{
for (column = 0; column < Col; column++)
{
if (virt_lcd[character] != text_lcd[character]) // We have a new character to write out
{
tft.setTextColor(blnkColour);
tft.setCursor(xoffs + fontXsize*column, yoffs + fontYsize*line);
tft.print(text_lcd[character]); // Erase
tft.setTextColor(fontColour);
tft.setCursor(xoffs + fontXsize*column, yoffs + fontYsize*line);
text_lcd[character] = virt_lcd[character];
tft.print(text_lcd[character]); // Write new
}
character++;
if (character>=TEXTBOXSIZE) character=TEXTBOXSIZE; // Redundant, make sure we don't go too far
}
}
}
//-----------------------------------------------------------------------------------------
// Print to a Virtual LCD - LCD_TEXTSIZE character long string representing a Column*Row LCD
//-----------------------------------------------------------------------------------------

void TextBox::write(char ch)
{
uint16_t virt_pos;

// Print to the ColxRow size virtual LCD
virt_pos = virt_x + Col*virt_y; // Determine position on virt LCD
if ((virt_pos >= TEXTBOXSIZE) || (virt_pos >= (Col*Row))) virt_pos = 0; // At end, wrap around to beginning
virt_lcd[virt_pos++] = ch; // Place character on virt LCD

// After print, derive new x,y coordinates in our Column by Row matrix
virt_x = virt_pos;
for(virt_y = 0; virt_y < Row && virt_x >= Col;virt_y++)
{
virt_x -=Col;
}
}
void TextBox::print(const char *ch_in)
{
uint16_t virt_len;

virt_len = strlen(ch_in); // Print to the Row*Col sized virtual LCD
for (uint16_t i = 0; i < virt_len; i++)
{
write(ch_in);
}
}

//-----------------------------------------------------------------------------------------
// SetCursor virtual LCD
//-----------------------------------------------------------------------------------------

void TextBox::setCursor(int16_t x, int16_t y)
{
virt_x = x;
virt_y = y;
}

//-----------------------------------------------------------------------------------------
// Clear virtual LCD
//-----------------------------------------------------------------------------------------

void TextBox::clear(void)
{
uint16_t lcdsize = Row * Col;
if (lcdsize > TEXTBOXSIZE) lcdsize = TEXTBOXSIZE;
for (uint16_t i=0; i<lcdsize; i++) virt_lcd=' '; // Print a lot of spaces to virt LCD
virt_x = 0;
virt_y = 0;
}
PSWRtft

Code:
ifndef _PSWRtft_h_
#define _PSWRtft_h_
#include <Arduino.h>
#include <SPI.h>
#include <RA8875.h>
#include "_fonts.h"
class PowerMeter
{
  public:
    //------------------------------------------------------------------------------
    // Init size, shape and colour of graph
    //           left x;    top y; length x; height y;   graph, low and high colour 
    void init (int16_t, int16_t, int16_t, int16_t, int16_t, int16_t, int16_t);
    void init (int16_t, int16_t, int16_t, int16_t);
    //------------------------------------------------------------------------------
    // Draw, Redraw or Erase Meter Scale.  range provides optinal unit information, such as "mW", "W", "kW"
    // input argument is a number from 1.0 and up, divided into 10  or 11 segments (11 if (scale*10)%11=0 )
    void scale(double s, char *range);      // Scale Erases if required and then draws everything
    void scale(double s) { scale(s, '\0'); }// Blank if no scale range string
    void erase(void);                       // Erases everything
    //------------------------------------------------------------------------------
    // Draw Meter Graph
    // input arguments are low value, high value and full scale value
    void graph(double, double, double);

  private:
    void drawscale(double, int16_t, char*); // Draws the scale for the graph. Colour to draw/erase
    void printunits(int16_t, char*);        // Prints an units indication at the last scale tick
    void drawframe(int16_t);                // Draws the frame around the graph
    void erasegraph(void);                  // Erase the current graph contents
    int16_t x           = 1; 
    int16_t y           = 15;
    int16_t len         = 725;
    int16_t height      = 70;
    int16_t GaugeColour = WHITE;
    int16_t LowColour   = YELLOW;
    int16_t HighColour  = BLUE; 
    int16_t blnkColour  = BLACK;
    double  lastmax;                        // Max Level for full readout.  We have to redraw all if this changes
    int16_t lastlow, lasthigh;              // Prev levels for the two gauges, used to redraw only what is necessary
    double  current_scale = 0;
    char    current_range[10];
    bool    erased = true;                  // Keep track of whether graph needs to be redrawn
};


class VSWRmeter
{
 
  public:
    
    //------------------------------------------------------------------------------
    // Init size, shape and colour of VSWR graph
    //        left x; top y; length x; height y;  graph, low SWR,  mid SWR, high SWR colour 
    void init (int16_t, int16_t, int16_t, int16_t, int16_t, int16_t, int16_t, int16_t);
    void init (int16_t, int16_t, int16_t, int16_t);
    //------------------------------------------------------------------------------
    // Draw or Erase VSWR Meter Scale (no value)
    void scale(void);
    void erase(void);  // Erases everything
    //------------------------------------------------------------------------------
    // Draw VSWR Meter Graph
    // input arguments are mid SWR, high SWR and actual SWR input value
    void graph(double, double, double);

  private:
    void drawscale(int16_t);
    int16_t x = 1; 
    int16_t y = 175;
    int16_t len         = 725; //300
    int16_t height      = 70;
    int16_t GaugeColour = WHITE;
    int16_t lSWRcolour  = GREEN;
    int16_t mSWRcolour  = ORANGE;
    int16_t hSWRcolour  = RED;
    int16_t blnkColour  = BLACK;
    int16_t scalemid, scalehigh;        // Calculated log10 of mid and high values
    int16_t lastlow, lastmid, lasthigh; // Previous values, used to redraw only what is necessary
    double  midthresh, highthresh;      // Keep track of Mid and High thresholds
    bool    erased = true;              // Keep track of whether graph needs to be redrawn
};


#define SCOPE_BUFSIZE  781            // NOTE: Max number of iterations during one X_trace iteration

class ModulationScope
{
  public:
    //------------------------------------------------------------------------------
    // Init size, shape and colour of Modulation Scope
    //          left x;   top y; length x; height y; border, trace and peak colour 
    void init (int16_t, int16_t, int16_t, int16_t, int16_t, int16_t, int16_t);
    void init (int16_t, int16_t, int16_t, int16_t);
    void init (void) { init(3, 150, 781, 190); }  // Default x, y coordinate settings

    //------------------------------------------------------------------------------
    // Draw scope if need be, and draw pending data onscreen
    void update(void);
    //------------------------------------------------------------------------------
    // Erase the scope widget
    void erase(void);
    //------------------------------------------------------------------------------
    // Update rate divisor
    void rate(int16_t);
    //------------------------------------------------------------------------------
    // Add one measurement to the x axis sweep (run from within interrupt function)
    // input arguments are level and fullscale
    void adddata(double, double);

  private:
    void draw(void);                // Draw scope if needed
    int16_t x;        //=   5; 
    int16_t y ;       //=   5;
    int16_t len;     //= 310;
    int16_t height;   //= 180;
    int16_t borderColour= GREY;
    int16_t traceColour = GREEN;
    int16_t peakColour  = YELLOW;
    int16_t blnkColour  = BLACK;
    int16_t y_axis0;                // Start positions and y axis max deviation, derived from x,y, len, height
    int16_t x_axis0;
    int16_t y_max;
    int16_t newdata[SCOPE_BUFSIZE]; // New data for the scope - fed with data from a circular buffer fed by the interrupt funciton
    int16_t in_pos;                 // Two circular buffer pointers
    int16_t out_pos;                // this one is also current position on the x axis
    int16_t olddata[SCOPE_BUFSIZE]; // Current data on the scope - to add or subtract from...
    int16_t rateDivisor=1;          // Rate divisor other than 1 results in only every n_th request drawn
    int16_t rateCount;
    bool    erased = false;         // Keep track of whether scope needs to be erased
    bool    drawn  = false;         // Keep track of whether scope needs to be redrawn

};


#define TEXTBOXSIZE  1800        // NOTE: Max size of character array (columns * rows) is Fixed at 1800 characters

class TextBox
{
  public:
    //------------------------------------------------------------------------------
    // Init size, shape and colour of Text LCD.
    // variables are columns, rows; upper left corner x, y; Font_name, FG Colour, BG Colour
    void init (int16_t, int16_t, int16_t, int16_t, const ILI9341_t3_font_t &, int16_t, int16_t);
    void init (void) {  font = &DroidSansMono_20; }   // Default settings
    //-----------------------------------------------------------------------------------------
    // Move characters to LCD from virtual LCD, only updates information that has changed
    void transfer(void);
    //-----------------------------------------------------------------------------------------
    // Print to a Virtual LCD - Max LCD_TEXTSIZE character long string representing a Column*Row LCD
    void write(char);                   // Write char
    void print(const char *);           // primitive Print command, no smart formatting
    void setCursor(int16_t, int16_t);   // SetCursor virtual LCD
    void clear(void);                   // Clear virtual LCD
  
  private:
    int16_t xoffs = 330;                 // Graphics display offset coordinates 
    int16_t yoffs =  80;
    int16_t Col   = 40;                 // Default Columns and Rows
    int16_t Row   = 12;
    int16_t fontXsize = 24;             // Default font size coordinates for an 18 point font
    int16_t fontYsize = 17;
    char    text_lcd[TEXTBOXSIZE+1];    // Character array representing what is visible on LCD
    char    virt_lcd[TEXTBOXSIZE+1];    // Character array representing what is pending for LCD
    int16_t virt_x, virt_y;             // x and y text display coordinates
    const   ILI9341_t3_font_t *font;
    int16_t fontColour = WHITE;
    int16_t blnkColour = BLACK;
};

#endif
 
is here a solution or must I stick on version 1.57.2.

The screenshot you've shown is a warning, not an error. It is trying to tell you about an improper choice of syntax in your code.

You really should improve your code.

But if you absolutely will not improve your own code, and you do not wish to see warnings that your program is not correct C++ syntax, then you should stick with version 1.57.2 which uses the old gcc 5.4 toolchain. The older compilers do less checking for improper syntax.

But just to be clear, the problem is your own code is poorly written. Newer compilers give more warnings about poorly written code. It is not a problem with the newer software. It is a problem with your code.

Specifically on line 84, you wrote this:

Code:
  void scale(double s) { scale(s, '[B][COLOR="#FF0000"]\0'[/COLOR][/B]); }

Your other definition of scale() which takes 2 inputs says the 2nd input must be char *. Using anything which is not a char * is invalid, because of your own definition of the 2 input version.

This should probably use NULL or nullptr or 0 with a typecast to char *.

Code:
  void scale(double s) { scale(s, [B][COLOR="#008000"]NULL[/COLOR][/B]); }

The newer compiler is correct. It is not a flaw with the compiler. Your code is improper. Even if your improper code actually works fine, the syntax is not correct. You should really spend the time to improve your own code.
 
It looks like it might be being used in place of an empty string rather than NULL, so the correct replacement would be:
Code:
{ scale(s, ""); }

(Checking the argument against NULL is certainly not a bad thing though.)
 
Using "" will probably give a different compiler warning. The definition says the input type must be char *. A string literal is considered to be const, so the compiler will complain that you're passing a const string to a function which takes a non-const pointer.

If the scale() function doesn't actually write to the string, of course changing the 2 input define to scale(double, const char *) would be best. It's always better to use "const char *" as a function input for functions that don't alter the string, since it gives compatibility with const strings.

Edit: looking at the full code in msg #3, I see many functions which take char * as one of their inputs, but then only use it with print functions that don't write to the string. They should probably all be changed to const char *.
 
Compiler in Teensyduino V1.58

Dear Paul, others,

Compiling was ok but a real test not, Paul stated many times poorly code however this code (more than 10000 lines) was written 2017 and the compiler never noticed any problem than we can also say a short coming of the Teensyduino compiler in older version.

There was only one line of code that must be changed and well,

void scale(double s, char *range); // Scale Erases if required and then draws everything
void scale(double s) { scale(s, '\0'); }// Blank if no scale range string


IN

void scale(double s, char *range = NULL ); // Scale Erases if required and then draws everything
//void scale(double s) { scale(s, '\0'); }// Blank if no scale range string


The code was tested and works very well., in this way we are future proof!
Thanks all,

I changed all char to const char now I can compile with 1.58.1.

Best,

Johan
 
Paul stated many times poorly code however this code (more than 10000 lines) was written 2017 and the compiler never noticed any problem than we can also say a short coming of the Teensyduino compiler in older version.

There was only one line of code that must be changed and well,

void scale(double s, char *range); // Scale Erases if required and then draws everything
void scale(double s) { scale(s, '\0'); }// Blank if no scale range string

One thing Paul pointed out, and I'm not sure you understood, is that '\0' is not a valid argument to the function scale(). The second argument should have type char*, but '\0' is type char with value 0. So, you are passing 0 (NULL) to a pointer variable, and who knows what will happen. To repeat again what Paul said, you could replace '\0' with "" to get an empty C string, but "" has type const char*, so you should get at least a warning of passing a const to a non-const argument.
 
Not true, I understand you correctly.
const char* is not needed I use a char* Paul has pointed me in the good direction to use here a NULL instead of '\0' the point is that the lines of code can be converted directly into one line.

I mean this
Code:
void scale(double s, char *range = NULL );
instead of using two line of code
Code:
void scale(double s, char *range); Void scale(double s) { scale(s, '\0');

It's bizarre that this even works for now already 7 years and a few hundred working meters.

The code was tested today in real no compiler warnings and works out of the box so we can go with ease to the future with my project.

Best,
Johan


I feel really sad that I not see this before but the new compiler noticed that and that's for sure very good!
 
This is my result!

Used a Teensy 4.0 and RA8875 touchscreen TFT with GSL1680 controller.
This I will use as a automatic antenna tuner with three servo's for my 700 Watts RF FL2100Z amplifier.

Best,

Johan


PM.jpeg




Not true, I understand you correctly.
const char* is not needed I use a char* Paul has pointed me in the good direction to use here a NULL instead of '\0' the point is that the lines of code can be converted directly into one line.

I mean this
Code:
void scale(double s, char *range = NULL );
instead of using two line of code
Code:
void scale(double s, char *range); Void scale(double s) { scale(s, '\0');

It's bizarre that this even works for now already 7 years and a few hundred working meters.

The code was tested today in real no compiler warnings and works out of the box so we can go with ease to the future with my project.

Best,
Johan


I feel really sad that I not see this before but the new compiler noticed that and that's for sure very good!
 
Not true, I understand you correctly.
const char* is not needed I use a char* Paul has pointed me in the good direction to use here a NULL instead of '\0' the point is that the lines of code can be converted directly into one line.

I mean this
Code:
void scale(double s, char *range = NULL );
instead of using two line of code
Code:
void scale(double s, char *range); Void scale(double s) { scale(s, '\0');

It's bizarre that this even works for now already 7 years and a few hundred working meters.

The code was tested today in real no compiler warnings and works out of the box so we can go with ease to the future with my project.

Best,
Johan


I feel really sad that I not see this before but the new compiler noticed that and that's for sure very good!

In this particular case, I believe the issue is the language changed. In earlier versions of ISO C++, you could use 0 wherever a pointer was expected, and it converted it into the appropriate NULL pointer (and '\0' is just the integer constant 0). I recall the ISO C++ standard was changed that disallowed using 0 in that context. Since Teensydunio changed the C++ standard version, it catches these things.

FWIW, I really don't track C++ changes. Back in the 1980's, I was on the original ANSI C X3J11 committee that produced the first ANSI C standard, which became the ISO C standard (ANSI is the USA standards body, ISO is the world wide standards body). At the time, I was representing my employer (Data General). Since moving to Cygnus Solutions (and other employers after that) I have not been a member of the C standards committee, and I have never attended the C++ meetings. As a compiler developer at IBM, I read the new drafts of C and C++ from time to time, but generally I am not actively following the changes these days.
 
Hi Michael,

That explains a lot now it's clear thanks again for the clear explanation.

Best regards,
Johan
 
Back
Top