cancel
Showing results for 
Search instead for 
Did you mean: 

Help needed. Incorrect value prints to screen from my function.

Al-E-Bags
Senior

Hi all. I'm having trouble with the following function. My TouchGFX gui
has two radio button groups, each with three radio buttons.

The first selects between three different wire gauges, awg42, awg43 and awg44.
The second set selects between the resistance values of each of the wire gauges.

For each wire gauge, I have three resistance values, min, nom and max to
account for variance in the actual wire resistance in a real-world situation.
Obviously, resistance is based on a variety of external factors.

I have a single TextArea on the screen to which I want to print the decimal
value of the selected resistance.

So for example, I want to select a wire gauge of awg42 with a nominal resistance value
or, select a wire gauge of awg43 with a minimal resistance value and have the screen
update with the result.

So far, this is not happening. The TextArea is updated with the format specifier, not
the resistance value. I have tried snprintf alternatives but without success.

I'm using a typedef struct to hold all the resistance values for reasons of clarity.

 

//	typedef struct: WireResPerKm (res)
WireResPerKm res = {
	0.00f,	// zero resistance
	9.06f,	// max awg44 max resistance (Km)
	8.43f,	// nom awg44 nom resistance (Km)
	7.80f,	// min awg44 min resistance (Km)
	7.71f,	// max awg43 max resistance (Km)
	7.01f,	// nom awg43 nom resistance (Km)
	6.30f,	// min awg43 min resistance (Km)
	5.91f,	// max awg42 max resistance (Km)
	5.42f,	// nom awg42 nom resistance (Km)
	4.93f	// min awg42 min resistance (Km)
};    

//	Define WireResPerKm (res) struct
typedef struct {
	float zero_000;
	float awg44_max;
	float awg44_nom;
	float awg44_min;
	float awg43_max;
	float awg43_nom;
	float awg43_min;
	float awg42_max;
	float awg42_nom;
	float awg42_min;
} WireResPerKm;

 

Here is the function that I'm working with:

 

void MainView::awgParameters()
{
    float wire_res = res.zero_000;

    if (awg_btn_grp.getSelectedRadioButton() == &awg42_btn)
    {
        if (res_btn_grp.getSelectedRadioButton() == &resMin_btn)
        {
        	wire_res = res.awg42_min;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resNom_btn)
        {
        	wire_res = res.awg42_nom;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resMax_btn)
        {
        	wire_res = res.awg42_max;
        }
    }
    else if (awg_btn_grp.getSelectedRadioButton() == &awg43_btn)
    {
        if (res_btn_grp.getSelectedRadioButton() == &resMin_btn)
        {
        	wire_res = res.awg43_min;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resNom_btn)
        {
        	wire_res = res.awg43_nom;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resMax_btn)
        {
        	wire_res = res.awg43_max;
        }
    }
    else if (awg_btn_grp.getSelectedRadioButton() == &awg44_btn)
    {
        if (res_btn_grp.getSelectedRadioButton() == &resMin_btn)
        {
        	wire_res = res.awg44_min;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resNom_btn)
        {
        	wire_res = res.awg44_nom;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resMax_btn)
        {
        	wire_res = res.awg44_max;
        }
    }

    //Unicode::snprintfFloat(wire_res_valueBuffer, WIRE_RES_VALUE_SIZE, "%.3f", wire_res_val);
	//Unicode::snprintfFloat(wire_res_valueBuffer, sizeof(wire_res_valueBuffer), "%.3f", wire_res_val);
    Unicode::snprintf(wire_res_valueBuffer, 15, "%.3f", wire_res);
    wire_res_value.invalidate();
}

 

awgParameters() is called from the associated itemSelectHandler():

 

void MainView::awgItemSelectedHandler(const touchgfx::AbstractButton& src)
{

    if(&src== &awg42_btn) {
   	Unicode::snprintf(awg_selectionBuffer, 10, "AWG 42");
    }
    else if(&src== &awg43_btn) {
   	Unicode::snprintf(awg_selectionBuffer, 10, "AWG 43");
    }
    else if(&src== &awg44_btn) {
   	Unicode::snprintf(awg_selectionBuffer, 10, "AWG 44");
    }
    awg_selection.invalidate();
	awgParameters();
 }
 
 void MainView::resItemSelectedHandler(const touchgfx::AbstractButton& src)
{

	if(&src== &resMin_btn) {
   	Unicode::snprintf(res_selectionBuffer, 10, "Res Min");
    }
    else if(&src== &resNom_btn) {
   	Unicode::snprintf(res_selectionBuffer, 10, "Res Nom");
    }
    else if(&src== &resMax_btn) {
   	Unicode::snprintf(res_selectionBuffer, 10, "Res Max");
    }
    res_selection.invalidate();
	awgParameters();

 }

 

Callbacks are in place for both of the above in MainView:

 

 MainView::MainView() :
    scrollListItemSelectedCallback(this, &MainView::scrollListItemSelectedHandler),
    scrollWheelAnimateToCallback(this, &MainView::scrollWheelAnimateToHandler),
	awgItemSelectedCallback(this, &MainView::awgItemSelectedHandler),
	tplItemSelectedCallback(this, &MainView::tplItemSelectedHandler),
	resItemSelectedCallback(this, &MainView::tplItemSelectedHandler)
{
	//	...
}

 

I fail to understand exactly where my issue/issues lie. I have left myself wondering whether a nested if/else if statement is the correct way to be proceeding.

Screenshot 2024-12-29 084111.png

  Any help would be greatly appreciated. Thanks, and Happy New Year!

7 REPLIES 7

Perhaps it's a limitation of the snprintf() here in this context.

Can you also print to a terminal/debug channel here to confirm what exactly is choking.

Perhaps you could stage in a string via ftoa() dtoa() type construct?

How is the Coil Length/Windings code constructed?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Tesla DeLorean Hi.  

I have both coil length and windings(turns) calculations working in a previous mock up
of this project. Much has changed in this version of the gui as I try to improve on my code
however, these are the brief, basic steps I'll be using to calculate the above:

/**
 * \defgroup CalculateTurns
 * \brief calculate_turns().
 *
 * calculates the number of coil wire turns based on several parameters
 *
 * turns_val formula steps:
 * 1: tpl = divide the bobbin type height (in mm) by
 * 2: awg = the selected wire diameter (in mm) multply by
 * 3: lay = the number of coil wire layers muliply by
 * 4: max = the selected fill factor (the max permissible layers before
 *	the coil exceeds the physical boundaries of the bobbin being wound
 *	or when the theoretical coil resistance is achieved (whichever comes first) 
 *
 * example turns value: 10.8 / 0.0663mm * 47 * 0.99
 * result is 7,938.7 turns @ fill factor 0.99
 *
**/

and:

/**
 * \defgroup CalculateCoilLength
 * \brief calculate_coil_length().
 *
 * calculates the total coil length in meters
 *
 * coil_len_val formula steps:
 * 1: bbd = bobbin type base dimension (in mm) for a single wire wrap
 * 2: tpl = bobbin type height (in mm) divided by the selected awg wire dia
 * 3: divide the resulting value by 1000 to achieve length in meters
 * 4: lay = multiply the result by the number of coil wire layers
 *
 * example coil length values: 117.631mm * 170.62mm / meters (to attain meters) * 47 (layers)
 *
 * results in a coil length of 943.3 meters (which is in the coil resistance ball-park 
 * for a Strat type pickup) 
**/

There may be anomalies in my notes as they are a work in progress but as yet, the functions based on these calculations can not be implemented until I get round to implementing the number of turns per layer of the coil (this is also working in the mock up).

I'm kind of engrossed in nailing the issue I'm having with the wire resistance as mentioned in my
post so the actual resistance of the wound coil will not materialize until the code required for
wire resistance, turns per layer, coil length and number of windings is properly implemented in this
version of the gui.

I'm familiar with neither of the methods (ftoa() and dtoa()) you mention but I see they are used for converting decimals and floating point number to strings.  I assume these methods are similar to itoa?  I'll be sure to look
into them as an alternative, thanks for the heads up.

I thank you for your interest and your help thus far.

I was wondering more about the buffering and formatting of those which were working better/properly.

Unicode::snprintf(wire_res_valueBuffer, 15, "%.3f", wire_res);
wire_res_value.invalidate();

How does wire_res_valueBuffer relate to the wire_res_value object? Is it initialized properly?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Tesla DeLorean Hi. 

Apologies, I thought you were asking re. the construction of other working functions in my code.  

Yes, it appears to be properly and fully initialized in MainViewBase and, to the best of my knowledge is correctly set up in MainView also. 

in MainViewBase.cpp

    wire_res_value.setPosition(130, 3, 60, 20);
    wire_res_value.setColor(touchgfx::Color::getColorFromRGB(0, 0, 0));
    wire_res_value.setLinespacing(0);
    Unicode::snprintf(wire_res_valueBuffer, WIRE_RES_VALUE_SIZE, "%s", touchgfx::TypedText(T___SINGLEUSE_I9YL).getText());
    wire_res_value.setWildcard(wire_res_valueBuffer);
    wire_res_value.setTypedText(touchgfx::TypedText(T_DATA_8));
    wire_res_container.add(wire_res_value);

and in MainViewBase.hpp
	
	static const uint16_t WIRE_RES_VALUE_SIZE = 10;
    touchgfx::Unicode::UnicodeChar wire_res_valueBuffer[WIRE_RES_VALUE_SIZE];
	
	touchgfx::TextAreaWithOneWildcard wire_res_value;

 

 

I can declare an arbitrary floating point value to the 'wire_res' variable and it will print the result to 'wire_res_value' on the screen providing, that is, I bypass the nested if/else if statement by commenting out the entire block of code.

