Screen control

I am sure this is elementary to most but bear with me please. I am using Raspbian on a pi. How does one get a reading to print on screen in the same place on a continueing basis rather than printing on a new line and scrolling.

Malcolm Smith

--
T M Smith 
Using an ARMX6 and RISC OS 5.21 in the North Riding of Yorkshire
Reply to
T M Smith
Loading thread data ...

T M Smith wrote on 10/21/2017 4:04 PM:

Are you writing your own program? What is the text coming from?

If you just want to update the bottom line the program should send CR but no LF. If you want the text to appear at a specific location on the screen, you can send ANSI codes I believe, but I'm not totally clear on how Linux does it. But I believe each window is essentially a terminal emulator from the perspective of the program running in it.

--

Rick C 

Viewed the eclipse at Wintercrest Farms, 
on the centerline of totality since 1998
Reply to
rickman

Yep. Each console window is effectively a 24 x 80 colour screen. What language is the program written it? That's relevant because many languages have their own terminal management packages:

- Python has at least two

- Java has Swing and FX packages for displaying non-image data as well as image manipulation and display packages

- C has curses for writing editors like vi, etc, i.e. its meant for giving you fa-ne control of where you can write text to and receive input from a (typically) 24x80 character-mode terminal. There's also and also Gtk+ package for building 2D and 3D graphical displays.

GTK+ and Open GL support applications written in a variety of languages.

All of these have a fairly steep learning curve if you haven't used any of them, but the concepts they use are all fairly similar, so once you've understood one, using different graphical/terminal packages becomes a lot easier.

I've implemented a version of Curses for Java, using the information and API description in "Programming with Curses" (O'Reilly) partly because I could and partly to convince myself that I understood Curses well enough to do it.

--
martin@   | Martin Gregorie 
gregorie. | Essex, UK 
org       |
Reply to
Martin Gregorie

I am altering a python program and just wish to display readings of temperature etc. in the same place on screen after each update.

Malcolm

--
T M Smith 
Using an ARMX6 and RISC OS 5.21 in the North Riding of Yorkshire
Reply to
T M Smith

Is this to be run in a GUI window or on a text-mode console?

GUI window: it seems that Tkinter is the way to go: ===========

formatting link
as it seems to be the de-facto Python GUI package.

Console: there's a version of Curses ported to Python ======== IMO this is the way to go for a text-mode console, regardless of whether you're running the program in a console window on an Raspbian desktop or over an SSH session connected to a headless RPi. Or, of course, you can try (in pseudocode):

read initial temp value from sensor repeat write temp to console WITHOUT a newline read temp from sensor write backspaces to erase the last temp forever but using Tkinter or Curses will let you paint a nicer screen with a title and a captioned place to output the temp reading as well as a way to input a QUIT command. In addition, you'll learn a skill that's likely to be useful for other projects.

Also, though probably not useful here, take a look at xmessage, which is a convenient way to pop up messages on the desktop and input text by clicking buttons. It is designed to be use in shell scripts but could also be executed from any language that can run commands. Here's an example (tested):

echo "Can you read this?" | \ xmessage -buttons Yes,No -center -timeout 5 -print -file -

... which could do pretty much what you want: if called from a temperature sampling loop. Timeout would control the temperature sampling rate and using a single "Quit" button would be a clean way to stop the controlling program.

--
martin@   | Martin Gregorie 
gregorie. | Essex, UK 
org       |
Reply to
Martin Gregorie

Following myself up, here's a working example in a bash script:

#!/bin/bash t=20 c="" while [ -z "$c" ] do echo "Room temp is $t C" | \ xmessage -buttons Quit -center -timeout 5 -print -file - >x.txt t=$(expr $t + 1) c=$(cat x.txt) done

which increments and displays 't' every 5 seconds until you click 'Quit'.

--
martin@   | Martin Gregorie 
gregorie. | Essex, UK 
org       |
Reply to
Martin Gregorie

Thankyou Martin That should get me away since you have covered all the bases in youur reply Malcolm

--
T M Smith 
Using an ARMX6 and RISC OS 5.21 in the North Riding of Yorkshire
Reply to
T M Smith

On Sun, 22 Oct 2017 14:34:31 +0100, T M Smith declaimed the following:

You'd probably get better suggestions by showing the relevant snippet of existing code.

Since your original post implies the existing program is scrolling, I'm going to assume it is a simple console application (I don't see anyone going through the effort of creating a GUI application with a scrolling output, where a single line text widget would suffice).

-=-=-=-=- """ Simple demo for scroll vs non-scroll (Python 2.7, hence xrange and paren-less print) """

import sys import time

if "scroll" in sys.argv: print print for x in xrange(100): print "Pseudo-Temperature: %10.3f" % (x * 3.14159 - 25.5) time.sleep(1) elif "overwrite" in sys.argv: print print for x in xrange(100): sys.stdout.write("\rPseudo-Temperature: %10.3f" % (x * 3.14159 - 25.5)) time.sleep(1) else: print "\nPlease supply either 'scroll' or 'overwrite' on the command line"

-=-=-=-=- C:\Users\Wulfraed\Documents\Python Progs>so.py

Please supply either 'scroll' or 'overwrite' on the command line

C:\Users\Wulfraed\Documents\Python Progs>so scroll

Pseudo-Temperature: -25.500 Pseudo-Temperature: -22.358 Pseudo-Temperature: -19.217 Pseudo-Temperature: -16.075 Pseudo-Temperature: -12.934 Pseudo-Temperature: -9.792 Pseudo-Temperature: -6.650 Pseudo-Temperature: -3.509 Pseudo-Temperature: -0.367 Pseudo-Temperature: 2.774 Pseudo-Temperature: 5.916 Pseudo-Temperature: 9.057 Pseudo-Temperature: 12.199 Traceback (most recent call last): File "C:\Users\Wulfraed\Documents\Python Progs\so.py", line 14, in time.sleep(1) KeyboardInterrupt

C:\Users\Wulfraed\Documents\Python Progs>so overwrite

Pseudo-Temperature: 21.624Traceback (most recent call last): File "C:\Users\Wulfraed\Documents\Python Progs\so.py", line 21, in time.sleep(1) KeyboardInterrupt

C:\Users\Wulfraed\Documents\Python Progs>

{I killed the runs after a few seconds}

There is no control as to which line is updated -- the I/O takes place on whatever line the cursor/console is at when running. I used the %f formatting to set a fixed width for the output; otherwise one risks have a short value not overwrite the rest of a long value.

--
	Wulfraed                 Dennis Lee Bieber         AF6VN 
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/
Reply to
Dennis Lee Bieber

snippet

scrolling, I'm

This solution doesn't seem to be OS-agnostic, unfortunately.

On my system, Fedora 25 with Python 2.7.13, 'scroll' works as expected, but 'overwrite' doesn't display anything. Since that looks as if you ran it on some flavour of Windows, does it work as expected on a Raspbian box?

--
martin@   | Martin Gregorie 
gregorie. | Essex, UK 
org       |
Reply to
Martin Gregorie

This seems to work in Python:

import time, sys for i in xrange (20): sys.stdout.write ('\r' + str (i) + ' '*20) sys.stdout.flush() time.sleep (.5)

Reply to
Mel Wilson

On Sun, 22 Oct 2017 17:41:01 -0000 (UTC), Martin Gregorie declaimed the following:

sys.stdout.flush()

Adding the flush() produced output on Debian Stretch running in VirtualBox. Should have no effect on Windows.

--
	Wulfraed                 Dennis Lee Bieber         AF6VN 
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/
Reply to
Dennis Lee Bieber

T M Smith wrote on 10/22/2017 9:34 AM:

