minor changes
This commit is contained in:
commit
35817c2219
5 changed files with 226 additions and 0 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Geheimorganisation
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
29
README.md
Normal file
29
README.md
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Geheimbadge Firmware
|
||||||
|
This is the Geheimbadge firmware.
|
||||||
|
It wares the Geheimbadge firm.
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
Run `nix-shell` in this repo to enter an environment with all necessary tools.
|
||||||
|
Replace `/dev/ttyACM0` with the correct port for your system.
|
||||||
|
|
||||||
|
### Micropython
|
||||||
|
Download the latest [Firmware Release](https://micropython.org/download/esp32c6/) .bin file.
|
||||||
|
Flash the firmware using [esptool](https://github.com/espressif/esptool).
|
||||||
|
|
||||||
|
```shell
|
||||||
|
esptool.py --chip esp32c6 --port /dev/ttyACM0 erase_flash
|
||||||
|
esptool.py --chip esp32c6 --port /dev/ttyACM0 write_flash -z 0x0 esp32c6-20241129-v1.24.1.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scripts
|
||||||
|
Deployment via [rshell](https://github.com/dhylands/rshell) is recommendet.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
rshell --port /dev/ttyACM0 "cp ./*.py /pyboard"
|
||||||
|
```
|
||||||
|
|
||||||
|
### WiFi Config
|
||||||
|
Copy `sta-template.json` to `sta.json` and edit.
|
||||||
|
```shell
|
||||||
|
rshell --port /dev/ttyACM0 "cp ./sta.json /pyboard"
|
||||||
|
```
|
||||||
47
button.py
Normal file
47
button.py
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
from machine import Pin, Timer
|
||||||
|
from time import ticks_ms
|
||||||
|
|
||||||
|
|
||||||
|
class Button:
|
||||||
|
def __init__(self, pin_num, pull=Pin.PULL_UP, thresholds_ms=[1000, 3000]):
|
||||||
|
self.pin = Pin(pin_num, Pin.IN, pull)
|
||||||
|
self.pin_state = 1 if Pin.PULL_UP else 0
|
||||||
|
self.thresholds_ms = thresholds_ms
|
||||||
|
self.threshold_idx = 0
|
||||||
|
self.timer = Timer()
|
||||||
|
|
||||||
|
self.pin.irq(self._isr)
|
||||||
|
|
||||||
|
def _timer_cb(self, timer):
|
||||||
|
self.threshold_idx += 1
|
||||||
|
if self.threshold_idx < len(self.thresholds_ms):
|
||||||
|
timer.init(
|
||||||
|
period=self.thresholds_ms[self.threshold_idx]
|
||||||
|
- self.thresholds_ms[self.threshold_idx - 1],
|
||||||
|
mode=Timer.ONE_SHOT,
|
||||||
|
callback=self._timer_cb,
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.callback_fn:
|
||||||
|
self.callback_fn(self.pin_state, self.threshold_idx)
|
||||||
|
|
||||||
|
def _isr(self, pin):
|
||||||
|
pin_state = pin()
|
||||||
|
if pin_state != self.pin_state:
|
||||||
|
self.pin_state = pin_state
|
||||||
|
|
||||||
|
if pin_state == 0:
|
||||||
|
self.threshold_idx = 0
|
||||||
|
self.timer.init(
|
||||||
|
period=self.thresholds_ms[self.threshold_idx],
|
||||||
|
mode=Timer.ONE_SHOT,
|
||||||
|
callback=self._timer_cb,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.timer.deinit()
|
||||||
|
|
||||||
|
if self.callback_fn:
|
||||||
|
self.callback_fn(pin_state, self.threshold_idx)
|
||||||
|
|
||||||
|
def callback(self, fn):
|
||||||
|
self.callback_fn = fn
|
||||||
117
main.py
Normal file
117
main.py
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
from machine import Pin, ADC
|
||||||
|
from button import Button
|
||||||
|
from time import sleep, time, sleep_us
|
||||||
|
|
||||||
|
DEAD_ZONE = 0.125
|
||||||
|
TIMEOUT = 10
|
||||||
|
GAMMA = 1
|
||||||
|
DELAY_MIN_US = 500
|
||||||
|
DELAY_MAX_US = 100000
|
||||||
|
|
||||||
|
class Motor:
|
||||||
|
_LUT = [
|
||||||
|
(1, 0, 0, 0),
|
||||||
|
(1, 1, 0, 0),
|
||||||
|
(0, 1, 0, 0),
|
||||||
|
(0, 1, 1, 0),
|
||||||
|
(0, 0, 1, 0),
|
||||||
|
(0, 0, 1, 1),
|
||||||
|
(0, 0, 0, 1),
|
||||||
|
(1, 0, 0, 1),
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, pins, phase=0):
|
||||||
|
self._pins = pins
|
||||||
|
self._phase = phase
|
||||||
|
|
||||||
|
def update_pins(self):
|
||||||
|
pattern = self._LUT[self._phase]
|
||||||
|
for pin, value in zip(self._pins, pattern):
|
||||||
|
pin(value)
|
||||||
|
|
||||||
|
def step(self, dir):
|
||||||
|
dir = 1 if dir > 0 else -1 if dir < 0 else 0
|
||||||
|
self._phase = (self._phase + dir) % len(self._LUT)
|
||||||
|
self.update_pins()
|
||||||
|
|
||||||
|
def inc(self):
|
||||||
|
self.step(1)
|
||||||
|
|
||||||
|
def dec(self):
|
||||||
|
self.step(-1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def phase(self):
|
||||||
|
return self._phase
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
for pin in self._pins:
|
||||||
|
pin(0)
|
||||||
|
|
||||||
|
|
||||||
|
class Joystick:
|
||||||
|
_OFFSET = 30000
|
||||||
|
_RANGE = 2**16
|
||||||
|
|
||||||
|
def __init__(self, adcs):
|
||||||
|
self._adcs = adcs
|
||||||
|
|
||||||
|
def pos(self):
|
||||||
|
return [2 * adc.read_u16() / self._RANGE - 1 for adc in self._adcs]
|
||||||
|
|
||||||
|
|
||||||
|
# motor = Motor([Pin(i, Pin.OUT) for i in range (4)])
|
||||||
|
motors = [Motor([Pin(2 + i + 4 * j, Pin.OUT) for i in range(4)]) for j in range(3)]
|
||||||
|
motor_idx = 3
|
||||||
|
joystick = Joystick([ADC(i) for i in range(2)])
|
||||||
|
rgb_led = [Pin(20 - i, Pin.OUT) for i in range(3)]
|
||||||
|
for led in rgb_led:
|
||||||
|
led(0)
|
||||||
|
|
||||||
|
button = Button(22, thresholds_ms=[1000])
|
||||||
|
|
||||||
|
|
||||||
|
def button_cb(pin_state, threshold):
|
||||||
|
global motor_idx
|
||||||
|
if pin_state == 0 and threshold > 0:
|
||||||
|
motor_idx = (motor_idx + 1) % 4
|
||||||
|
for i in range(len(rgb_led)):
|
||||||
|
rgb_led[i](1 if i == motor_idx or motor_idx == 3 else 0)
|
||||||
|
|
||||||
|
|
||||||
|
button.callback(button_cb)
|
||||||
|
|
||||||
|
for i in range(len(rgb_led)):
|
||||||
|
rgb_led[i](1 if i == motor_idx or motor_idx == 3 else 0)
|
||||||
|
|
||||||
|
for motor in motors:
|
||||||
|
motor.update_pins()
|
||||||
|
|
||||||
|
now = time()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
joystick_pos = joystick.pos()[1]
|
||||||
|
abs_pos = abs(joystick_pos)
|
||||||
|
step_dir =1 if joystick_pos < 0 else -1
|
||||||
|
dir = joystick_pos < 0
|
||||||
|
|
||||||
|
if abs_pos > DEAD_ZONE:
|
||||||
|
print(joystick_pos, abs_pos)
|
||||||
|
now = time()
|
||||||
|
if motor_idx != 3:
|
||||||
|
motors[motor_idx].step(step_dir)
|
||||||
|
else:
|
||||||
|
for motor in motors:
|
||||||
|
motor.step(step_dir)
|
||||||
|
|
||||||
|
normalized = (abs_pos - DEAD_ZONE) / (1-DEAD_ZONE)
|
||||||
|
delay_us = DELAY_MIN_US + (DELAY_MAX_US- DELAY_MIN_US) * (1-normalized**GAMMA)
|
||||||
|
sleep_us(int(delay_us))
|
||||||
|
else:
|
||||||
|
sleep(0.01)
|
||||||
|
|
||||||
|
if time() - now > TIMEOUT:
|
||||||
|
for motor in motors:
|
||||||
|
motor.off()
|
||||||
|
|
||||||
|
# sleep(0.0025)
|
||||||
12
shell.nix
Normal file
12
shell.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
with import <nixpkgs> {} ;
|
||||||
|
|
||||||
|
mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
rshell
|
||||||
|
esptool
|
||||||
|
(python3.withPackages (p: with p;[
|
||||||
|
pyserial
|
||||||
|
black
|
||||||
|
]))
|
||||||
|
];
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue