jonny999999 / armchair_fw Goto Github PK
View Code? Open in Web Editor NEWFirmware for a homemade automated electric armchair using an esp32 controller on a custom pcb
Home Page: https://pfusch.zone/electric-armchair-v2
Firmware for a homemade automated electric armchair using an esp32 controller on a custom pcb
Home Page: https://pfusch.zone/electric-armchair-v2
custom speed sensors with optical sensor and encoder disk.
The current firmware returns random direction
even though joystick is calibrated recently, the armchair moves slightly / shakes randomly when not touching joystick
joystick
chair adjustment
change parameters of motorctl e.g. max duty, max current...
hardware is prepared for ds18b20 temperature sensors
display stats
config menu
Sometimes when driving in JOYSTICK mode and switching to MENU while driving the armchair did not stop
Even though idleBothMotors() is executed when switching to MENU mode sometimes the motors stay on!
Race condition in control and button task: stick mode still executing while mode already switched
re-arrange delay in modes?
add mutex to wait for finished cycle?
also re-test 10s timeout in motorctl since it logged the error message but did not stop?
Re-evaluate the approach only setting the duty once at mode change in general
Scale coordinates of joystick to have more precision (joystick travel) at slower speeds.
Currently implemented with linear scaling (see below), however this currently results in a weird/unexpected acceleration at the rapid change of scaling.
=> find a better way to scale the coordinates
first tried with exponential scaling: 1c6586c
=> smooth but some some area with almost no output change at start
then linear scaling with switching point: b460a52
=> can be adjusted precisely but the point it switches to the other slope is very hard/noticeable while driving
have a function that represents the desired scaling curve
example: https://www.desmos.com/calculator/cahqdxeshd
since outsourcing code to common/ folder i could not get joystick logging to work
needs testing (mayby sdkconfig was fault?)
workaround: replace LOGD with LOGE in joystick.cpp
needs testing
might be other reason why fans just stayed on once
edit:
could not reproduce, other situation?
when rotating (joystick along x-axis) above a certain duty (stick radius) the inner tire slips always.
which just ruins grass or tires...
While testing V2.2.1 Idling in joystick mode seems unreliable...
Noticed Armchair randomly starting to move without touching the stick several times.
Even though i just calibrated it a few seconds ago.
Already observed that kind of random action for a few seconds while testing, when putting down the stick on the bench.
prevent uncomfortable shaking at change between joystick position enum
especially between forward right and full turn (y=0 <-> y>0)
Also related to #37
as in old firmware project add support for limiting current, hardware already implemented
Needs testing, certainly is difficult to make precise movements after some time (probably massage mode?).
reset to defaults (tested)
or restart armchair?
due to new driver deceleration is slower by default due to otherwise unintended hard braking
when driving forward fast and releasing joystick it takes configured fade time (1,9s) for the motors to brake.
In some situations faster reaction is necessary
when joystick already in other direction than currently fading from:
fade down faster or brake immediately
Added this in 021a366 needs testing though:
issue: moving joystick straight, but it takes some seconds time for right motor to accelerate from 0...
result:
add firmware for reading newly added rotary encoder
Currently the handle function is run extremely fast in task_motorctl all the time
Which causes issues seen in #42
Also noticed the controller is getting quite warm
original char adjustmen electronic broke down 3 time by now
=> replace it with custom control
currently a fix conversion factor is defined to convert adc voltage to battery voltage (due to voltage divider)
armchair_fw/board_single/main/display.cpp
Line 85 in 69a421a
however noticed during discharge test that the low voltage was not very accurate
specifically while charging the display showed 24.8V (3.54V per cell) and the power supply showed 22.4V at 5A
so the factor must be too high or not linear?
=> do tests with voltmeter and lab power supply to optimize that conversion factor
Joystick currently simply defines the target duty.
It might be useful or interesting to test other setting other target units.
current behavior
currently making a hard turn using joystick in any quadrant seems weird / is almost not possible
thus changing to full turn mode (wheels in opposite direction) is usually necessary.
x / y coordinates do not snap to -1
even though the confiured max adc value is reached
apparently snap feature works the wrong way
might also fix weird turning behavior since radius gets calculated correctly?
very annoying bug with motor driver:
sometimes a motor seemingly randomly freezes for a few seconds, then immediately starts at current set duty again - feels very bugged
especially when trying to add angle threshold (snap to 1 / 0) for tighter turn radius so one motor is off while turning
this bug basically occurs every time -> inner motor does not start again after curve
when 1 motor frozen, release joystick so both motors are off, then go again
both motors forward
motor1 duty to 0
motor1 duty positive
==> motor1 freezes / stays off
==> after a few seconds it starts
both motors to 0
both motors forward
==> both motors respond again
- leave duty on in idle
- never switch do idle
- always stay in FWD with some duty on
- reduce max duty to 60%
same issue persists
1 motor gets close to 0 duty while other is on it freezes
Notes/Ideas for improving normal turning behavior
already implemented feature so inner motor is completely off for larger joystick area
can be enabled when #18 is fixed.
see joystick.cpp line 325
noticed that first angle of joystick is not really used (small ratio difference never really used e.g. 1:0.95)
meaning you always move joysitck to 45 Degree immediately when the goal is to slightly adjust direction
=> this results in wasted joystick resolution
EDIT: re-evaluate that - issue only persists at fast speed. when driving slow the detail is required
only at certain radius or speed? issue with sudden transition point
currently when turning the inner tire simply gets slower depending on angle.
idea: when inner tire slows down, also increase outer tire speed.
or think the other way: detect when obviously wanting to drive slow e.g. driving fast on garden then slow parking in shed -> scale differently until at max radius again
if current radius is not 1 duty for overdrive available
if max-duty is configured less then 100% duty for overdrive is available
find a way to somehow dynamically add the access duty to outer tire instead of keeping it at maxDuty * radius
ideas and todo's for improving the chair adjustment are collected here.
Also see noted todo's in chairAdjust.cpp
e.g. parked armchair with cover for days, ON state remains unnoticed
currently armchair switches from active mode (JOYSTICK, HTTP...) to IDLE mode when there is no activity for 5 minutes
board, driver, display, sensors, usb-charger etc. use up power even in IDLE mode
currently joystick min/max value of each axis is currently hardcoded in config
only the jostick center position is auto-calibrated during startup.
noticed that min/max adc values drift every other day... resulting in weird joystick behaivor
e.g. radius never reaches 1 thus drives slow in certain direction
already partially fixed this in 3fa2f17 (fixed random longer movement during shaking)
however there is still too long movement exactly when switching shake modes (move joystick to different quadrant)
problem with joystick resolution / travel
when maxDuty is high you can drive fast but have no precision while driving slow (even though scaling improved that)
when maxDuty is low you can maneuver precisely but have slow max speed
time/speed based maxDuty adjustment
start with low max-duty to generate motor commands
when at 100% for long time OR certain speed? Increase max duty
sport mode ignores this
due to separate boards
changes in configuration of motorctl have to be sent via uart to the motorctl board
the controlledmotor objects are no longer accessable directly thus certain features were disabled and need rework
prevent complete battery discharge in idle when forgetting main switch
Noticed a few times that armchair started driving forward for some time (2-3s) with no user input / no way to stop
after switching from massage to joystick mode
--> test and fix this
Task list for hardware changes
this needs testing
noticed a few times that controller crashes and restarts
maybe when releasing the joystick very quickly
When using hardware-text scrolling, which was introduced in screensaver status-screen in 3514dd6 and before, a bugged column of pixels scrolls over the entire display.
Most likely issue using a 132 pixel display with 128 library (reason of OFFSET_X = 2 is neccesary).
not enough gpio pins available
-> second pcb?
Currently one mosfet controlling a relay for chair-adjust is on by default on startup or flashing until the chair-adjust is initialized. (GPIO15)
strapping pin
https://esp32.com/viewtopic.php?t=297
https://electronics.stackexchange.com/questions/622750/esp32-boot-strapping-pins-problem-gpio15-and-gpio5
new features might break the old 2 board approach.
Listing issues here that need to be patched in case two board approach is re-used
Compatible until tag V2.1
when driving a slight turn at medium speed (r=0.5), then moving the stick back to Y to drive straight while keeping the radius approx 0.5 the duty jumps for about 10% which is noticeable with low accel limit
issue with axis-tolerance snapping? thus ratio instantly changes
log when moving the joystick from slight right of y-axis to Y-axis while keeping radius
W (166371) joystickCommands: left=17.67, right=0.51 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166421) joystickCommands: left=17.27, right=0.81 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166471) joystickCommands: left=16.94, right=1.35 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166521) joystickCommands: left=16.99, right=1.85 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166571) joystickCommands: left=17.05, right=2.13 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166621) joystickCommands: left=16.59, right=2.48 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166671) joystickCommands: left=16.17, right=2.75 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166721) joystickCommands: left=15.92, right=2.91 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166771) joystickCommands: left=15.15, right=3.32 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166821) joystickCommands: left=14.36, right=3.80 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166871) joystickCommands: left=13.40, right=4.20 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166921) joystickCommands: left=13.09, right=4.45 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (166971) joystickCommands: left=12.73, right=4.80 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167021) joystickCommands: left=12.01, right=5.49 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167071) joystickCommands: left=11.88, right=5.74 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167121) joystickCommands: left=11.42, right=6.33 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167171) joystickCommands: left=11.16, right=6.70 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167221) joystickCommands: left=10.98, right=7.04 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167271) joystickCommands: left=10.82, right=7.14 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167321) joystickCommands: left=10.33, right=7.75 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167371) joystickCommands: left=10.17, right=7.95 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167421) joystickCommands: left=9.98, right=8.34 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167471) joystickCommands: left=9.73, right=8.74 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167521) joystickCommands: left=9.37, right=9.26 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167571) joystickCommands: left=9.19, right=9.74 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167621) joystickCommands: left=8.97, right=10.14 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167671) joystickCommands: left=8.81, right=10.73 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167721) joystickCommands: left=15.28, right=15.28 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167771) joystickCommands: left=15.54, right=15.54 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167821) joystickCommands: left=15.58, right=15.58 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167871) joystickCommands: left=15.36, right=15.36 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167921) joystickCommands: left=15.61, right=15.61 -- dutyMax=50, dutyBoost=35, dutyOffset=5
W (167971) joystickCommands: left=15.87, right=15.87 -- dutyMax=50, dutyBoost=35, dutyOffset=
slow fade when accelerating
fast fade when turning / changing driving direction
currently when releasing the joystick while moving and immediately moving it again in the same position the motors stop and start ramping up again from 0, this results in weird driving experience
when duty was already higher within the last second, ignore the ramp and set target duty immediately
EDIT: utilize available speed-sensors for that?
When change to objects in HEAP and passing with pointers instead of having global variables was introduced in 2fcf17f i noticed the following:
In MENU mode scrolling in menu turning the encoder fast worked fine, but slowly one tick at a time was not detected at all
while debugging found out disabling motorctl task or increasing the delay in that task helps
while commenting out more code step by step found out the call of motordriver method to set duty in lambda function caused the lag
alloca
in f63d8a3 (branch t_motordriver-in-stack-pointer)
HEAP is significantly slower depending on position? (randomly worked fine once)
calling methods via pointer is (sometimes) less performant than caling them directtly?!
Currently two separate functions are preset for each variable stored persistently in nvs. That results in a significant amount of duplicate code!
Pass string to storage and pointers to default and target value?
currently fans are controlled per motor object
make this a independent task?
individual control must be dropped because now fans are powered with one common pin
currently simply configured same pin, will cause bugs...
It was planned that wifi only starts when changing to HTTP mode (in control.cpp) however wifi_init_client() or wifi_init_ap() fails / crashes the controller with the below error when run from control.cpp.
When run from main.cpp wifi_init and wifi_deinit works totally fine every time for some reason?!
I (11707) control: noting to execute when changing FROM this mode
W (11717) control: switching to http mode -> enabling http and wifi
I (11717) control: init wifi...
assert failed: xQueueSemaphoreTake queue.c:1549 (pxQueue->uxItemSize == 0)
Backtrace:0x40081a5e:0x3ffbd2d00x40088575:0x3ffbd2f0 0x4008f225:0x3ff
...
currently starting wifi every time at startup (never disable) independent of mode...
Display messed up after driving? some time.
see photos:
currently startup takes very long due to ADC-lock aquire error spam.
its probably best to initialize the objects in a function called from main() instead of simply in config.cpp
since it currently happens at unknown time - probably too early at startup thus adc not available yet
slow mode for people that struggle handling the joystick (they just go full radius or nothing)
currently motor duty is checked for change to reset the timeout count
reset timeout when there was any input
reset timeout differently in different modes? e.g.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.