Enabling printf to work

I am using the arducam_dvp library to communicate with an Arducam HM01B0 camera from my Arduino Giga R1 board. I am trying to use the printRegs() routine in the HM01B0 driver. I was expecting it to print register values to the Serial Monitor, but nothing prints there.

Here is my complete test program:

#include "arducam_dvp.h"
#include "Himax_HM01B0/himax.h"

HM01B0 himax;
Camera cam(himax);

void setup()
{    
    Serial.begin(9600);   // register values will be printed in the serial monitor
    while (!Serial)
    {
        ; // Wait for the serial port to connect.
    }

    // Init the cam QVGA, 30FPS
    if (!cam.begin(CAMERA_R320x320, CAMERA_GRAYSCALE, 30))
    {
      Serial.print("cam.begin failed\n");
    }

    Serial.print("\nThe register values are:\n\n");
    himax.printRegs();
    Serial.print("\nEnd of printout\n");
}

void loop()
{
    
}

I looked at the source code in the library (file Arduino/libraries/arducam_dvp/src/Himax_HM01B0/himax.cpp) and found that the library source code looks like this:

uint8_t HM01B0::printRegs()
{
    for (uint32_t i=0; himax_default_regs[i][0]; i++) {
        printf("0x%04X: 0x%02X  0x%02X \n",
                himax_default_regs[i][0],
                himax_default_regs[i][1],
                regRead(HM01B0_I2C_ADDR, himax_default_regs[i][0], true));
    }
    return 0;
}

I see that the library code is using printf() which I didn't think worked in the Arduino environment. But there must be a way to enable it or get it to work, otherwise why did they code this function to use a printf?

So my question is: How do I get the printf to work?

I found another forum post with a similar question and they suggested writing a custom putc routine and adding the line

fdevopen( &myputc, 0);

in my main program. However, the symbol fdevopen is undefined, so I was unable to do that.

I am using the Arduino Giga R1 board.

Did you

# include <stdio.h>

?

Check this thread, it may have a detail you are missing.

On the UNO and its ilk, there is no support for floating point.

HTH

a7

I tried adding #include <stdio.h>, but that did not help.

Using the method given in that article, I get the error message: "fdev_setup_stream was not declared in this scope."

Show the complete compile message "error" in code tags.

My approach would be to replace all references to printf() with snprintf() and Serial.print().

In this case, for example,

   char buf[60];
   for (uint32_t i=0; himax_default_regs[i][0]; i++) {
   snprintf(buf, 60,"0x%04X: 0x%02X  0x%02X \n",
                himax_default_regs[i][0],
                himax_default_regs[i][1],
                regRead(HM01B0_I2C_ADDR, himax_default_regs[i][0], true));

    Serial.print(buf);
...

AVR LibC (the standard C library for Arduino AVR chips)

HAS NO printf()!

AVR LibC Manual.

What we have is a Java class, Serial with print functions.

@bluejets Thank you for enlightening me on proper posting protocol.

@jremington I do not want to modify the library code. Any edits I made would get lost if a new version of the library came out.

Whoever coded the library used the printf function. They must have had a reason. I am guessing there is some way to enable printf's in libraries not under your control to work.

@GoForSmoke I agree with you. Then why did the person who coded the library (presumably the software group at Arducam), which is specifically written for the Arduino platform, use a printf in their code?

That board uses an ARM chip, not an AVR.

I've found a couple of suggestions to put the following line at the start of the sketch to enable printf() to send to Serial, but have no hardware to test it.

REDIRECT_STDOUT_TO(Serial)
2 Likes

Ask ArduCam for advice.

@david_2018 That worked! Thank you.

The solution was:

REDIRECT_STDOUT_TO(Serial)
2 Likes

How should I know? Did they use a macro?
There was at least one thread in the past just on this issue and another where someone wanted to make their own. Feel free to look them up!

That's not true, either (even though it's irrelevant to OP Giga (ARM) based problem.)
avr-libc has a printf (that doesn't support floating point), but it's not "connected" to anything. You have to add some code to your sketch to provide that connection. That looks like:

int fput(char c, FILE* f) {
  Serial.write( c);
  return 0;
}

void setup() {
  Serial.begin(9600);
  stdout = fdevopen(fput, NULL);
}
2 Likes