Reputation: 117
I have this code that reads 16 analog analog sensors connected though multiplexer and ADC to my GPIOs and converts everything to a character accordingly and writes in to my terminal side by side each character, how can I delete and replace just the last printed character? Now it just covers the last printed character and print right next to it the new. The purpose of this project is to create an oldschool sms texter emulator.
This is my code:
#!/usr/bin/python
import time
import RPi.GPIO as GPIO
import spidev # import the SPI driver
from time import sleep
from array import *
DEBUG = False
vref = 3.3 * 1000 # V-Ref in mV (Vref = VDD for the MCP3002)
resolution = 2**10 # for 10 bits of resolution
calibration = 38 # in mV, to make up for the precision of the components
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
start_time=time.time()
elapsed_time=time.time()
keypressed=0
i=0
keyreleased = False
sensor16=['1','-','\\','/','*','!']
sensor15=['4','G','H','I']
sensor14=['7','P','Q','R','S']
sensor13=['*']
sensor12=['2','A','B','C']
sensor11=['5','J','K','L']
sensor10=['8','T','U','V']
sensor09=['0',' ']
sensor08=['3','D','E','F']
sensor07=['6','M','N','O']
sensor06=['9','W','X','Y','Z']
sensor05=['#']
sensor04=['BACKSPACE']
sensor03=['DELETE ALL']
sensor02=['READ']
sensor01=['TRANSMITE']
sensor=[sensor01,sensor02,sensor03,sensor04,sensor05,sensor06,sensor07,sensor08,sensor09,sensor10,sensor11,sensor12,sensor13,sensor14,sensor15,sensor16]
max_press=[1,1,1,1,1,5,4,4,2,4,4,4,1,5,4,6]
num_press=0
steps=0
# MCP3002 Control bits
#
# 7 6 5 4 3 2 1 0
# X 1 S O M X X X
#
# bit 6 = Start Bit
# S = SGL or \DIFF SGL = 1 = Single Channel, 0 = \DIFF is pseudo differential
# O = ODD or \SIGN
# in Single Ended Mode (SGL = 1)
# ODD 0 = CH0 = + GND = - (read CH0)
# 1 = CH1 = + GND = - (read CH1)
# in Pseudo Diff Mode (SGL = 0)
# ODD 0 = CH0 = IN+, CH1 = IN-
# 1 = CH0 = IN-, CH1 = IN+
#
# M = MSBF
# MSBF = 1 = LSB first format
# 0 = MSB first format
# ------------------------------------------------------------------------------
#events = (uinput.KEY_X, uinput.KEY_H, uinput.KEY_E, uinput.KEY_L, uinput.KEY_O)
#device = uinput.Device(events)
# SPI setup
spi_max_speed = 1000000 # 1 MHz (1.2MHz = max for 2V7 ref/supply)
# reason is that the ADC input cap needs time to get charged to the input level.
CE = 0 # CE0 | CE1, selection of the SPI device
spi = spidev.SpiDev()
spi.open(0,CE) # Open up the communication to the device
spi.max_speed_hz = spi_max_speed
#
# create a function that sets the configuration parameters and gets the results
# from the MCP3002
#
#events = (uinput.KEY_X, uinput.KEY_H, uinput.KEY_E, uinput.KEY_L, uinput.KEY_O)
#device = uinput.Device(events)
def read_mcp3002(channel):
# see datasheet for more information
# 8 bit control :
# X, Strt, SGL|!DIFF, ODD|!SIGN, MSBF, X, X, X
# 0, 1, 1=SGL, 0 = CH0 , 0 , 0, 0, 0 = 96d
# 0, 1, 1=SGL, 1 = CH1 , 0 , 0, 0, 0 = 112d
if channel == 0:
cmd = 0b01100000
else:
cmd = 0b01110000
if DEBUG : print("cmd = ", cmd)
spi_data = spi.xfer2([cmd,0]) # send hi_byte, low_byte; receive hi_byte, low_byte
if DEBUG : print("Raw ADC (hi-byte, low_byte) = {}".format(spi_data))
# receive data range: 000..3FF (10 bits)
# MSB first: (set control bit in cmd for LSB first)
# spidata[0] = X, X, X, X, X, 0, B9, B8
# spidata[1] = B7, B6, B5, B4, B3, B2, B1, B0
# LSB: mask all but B9 & B8, shift to left and add to the MSB
adc_data = ((spi_data[0] & 3) << 8) + spi_data[1]
return adc_data
try:
while True:
for x in range(0, 16): # setting the 4 channels of the multiplexer HIGH or LOW accordinlgy
if x == 0:
GPIO.output(7, 0)
GPIO.output(11, 0)
GPIO.output(13, 0)
GPIO.output(15, 0)
elif x == 1:
GPIO.output(7, 1)
GPIO.output(11, 0)
GPIO.output(13, 0)
GPIO.output(15, 0)
elif x == 2:
GPIO.output(7, 0)
GPIO.output(11, 1)
GPIO.output(13, 0)
GPIO.output(15, 0)
elif x == 3:
GPIO.output(7, 1)
GPIO.output(11, 1)
GPIO.output(13, 0)
GPIO.output(15, 0)
elif x == 4:
GPIO.output(7, 0)
GPIO.output(11, 0)
GPIO.output(13, 1)
GPIO.output(15, 0)
elif x == 5:
GPIO.output(7, 1)
GPIO.output(11, 0)
GPIO.output(13, 1)
GPIO.output(15, 0)
elif x == 6:
GPIO.output(7, 0)
GPIO.output(11, 1)
GPIO.output(13, 1)
GPIO.output(15, 0)
elif x == 7:
GPIO.output(7, 1)
GPIO.output(11, 1)
GPIO.output(13, 1)
GPIO.output(15, 0)
elif x == 8:
GPIO.output(7, 0)
GPIO.output(11, 0)
GPIO.output(13, 0)
GPIO.output(15, 1)
elif x == 9:
GPIO.output(7, 1)
GPIO.output(11, 0)
GPIO.output(13, 0)
GPIO.output(15, 1)
elif x == 10:
GPIO.output(7, 0)
GPIO.output(11, 1)
GPIO.output(13, 0)
GPIO.output(15, 1)
elif x == 11:
GPIO.output(7, 1)
GPIO.output(11, 1)
GPIO.output(13, 0)
GPIO.output(15, 1)
elif x == 12:
GPIO.output(7, 0)
GPIO.output(11, 0)
GPIO.output(13, 1)
GPIO.output(15, 1)
elif x == 13:
GPIO.output(7, 1)
GPIO.output(11, 0)
GPIO.output(13, 1)
GPIO.output(15, 1)
elif x == 14:
GPIO.output(7, 0)
GPIO.output(11, 1)
GPIO.output(13, 1)
GPIO.output(15, 1)
elif x == 15:
GPIO.output(7, 1)
GPIO.output(11, 1)
GPIO.output(13, 1)
GPIO.output(15, 1)
# average three readings to get a more stable one
channeldata_1 = read_mcp3002(0) # get CH0 input
sleep(0.001)
channeldata_2 = read_mcp3002(0) # get CH0 input
sleep(0.001)
channeldata_3 = read_mcp3002(0) # get CH0 input
channeldata = (channeldata_1+channeldata_2+channeldata_3)/3
#
# Voltage = (CHX data * (V-ref [= 3300 mV] * 2 [= 1:2 input divider]) / 1024 [= 10bit resolution]
#
voltage = int(round(((channeldata * vref * 2) / resolution),0))+ calibration
if DEBUG : print("Data (bin) {0:010b}".format(channeldata))
if x==15 : # some problem with this sensor so i had to go and twicked the thresshold
voltage = voltage - 500
#time.sleep(0.05)
if ( voltage > 2500) : #key is released
keyreleased = True
if ( voltage < 2500) : #key is pressed
keyreleased=False
keypressed=x #define which key is pressed
# print(i)
if key == keypressed :
while keyreleased == False :
#for i in range (max_press[keypressed]):
# average three readings to get a more stable one
channeldata_1 = read_mcp3002(0) # get CH0 input
sleep(0.001)
channeldata_2 = read_mcp3002(0) # get CH0 input
sleep(0.001)
channeldata_3 = read_mcp3002(0) # get CH0 input
channeldata = (channeldata_1+channeldata_2+channeldata_3)/3
#
# Voltage = (CHX data * (V-ref [= 3300 mV] * 2 [= 1:2 input divider]) / 1024 [= 10bit resolution]
#
voltage = int(round(((channeldata * vref * 2) / resolution),0))+ calibration
if DEBUG : print("Data (bin) {0:010b}".format(channeldata))
if x==15 : # some problem with this sensor so i had to go and twicked the thresshold
voltage = voltage - 500
#time.sleep(0.05)
if ( voltage > 2500) : #key is released
keyreleased = True
i=0
if i < max_press[keypressed] and keyreleased == False :
########################################################
#this is where my characters are printed but i need to #
#print them side by side and to delete just the last #
#character if i have to !!!!!!!!!!! #
########################################################
print("\b", sensor[keypressed][i], end="", flush=True)
time.sleep(0.5)
i=i+1
else :
i=0
GPIO.output(7, 0)
GPIO.output(11, 0)
GPIO.output(13, 0)
GPIO.output(15, 0)
key = keypressed
start_time=time.time()
if DEBUG : print("-----------------")
except KeyboardInterrupt: # Ctrl-C
if DEBUG : print ("Closing SPI channel")
spi.close()
def main():
pass
if __name__ == '__main__':
main()
Any idea how?
Upvotes: 2
Views: 2519
Reputation: 4674
Most terminals move the caret backwards once when the backspace character (ASCII 0x08) is printed:
sys.stdout.write('...'); # print "..."
time.sleep(1); # wait a second
sys.stdout.write('\010\010\010Done.\n') # replace "..." with "Done."
To remove text simply move backward with the backspace character and then write spaces.
Alternatively, on most terminals:
sys.stdout.write('...'); # print "..."
time.sleep(1); # wait a second
sys.stdout.write('\033[2K\033[1G') # erase line and go to beginning of line
sys.stdout.write('Done.\n') # print "Done."
You can use any of the following ANSI escape sequences on terminals that support them (which is most modern terminals):
'\033[#D'
: Move cursor left by #
characters.'\033[2K'
: Clear current line (but don't move cursor).'\033[1K'
: Clear line to the left of current position.'\033[0K'
: Clear line to the right of current position.'\033[1G'
: Move cursor to beginning of line.'\033[#;#f'
: Move cursor to specific position. First #
is row number, second #
is column number.Wikipedia as a convenient summary of ANSI Escape Codes.
Upvotes: 8