Page 1 of 2
Control-C program via rshell etc
Posted: Sun Aug 18, 2019 1:53 am
by rpr
I have an infinite loop running on my ESP8266 started at the end of my main.py. The program works fine and is sending data over mqtt. How can I interrupt it via rshell etc? rshell keeps waiting at the "Testing if ubinascii.unhexlify exists ..." How can I send a ctrl-C? Thanks for your help.
This is my boot.py.
Code: Select all
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import uos, machine
#uos.dupterm(None, 1) # disable REPL on UART(0)
import gc
#import webrepl
#webrepl.start()
gc.collect()
Re: Control-C program via rshell etc
Posted: Sun Aug 18, 2019 8:06 am
by pythoncoder
I have encountered this one too. I don't know an entirely satisfactory fix. The nuclear solution is of course to erase flash and start again. The more practical way is to have main.py look like this
Code: Select all
import time
time.sleep(5)
import my_module
You should find that after a reset or power cycle you have 5 secs to connect and interrupt the program.
Re: Control-C program via rshell etc
Posted: Sun Aug 18, 2019 9:07 am
by Roberthh
You could also start a different terminal emulator like Putty or picocom and push Ctrl-C there.
Re: Control-C program via rshell etc
Posted: Sun Aug 18, 2019 9:12 am
by rpr
Peter, many thanks.
I've been using the nuclear option so far. A little annoying but worked. I will try out your more practical solution.
Re: Control-C program via rshell etc
Posted: Sun Aug 18, 2019 12:26 pm
by jimmo
rpr wrote: ↑Sun Aug 18, 2019 1:53 am
I have an infinite loop running on my ESP8266
Is this just a "while True: pass". What you're describing _should_ work, so sounds like there's a bug somewhere. Do you still have the console connected to the serial port when you run rshell?
pythoncoder wrote: ↑Sun Aug 18, 2019 8:06 am
The more practical way is to have main.py look like this
The first thing rshell does is sent Ctrl-C twice, so I don't understand why this would be any different to the time.sleep(). Or am I missing something?
I just tested this quickly on my esp8266. I'm using `pyboard.py -f`, but it's effectively the same as rshell. (I think rshell uses pyboard.py, or a derivative of, internally).
main_loop.py:
Code: Select all
pyboard.py --device /dev/ttyUSB0 -f cp main_loop.py :main.py
(soft reset ESP8266, verify in terminal that it's stuck in the infinite loop)
Code: Select all
$ ./tools/pyboard.py --device /dev/ttyUSB0 -f ls
ls :
230 boot.py
19 main.py
Re: Control-C program via rshell etc
Posted: Mon Aug 19, 2019 10:01 am
by pythoncoder
In the case of
(to my surprise) you can indeed get in with rshell.
I have encountered cases with real applications where you cannot, and a brief delay provides a handy fix. Perhaps there are worse cases, for example if the application is waiting on a blocking call? Although in my code I try to avoid this...
Re: Control-C program via rshell etc
Posted: Mon Aug 19, 2019 10:14 am
by Roberthh
That's what I tested. The problem arises when the code is waiting in a blocking call. Then ir will not be tested, whether a Ctrl-C happened.
Re: Control-C program via rshell etc
Posted: Mon Aug 19, 2019 10:17 pm
by rpr
I'm taking sensor data from a dht22 and using Peter's mqtt_as module. Here is the code. It has been working perfectly for about 36 hours now. I'm going to let it run for a few more days to check. Though it would be nice to do a Ctrl-C.
Code: Select all
from mqtt_as import MQTTClient
from configmqtt import config
import uasyncio as asyncio
import dht
from machine import Pin
def dhtmeas():
d = dht.DHT22(Pin(14))
d.measure()
return d.temperature(), d.humidity()
SERVER = '192.168.1.2' # Change to suit e.g. 'iot.eclipse.org'
async def main(client):
await client.connect()
n = 0
while True:
await asyncio.sleep(30)
print('publish', n)
t, h = dhtmeas()
print(t,h)
msg="Temp = " + str(t) + " C ; RH = " + str(h) + " %"
# If WiFi is down the following will pause for the duration.
await client.publish('sensors/DHT22-01', msg, qos = 1)
n += 1
config['server'] = SERVER
MQTTClient.DEBUG = True # Optional: print diagnostic messages
client = MQTTClient(config)
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main(client))
finally:
client.close() # Prevent LmacRxBlk:1 errors
Re: Control-C program via rshell etc
Posted: Tue Aug 20, 2019 6:38 am
by pythoncoder
I don't have an answer as to why my library prevents ctrl-c. It clearly doesn't block - it uses uasyncio and makes extensive use of concurrent tasks. The whole thing would croak if a task executed a blocking call. This has piqued my curiosity and I will investigate. Alas I'm busy at the moment so it may be a while before I get to look at it.
A workround if you need to shut it down remotely might be to subscribe to a "kill" topic and send it a message.
Re: Control-C program via rshell etc
Posted: Tue Aug 20, 2019 6:45 am
by pythoncoder
One comment on the code. This won't fix the problem but relates to general efficiency. You instantiate the DHT (and the Pin) every time you read it. My approach would be to instantiate these once only:
Code: Select all
def dhtmeas(d):
d.measure()
return d.temperature(), d.humidity()
SERVER = '192.168.1.2' # Change to suit e.g. 'iot.eclipse.org'
async def main(client):
await client.connect()
d = dht.DHT22(Pin(14)) # Instantiate
n = 0
while True:
await asyncio.sleep(30)
print('publish', n)
t, h = dhtmeas(d)
You might also dispense with
dhtmeas and inline its contents.