Arduino Nano Cycle Analyst (and other) companion TidBits

amberwolf

Administrator
Staff member
Joined
Aug 17, 2009
Messages
40,767
Location
Phoenix, AZ, USA, Earth, Sol, Local Bubble, Orion
Ok, so I finally went digital, and got a set of three (so blowing one up wont' delay me much) Arduino Nanos here:
https://www.amazon.com/gp/product/B01DLIJQA2?psc=1
(because it was fast and convenient and others here bought other things successfully from them), and have officially started attempting to learn how to use them, instead of designing and building a bunch of analog circuits (which I honestly will probably never get around to) to do the things in this thread:
https://endless-sphere.com/forums/viewtopic.php?f=2&t=92973

Basically the stuff is mostly adjuncts to the Cycle Analyst v3 to make it do things the way I want to, rather than the way it's designed to, by working around the stuff it doesn't do and feeding it misinformation to make it do the other stuff it *would* do if it didnt' require certain inputs differently than how I need them to work. :)

Maybe they'll be useful to someone else, once complete. Right now, they're just ideas, and I'll go borrow code from various projects on the
https://create.arduino.cc/projecthub
or various libraries as I figure out what I need and what might do that, and then hack it all together to do the stuff I need. (the same way I make my bikes ;) )

This shouldn't be that hard, since I sort of knew BASIC on the Vic20 back in the early/mid 1980s, right? :lol: And I vaguely remember assembly on a 6500 (or was that 6800? dont' remember....) from DeVry (same era, few years later). :pancake:

Though...I look at the C# code in various projects and my brain sort of just turns off, so maybe it wont' be as easy as I would like.

Tonight, I officially started my journey...uploaded the Blink example to one and it didn't explode :flame: , so I copy/pasted the blink code 8 more times in the loop and changed the three first and last ones to 300 instead of 1000, and the last to 2000. Now the blink message is appropriate. :lol:


This post
https://endless-sphere.com/forums/viewtopic.php?f=2&t=92973#p1556213 has some good specifics about what I wanted to do at that time, most of which is still the goal.


Next, I'll make separate posts in this thread with the actual "design" and code as I start them, and keep that specific post updated with the latest version of whatever I come up with, while other posts in the thread will stay as discussion / replies / etc (and hopefully participation by all y'all readers, cuz I iz gunna need sum helpz!). I'll also update this post with links to each "unit" / function (each of which may require a separate Nano, they don't hold a lot of code!), and the basic description of what each one is meant to do, etc. I "reserved" the first several posts to hold the first separate units / functions as I come up with them.

I decided to call each of these separate modules a TidBit. :)


Some of the functions below, if the code will all fit in the same Nano, could share the same Nano hardware, since there are enough I/O pins for several functions, and some of them share the same I/O needs. Especially the first four, so far, should all be able to fit in one.

So whereever possible, I am going to give the same variable names and same I/O pin names for those shared functions, so that if the code were just copied/pasted into a single "sketch" it would then be compilable and uploadable as one unit to one Nano...I think. :oops:

Torque PAS cadence-input override, for pure TS operation:
https://endless-sphere.com/forums/viewtopic.php?f=2&t=110497&p=1618937#p1618937

Torque Steering throttle signal splitter
https://endless-sphere.com/forums/viewtopic.php?f=2&t=110497&p=1618938#p1618938

GTFOOTW mode (full power override for emergencies)
https://endless-sphere.com/forums/viewtopic.php?f=2&t=110497&p=1618936#p1618939

Reverse pedalling throttle control for reverse motor operation *or* proportional braking control
https://endless-sphere.com/forums/viewtopic.php?f=2&t=110497&p=1618940#p1618940

Graphical CA Display Adapter
https://endless-sphere.com/forums/viewtopic.php?f=2&t=110497&p=1618941#p1618941
 
Some details on operation were worked out last here, over here:
https://endless-sphere.com/forums/viewtopic.php?f=2&t=92973#p1556213
which I'll edit into this post later.


The first thing I need to do is make something that takes the TDCM BB torque and cadence sensor inputs and feeds them to the CAv3 in a way that allows the CA to operate purely off the torque sensor from a dead stop (presently it requires the cadence sensor to be outputting first)...but also filters out little noises and spikes from the TS so it doesn't accidentally trigger the CA into making the trike take off by itself.

The simplest way to do that is to only start passing the TS signal (or rather, overriding the cadence sensor input with a false signal so the CA thinks it's moving) once the TS signal is above some threshold taht can only happen if I'm actively pushing on the cranks, but not so hard that I am hurting my not-so-healthy joints. Just enough pressure to be sure it's intentional.

Once the speedo signal (probably from the same 3-pole wheel sensor the CA is on, but a separate one if I have to) is above a certain RPM, basically once the trike is definitely moving, then it'll switch over to cadence operation and ignore the torque sensor data. This is because cadence mode works perfectly fine for actual riding once moving...I just can't always startup the trike from a stop, especially on any even small uphill incline, without using a blip of throttle to get moving. And I don't want to use the throttle at all, unless I have to do it as a backup (like for the decreasingly rare times I can't use one leg or the other and thus cant' pedal normally, if at all), because my hands don't always work right either....

It may be simpler (as far as CA settings go) to just use Cadence PAS mode there, and have the TS only input to the Nano, and have the Nano use that signal to create a throttle signal. It could have an autocalibrate mode like on some bikes with TSs that you just keep your feet off the pedals for the first few seconds when you turn it on. (meaning I could press the reset button on the Nano to do this at any time, as well).


An additional part of this unit would determines if I stop pedalling, and immediately cuts the throttle output off from the CA's output, zero delay. This is because it is too dangerous to allow any delay in shutoff in some circumstances, and the CA doesn't always "instantly" shut off output when I cease pedalling. Since the CA *does* instantly stop outputting throttle signal as soon as I rotate pedals backwards a bit, a simple way is to send the CA a reverse-pedal-cadence-sensor output momentarily every time I stop pedalling.

I'm not sure how to better determine (than the CA already does) that I've stopped moving the cranks *instantly*, except perhaps to measure pressure on the torque sensor *and* count cadence pulses, tracking htem over time, and then if they both drop / stop, then shutoff the CA's output. I forget how many poles the TDCM BB has, but the CA doesn't respond instnatly to them (sometimes it takes over a second!) by ceasing throttle output. If it's the number of poles, I am willing to make my own magnet ring and PAS sensor for the Nano to read (the CA is limited to I think the number I'm already using, cant' recall for sure) to get the best resolution reasonable.

If there's a better way to do this, I'm open to ideas. :)

