Rather than launch into a laundry list of all the details of what hasn't been blogged, I'm just going to pick up from 'now', since my current project is in a good spot to start documenting things in this format. Along the way I'll probably mention the stuff I've skipped over when it's relevant here.
Speaking of documentation, I did some admin work earlier this year to better manage my own projects and some of the details better. I find that for really small projects maintaining a formal project plan is overkill, even if I use software like SG Project (which is super-speedy-easy to use). This is especially true if I'm just trying to capture some fresh ideas for a possible future project.
Better is simply a few pages of paper with some standard sections that capture the early Gate requirements and decisions, and the subsequent drawings, schematics, and testing details. I can keep a dozen simple projects in a single 2" binder, and if an idea crosses over between projects I can capture it in a block-design section for re-use. The binder also boots instantly, needs no software, patches, or power - so I can get the more fleeting thoughts down quickly. The idea to work this way came partly from David Allen, creator of 'Getting Things Done', or GTD.
This blog fills a slightly different niche - the larger 'why'. While the docs in the binder explain some of the technical 'why', it's missing the narrative in which decisions are made. In reading 'Mars and Me', a blog about the first 1000+ sols of activity of the rovers Spirit and Opportunity, I noticed that the narrative format presents the technical challenges in a way that technical documents can't.
Today I'm working on the software that interprets bytecode, and this bytecode is what will (hopefully) operate a bunch of my projects going forward. The test case is a sun-tracking solar panel array, which was mostly built last fall and this spring. It powers a couple of other projects which I'll describe here in the future.
The bytecode itself is held in Opcode + Parameter pairs, which exist in 32 byte 'Elements'. The first 4 bytes contain scheduling information, the last 28 bytes contain 14 pairs of instructions which are executed sequentially.
Normally elements are organized in 'Pages', which are 32 elements long. This is tidy because each page is then 1KB (1024) bytes long. This doesn't always hold true, especially when talking about the EEPROM inside an AVR chip (the same chips used in 8 bit Arduino boards, usually the 328p). But it's handy for things like I2C memories, like the 32KB (256kbit) EEPROM chips or 256KB FRAM chips.
I wrote up a memory map that basically describes all memories as having the same layout in the lower most bytes:
- The Config;
- Four copies of the config registers, each 64 bytes long. This allows for config backups and different running-configs vs boot-config.
- The Map;
- Four bytes for each config, for flags, versions, etc.
- Four bytes for each of four prime STATE sequence page+element locations and length
- Four bytes for each of eight SUB sequence page+ element locations and length
- Four bytes for each of four STATE log page+element locations and length
- Four bytes for each of four UPLINK buffer locations & length
- Four bytes for each of four DOWNLINK buffer locations & length
- POTC (Power On Test and Checkout) - SEQ0
- RUN (Automated operations) - SEQ1
- MANUAL (for user interaction) - SEQ2
- ERROR (you guessed it) - SEQ3
Given no external inputs the system will start with POTC, then drop into RUN. There is an AUTO/MANUAL switch on the panel, this drops it out of RUN into MANUAL mode so the array won't move on it's own. If any of those states detects an issue preventing safe operations the whole thing drops into ERROR, which again stops any automated motion, and also attempts to communicate status and get new instructions. Each of these prime states have an associated collection of elements (and remember, each element is 14 sequential instructions) with a unique schedule.
The schedule data contains the numbers and flags to represent anything from 'do this once at this date and time' to 'do this every day'. When you consider what a typical day might be like for the array it should be obvious why it's interesting:
- Don't move prior to 9:00am. It's noisy and we don't get any additional power. Basically, sleep.
- Do a communications uplink/downlink to dump the overnight logs and get any pending commands
- Move to 'first position' at 9:00am and start tracking for the rest of the day
- At 8 or 9 pm (or earlier in winter), move to the SAFE position. Again, don't do this too late.
- Once we are in SAFE position, do a comms to dump of the performance data for the day.
- Config for, and enter sleep mode. The array sleeps by multiple naps of 8 seconds each. Every 225 naps (30 minutes) there is the possibility for taking a snapshot of sensor data (ie temperature and position).
This is *just* complicated enough to break my KISS rule (Keep It Simple, Stupid!), but it allows for multiple, possibly different copies of data and code to exist in flash (PROGMEM) or EEPROM in the AVR itself, in external EEPROM, or in external FRAM. I envision the use-cases like so:
- AVR Flash (ie PROGMEM) - the ultimate fall-back version. Simple but reliable.
- AVR EEPROM - there is less space than Flash, but enough to test out new (simple) code.
- EXT EEPROM - cheap 32KB memory on an I2C bus. Lots of space for more complex code and logs.
- EXT FRAM - for under $10: 256KB on the I2C bus. TONS for code, logs, comm buffers, etc.
If you wonder about the wisdom of creating such a complicated system for what normally are fixed-position solar panels, you'd be right. The conventional thinking is that with the low cost of solar panels vs the actuators, electronics, and software to move them, it's cheaper to just buy more fixed-position panels. Generally, it is.
What can mess with that logic are things like local bylaws, available space, installation costs, and in my case, using the system as a test-bed for rover-like software. And if I can create a system for scheduled, autonomous operations that is robust and reliable I can reuse it on many future projects.