Is anything else being displayed on the screen? Is writing to the bottom line of the screen without scrolling good enough or do you wish to put the temperature at the top of the display while the rest of the display scrolls?

--

Rick C 

Viewed the eclipse at Wintercrest Farms, 
on the centerline of totality since 1998
Reply to
rickman

Excellent, thanks. Works here after adding sys.stdout.flush()

--
martin@   | Martin Gregorie 
gregorie. | Essex, UK 
org       |
Reply to
Martin Gregorie

if you're running this in a console, check out how 'curses' works. You can also try the VT ANSI escape sequences yourself.

you can also send a 'home' cursor to the screen to overwrite the same line over and over...

formatting link

I think the right sequence for 'home cursor' is:

[1G

in C code it would be:

"\x1b[1G"

so don't do a line feed '\n' at the end, but do THAT instead, and I think the line will overwrite itself. That's what you wanted, right?

(I've done this before but I don't have the code in front of me at the moment)

OK curiosity bugs me now and so I wrote this:

#include #include

int main() { int i1;

for(i1=0; i1 < 500; i1++) { printf("Here I am: %d \x1b[1G", i1); fflush(stdout); usleep(100000); } }

try it, you'll like it!

Reply to
Big Bad Bob

I posted a sample C program. here's a sample python program using the ANSI sequence to "home the cursor":

import time import sys

for xx in range(0,500) : print "here I am ", xx, "\x1b[1G", sys.stdout.flush() time.sleep(0.1)

(note ',' at end of print, which doesn't do a line feed - also need the 'flush' to make sure it outputs immediately)

enjoy

Reply to
Big Bad Bob

yeah I think it's working too hard. see my example (as in the other post)

import time import sys

for xx in range(0,500) : print "here I am ", xx, "\x1b[1G", sys.stdout.flush() time.sleep(0.1)

scrolling is easy. this shows how to use an ANSI sequence to move the cursor. In theory, you can move it wherever you want. In this case it's to the beginning of the current line, and the ',' at the end of 'print' keeps the line feed from being sent. then there's the 'flush'. NOW you can use 'print' (instead of 'sys.stdout.write') and take advantage of the built-in data output stuff, and send ANSI sequences to move the cursor to the next spot (whatever that might be), or you could move it to that spot BEFORE you output anything, whatever. All very flexible. Requires an ANSI terminal. Fortunately, that works for ssh and Linux X11 desktop consoles.

or if you want use "\r" (should work, didn't try it)

print "here I am ", xx, "\r",

Reply to
Big Bad Bob

instead of flushing every time you could: # reopen stdout file descriptor with write mode # and 0 as the buffer size (unbuffered) sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

see

formatting link

There seems to be other ways too, like passing -u to the interpreter or setting env var PYTHONUNBUFFERED

These two last I did not test, but some years ago I did reopneh stdout with 0 buffer and it worked fine (on python 2.7 at least)

--
--
Reply to
Björn Lundin

I'm surprised no one has mentioned the easiest way if you have a command line program that displays a one off reading of 1 or more lines of text. Simply use the watch command (sudo apt-get install watch) to run the command every so many seconds, displaying the result in the same place on the screen.

e.g. To show the CPU temperature every 1 seconds.

watch -n 1 /opt/vc/bin/vcgencmd measure_temp

---druck

Reply to
druck

Neat, though the intervals between executions of the child process seem to be a little random (Lenovo T440 running Fedora 25). Running

watch -n 1 date

displays the date/time with intervals of one or two seconds and the delay doesn't always agree with the displayed interval. That said, it seems a lot more regular with a 5 sec interval.

--
martin@   | Martin Gregorie 
gregorie. | Essex, UK 
org       |
Reply to
Martin Gregorie

Thankyou Martin and Dennis, it works for me also though I will also explore TKinter.

Malcolm Smith

--
T M Smith 
Using an ARMX6 and RISC OS 5.21 in the North Riding of Yorkshire
Reply to
T M Smith

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.