For now, there's no code here, but this is where it will be once I figure any of it out:
Code:
Nothing here yet :(

and here is where the circuit diagrams and wiring instructions will be for wiring up the Nano to the Torque Sensor and Cadence Sensor on the TDCM, and then from the Nano output to the CAv3 PAS connector input. And anything else that's required for that.
 
Another thing I'd like to do is "split" the single throttle output signal from the CAv3 into two separate signals which, modified by code that reads a sensor on the steerer detecting how hard I'm turning and which direction, increase throttle amount on the outboard wheel, and decrease it on the inboard wheel, more the harder the turn is.

I used to do this manually with two separate throttles before I setup the PAS on the trike, and decided I preferred using the PAS to control it all most of the time (except when a leg hurts too much to pedal, or I can't for some other reason). It works very well for sharpening turns and increasing control and agility of the trike, so it's worth the work in creating this.

For the steerer position sensor, I can probably use a cable-operated throttle, with one end of the cable attached to a mounting point on the steerer tube (or more likely the base of the stem), and the other at a COT. Then adjust cable pull so it is half pulled when steering is centered. I'm not sure if there would directly be enough pull with the pulley size the COT comes with, so I might ahve to make a new larger pulley, to accomodate the full potential rotation of the steerer including when sitting flopped over at a stop (so that I can climb off the seat without the bars being in the way). Thus half the COT's voltage would be straight down the road, and more than that would be, say, right turn, and less would be left.

All it has to do is act like a stereo's Balance control, and send proportionally more of whatever throttle signal is coming from the CA to the outboard motor in any turn, and proportionally less to the inboard.

Code for this will go here:
Code:

and schematics/wiring/etc here:
 
Basically this is intended to override the 20MPH speed limit I have the CA setup with, under some unusual specific input condition that I don't have to think about doing, but which means that I am trying to get out of someone's way (like a car changing lanes into my position, etc) and absolutely have to have max power and speed to do it, for however many seconds it takes.

Originally this would have been only if I am at full throttle on both hand throttles at the same time, but I only have a righthand throttle ATM, and there's always the possibility I may only be able to use one hand to operate throttle even if I have two on the trike. So most likely having it so that I am "slamming" the throttle (either or both) to full, from whereever it had been, in a quick enough amount of time that it's obviously not a normal acceleration request. A button would do it but I'd have to think about pushing it and that could waste enough time to keep this from preventing a collision/etc.

Code here:
Code:

Hardware here:
 
Something I'd also love to do is be able to pedal backwards to back up the trike. I'm not sure if this is practical or not simply because backing up will force the freewheels in the system to engage and force the pedals to turn backward on their own, and thus could cause positive feedback and a runaway condition. Of course the ebrakes would shut the motor off still, but better not to get into that kind of situation. ;)

An automated way to shut it off would be to detect torque on the TS while in reversing mode, which would indicate I was trying to *stop* going backwards, and shutoff the motor system.

I've also considered using backwards pedalling for proportional regen braking control (I already have this via brake lever, which is a faster reaction time to use, but there are times my hands don't work like they should, and being able to do it with my feet would be useful then).

Code:
Code:

hardware:
 
This one is less important for me than for various people out there that would love to use the CA...but flat out won't do it because of it's simple two-line alphanumeric character readout. :(

I'd like it because there are many times I have wished I had a different combination of stuff on my screen than the things the CA allows, including often enough some of the things you can ONLY see when you are actually in Setup.

I suspect the latter may not be available; I have not yet checked the list of things the CA outputs via the serial port. But even some stuff it probably doesn't output, such as limit flags, can actually still be displayed, via a little "CA emulator" program. ;) If all of the CA's inputs and outputs are also monitored, then those can also be displayed (as icons or readouts).

Basic idea, not well developed yet:

Arduino variation (probalby have to be a lot bigger than the Nano because of all the functions needed) first does the basic job of the Grin Analogger: it takes serial data stream and parses it into a table of variables. But it also reads various inputs that are paralleled to the CA's external wiring (throttle in and out, brake lever, PAS cadence and torque sensor inputs, temperature input, etc--anything that isn't in that serial data stream or needs faster data acquisition than the stream can provide, if anything is like that) and parses that data into more variables in that table.

The table is stored as a running file in RAM (possibly flash if it's avaialble, or external storage if the module has a card slot), so averages can be tallied for some things, rather than simply always displaying the instantaneous value (which isn't always useful while riding).

The CA emulator has a stored table of all of the user settings in the CA, which are input to it by the user on first startup (or by entering a menu to do this, or if there is no UI onboard then by entering them into the code prior to compiling and sending to the Arduino module). The emulator doesn't really fully emulate what the CA does, since I have no idea what most of that code is. But quite a few things are easy to figure out and calculate based on the known ranges of settings, the actual user settings, the things the CA manual says it does, and what the CA actually shows on screen when various things happen.

