Hi fellow tinkerers,
Since i struggled a bit to find answers in this forum i figured I'll upload my lisp script that i used now for 800km (16km of altitude, there are roughly 400m/20km) while commuting. This worked for me to get variable pedal assist level with regen-braking (thumb throttle in rear brake lever). I use the grintech (9c) RH212, a flipsky 75100 pro v2, a 4 wire pas sensor and a 14s 25ah battery from cham rider. I just updated my firmware to the 6.06 version (I think) and the script works fine with it. I hope this helps someone out there, as it would have helped me ;)
Cheers
;this is a combination of the codes from blowman (vesc forum) and ebike builder (youtube). i can only partially take credit for it
;run the vesc esc in the adc app (control type 'Current No ReverseBrake ADC2'). i used a 12 pole 4 wire pas sensor that is connected to rx and tx pins of the uart connection
;the code figures out if pedaling is present and then maps the adc1 to the throttle, this gives a constant torque pas. I removed the spring from a thum throttle which i can now use to set the assistance i like (like suggested by blowman).
;i disassembled a second thumb throttle and put it into the handle of my rear brake. it is connected to adc2, so i can regen brake befor the disc brake engages. when the brake is pulled, assistance is switched off completely. there is a weird threshold of 1.38 V that works well for me. ususally my open brake is at 0.95 V. i suspect noise, or filtering interference...mybe a debounce timer or a state machine could be more elegant here.
;be aware: I really had to beef up my torque arm setup to prevent the axle from wiggling around when switching from forward to regen braking
;backpedaling something like two full rotations switches between legal speed limit and speed-mode. use this responsibly and not on public bike paths and streets opf courxe ;)
;i left some un-commented stuff there that is nice for trouble shooting
(gpio-configure 'pin-rx 'pin-mode-in-pd)
(gpio-configure 'pin-tx 'pin-mode-in-pd)
;config
(define invert 0)
(define pas-timeout-secs 0.25)
(define legal-erpm 5600) ; ca 26km/H with 26 inch tire, 26*1000/60/(0.660*pi)*26
(define speed-erpm 12000) ; 8150: ca 39km/h for speedmode; use profile to set absolute top speed
(define erpm 5600); start in legal mode
;state
(define pas-active 0)
(define brake-active 0)
(define pulses 0) ;positive when pedal forward
(define last-pulse-time (systime))
(define secs-since-pulse 0)
;(define pulses-per-sec 0)
;(define forwards 0) ;1 if pedaling forwards
;(define backwards 0) ;1 if pedaling backwards
;(define stopped 1) ;0 if pedaling forward or backwards, 1 if stopeed
(define rx 0)
(define rx-prev 0)
(define tx 0)
(define tx-prev 0)
;use this to set pas active
(defun set-pas-active (new-pas-active)
(progn
; only run this if value is changing
(if (not-eq pas-active new-pas-active)
(progn
(define pas-active new-pas-active)
(if (eq pas-active 1)
(print "pas active"))
(if (eq pas-active 0)
(progn
(print "pas stop")
(define pulses 0)
; (define pulses-per-sec 0)
)
)
)
)
)
)
(defun set-brake-active (new-brake-active)
(progn
(if (not-eq brake-active new-brake-active)
(progn
(define brake-active new-brake-active)
(if (eq brake-active 1)
(print "brake active"))
(if (eq brake-active 0)
(progn
(print "brake stop")
(define pulses 0)
; (define pulses-per-sec 0)
)
)
)
)
)
)
; called when pas pulse detected
(defun pulse-detected (direction)
(progn
; pas inverted check
(if (eq invert 1)
(if (eq direction 1)
(define direction 0)
)if (eq direction 0)
(define direction 1)
)
(if (eq direction 1) ;forwards
(progn
; (print "pulse-detected: forwards")
(define pulses (+ pulses 1))
(define last-pulse-time (systime))
; (define forwards 1)
; (define backwards 0)
; (define stopped 0)
; check if pas should start
(if (and (eq pas-active 0) (>= pulses 2))
(progn
(set-pas-active 1)
(set-brake-active 0)
)
)
)
);else
(if (eq direction 0)
(progn
; (print "pulse-detected: backwards")
(define pulses (- pulses 1))
(define last-pulse-time (systime))
(set-pas-active 0)
; (define backwards 1)
; (define forwards 0)
; (define stopped 0)
; check if brake should start
(if (and (eq brake-active 0) (<= pulses -40))
(progn
(set-brake-active 1)
(set-pas-active 0)
)
)
))
)
)
;runs in main loop to process pas-state
(defun update-pas-state ()
(progn
(define secs-since-pulse (secs-since last-pulse-time))
(define rx-prev rx) ;save previous rx
(define rx (gpio-read 'pin-rx)) ;update rx
(define tx-prev tx) ;save previous tx
(define tx (gpio-read 'pin-tx)) ;update tx
;logic to invert direction
(define fwd (if (eq invert 1) 1 0))
(define back (if (eq invert 1) 0 1))
;detect rising and falling edges on rx
(if (and (eq rx 1) (eq rx-prev 0)) ;rising edge on rx
(if (eq tx 0)
(pulse-detected fwd)
;else
(pulse-detected back)
)
(if (and (eq rx 0) (eq rx-prev 1))
(if (eq tx 1)
(pulse-detected fwd)
;else
(pulse-detected back)
)
)
)
;pas timeout detection
(if (and (eq pas-active 1) (> secs-since-pulse pas-timeout-secs))
(progn
(print "pas timeout")
(set-pas-active 0)
)
)
;brake timeout detection
(if (and (< pulses -2) (> secs-since-pulse pas-timeout-secs))
(progn
;(print "brake timeout")
(define pulses 0)
(set-brake-active 0)
)
)
)
)
;main loop
(loopwhile t
(progn
(update-pas-state)
(if (and (eq pas-active 1) (<= (get-rpm) erpm) (< (get-adc 2) 1.38)) ;map adc1 to throttle when pedaling, below erpm setpoint and no pulled brake
(app-adc-detach 1 0)
(app-adc-detach 1 2)
)
(if (eq brake-active 1) ;on 'brake-active' switch between legal and speed mode; actual regen brake is activated by adc2
(progn
(if (eq erpm legal-erpm)
(progn
(define erpm speed-erpm)
(print "speed-mode")
(set-brake-active 0)
);else
(progn
(define erpm legal-erpm)
(print "legal-mode")
(set-brake-active 0)
)
)
)
)
(sleep 0.005) ; run at 200Hz
)
)

Hey. I like this idea but I have no experience with coding whatsoever. Can I do this with 3-wire PAS, one throttle for acceleration and one modified throttle for PAS level? I have the PAS now connected to PPM input, throttle at ADC1 and brake at ADC2 and I would like to have both options throttle and PAS level selection.
Hi Valopall,
You can also do this for sure with the 3-wire PAS sensor connected to the PWM input. You'd have to adapt the code to the different input, however. I don't know the encoding of those sensors, but the direction detection will most likely be a bit different.
Regarding the third throttle:
So my code decides on whether to use the input from the throttle in adc1 or not, based on PAS input, ERPM, and ADC2 input. So you can't just use another throttle without changing the code quite a bit. I think your best option would be to use a button or, for the backpedal detection (maybe dangerous if activated accidentally), to switch between PAS level selection and throttle (using the same throttle).
You could add the logic to this main decision:
(if (and (eq pas-active 1) (<= (get-rpm) erpm) (< (get-adc 2) 1.38)) ;map adc1 to throttle when pedaling, below erpm setpoint and no pulled brake (app-adc-detach 1 0) (app-adc-detach 1 2)something like: if PAS or button: use the throttle input...
In any case, you'll probably have to get into coding at least a tiny bit. I am also not very familiar with it, but I think this is a good project to get started with it. Don't be intimidated by it, but be prepared that it will take a few afternoons :p
Hope this helps.
Cheers,
Lukas