Close

commonCode, commonCode, I haven't forgotten ye...

A project log for commonCode (not exclusively for AVRs)

A shit-ton of things that are useful for a shit-ton of projects. (and, Think 'apt-get' for reusable project-code)

eric-hertzEric Hertz 03/06/2016 at 11:380 Comments

commonCode is one of those things I (generally) work on as a side-aspect of other projects...

So, lately, I've been working on my #Big Ol' Modular CNC and various aspects thereof... mostly the motor-control and position-sensing aspects, these days...

The latest is #anaQuad!, which will *definitely* be added as a new 'commonThing' soon. This guy... well, take a really low resolution analog-output optical encoder (like that from a computer's ball-mouse) and bump that resolution *way* up using an ADC. Currently I'm working with a 72-slot encoder-disk and anaQuad's able to resolve a resolution of 1152 positions per revolution, without adding a whole lot more processing-time than a regular-ol' quadrature-decoding algorithm (e.g. 'encoderDirect'). This guy also has the benefit of... if it somehow falls behind the actual motion, as long as it's less than half a slot, it'll eventually "catch up"... so no "invalid quadrature states".

I dig it.

---------------------------------------

I've been working with PIC32's for a bit, now... The *vast majority* of commonCode was developed on AVRs, so I'm coming up with new ways to make the system more 'architecture agnostic', and including those new discoveries in my progress with commonCode.

The latest, I guess, is that there seems to be a sort of "core" bit of code that remains almost completely unchanged, regardless of the architecture. Then there are certain architecture-(and project!)-specific aspects that that 'core' relies on...

E.G. for the 'heartBeat', there's the bit that handles the fading/blinking of the LED, knowing when to switch the pin to an input, waiting for pull-up resistors to overcome capacitances, then reading whether the button is pressed... That's the "core" of the heartBeat code.

Whereas, there's a tiny bit that's architecture/project-specific... E.G. *which* pin is used for the heartbeat...? How is that pin accessed...? (how do you make it an output, set it high or low, for the LED, and then switch it to an input for the pushbutton...?).

I went to a bit of effort to keep some sort of standardization, there, based not only on the switching of pinouts/projects, but also for the switching of architectures *while* keeping it backwards-compatible with old projects... I think I went about that wrong.

Rather'n telling the 'heartBeat' commonThing which *pin* to use, (which gets a bit complicated when switching between MCU's), instead, maybe, tell it *how to access* the pin...

So... heartBeat, now, has a few functions which must be defined specific to the project, something like "heart_setLED(on/off)", "heart_switchToInput()", "heart_readInput()". These guys are *REALLY* simple. heart_setLED(on/off) is basically nothing more than something like if(on) setBit(pinNum, PORT); else clearBit(pinNum, PORT). And, frankly, for the most-part, they can be the same for the vast-majority of projects, especially those on the same architecture.

So... where am I going with this...?

It gets a bit more complicated, e.g. with anaQuad, which makes use of ADCs... Each architecture's ADCs will have a different interface, different registers... so those will have to be set-up prior... So, anaQuad is supplied with a project-specific function for getting the values from the ADC...

OK, so this is where it gets interesting... There's no reason heartBeat's "heart_setLED()" function has to access a *pin*... It could do *anything*... It could, just as well, contain a 'printf()' call, that prints a '.' on a terminal-window when the LED should be off, or a '*' when it's on...

Or, for anaQuad, the "anaQuad_getChannelVal(A/B)" function could just as easily grab a value from a ... webpage... for all it cares.

This makes *testing* really easy... anaQuad's desktop-based test-application just fills the getChannelVal() functions with values from C's built-in sin() function (and a little math). But the *core* of anaQuad is usable on any architecture, from any sinusoidal (or maybe even triangular) source, with a tiny bit of configuration. So.......

I think this is where commonCode is going... Rather'n having several configuration-options, instead have a project-localized configuration file... (which, obviously, can be copied directly from project-to-project, as long as the architecture/pinout doesn't change).

Yeah... I guess this is pretty much the concept behind abstraction, in general... I never tried to claim I don't reinvent the wheel.

Oh, and, since those localized-functions are generally only called *once* within the "core", there's no reason they shouldn't be inlined (and plausibly optimized to nothing more than a single register read/write). So... it should be just-as-fast as my old method. (as opposed to, say, relying on supplying arguments and switching return-values).

Anyways... I haven't forgotten yah, commonCode... "You were always on my mind..."

Discussions