The emulator reads the variable table for all the hardwre inputs, and the other relevant data taht came from the serial input. It makes calculations and sets flags or creates numbers based on those, and puts them in more variables in the table.

The display routine reads first a table of stuff the user wants to show on the gauges and icons, as well as which gauges and icons are being used and where they go on the screen. Then it looks for those things in the table of variables and displays those readings as needed, updating the display as they change.

This should be able to include most, probably all, of the data the CA can show on it's screen, including all the limit flags, and all of the watts, amps, volts, speed, etc etc, *as well as* things like the pedal movment monitor, the throttle indicator, and the brake indicator (and can also show the actual values of those things).

The next question is...do these things get displayed directly on that Arduino's screen (there are some nice ones out there), or do they get sent to something like Casainho et. al.'s LCD display using an Open Source Standard? Or does it get written for both?

The idea is to make the display "beautiful"-capable, so that really picky people are willing to go the extra mile of setting it all up so they can use a CA on their bike when they otherwise simply won't because of it's looks.

But it also needs to be able to be waterproof; I haven't looked for a waterproof Arduino unit / display (they dont' have to be one unit together, but that's handier). If possible, having code that can just tell "any" Arduino display to show stuff the way we want would be great...but I expect it doesn't work that way and that the code has to be made for a specific display. Which means there have to be some branches for different displays, if that comes up.

There's also the possibility of sending the data over bluetooth to an android device for display, but that is complicated and problem prone, and requires compatiblity testing with many devices and BT versions and OS versions, etc., and every time OS's update or change anything, the app is useless and has to be rewritten for the OS update, so you can't just set it up, install it, and forget about it. The project has to go on forever and ever to stay useful and compatible. So if someone wants to branch out and do that part, go right ahead. I'll skip that option. :lol:
 
Another thing that would be useful to some is a way to either activate their bike only when they're holding the handlebars, or sitting on the seat, or something that requires their personal proximity.

And/or a way to change modes of the bike so that if they are the one in proximity then it has it's normal power and capabilities, and if they are not, it only works in a "demo" or "low power / speed" mode, so they can safely allow inexperienced riders to try out their bike for whatever reason.

So a nano/etc with something like this
https://www.mouser.com/new/onion/onion-rfid-nfc-board/
whcih has an RFID/NFC antenna and control chip, along with a couple of 100-byte tags, could be used to do either of the above, by placing the tag in a wallet in a fannypack or back pocket, or a glove or wristband, whatever is close enough for that antenna, whereever it is placed on the bike.

There are of course dozens of similar things for the arduino, like these
https://www.mouser.com/Embedded-Solutions/Engineering-Tools/RF-Wireless-Development-Tools/RFID-Transponder-Tools/_/N-90obk?Keyword=arduino&FS=True and many others out there. There's even a ready made bracelet
https://www.mouser.com/ProductDetail/Adafruit/4043/?qs=vLWxofP3U2wrtLAckMeZWQ%3D%3D

LImiting speed or power or whatever can be done by using presets in the CA (which could be locked out from any other activation mode by simply disconnecting the button cable inside the CA case), and having the Nano switch between the presets. How it would know which preset is in use means it has to reset the CA first, wait for it to reboot, then change presets by a toggle signal to the button. Could also be done without having to do that by using the CA's AuxIn and the "three speed switch" mode of preset control, so that it can use a serial-controlled-resistor (digipot) that's attached to the AuxIn of the CA, to change the resistance as needed. Or it could output a PWM signal to an RC filter and directly input an analog voltage into the AuxIn port.

