Platform + ESP8266 printf ERROR at compilation

Friends, I’m a beginner, but I’m doing a fairly serious application project. The project uses a radio channel on the NRF to transmit data. To understand the work of NRF, I try to compile examples and get a printf error ("% x", min (0xf, values [i]));
I do not understand how to get rid of this error, help.

Can you link which sketch you are compiling exactly? And your platformio.ini? And the exact error message?

platformio.ini

[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
upload_port = /dev/cu.wchusbserial1420

my main code works fine with this configuration, but the sample code does not compile

I read that there are problems when using printf for ESP8266, but I do not understand the essence of the problem

error:

/Users/ruslanp/Documents/PlatformIO/Projects/nodeMCU NRF/src/main.ino:122:34: error: no matching function for call to 'min(int, uint8_t&)'
     printf("%x",min(0xf,values[i]));

code:

#include <arduino.h>  
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <ArduinoJson.h>

//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 7 & 8

RF24 radio(7,8);

//
// Channel info
//

const uint8_t num_channels = 126;
uint8_t values[num_channels];

//
// Setup
//

void setup(void)
{
  //
  // Print preamble
  //

  Serial.begin(115200);
  printf_begin();
  Serial.println(F("\n\rRF24/examples/scanner/"));

  //
  // Setup and configure rf radio
  //

  radio.begin();
  radio.setAutoAck(false);

  // Get into standby mode
  radio.startListening();
  radio.stopListening();

  radio.printDetails();

  // Print out header, high then low digit
  int i = 0;
  while ( i < num_channels )
  {
    printf("%x",i>>4);
    ++i;
  }
  Serial.println();
  i = 0;
  while ( i < num_channels )
  {
    printf("%x",i&0xf);
    ++i;
  }
  Serial.println();
}

//
// Loop
//

const int num_reps = 100;

void loop(void)
{
  // Clear measurement values
  memset(values,0,sizeof(values));

  // Scan all channels num_reps times
  int rep_counter = num_reps;
  while (rep_counter--)
  {
    int i = num_channels;
    while (i--)
    {
      // Select this channel
      radio.setChannel(i);

      // Listen for a little
      radio.startListening();
      delayMicroseconds(128);
      radio.stopListening();

      // Did we get a carrier?
      if ( radio.testCarrier() ){
        ++values[i];
      }
    }
  }

  // Print out channel measurements, clamped to a single hex digit
  int i = 0;
  while ( i < num_channels )
  {
    printf("%x",min(0xf,values[i]));
    ++i;
  }
  Serial.println();
}

By calling min you are using the std::min template.

The error in eclipse is e.g.

grafik

So the problem here is that it cannot find a valid candidate. The std::min template function expects both arguments to be of the same type.

  /**
   *  @brief This does what you think it does.
   *  @ingroup sorting_algorithms
   *  @param  __a  A thing of arbitrary type.
   *  @param  __b  Another thing of arbitrary type.
   *  @return   The lesser of the parameters.
   *
   *  This is the simple classic generic implementation.  It will work on
   *  temporary expressions, since they are only evaluated once, unlike a
   *  preprocessor macro.
  */
  template<typename _Tp>
    inline const _Tp&
    min(const _Tp& __a, const _Tp& __b)
    {
      // concept requirements
      __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
      //return __b < __a ? __b : __a;
      if (__b < __a)
	return __b;
      return __a;
    }

However since you are inputting the integer constant 0xf as the righth this interperted as the int type. On the right you have a uint8_t from the array. So those are not compatible. You must cast the left expression to a uint8_t as well.

  while ( i < num_channels )
  {
    printf("%x",min((uint8_t)0xf,values[i]));
    ++i;
  }

However, you don’t need the min function at all right? You set all values of the array to 0 initially and want to print out the number of responses on that channel So why not directly values[i] but only to a maximum of 0xf = 15? The number can get easily larget than 15 because you have num_reps = 100; so you can get at maximum 100 as values[i].

I am sure that you are absolutely right, but this example is taken from the library, it compiles perfectly in Arduino IDE for Arduino Nano(!!!), but does not want to compile in VSС + platformio.

Obviously, the problem is that some connections are not established in the platform or additional libraries need to be used. Probably…

So that’s a different platform and eventually a different C++ version. PIO compiles it with -std=c++11 for the ESP8266, as should the Arduino IDE version. Does it compile in the Arduino IDE when set for the NodeMCU?

1 Like

No, in Arduini IDE for nodeMCU not compiled

So the errors are consistent, no problem then :slight_smile: .

Many thanks! Your solution works, though now something incomprehensible is displayed in my terminal, but it may be because the pins are connected incorrectly, I will check this.

Can you show the output of that? Can you also try the code

    printf("%x",(unsigned) min((uint8_t)0xf,values[i]));

Maybe %x wants to read 4 bytes from the argument and not 1.

This is different from the result, but obviously this is a data type problem. Maybe you understand what needs to be done to get real indicators of channels and noise?!

Soft WDT reset
 >>>stack>>>
ctx: cont
sp: 3ffffdb0 end: 3fffffc0 offset: 01b0
3fffff60:  40100250 3ffee368 3ffee368 402011e6  
3fffff70:  40100250 00000052 3ffee368 40201568  
3fffff80:  3fffdad0 3ffee368 00000052 40201100  
3fffff90:  feefeffe feefeffe feefeffe 3ffee404  
3fffffa0:  3fffdad0 00000000 3ffee3c4 40202308  
3fffffb0:  feefeffe feefeffe 3ffe84e4 40100c81  
<<<stack<<<
@H
RF24/examples/scanner/
STATUS           = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR          = 0xe7e7e7e7e7
RX_PW_P0-6       = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA            = 0x00
EN_RXADDR        = 0x03
RF_CH            = 0x4c
RF_SETUP         = 0x07
CONFIG           = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate        = 1MBPS
Model            = nRF24L01+
CRC Length       = 16 bits
PA Power         = PA_MAX

00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777701

This is the output printf ("% x", min ((uint8_t) 0xf, values [i]));
Now I will check printf ("% x", (unsigned) min ((uint8_t) 0xf, values [i]));

o_o There might a race with the flushing of the Serial.println() at the end?
Can you repalce that with just printf("\n"); to flush the buffer? Are the newlines then fixed?

That’s expected because the loop has many iterations and runs for a long time, but the ESP8266’s watchdog needs to be reset. Add a call to yield() before the call radio.setChannel(i); for example.

I can not publish multiple images. This is the conclusion when printf(“%x”,(unsigned) min((uint8_t)0xf,values[i]));

Can you try this printing code instead?

  while ( i < num_channels )
  {
    Serial.println("Channel " + String(i) + ": " + String(values[i]) + " times carrier detected");
    ++i;
  }

printf(“%x”,min((uint8_t)0xf,values[i]));

RF24/examples/scanner/
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX

00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777701

Soft WDT reset

          >>>stack>>>

                     ctx: cont
                              sp: 3ffffdb0 end: 3fffffc0 offset: 01b0
                                                                     3fffff60:  40100250 3ffee368 3ffee368 402011e6  
                                                                                                                     3fffff70:  40100250 00000052 3ffee368 40201568  
                                       3fffff80:  3fffdad0 3ffee368 00000052 40201100  
                                                                                       3fffff90:  feefeffe feefeffe feefeffe 3ffee404  
         3fffffa0:  3fffdad0 00000000 3ffee3c4 40202308  
                                                         3fffffb0:  feefeffe feefeffe 3ffe84e4 40100c81  
                                                                                                         <<<stack<<<
                                                                                                                    )@H

