Nooe
Posts: 3
Joined: Tue May 28, 2019 9:17 am

printf issue on raspbian

Tue May 28, 2019 11:37 am

Hi! I'm having a weird problem with printf. It may be a basic one but i don't understand what's happening here.
What I'm trying to do is print a message and wait for user to press a button on GPIOs. The problem is that printfs are not displayed at the right time. The program is waiting for the button and then it will display the message.

The function is really basic :

Code: Select all

void wait_bp(char message[],int button)	//button : WiringPi pin for GPIOs
{
	printf("\n");
	printf(message);
	do{
	}while(digitalRead(button)==1);
	
	
}
The most disturbing thing is that I can see that the "\n" is displayed correctly but the message doesn't appear until I press the button.


I'm using gcc Raspbian 6.3.0-18 on a Raspberry pi 3.
Thanks! :)

User avatar
scootergarrett
Posts: 46
Joined: Sat Apr 19, 2014 2:36 pm

Re: printf issue on raspbian

Tue May 28, 2019 12:34 pm

I'm thinking you need to do a "screen flush".

jahboater
Posts: 4478
Joined: Wed Feb 04, 2015 6:38 pm

Re: printf issue on raspbian

Tue May 28, 2019 12:53 pm

If "message" doesn't end with a new line, do this after the printf:

fflush(stdout);

Or use stderr which is unbuffered, or use setbuf() to turn off buffering.

Nooe
Posts: 3
Joined: Tue May 28, 2019 9:17 am

Re: printf issue on raspbian

Tue May 28, 2019 1:33 pm

Thanks for the quick answer! It works with fflush but I don't understand when it's necessary to use it.
This is the beginning of the main:

Code: Select all

int main()
{
	wiringPiSetup();
	initscr();
	
	const int BatStatA = 0;
	const int BatStatB = 1;
	const int SwRst = 12;
	const int SwPow = 13;
	const int SwFun = 14;
	const int SwCOpen = 30;
	const int PwmSys = 26;
	const int SysSign = 6;
	
	pinMode(BatStatA, OUTPUT);
	pinMode(BatStatB, OUTPUT);
	pinMode(SwRst, INPUT);
	pinMode(SwPow, INPUT);
	pinMode(SwFun, INPUT);
	pinMode(SwCOpen, INPUT);
	pinMode(PwmSys, PWM_OUTPUT);
	pinMode(SysSign, OUTPUT);
	
	pullUpDnControl(SwRst, PUD_UP);
	pullUpDnControl(SwFun, PUD_UP);
	pullUpDnControl(SwPow, PUD_OFF);
	
	pwmSetMode (PWM_MODE_MS);
	pwmSetClock(3000);
	pwmSetRange(1000);
	pwmWrite(PwmSys,0);
//	pwmWrite(SysSign,0);
	digitalWrite(SysSign,LOW);

	int buf_test1 = 0;
	int buf_test2 = 0;
	int buf_test3 = 0;
	int buf_test4 = 0;
	int etape_val = 0;
	
	
	
	printf("Test de la carte Junction \n\r ",2);
	printf("\n");
	
	while(quest("\nTous les branchements controles pour le lancement du test (O/N) ?")==0){
	}
	
	print("Lancement des 3 tests ...\n", 2);
	
	
Here, only the last print is working well

jahboater
Posts: 4478
Joined: Wed Feb 04, 2015 6:38 pm

Re: printf issue on raspbian

Tue May 28, 2019 1:44 pm

Nooe wrote:
Tue May 28, 2019 1:33 pm
Thanks for the quick answer! It works with fflush but I don't understand when it's necessary to use it.
Read the man page for setbuf() (man setbuf) which may explain things.

stdout is a layer of buffered I/O above the write() system call (see man 2 write)

If you don't need the fancy formatting offered by printf, you can use the simpler puts() which is still buffered, or use the write() system call directly.

Code: Select all

#include <unistd.h>

int
main( void )
{
  write( 1, "Hello world", 11 );
}
This writes to the screen immediately, even without the final "\n" and will be both faster and very much smaller of course.

Note also, GCC will likely convert printf( "hello world\n" ), to puts( "hello world" ) anyway.

See also the strace command to see what system calls are really being made by your program!

jahboater
Posts: 4478
Joined: Wed Feb 04, 2015 6:38 pm

Re: printf issue on raspbian

Tue May 28, 2019 1:54 pm

I have just seen that you are using ncurses initscr() which changes everything!
Best not to mix stdio with curses.

Nooe
Posts: 3
Joined: Tue May 28, 2019 9:17 am

Re: printf issue on raspbian

Tue May 28, 2019 2:27 pm

jahboater wrote:
Tue May 28, 2019 1:54 pm
I have just seen that you are using ncurses initscr() which changes everything!
Best not to mix stdio with curses.
Ok thanks again, I'll try whitout stdio.

deepo
Posts: 25
Joined: Sun Dec 30, 2018 8:36 pm

Re: printf issue on raspbian

Wed May 29, 2019 9:59 pm

Your while loop does not contain any code to release the CPU for other purposes, such as flushing stdout.
Maybe adding a small pause will help?
Look at this post for short sleeps: viewtopic.php?t=80705

/Mogens

jahboater
Posts: 4478
Joined: Wed Feb 04, 2015 6:38 pm

Re: printf issue on raspbian

Wed May 29, 2019 10:06 pm

deepo wrote:
Wed May 29, 2019 9:59 pm
Your while loop does not contain any code to release the CPU for other purposes, such as flushing stdout.
Maybe adding a small pause will help?
I think its done synchronously (if its going to flush the buffer).

User avatar
Paeryn
Posts: 2570
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: printf issue on raspbian

Thu May 30, 2019 1:40 am

jahboater wrote:
Wed May 29, 2019 10:06 pm
deepo wrote:
Wed May 29, 2019 9:59 pm
Your while loop does not contain any code to release the CPU for other purposes, such as flushing stdout.
Maybe adding a small pause will help?
I think its done synchronously (if its going to flush the buffer).
Yes, waiting after a printf() isn't going to affect a flush, at worst it will induce a short (probably imperceptible) delay until the Kernel makes the terminal emulator active to update the screen.

Stdout is by default in one of two buffered states, if it determines that it is connected to an interactive environment then it will be line buffered so flushing only happens on a newline character (or you explicitly flush or the buffer is full). If stdout isn't deemed to be interactive (e.g. it's a regular file) then it will be fully buffered so flushing will only happen when the buffer is full or is explicitly flushed, or the stream is being closed.

If as was pointed out earlier, the OP is using curses and you shoudn't mix printf() style printing when curses is managing the screen. Neither side knows what state the display is in and will happily plaster thier interrpetation .
She who travels light — forgot something.

Return to “C/C++”