This leads me to believe that I have an issue with the RadioButtonGroup implementation in that the  'getSelectedRadioButton()' calls are not finding the associated radioButtons (I may be wrong, I usually am)?   

I'm going to spend some time with printf output to console today and see if it bears any fruit.  Thanks again for your time.

GaetanGodart
ST Employee

Hello @Al-E-Bags ,

 

I am not sure which buffer store your value, is it awg_selectionBuffer, res_selectionBuffer or something else.
Also, it seems to print "..3." but what is the value expected.

Either way, could you try to use the snprintfFloat function if you are printing a float?
See this video .

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Unicode::snprintf(wire_res_valueBuffer, WIRE_RES_VALUE_SIZE, "%s", touchgfx::TypedText(T___SINGLEUSE_I9YL).getText()); // This code is changing the buffer content


wire_res_value.setWildcard(wire_res_valueBuffer); // This code is pushing the string in the buffer, to the object, are you doing this for your float value?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Tesla DeLorean Hi. 

I am setting the Wildcard here in the MainView::setupScreen() function:

void MainView::setupScreen()
{
    scrollList.setItemSelectedCallback(scrollListItemSelectedCallback);
    scrollWheel.setAnimateToCallback(scrollWheelAnimateToCallback);

    for (int i = 0; i < scrollListListItems.getNumberOfDrawables(); i++)
    {
        scrollList.itemChanged(i);
    }
    scrollWheel.animateToItem(0);

	// ... other snprintfFloat();
	
	Unicode::snprintfFloat(wire_res_valueBuffer, sizeof(wire_res_valueBuffer), "%.3f", 0.0f);
	wire_res_value.setWildcard(wire_res_valueBuffer);


	// ... other .invalidate(); 
	
	wire_res_value.invalidate();

}

@GaetanGodart Hi.


Also, it seems to print "..3." but what is the value expected.

The value "..3." is the value of the format specifier as a result of the
incorrect snprintf function. The values I expect are contained in the
typedef struct WireResPerKm. These should be called from the
awgParameters() function if/else if implementation:

//	typedef struct: WireResPerKm (res)
WireResPerKm res = {
	
	//... other values
	
	6.30f,	// min awg43 min resistance (Km)
	5.91f,	// max awg42 max resistance (Km)
	5.42f,	// nom awg42 nom resistance (Km)
	4.93f	// min awg42 min resistance (Km)
};

//	Define WireResPerKm (res) struct
typedef struct {
	
	//... other definitions
	
	float awg43_min;
	float awg42_max;
	float awg42_nom;
	float awg42_min;
} WireResPerKm;

@Tesla DeLorean and @GaetanGodart 

As expected, stripping out the existing if / else if code, the value assigned to the variable wire_res is printed correctly to wire_res_value TextArea: 

void MainView::awgParameters()
{
	//	works as expected by omitting else/else if code from the function body.
	//	The value of wire_res is printed to the 'wire_res_value' TextArea

	float wire_res = res.awg42_max;
	// or float wire_res = 5.91f;
	
    Unicode::snprintfFloat(wire_res_valueBuffer, WIRE_RES_VALUE_SIZE, "%.3f", wire_res);
    wire_res_value.invalidate();
}

 With the if / else if code present, the wire_res value is ignored and nothing is printed to the TextArea:

void MainView::awgParameters()
{
    //float wire_res = res.zero_000;
    float wire_res = 5.125f;

	// this function code does not produce a result. The value
	// of 'wire_res' variable is not being printed to the 'wire_res_value' TextArea
	
    if (awg_btn_grp.getSelectedRadioButton() == &awg42_btn)
    {
        if (res_btn_grp.getSelectedRadioButton() == &resMin_btn)
        {
        	wire_res = res.awg42_min;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resNom_btn)
        {
        	wire_res = res.awg42_nom;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resMax_btn)
        {
        	wire_res = res.awg42_max;
        }
    }
    else if (awg_btn_grp.getSelectedRadioButton() == &awg43_btn)
    {
        if (res_btn_grp.getSelectedRadioButton() == &resMin_btn)
        {
        	wire_res = res.awg43_min;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resNom_btn)
        {
        	wire_res = res.awg43_nom;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resMax_btn)
        {
        	wire_res = res.awg43_max;
        }
    }
    else if (awg_btn_grp.getSelectedRadioButton() == &awg44_btn)
    {
        if (res_btn_grp.getSelectedRadioButton() == &resMin_btn)
        {
        	wire_res = res.awg44_min;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resNom_btn)
        {
        	wire_res = res.awg44_nom;
        }
        else if (res_btn_grp.getSelectedRadioButton() == &resMax_btn)
        {
        	wire_res = res.awg44_max;
        }
    }
	//	function code end 
	
    Unicode::snprintfFloat(wire_res_valueBuffer, WIRE_RES_VALUE_SIZE, "%.3f", wire_res);
    wire_res_value.invalidate();
}

 Thanks