commit 807557949692553d07ce6d4811e7d5dd06e6d8b5 Author: Konstantin Koslowski Date: Thu Jul 15 21:41:20 2021 +0200 tx-udp: initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..183c24a --- /dev/null +++ b/.gitignore @@ -0,0 +1,148 @@ + +# Created by https://www.gitignore.io/api/python,visualstudiocode +# Edit at https://www.gitignore.io/?templates=python,visualstudiocode + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history + +# End of https://www.gitignore.io/api/python,visualstudiocode + +### Micropy Cli ### +.micropy/ +!micropy.json +!src/libcredentials.py +credentials.py diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..aaf8a5f --- /dev/null +++ b/.pylintrc @@ -0,0 +1,22 @@ +[MASTER] +# Loaded Stubs: esp8266-micropython-1.11.0 +init-hook='import sys;sys.path[1:1]=["src/lib",".micropy/BradenM-micropy-stubs-c89b5ef/frozen", ".micropy/BradenM-micropy-stubs-e1b8ce6/frozen", ".micropy/BradenM-micropy-stubs-c89b5ef/stubs", ".micropy/uc-wifi-tx-udp", ]' + +[MESSAGES CONTROL] +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". + +disable = missing-docstring, line-too-long, trailing-newlines, broad-except, logging-format-interpolation, invalid-name, empty-docstring, + no-method-argument, assignment-from-no-return, too-many-function-args, unexpected-keyword-arg + # the 2nd line deals with the limited information in the generated stubs. diff --git a/README.py b/README.py new file mode 100644 index 0000000..e1fb3f4 --- /dev/null +++ b/README.py @@ -0,0 +1,3 @@ +# uc-wifi-tx-udp + +esp8266 with buttons, send commands via udp diff --git a/dev-requirements.txt b/dev-requirements.txt new file mode 100644 index 0000000..0e59408 --- /dev/null +++ b/dev-requirements.txt @@ -0,0 +1 @@ +micropy-cli diff --git a/micropy.json b/micropy.json new file mode 100644 index 0000000..99f09be --- /dev/null +++ b/micropy.json @@ -0,0 +1,14 @@ +{ + "name": "uc-wifi-tx-udp", + "stubs": { + "esp8266-micropython-1.11.0": "1.2.0" + }, + "dev-packages": { + "micropy-cli": "*" + }, + "packages": {}, + "config": { + "vscode": true, + "pylint": true + } +} diff --git a/pymakr.conf b/pymakr.conf new file mode 100644 index 0000000..f54d47b --- /dev/null +++ b/pymakr.conf @@ -0,0 +1,21 @@ +{ + "address": "/dev/ttyUSB1", + "username": "micro", + "password": "python", + "sync_folder": "src", + "open_on_start": true, + "safe_boot_on_upload": false, + "py_ignore": [ + "pymakr.conf", + ".vscode", + ".gitignore", + ".git", + "project.pymakr", + "env", + "venv", + ".python-version", + ".micropy/", + "micropy.json" + ], + "fast_upload": false +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/boot.py b/src/boot.py new file mode 100644 index 0000000..a328c7a --- /dev/null +++ b/src/boot.py @@ -0,0 +1 @@ +# boot.py - - runs on boot-up \ No newline at end of file diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..4cea0b1 --- /dev/null +++ b/src/main.py @@ -0,0 +1,75 @@ +# main.py +import machine +import socket +from time import sleep +from wifi import WifiSTA + + +## Pins +PIN_UP = 14 # D5 +PIN_LE = 12 # D6 +PIN_RI = 13 # D7 +# PIN_DN = 16 # D0 - does not support pull +PIN_DN = 2 # D4 +PIN_B1 = 0 # D2 +PIN_B2 = 4 # D3 +## Delay +DELAY_CMD = 0.1 +## HOST +RX_ADDR = ("192.168.11.220", 80) +# RX_ADDR = ("192.168.0.1", 80) + +ts_cmd = 0 +s = None + +def handle_btn_up(pin): + send_cmd("fwd") + +def handle_btn_dn(pin): + send_cmd("rev") + +def handle_btn_le(pin): + send_cmd("left") + +def handle_btn_ri(pin): + send_cmd("right") + +def handle_btn_b1(pin): + send_cmd("b1") + +def handle_btn_b2(pin): + send_cmd("b2") + +def send_cmd(cmd): + print("cmd: {}".format(cmd)) + global s, ts_cmd + # if time.time() > (ts_cmd + DELAY_CMD): + # ts_cmd = time.time() + try: + s.sendto(cmd.encode(), RX_ADDR) + except Exception as ex: + print("Exception Type:{}, args: {}".format(type(ex).__name__, ex.args)) + +def main(): + global s + wifiSTA = WifiSTA() + ## initialize buttons and IRQs + btn_up = machine.Pin(PIN_UP, machine.Pin.IN, machine.Pin.PULL_UP) + btn_up.irq(trigger=machine.Pin.IRQ_FALLING, handler=handle_btn_up) + btn_dn = machine.Pin(PIN_DN, machine.Pin.IN, machine.Pin.PULL_UP) + btn_dn.irq(trigger=machine.Pin.IRQ_FALLING, handler=handle_btn_dn) + btn_le = machine.Pin(PIN_LE, machine.Pin.IN, machine.Pin.PULL_UP) + btn_le.irq(trigger=machine.Pin.IRQ_FALLING, handler=handle_btn_le) + btn_ri = machine.Pin(PIN_RI, machine.Pin.IN, machine.Pin.PULL_UP) + btn_ri.irq(trigger=machine.Pin.IRQ_FALLING, handler=handle_btn_ri) + btn_b1 = machine.Pin(PIN_B1, machine.Pin.IN, machine.Pin.PULL_UP) + btn_b1.irq(trigger=machine.Pin.IRQ_FALLING, handler=handle_btn_b1) + btn_b2 = machine.Pin(PIN_B2, machine.Pin.IN, machine.Pin.PULL_UP) + btn_b2.irq(trigger=machine.Pin.IRQ_FALLING, handler=handle_btn_b2) + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + while True: + sleep(0.01) + +if __name__ == "__main__": + main() diff --git a/src/wifi.py b/src/wifi.py new file mode 100644 index 0000000..b7c8d66 --- /dev/null +++ b/src/wifi.py @@ -0,0 +1,43 @@ +from credentials import * +import network +import time + +address = "192.168.0.1" +netmask = "255.255.255.0" +gateway = "192.168.0.1" +dns = "192.168.0.1" + + +class WifiAP: + def __init__(self): + self.if_ap = network.WLAN(network.AP_IF) + self.if_sta = network.WLAN(network.STA_IF) + self.if_sta.active(False) + self.if_ap.active(True) + self.if_ap.ifconfig([address, netmask, gateway, dns]) + self.if_ap.config(essid=SSID, password=PASS) + print("network config {}".format(self.if_ap.ifconfig())) + +class WifiSTA: + def __init__(self): + self.if_ap = network.WLAN(network.AP_IF) + self.if_sta = network.WLAN(network.STA_IF) + self.if_ap.active(False) + self.if_sta.active(True) + self.if_sta.connect(SSID, PASS) + # self.wifi_thread = threading.Thread(target=self.wifi_thread_fn) + while not self.if_sta.isconnected(): + time.sleep(0.1) + print("network config {}".format(self.if_sta.ifconfig())) + # self.wifi_thread.start() + + # def wifi_thread_fn(self): + # while True: + # if not self.if_sta.isconnected(): + # print("reconnecting...") + # self.if_sta.connect(SSID, PASS) + # while not self.if_sta.isconnected(): + # time.sleep(0.1) + # print("network config {}".format(self.if_sta.ifconfig())) + # else: + # time.sleep(0.1) \ No newline at end of file