RF24/examples/scanner/

========================
printf(“%x”,(unsigned) min((uint8_t)0xf,values[i]));

RF24/examples/scanner/
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX

00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777701

Soft WDT reset

          >>>stack>>>

                     ctx: cont
                              sp: 3ffffdb0 end: 3fffffc0 offset: 01b0
                                                                     3fffff60:  40100250 3ffee368 3ffee368 402011e6  
                                                                                                                     3fffff70:  40100250 00000052 3ffee368 40201568  
                                       3fffff80:  3fffdad0 3ffee368 00000052 40201100  
                                                                                       3fffff90:  feefeffe feefeffe feefeffe 3ffee404  
         3fffffa0:  3fffdad0 00000000 3ffee3c4 40202308  
                                                         3fffffb0:  feefeffe feefeffe 3ffe84e4 40100c81  
                                                                                                         <<<stack<<<
                                                                                                                    ,ԅ

RF24/examples/scanner/

=====================================
yield();

  radio.setChannel(i);

There is some bias, but it works !!!
HURRAH!!!

RF24/examples/scanner/
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x00
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX

00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777701
23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd1121
28b89996786aaa801020105110202001111220001100100000000000000000000000000000002200000000000000000000000000000000000000000000115008
79978b8a9a7781111012311102021020110000110000000000000000000000000000000001400000000000000000000000000000000000000000000013111898
b88a6577ab9102012112110101111110000010000000000000000000000000000000000000000000000000000000000000000000000000000000003023186777
9889776771120210601111020201110000100000000000000000000000000000000000000000000000000000000000000000000000000000000011122779a977
6aaa99901101043311101011211100001000000000000000000000000000000000000000000000000000000000000000000000000000000000112109897b679a
97779110201341111110112103000020000000000000000000000000000000000021000000000000000000000000000000000000000000000322278a99875767
9a901103133120110102011100001000000010000001000000000000000000001000000000000000000000000000000000000000000000132026557866776767
50211201021121101101020000100000000000000000000000000000000000100000000000000000000000000000000000000000000004121988977675669970
11111322011110211212000010000000000000000000000000000000000100000000000000000000000000000000000000000000001122088a998c7975566111
10211111121110111110000000100000000000000000000000000000010000000000000000000000000000000000000000000000104115678978688786820201
22311101011110202000110020000000000000000000000000000001000000000000000000000000000000000000000000000010220699776886948681121020
1111020201101110000000100000000000000000000000000000000000000000000000000000000000000000000000000000102025a88b688b9aa79101111312
20111111112000001000000000000000000000000000000000010000000000000000000000000000000000000000000000013115677788798877801111022121
11111101010000200000000000000000000000000000000010100000000000000000000000000000000000000000000012221589578a9b9c9a71102113220110

Having removed the print in two lines, I got a “soft” line, which scales together with the terminal window, so I can see the result, now I will check your next recommendation.

The abcdef doesn’t seem healthy. The %x specifier probably prints these because it prints 4 bytes. So you should use

printf ("%02x", (unsigned) min ((uint8_t) 0xf, values [i]));

If you want 2 hex characters (since values can only ever go from 0x0 to 0xf, you could even do %01x though)

Why do you want to print the channels as hex digits though?

while ( i < num_channels ) { printf(“%x”,min((uint8_t)0xf,values[i])); ++i; }
But this is already a small problem, most importantly the scanner works!

I have no tasks displaying the channel number in sixteenth format. My main task is to start the radio module, make sure that it works, and go to the main task. Data transmission for dynamic lighting. As I wrote earlier, the task was to use a radio channel instead of wires for an array of remote spotlights.
Unfortunately, I have a limit on the number of messages, and I could not write you yesterday.
Thank you so much for your help!