Skip to content

Commit

Permalink
Add exception window for camflasher, begin documentation for camflasher
Browse files Browse the repository at this point in the history
  • Loading branch information
remibert committed Jan 16, 2022
1 parent 7b2410a commit dd92586
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 39 deletions.
Binary file removed images/DeviceCom.png
Binary file not shown.
Binary file added images/Device_ESP32CAM-MB.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Device_ESP32CAM.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Device_LOLIN32.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Device_NODEMCU.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Device_TTGO.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/ManageDevice.png
Binary file not shown.
18 changes: 16 additions & 2 deletions modules/lib/shell/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@
SELECT_LEFT = ["\x1b[1;2D"]
SELECT_PAGE_UP = ["\x1b[1;10A","\x1b[1;4A","\x1b[5;2~"]
SELECT_PAGE_DOWN = ["\x1b[1;10B","\x1b[1;4B","\x1b[6;2~"]
SELECT_HOME = ["\x1b[1;6H", "\x1b[1;2H","\x1b[1;10D"]
SELECT_END = ["\x1b[1;6F", "\x1b[1;2F","\x1b[1;10C"]
SELECT_HOME = ["\x1b[1;2H","\x1b[1;10D"]
SELECT_END = ["\x1b[1;2F","\x1b[1;10C"]
SELECT_TOP = ["\x1b[1;6H"]
SELECT_BOTTOM = ["\x1b[1;6F"]
SELECT_ALL = ["\x01"]
SELECT_NEXT_WORD = ["\x1b[1;6C","\x1b[1;4C"]
SELECT_PREV_WORD = ["\x1b[1;6D","\x1b[1;4D"]
Expand Down Expand Up @@ -949,6 +951,16 @@ def select_previous_word(self):
self.open_selection()
self.move_word(-1)

def select_top(self):
""" Manage select to the first line of text """
self.open_selection()
self.change_line(-100000000000)

def select_bottom(self):
""" Manage select to the last line of text """
self.open_selection()
self.change_line(100000000000)

def page_up(self, keys):
""" Manage page up key """
self.hide_selection()
Expand Down Expand Up @@ -1458,6 +1470,8 @@ def treat_key(self, keys):
elif keys[0] in SELECT_LEFT: self.select_left(keys)
elif keys[0] in SELECT_HOME: self.select_home()
elif keys[0] in SELECT_END: self.select_end()
elif keys[0] in SELECT_TOP: self.select_top()
elif keys[0] in SELECT_BOTTOM: self.select_bottom()
elif keys[0] in SELECT_PAGE_UP: self.select_page_up(keys)
elif keys[0] in SELECT_PAGE_DOWN:self.select_page_down(keys)
elif keys[0] in SELECT_ALL: self.select_all()
Expand Down
42 changes: 42 additions & 0 deletions tools/camflasher/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# camflasher
![](/tools/camflasher/icons/camflasher.ico "Camflasher")

Camflasher is a tool which allows to flash pycameresp firmware. It display all traces received from the device. It offer the possibility to access the esp32 shell, edit files from esp32 and execute them.

# Firmwares and devices supported

Below are the devices compatible with pycameresp :

![ESP32CAM](/images/Device_ESP32CAM.jpg "ESP32CAM") ![ESP32CAM-MB](/images/Device_ESP32CAM-MB.jpg "ESP32CAM-MB")

[ESP32-CAM, ESP32-CAM-MB](https://github.com/remibert/pycameresp/releases/download/V2/ESP32CAM-firmware.bin)

![NODEMCU](/images/Device_NODEMCU.jpg "NODE MCU") ![LOLIN32](/images/Device_LOLIN32.jpg "LOLIN32")

[ESP32-NODEMCU, LOLIN32, ESP32 without SPIRAM ](https://github.com/remibert/pycameresp/releases/download/V2/GENERIC-firmware.bin)

![TTGO](/images/Device_TTGO.jpg "TTGO")

[ESP32-TTGO-T8 or ESP32 with SPIRAM ](https://github.com/remibert/pycameresp/releases/download/V2/GENERIC_SPIRAM-firmware.bin)

# Drivers for your computer

A driver can be required by your computer, all drivers are below, select the driver required by your device and your computer :

- [CH341 drivers](http://www.wch.cn/download/CH341SER_ZIP.html)

- [CP210 drivers](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers)

- [FTDI drivers](https://ftdichip.com/drivers/vcp-drivers/)

# Specific wiring for esp32cam

The ESP32-CAM does not have a usb connection, you have to add a usb/serial converter :

![Esp32camProgram.png](/images/Esp32camProgram.png "Esp32Cam flash firmware wiring")

Put jumper on GPIO 0 to GND for programming the firmware.
Remove it once the firmware has been programmed, press reset button after.



27 changes: 16 additions & 11 deletions tools/camflasher/flasher.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import threading
import queue
import time
import sys
from serial import Serial

class ThreadSerial(threading.Thread):
Expand All @@ -15,7 +16,6 @@ def __init__(self, receive_callback):
self.port = ""
self.loop = True
self.buffer = b""
self.buffer2 = b""

self.CONNECT = 0
self.DISCONNECT = 1
Expand Down Expand Up @@ -70,15 +70,21 @@ def on_write(self, command, data):
try:
if len(data) > 32:
while len(data) > 0:
buf = data[:32]
data = data[32:]
self.serial.write(buf)
data_to_send = data[:8]
data = data[8:]
self.serial.write(data_to_send)
if len(data) > 0:
time.sleep(0.1)
while self.serial.in_waiting > 0:
self.receive_callback(self.serial.read(self.serial.in_waiting))
if self.serial.in_waiting == 0:
time.sleep(0.2)
for i in range(15):
time.sleep(0.01)
if self.serial.in_waiting > 0:
break
while self.serial.in_waiting > 0:
self.receive_callback(self.serial.read(self.serial.in_waiting))
if self.serial.in_waiting == 0:
for i in range(15):
time.sleep(0.01)
if self.serial.in_waiting > 0:
break
else:
self.serial.write(data)
except Exception as err:
Expand Down Expand Up @@ -240,7 +246,6 @@ def decode(self, data):

def flasher(self, port, baud, firmware, erase):
""" Flasher of firmware it use the esptool.py command """
from traceback import format_exc
import esptool

# Disconnect serial link
Expand All @@ -264,7 +269,7 @@ def flasher(self, port, baud, firmware, erase):
esptool.main(flash_command)
print("\n\x1B[42;93mFlashed with success. Remove strap and press reset button\x1B[m")
except:
print("\x1B[93;101mFirmware flash failed : \n%s\x1B[m"%format_exc())
print("\n\x1B[93;101mFlash failed\n\x1B[m")

# Connect serial link
self.serial_thread.connect(port)
Expand Down
72 changes: 46 additions & 26 deletions tools/camflasher/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
try:
from PyQt6 import uic
from PyQt6.QtCore import QTimer, QEvent, Qt
from PyQt6.QtWidgets import QFileDialog, QMainWindow, QDialog, QMenu, QApplication, QMessageBox
from PyQt6.QtWidgets import QFileDialog, QMainWindow, QDialog, QMenu, QApplication, QMessageBox, QErrorMessage
from PyQt6.QtGui import QCursor,QAction
except:
from PyQt5 import uic
from PyQt5.QtCore import QTimer, QEvent, Qt
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QDialog, QMenu, QApplication, QMessageBox, QAction
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QDialog, QMenu, QApplication, QMessageBox, QErrorMessage, QAction
from PyQt5.QtGui import QCursor
from serial.tools import list_ports
from flasher import Flasher
Expand All @@ -40,31 +40,31 @@

# Function keys
function_keys = {
Qt.Key.Key_F1 : [b'\x1bOP' ,b'\x1b[1;2P'],
Qt.Key.Key_F2 : [b'\x1bOQ' ,b'\x1b[1;2Q'],
Qt.Key.Key_F3 : [b'\x1bOR' ,b'\x1b[1;2R'],
Qt.Key.Key_F4 : [b'\x1bOS' ,b'\x1b[1;2S'],
Qt.Key.Key_F5 : [b'\x1b[15~',b'\x1b[15;2~'],
Qt.Key.Key_F6 : [b'\x1b[17~',b'\x1b[17;2~'],
Qt.Key.Key_F6 : [b'\x1b[18~',b'\x1b[18;2~'],
Qt.Key.Key_F8 : [b'\x1b[19~',b'\x1b[19;2~'],
Qt.Key.Key_F9 : [b'\x1b[20~',b'\x1b[20;2~'],
Qt.Key.Key_F10 : [b'\x1b[21~',b'\x1b[21;2~'],
Qt.Key.Key_F11 : [b'\x1b[23~',b'\x1b[23;2~'],
Qt.Key.Key_F12 : [b'\x1b[24~',b'\x1b[24;2~'],
Qt.Key.Key_F1 : [b"\x1bOP" ,b"\x1b[1;2P"],
Qt.Key.Key_F2 : [b"\x1bOQ" ,b"\x1b[1;2Q"],
Qt.Key.Key_F3 : [b"\x1bOR" ,b"\x1b[1;2R"],
Qt.Key.Key_F4 : [b"\x1bOS" ,b"\x1b[1;2S"],
Qt.Key.Key_F5 : [b"\x1b[15~",b"\x1b[15;2~"],
Qt.Key.Key_F6 : [b"\x1b[17~",b"\x1b[17;2~"],
Qt.Key.Key_F6 : [b"\x1b[18~",b"\x1b[18;2~"],
Qt.Key.Key_F8 : [b"\x1b[19~",b"\x1b[19;2~"],
Qt.Key.Key_F9 : [b"\x1b[20~",b"\x1b[20;2~"],
Qt.Key.Key_F10 : [b"\x1b[21~",b"\x1b[21;2~"],
Qt.Key.Key_F11 : [b"\x1b[23~",b"\x1b[23;2~"],
Qt.Key.Key_F12 : [b"\x1b[24~",b"\x1b[24;2~"],
}

# Arrow keys, page up and down, home and end
move_keys = {
# Nothing Shift Meta Alt Control Shift+Alt Shift+Meta Shift+Control
Qt.Key.Key_Up : [b'\x1b[A' ,b'\x1b[1;2A',b'\x1b[1;5A',b'\x1b\x1b[A' ,b'\x1b[A' ,b'\x1b[1;2A',b'\x1b[1;6A',b'\x1b[1;6A'],
Qt.Key.Key_Down : [b'\x1b[B' ,b'\x1b[1;2B',b'\x1b[1;5B',b'\x1b\x1b[B' ,b'\x1b[B' ,b'\x1b[1;2B',b'\x1b[1;6B',b'\x1b[1;6B'],
Qt.Key.Key_Right : [b'\x1b[C' ,b'\x1b[1;2C',b'\x1b[1;5C',b'\x1b\x1b[C' ,b'\x1b[C' ,b'\x1b[1;2C',b'\x1b[1;6C',b'\x1b[1;6C'],
Qt.Key.Key_Left : [b'\x1b[D' ,b'\x1b[1;2D',b'\x1b[1;5D',b'\x1b\x1b[D' ,b'\x1b[D' ,b'\x1b[1;2D',b'\x1b[1;6D',b'\x1b[1;6D'],
Qt.Key.Key_Home : [b'\x1b[H' ,b'\x1b[1;2H',b'\x1b[1;5H',b'\x1b[1;9H' ,b'\x1b[H' ,b'\x1b[1;2H',b'\x1b[1;6H',b'\x1b[1;6H'],
Qt.Key.Key_End : [b'\x1b[F' ,b'\x1b[1;2F',b'\x1b[1;5F',b'\x1b[1;9F' ,b'\x1b[F' ,b'\x1b[1;2F',b'\x1b[1;6F',b'\x1b[1;6F'],
Qt.Key.Key_PageUp : [b'\x1b[5~',b"\x1b[1;4A",b'\x1b[5~' ,b'\x1b\x1b[5~',b'\x1b[5~',b'\x1b[5~' ,b'\x1b[5~' ,b'\x1b[5~' ],
Qt.Key.Key_PageDown : [b'\x1b[6~',b"\x1b[1;4B",b'\x1b[6~' ,b'\x1b\x1b[6~',b'\x1b[6~',b'\x1b[6~' ,b'\x1b[6~' ,b'\x1b[6~' ],
# Nothing Shift Meta Alt Control Shift+Alt Shift+Meta Shift+Control
Qt.Key.Key_Up : [b"\x1b[A" ,b"\x1b[1;2A",b"\x1b[1;5A",b"\x1b\x1b[A" ,b"\x1b[1;5A" ,b"\x1b[1;2A",b"\x1b[1;6A",b"\x1b[1;6A"],
Qt.Key.Key_Down : [b"\x1b[B" ,b"\x1b[1;2B",b"\x1b[1;5B",b"\x1b\x1b[B" ,b"\x1b[1;5B" ,b"\x1b[1;2B",b"\x1b[1;6B",b"\x1b[1;6B"],
Qt.Key.Key_Right : [b"\x1b[C" ,b"\x1b[1;2C",b"\x1b[1;5C",b"\x1b\x1b[C" ,b"\x1b[1;5C" ,b"\x1b[1;2C",b"\x1b[1;6C",b"\x1b[1;6C"],
Qt.Key.Key_Left : [b"\x1b[D" ,b"\x1b[1;2D",b"\x1b[1;5D",b"\x1b\x1b[D" ,b"\x1b[1;5D" ,b"\x1b[1;2D",b"\x1b[1;6D",b"\x1b[1;6D"],
Qt.Key.Key_Home : [b"\x1b[H" ,b"\x1b[1;2H",b"\x1b[1;5H",b"\x1b[1;9H" ,b"\x1b[H" ,b"\x1b[1;2H",b"\x1b[1;6H",b"\x1b[1;6H"],
Qt.Key.Key_End : [b"\x1b[F" ,b"\x1b[1;2F",b"\x1b[1;5F",b"\x1b[1;9F" ,b"\x1b[F" ,b"\x1b[1;2F",b"\x1b[1;6F",b"\x1b[1;6F"],
Qt.Key.Key_PageUp : [b"\x1b[5~",b"\x1b[1;4A",b"\x1b[5~" ,b"\x1b\x1b[5~",b"\x1b[5~" ,b"\x1b[5~" ,b"\x1b[5~" ,b"\x1b[5~" ],
Qt.Key.Key_PageDown : [b"\x1b[6~",b"\x1b[1;4B",b"\x1b[6~" ,b"\x1b\x1b[6~",b"\x1b[6~" ,b"\x1b[6~" ,b"\x1b[6~" ,b"\x1b[6~" ],
}

def convert_key_to_vt100(key_event):
Expand Down Expand Up @@ -109,7 +109,12 @@ def convert_key_to_vt100(key_event):
else:
result = normal
else:
result = key_event.text().encode("utf-8")
# If control letter pressed
if key >= 65 and key <= 90 and (modifier & Qt.KeyboardModifier.ControlModifier or modifier & Qt.KeyboardModifier.MetaModifier):
key -= 64
result = key.to_bytes(1,"little")
else:
result = key_event.text().encode("utf-8")
return result

class AboutDialog(QDialog):
Expand Down Expand Up @@ -174,7 +179,8 @@ def __init__(self):
from camflasher import Ui_main_window
self.window = Ui_main_window()
self.window.setupUi(self)

self.window.output.setAcceptDrops(False)
self.window.output.setReadOnly(True)
self.window.output.installEventFilter(self)

self.flash_dialog = FlashDialog(self)
Expand Down Expand Up @@ -280,7 +286,6 @@ def paste(self):
paste = paste.replace("\n","\r")
paste = paste.encode("utf-8")
self.flasher.send_key(paste)
self.console.stdout.write("Paste '%s'\n"%QApplication.clipboard().text())

def eventFilter(self, obj, event):
""" Treat key pressed on console """
Expand Down Expand Up @@ -394,9 +399,24 @@ def closeEvent(self, event):
# Stop serial thread
self.flasher.quit()

def except_hook(cls, exception, traceback):
""" Exception hook """
from traceback import extract_tb
msg = QErrorMessage()
text = '<code>' + str(exception) + "<br>"
for filename, line, method, content in extract_tb(traceback) :
text += '&nbsp;&nbsp;&nbsp;&nbsp;<FONT COLOR="#ff0000">File "%s", line %d, in %s</FONT><br>'%(filename,line,method)
text += '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s<br>'%(content)
text += "</code>"
msg.resize(800, 400)
msg.showMessage(text)
msg.exec()
sys.__excepthook__(cls, exception, traceback)

def main():
""" Main application """
app = QApplication(sys.argv)
sys.excepthook = except_hook
window = CamFlasher()
app.exec()

Expand Down

0 comments on commit dd92586

Please sign in to comment.