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