For a bike without any CA, the digipot could be used to attenuate the throttle signal to the controller, limiting how much the throttle can be increased to. (there are other more complex ways to do it, but most of them require opening up the controller and altering it's circuitry, such as to put the digipot in the shunt-to-MCU amplification circuit to allow changing the current limit...but these are beyond the ability or willingness of many people, while the other is only a simple wire splice).


Activating the bike or disabling it can be done by using a simple open-collector transistor (or driver chip) controlled by a digital output pin of the Nano. The open-collector would connect to the ebrake line of the CA, pulling it to ground, disabling the CA's ability to output any throttle.

Alternately it can connect to the throttle signal of a non-CA-using bike, grounding the throttle line and disabling the bike. (the way the old CA2 did things).

More to come as this is worked out.

No hardware/schematic yet.

No code yet
Code:
 
Something that has been wanted by quite a few people is something more complicated than the Torque PAS cadence-input override, for pure TS operation module, that does what the long-unavailable BEAM-TS unit did, which is to take a torque input off the pedal drivetrain and convert it directly into a throttle voltage.

BEAM-TS did it using it's own sensor that rode on the chain on a tensioner. I don't want to develop hardware like that, so all this unit would be is something that autocalibrates to zero on Reset or PowerUp for whatever torque sensor is already on the bike and connected to it. The code will need to be hand-edited by the user before upload to the Nano to put in whichever value ranges are expected for their sensor, with a few "commented out" well-known examples already in it that they can put in (or just uncomment).

I expect this will be a fairly touchy device needing careful coding, since it will need safety cutouts so that sensor drift or failure can't cause a runaway condition. It'll also need a way to detect drift and failures, of which I only have a vague idea for ATM.
 
WHile not really a CycleAnalyst addon, actually a "replacement" for one of it's functions, this may be useful for minimalist ebike setups where no typical display on the handlebars is wanted for whatever reason.

This is inspired by RickInPhoenix's two-LED battery capacity gauge, which blinks them in patterns to indicate levels of capacity remaining.
https://endless-sphere.com/forums/viewtopic.php?f=14&t=110900
When reading it, and thinking "but I won't have time to take from traffic/etc to watch for the blinks", I came up wiht an alternate UI
https://endless-sphere.com/forums/viewtopic.php?f=14&t=110900&p=1625900#p1625812
which would use an RGB LED to indicate capacity by color, fading continuously from violet down the rainbow to red as the battery drains. It would be less precise but more quickly informative at a glance vs something in time-domain, and takes only the space on the bars (or wherever) needed for enough LED surface area to be easily seen.

Since I don't like bright point sources, but would need something daylight visible, that is also not too bright while riding in traffic at night, I'd probably use three PWM'd outputs to drive the R, G, and B of a larger-surface-area LED (array?), perhaps a half inch on a side with a diffuse surface, and an analog input to read a light sensor (photoresistor in a voltage divider?) to dim the LED as ambient light also dims. If no analog input is available, then the photoresistor could control an offset of the base voltage to a transistor that controls the current thru the common connection of the RGB LED(s).

It took me quite a while of poking around a few minutes here and there, but I think I found a usable single-LED RGB unit:
https://www.mouser.com/ProductDetail/Lumex/SML-LX1610RGBW-A?qs=eSEc0Vu%252BM6829Q4s%252BDssNg%3D%3D
though it is almost $9 (plus shipping). It is of course possible to use separate R G and B LEDs to do this, but I would prefer a single already-diffused unit of around a fingernail's surface area, and that is exactly what that LED is. :)
https://www.mouser.com/datasheet/2/244/SML-LX1610RGBW%20A-82809.pdf
SML-LX1610RGBWA.jpg
View attachment SML-LX1610RGBW A-82809.pdf

The code from RickInPhoenix's gauge may be a good start, though he uses the ATtiny85, so I don't know what adaptations would be needed. Jeremy Harris also has one with yet another UI here:
https://endless-sphere.com/forums/viewtopic.php?f=2&t=22675
that may be useful for adaptation.
 
amberwolf said:
Just enough pressure to be sure it's intentional.

Hey amberwolf - thanks for taking this on. I think there may be many people who will benefit from advancing the ways that human input signals/data results in a safer, more intuitive, and enjoyable ride.

I am going to be especially curious to see how the vehicle can be made to safely start the instant torque is applied to the pedals - long before the cranks begin their rotation. Starting under load from a dead start (as when you're pulled up at a red light while pulling a trailer) is a constant use case, and it would be wonderful to find a solution which is both safe *and* effective, other than a manual throttle.

As you said, it's about determining what is "just enough pressure".
 
I'd rather do this with help from someone experienced at Arduino programming, if you know anyone. ;)

I thought about creating an account over on the Arduino forum linked above, and starting a project thread there, but I am not sure after poking around that there is anyone there with this kind of ebike specific experience to understand what I am trying to do. Most of the ebike related projects I could find are primitive at best, or by those with less understanding than I already have of the ideas themselves (though I know nothing of their coding expertise).

But I'm sure eventually I'll figure it out; there's enough projects with similar input or output scenarios that I can likely get code snippets that can be figured out and modified to do what I want, eventually, as long as I first clearly define each stage of operation, which I will begin to do below. (I used to do "Just In Time" manufacturing manuals back in the 90s at Honeywell for assembly lines, so I know how to break stuff down into literal one-step-at-a-time lists; it's just very tedious).


As for usage: As envisioned, it is something that would only work on a trike or other usage scenario where you may have your feet (or hands for a rowbike) resting on the cranks, but not pressing except when actively trying to accelerate.

If it is to be used in situations that require applying pressure while stopped (like stopping on an uphill without using a brake) then this won't work.

It can't be used on stuff where trackstands and the like are expected.

There are other limitations to it's use that aren't coming to mind at the moment.


Determining amount of torque to react to will likely be a per-installation necessity, so each user will have to alter the code slightly to account for this, probably with experimentation to determine final value after seeing readings on teh CA screen in inital testing to get a base value.

Regardless of the way it's done the user will have to at least change some values for TS baseline voltage ranges in the code to match the sensor they're actually using, as there are a number of completely different output schemas in use. It may be possible to create code that could be "preinstalled" but commented out for a number of them, and then the user just uncomments out the section they need to use before sending to the Nano or other Arduino device they'll be using.



There are also (at least) two ways to do implement with the Nano.

The first way uses the Nano to do all the TS stuff and leaves the CA to deal with all the Cadence stuff. The Nano completely intercepts the TS signal from the BB, never sending it to the CA at all, and simply converts it into a throttle signal that goes directly to the controllers in place of the CA's signal *as long as detected speed is zero*, AND *TS output is above XXXX volts*. The CA's throttle signal is passed thru instead when speed is non-zero. This is a bit harder as it requires a power-on reset-to-zero of the sensor reading every time, accepting whatever the present signal is at power on to be zero pedal force. (since there is no UI for the Nano for the user to do any resetting or calibration.) (I will edit this into a step-by-step list later)

Step By Step List:

Variable definitions and I/O list:
--CTO is PWM output, 3 digit decimal number, variable name CTO
--CATI is analog input, 3 digit decimal number, variable name CATI
--TS is analog input, 3 digit decimal number, variable name TS
--TSTV is fixed value 3 digit decimal number, variable name TVTS, set to equal minimum voltage required from TS (minimum force required by rider to activate torque startup mode)
--ROR is binary variable flag output of comparative timer that checks RATE OF RISE (ROR) of TS signal, to eliminate noise spikes and gentle accidental pushes (don't know how to do this)
--SP is digital input, timed counter cleared every 2000ms, incremented from 0 by 1 on each input pulse, variable name SP
--TIMEOUT is binary variable flag output of XXXXXms counter, if exceeded shuts down ACTIVE STATE and returns to IDLE STATE (safety cutoff) (probably a couple of seconds maximum? typically only takes half a second of full throttle to start trike up enough to begin pedalling) May require experimental determination.

IDLE STATE:
--TS below threshold value (TSTV)
--CA throttle in (CATI) is any value
--Nano outputs CATI voltage / PWM equivalent to Controller Throttle Out (CTO)

Idle State Rules:
--If TS < TSTV then CTO = CATI, else goto ACTIVE STATE

ACTIVE STATE:
--TS rises rapidly from user input to just above TSTV
--ROR flag goes to 1 indicating TS input
--Speed sensor (SP) no pulses
--CA throttle in (CATI) is 0.79v (off)
--Nano begins ramping up PWM pulsewidth to Controller Throttle Out (CTO) to increase throttle voltage (ramp rate 5v/s)

Active State Rules:
--As long as TS > than TSTV, and SP = no pulses, ACTIVE STATE continues.
--The greater the positive difference between TS and TSTV, the faster the ramp-up (don't know how to state this as programming rule)
--If PWM of CTO = 4v equivalent, rampup stops (maximum typical throttle input to controllers)
--When SP receives first pulse, rapid rampdown of CTO begins (ramp rate 5v/s)
--If SP receives second pulse during rampdown, CTO is ramped down to CATI (goto IDLE STATE).
--If CATI > CTO, CTO is made equal to CATI (goto IDLE STATE)
--If TIMEOUT = 1, goto IDLE STATE
Rules may not be in the right order. Working that out. ;)

This way requires:
--digital input from speedo signal output
--analog input from TS signal output.
--analog input from CA-output throttle signal
--analog output to throttle signal to controller
--external smoothing hardware for PWM signal above to controller throttle inputs (RC filter, etc)



The second way is easier, and leaves the CA to do what the CA does well, and just bypasses the CA's safety limitation. The TS is not intercepted, just tapped into for a reading. The Nano simply sends a fake constant cadence signal (what amounts to say, 50rpm, whatever the CA is setup to respond maximum to) to the CA in place of the actual signal (which is intercepted) *as long as detected speed is zero* AND *TS output is above XXXX volts*. Real cadence is passed to the CA as soon as speed is non-zero. (I will edit this into a step-by-step list later)

This way requires:
--digital input from speedo signal output
--digital input from cadence signal output
--analog input from TS signal output.
--digital output to CA-cadence signal input






FWIW, one of the reasons I am finally tackling this (and some other semi-related stuff that will end up in this thread) myself is that I can't seem to get anyone else interested in even trying. :( I've discovered over the years that in general those without a disability of a particular type don't comprehend that specific workarounds are needed for each individual user and their specific scenarios. And some don't comprehend *any* disability...or they do, but just don't care. The latter problem is most common in technology people like computer (or other software, but especially UI stuff) programmers and hardware developers, because they have a way they envision things to work, and they just don't give a flying f*** whether anyone else uses things that way or not. Their attitude typically applies to *everything* that actual users have to say about their stuff, whether they're disabled or not. There are *some few* that listen, but not very many, even if the necessary change to make something more versatile was trivial, or even already existed but was disallowed.
 
I echo your sentiments about designers commonly seeing things only through their own eyes. I can always tell the age of the person who designed/programmed a web app, for instance, by simply looking at the default font size. It's not easy to get people to think about how they view the world. (sad face here)

We both know and appreciate the wonders of the CA, and the genius behind it. I think any solution that we can come up might be easier to implement if it somehow acts as a pre-processor to data already being handled by the CA, instead of bypassing the CA and talking directly to the controller. As you said, it's a matter of "fooling" the CA into thinking that either the torque or the PAS signals are something other than would normally be the case.

In an alternate universe, I'd imagine being able to acquire a CA with access to the source code and supporting software tools that would let us come up with 'custom' versions of the CA. After Justin had mercy on my futile efforts to add e-assist to rowbikes (which have no pedals), I'm now the happy beneficiary of using a CA flashed with Grin's "Skateboard" firmware. This device is living proof of the fact that the CA can indeed start a vehicle from a dead start with a single torque input. A second torque signal will slow it down. Yup, it's all about the software.

Unfortunately I'm not the skilled programmer that I wish I were. I do some hacking of Arduino code, but it's mostly cut&paste and tweaking. The good news is that with existing libraries, this approach is often good enough.

I think you've already a great job of breaking this down into several categories/tasks. By making additionally detailed lists, you're making this even more likely to happen. I'll try to help if I can.
 
I broke the list down a lot; Iv'e also placed the below in my previous post:

Step By Step List:

Variable definitions and I/O list:
--CTO is PWM output, 3 digit decimal number, variable name CTO
--CATI is analog input, 3 digit decimal number, variable name CATI
--TS is analog input, 3 digit decimal number, variable name TS
--TSTV is fixed value 3 digit decimal number, variable name TVTS, set to equal minimum voltage required from TS (minimum force required by rider to activate torque startup mode)
--ROR is binary variable flag output of comparative timer that checks RATE OF RISE (ROR) of TS signal, to eliminate noise spikes and gentle accidental pushes (don't know how to do this)
--SP is digital input, timed counter cleared every 2000ms, incremented from 0 by 1 on each input pulse, variable name SP
--TIMEOUT is binary variable flag output of XXXXXms counter, if exceeded shuts down ACTIVE STATE and returns to IDLE STATE (safety cutoff) (probably a couple of seconds maximum? typically only takes half a second of full throttle to start trike up enough to begin pedalling) May require experimental determination.

IDLE STATE:
--TS below threshold value (TSTV)
--CA throttle in (CATI) is any value
--Nano outputs CATI voltage / PWM equivalent to Controller Throttle Out (CTO)

Idle State Rules:
--If TS < TSTV then CTO = CATI, else goto ACTIVE STATE

ACTIVE STATE:
--TS rises rapidly from user input to just above TSTV
--ROR flag goes to 1 indicating TS input
--Speed sensor (SP) no pulses
--CA throttle in (CATI) is 0.79v (off)
--Nano begins ramping up PWM pulsewidth to Controller Throttle Out (CTO) to increase throttle voltage (ramp rate 5v/s)

Active State Rules:
--As long as TS > than TSTV, and SP = no pulses, ACTIVE STATE continues.
--The greater the positive difference between TS and TSTV, the faster the ramp-up (don't know how to state this as programming rule)
--If PWM of CTO = 4v equivalent, rampup stops (maximum typical throttle input to controllers)
--When SP receives first pulse, rapid rampdown of CTO begins (ramp rate 5v/s)
--If SP receives second pulse during rampdown, CTO is ramped down to CATI (goto IDLE STATE).
--If CATI > CTO, CTO is made equal to CATI (goto IDLE STATE)
--If TIMEOUT = 1, goto IDLE STATE
Rules may not be in the right order. Working that out. ;)
 
rowbiker said:
We both know and appreciate the wonders of the CA, and the genius behind it. I think any solution that we can come up might be easier to implement if it somehow acts as a pre-processor to data already being handled by the CA, instead of bypassing the CA and talking directly to the controller. As you said, it's a matter of "fooling" the CA into thinking that either the torque or the PAS signals are something other than would normally be the case.
Yes, this is why I am trying not to "reinvent" the CA, as a number of others have done. I just want to change a bit of it's behaviors, and leverage everythign else that it already does well, to make my trike do what I need it to. And hopefully, in the process, make little pieces that others can adapt to their own special requirements. (because once a thing exists...adapting it just a little bit to something else is not usually very hard).


In an alternate universe, I'd imagine being able to acquire a CA with access to the source code and supporting software tools that would let us come up with 'custom' versions of the CA. After Justin had mercy on my futile efforts to add e-assist to rowbikes (which have no pedals), I'm now the happy beneficiary of using a CA flashed with Grin's "Skateboard" firmware. This device is living proof of the fact that the CA can indeed start a vehicle from a dead start with a single torque input. A second torque signal will slow it down. Yup, it's all about the software.
Yeah, and if I could just slightly change that ESK8 FW, and maybe merge some bits of teh regular CA FW, I'd probably be a really happy camper. ;) But...since that will never happen, and I definitely can't afford to pay Grin for custom CA code (though they'd do it if I could, I'm sure), this thread and project(s) was born. :idea:




Unfortunately I'm not the skilled programmer that I wish I were. I do some hacking of Arduino code, but it's mostly cut&paste and tweaking. The good news is that with existing libraries, this approach is often good enough.
I hope so, because I don't know C# at all, just the basics of BASIC programming (which are fairly easy to recall while doing this stuff, if not to think in or write in), and the old assembly stuff (whcih I recall scattered remnants of, like using the reference card for commands, and many many hours redoing code because I forgot one little thing...it was terrible!).

I *think* I can cut and paste and hack existing code, having looked thru various projects on that site before I even started this. :) But I don't *really* know what I'm doing. :oops:


I think you've already a great job of breaking this down into several categories/tasks. By making additionally detailed lists, you're making this even more likely to happen. I'll try to help if I can.

I appreciate anything, even if it's just a "whoops check". ;)
 
It's possible that our mutual lack of experience with the actual Arduino code isn't going to be a deal-breaker. Getting to the correct syntax may require some effort, but I know people who are fluent in Arduino code and would be willing to provide help. They just don't know as much about ebike propulsion needs as you do.

I think the next step might be to write 'pseudocode' in whatever generic computer language you feel comfortable with. You can use if/then/else and case statements without regard to syntax technicalities like whether or not line endings require a semicolon or not. You're already well on the way by definining the necessary variables and constants. Make liberal use of comment sections. Once we have the desired behaviors encoded in pseudocode, we can worry about getting it translated into something that will actually run on the microcontroller of our choice -- whether that's going to be an arduino or something else.
 
H'mmmm

A couple of observations.

Lose the decimal numbers. Use integers instead. Integer math is a whole lot faster. Your analog ins and outs are going to be limited to integer values between 0 and 255 anyway (10 bits for ADC and 8 bits for PWM).

EDIT: I should have mentioned that the last 2 bits of the ADC are likely noise.

You speedo and PAS cadence inputs are simple digital pulse trains. You will most likely want a interrupt service routine to count them. First thing to do is determine the signal level. You might be able to do that with a multimeter but it might require a scope. Next you need a ballpark range for the rate. That is simple math. A cadence of 60 with 10 PAS magnets is going to get you 600 pulses a minute or 10 pulses per second (relative slow by MPU terms). The bigger question is what is the duration of each pulse? You will need that so that you can mimic the output pulse trains. That is where a scope would be helpful.

https://youtu.be/44XWCoWICEg or Google "DIY arduino Nano Oscilloscope"

Same thing for the speedo input.

Outputting a digital pulse trains should be fairly simple once you figure out the level and rate. It is a good use for a timer service routine. Set up a relative higher rate (say 100-200 times per second). For each pulse train you need two global variables:
1 ) Counter: the current number passes through the timer routine
2 ) Limit: number of passes between each pulse.
For each pass and each train you:
1 ) increment the counter
2 ) compare it to the limit
3 ) if the counter is greater than the limit then
fire a pulse
reset the counter to zero
else do nothing

Assuming that your analog signals are less than 5 volts dc, reading the ADC is fairly simple. You just need to determine how often you want read it. However if the voltage is TOO low than then you may need a opamp or transistor to boost it. You can stick that in the timer routine as well. Store the result in a global variable.

In your main loop you read the variables and take whatever action is required.

You will also likely need some 'electronic glue' to adjust the input and output levels to match those of the existing signals. That is the difficult part for me because I do not understand the electronics. Also the 'reference voltage' for analog inputs can be a source of problems depending on the power supply. In theory you can use the internal reference or Nano's 5V regulator but if either turns out to be 'flakey' then you might want to consider voltage regulator or zener to stabilize it.

I would start with getting the inputs to working.
 
First, thank you very much for the post; some little bits of this I am reminded of vaguely from way way way back.

Like interrupts...I have one of those named Kirin laying on my legs, activating whenever I get to typing very long or what she thinks is just staring at the screen. :) And another, Yogi, across the room that has a void interrupt check in his tummy quite often.

Inline some questions and some explanations (that made me realize I need to be a lot more specific in my breakdowns / pseudocode and comments):

LewTwo said:
Lose the decimal numbers. Use integers instead. Integer math is a whole lot faster. Your analog ins and outs are going to be limited to integer values between 0 and 255 anyway (10 bits for ADC and 8 bits for PWM).
OK, I guess it doesn't really matter if they are decimals in the program, as long as the end result on the output comes out right. I guess I was thinking about it from the point of view that the voltages would be in the 0.00 to 5.00 range, with it being pretty important to have at least that many decimal places, as the behavior can be different from a 0.01v difference, sometimes. I don't know if rounding errors will matter in this application.

EDIT: I should have mentioned that the last 2 bits of the ADC are likely noise.
ADC noise...yes, I recall some stuff about that, some are better than ohters; these are rpobably low-end, and there's probably going to be electrical noise in the system from motor operation (especially since at startup from a stop the system will be seeing the highest currents it ever does).

2 bits of 10 is....I forget how to figure out what percentage of the total that is. the last 2 bits means up to a value of three (four values), and 10 bits means a total value of 1024? So...would that be 4 / 1024 = 0.004% error? Yeah, me and math...we dont' get along so well. :oops: Isn't this why we made computers in the first place?


You speedo and PAS cadence inputs are simple digital pulse trains. You will most likely want a interrupt service routine to count them. First thing to do is determine the signal level. You might be able to do that with a multimeter but it might require a scope.
Thankfully I have one, though basic, an old "portable" Hitachi. But I am also working on setting up an android device as a single-channel scope via it's headphone jack, using the Physics Toolbox Suite (or other scope app) that reads the headphone's mic signal. I already have a TRRS cable on order to then build a signal "isolator" of a sort, that will also be able to variably attenuate the signals, so they aren't enough to blow up the mic input. (I used a desktop PC soundcard as a scope ages and ages ago but don't have any of that stuff anymore, so have to start over).

Signal level should be easy--anything between 0.00v and 1.00v is a zero, and anything above 4.00v is a one. I'll have to verify this to be completely sure, but it should be true. It also shouldn't matter with the digital input anyway, right? and both of those signals would be pretty low speed, so unlikely to have to worry about ramping / rise or fall times.

Next you need a ballpark range for the rate. That is simple math. A cadence of 60 with 10 PAS magnets is going to get you 600 pulses a minute or 10 pulses per second (relative slow by MPU terms). The bigger question is what is the duration of each pulse? You will need that so that you can mimic the output pulse trains. That is where a scope would be helpful.
The rate for the cadence sounds close, but I think the THUN sensor uses 12 magnets. My present speedo signal to the CA uses three magnets on a 26" wheel. But on that one all I really need to know is if the wheel is moving at all, because if it is then the torque-override isn't needed anymore and it can go back to IDLE STATE. So if it gets any pulse from the speedo (pretty short duration, probably a few ms to a few dozen at most), it can begin winding down the output. I suppose since there's three, it can start that after two pulses instead.

I don't need to mimic the speedo, since it's only an input, but you're right that I do need to mimic the cadence signal. I guess I was simply thinking that I'd have the program just force the output to "track" the input whenever in IDLE STATE, but hadn't considered how to construct the output from scratch for the ACTIVE STATE. :oops:

And here I was thinking it had just started to look like a simpler task than I had first thought.

And you just had to bring up math. "Simple math" at that. ;) I was *sure* someone told me there would be no math....



Outputting a digital pulse trains should be fairly simple once you figure out the level and rate. It is a good use for a timer service routine. Set up a relative higher rate (say 100-200 times per second). For each pulse train you need two global variables:
1 ) Counter: the current number passes through the timer routine
2 ) Limit: number of passes between each pulse.
For each pass and each train you:
1 ) increment the counter
2 ) compare it to the limit
3 ) if the counter is greater than the limit then
fire a pulse
reset the counter to zero
else do nothing

Assuming that your analog signals are less than 5 volts dc, reading the ADC is fairly simple. You just need to determine how often you want read it. However if the voltage is TOO low than then you may need a opamp or transistor to boost it. You can stick that in the timer routine as well. Store the result in a global variable.

In your main loop you read the variables and take whatever action is required.
THat is all very valuable. :) Now I will have to let my brain soak all this up so I can then sit down and "pseudocode" what I need things to do in more detail.


You will also likely need some 'electronic glue' to adjust the input and output levels to match those of the existing signals. That is the difficult part for me because I do not understand the electronics.
If you mean the digital signals...those should just work as regular 0v off and 5v on signals. "TTL-level", we used to call it. :) So the Nano outputs should be able to directly connect to the CA's inputs.

The analog signals, at least on the output side, are going to require at least an RC low-pass filter to convert the PWM into a "DC" voltage, since AFAICT there isn't an actual analog out on the Nano. If there was an analog out, that could also *probably* just connect to the necessary places in the bike's devices directly. Might be safer to use an op-amp between them...but building external circuits requiring more than a couple of strung-together passive components will probably need a PCB and support circuitry, and I'm trying to avoid any of that. ;) I don't want to have the Nano be the cheapest part of this...I'd prefer that it is the most expensive. :lol:


Also the 'reference voltage' for analog inputs can be a source of problems depending on the power supply. In theory you can use the internal reference or Nano's 5V regulator but if either turns out to be 'flakey' then you might want to consider voltage regulator or zener to stabilize it.
The power supply for the Nano is, if I have a spare that works on the traction battery's empty to full range, just a typical phone/etc USB "charger", with the AC input wires connected to the main battery whenever the trike is powered on, and the 5V USB output connected to the Nano's USB port. If I don't have one that will work, I'll get one of the tiny 100VDCin, 5VDCout boards for a couple bucks.

The power supply for the cadence and torque sensors is from the Cycle Analyst, which should be steady enough, but I guess I'll need to verify that, too.

All of these will share a common ground, which I hope will simplify things, but I already have plenty of experience with systems where common ground is anything but, as far as the signals picked up on it and referenced to it are concerned. :roll:

However, the Nano is so small, I am *hoping* to fit it inside the CA's case itself. That will greatly minimize all wiring runs and induced signal problems, since all the signals it needs are right there on the CA PCB edge pads. :)

I have a whole spare CA and THUN sensor as well, which I plan to be the first guinea pigs for the project rather than trying it on the actual trike (until it's at least past the first beta stage!).


I would start with getting the inputs to working.
This sounds like a good plan. Without any outputs, though, how will I know when the input side is working, since the Nano has no display or anything (well, there is one LED that can be controlled; I guess I could put a temporary "blink this if" thing in the output parts?).
 
rowbiker said:
It's possible that our mutual lack of experience with the actual Arduino code isn't going to be a deal-breaker. Getting to the correct syntax may require some effort, but I know people who are fluent in Arduino code and would be willing to provide help. They just don't know as much about ebike propulsion needs as you do.

I think the next step might be to write 'pseudocode' in whatever generic computer language you feel comfortable with. You can use if/then/else and case statements without regard to syntax technicalities like whether or not line endings require a semicolon or not. You're already well on the way by definining the necessary variables and constants. Make liberal use of comment sections. Once we have the desired behaviors encoded in pseudocode, we can worry about getting it translated into something that will actually run on the microcontroller of our choice -- whether that's going to be an arduino or something else.
This sounds like a workable plan. :) I'm going to ponder on LewTwo's info until my brain begins telling me things and then I'll start writing them up. Might be a few days, but hopefully I'll have something more tomorrow night (depends mostly on how exhausted I get from my dayjob).
 
Looks like this is shaping up nicely now that you have a clear idea of how you want it to behave with different inputs and outputs.

amberwolf said:
This sounds like a good plan. Without any outputs, though, how will I know when the input side is working, since the Nano has no display or anything (well, there is one LED that can be controlled; I guess I could put a temporary "blink this if" thing in the output parts?).

Check out the AnalogReadSerial or DigitalReadSerial example arduino sketches. Most (all?) arduino boards can send serial data through the usb port. So you can insert serial print statements in your code which you can read off through the terminal in the arduino IDE.
 
amberwolf said:
The power supply for the cadence and torque sensors is from the Cycle Analyst, which should be steady enough, but I guess I'll need to verify that, too.
Remember that the CA supplies unregulated 10VDC at a very limited current for the PAS and torque input sensors. It's good enough to directly power the pickups I've encountered, including the TDCM bottom bracket.

For the project involving handlebar mounted strain gages to get the torque (rowbike), I needed a tightly regulated 5VDC that was NOT the CA's 5V (although they shared a common ground). I used the 10VDC as the input to a dedicated 5VDC linear regulator to drive that circuitry and it has been working flawlessly. See the PCB at https://erowbike.com/ina#ina_populated_pcb_v100 for more details.

Obviously this will only work if the total current required by your nano "pre-processor" circuit is within the CA's 10VDC output range. Also IIRC, the higher the voltage of the traction pack, the lower the amount of current available from the CA.
 
I like the tree you're barking up, AW.

I am actually not a fan of the CA V3 at all due to throttle lag i've experienced in many setups using it.
I'm not sure if that's a matter of tuning the CA V3 better or an inherent quality of it's programming.
I also want 3 speed switch capability, like the old school infineon clones.. but the CA does not do this easily.

Would love to see what you come up with, and i'm considering learning arduino myself because i'm thinking about building products outside of the EV realm using the ATMegas.

Would much rather program in straight procedural C code than learn ardunio's variant of it though.. perhaps there exists an aftermarket compiler or transpiler.
 
amberwolf said:
......
I would start with getting the inputs to working.
This sounds like a good plan. Without any outputs, though, how will I know when the input side is working, since the Nano has no display or anything (well, there is one LED that can be controlled; I guess I could put a temporary "blink this if" thing in the output parts?).
In the Arduino development IDE the Nano connects to the PC via a terminal window.Just 'print' the results there :D

You will find that the "print" statement (wait I think that they changed it to function a couple of years ago) has the ability to format your 'integer' values to something more like you are expecting (like decimal values between 0 and 5 volts).

Just consider the ADC and PWM to be 8 bits. That means that you will have a resolution on 0-5 volts of about 0.02 volts. I think that should be adequate for your purposes.
(Hint: shift right two bits to convert 10 bit ADC to 8 bit ADC ... drop the noise)


Sorry ... it has been a while since I did any programing (Arduino or otherwise).
Senility starts to set in after a while.
 
amberwolf said:
If you mean the digital signals...those should just work as regular 0v off and 5v on signals. "TTL-level", we used to call it. :) So the Nano outputs should be able to directly connect to the CA's inputs.

I was thinking they (PAS and Speedo) were a magnet passing a pickup coil. I had not thought of them triggering a switch (aka Hall effect transistor). That makes sense considering how the throttles work. That should simply things a bit. In that case duration may be the only gotcha to overcome.
 
Back
Top