Kicks Condor

LEECHING AND LINKING IN THE HYPERTEXT KINGDOM

I FIRST DISCOVERED
THE 【TECHS-MECHS】WHO
ARE A CLAN OF SOUTH
OF THE BORDER GUNDAM
BREAKING DOWN
IMMIGRATION FENCES
WITH THEIR
IMPRESSIVE MANOS
MECANICAS

PLUNDER THE ARCHIVES

This page is also on dat.

MOVING ALONG LET'S SEE MY FAVORITE PLACES I NO LONGER LINK TO ANYTHING THATS VERY FAMOUS

philosopher.life, the 'wiki'/'avatar'/'life' of h0p3. serious rabbithole.

indieseek blog, bumped into brad somehow and we crosstalk a ton about the web.

linkport by joe jenett---blogs at i.webthings.

an eye on: ᛝ ᛝ ᛝ — lucid. whimsy.space, caesar naples.

indieweb: .xyz, eli, c.rwr, boffosocko.

nostalgia: geocities.institute, bad cmd.

true hackers: ccc.de, fffff.at, voja antonić, cnlohr, esoteric.codes.

chips: zeptobars, scargill, 41j.

dwm, julia, tridactyl these are things you'll want on linux.

neil c very famous but should be a world icon.

the world or cate le bon you pick.

sammyclassicsonicfan the original teen rage adventure.

innovation.isotropic.org probly the best carl chudyk game.

and opinionated gamers for non-chudyk game analysis.

my twitter. my github. minor things.

#code

I use three main tags on this blog:

  • hypertext: linking, the Web, the future of it all.

  • garage: art and creation, tinkering, zines and books, kind of a junk drawer—sorry!

  • elementary: schooling for young kids.

14 Dec 2018

LOGO as LEGOs

Building three-dimensional voxel-type pottery and maps with Python.

Need to investigate this further for my students—a language for writing LEGO-building algorithms, perhaps inspired by LOGO. There is a real need for more modern tiny languages (and One-Line Languages) that give children a taste of novel, playful creation. (Not the impractical abominations that code.org and such have given us.)

Seems like a dozen fascinating project could spring from this one. Are there similar projects that produce Paint 3D-style output?

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

17 Nov 2018

One-Line Languages

It’s more common to converse with a computer than to just dictate our instructions to it.

I’ve been helping a friend with a Discord bot, which has opened my eyes to the explosion of chatbots in recent years. Yes, there are the really lame chatbots, usually AI-driven—I searched for “lame chatbots” and was guided to chatbot.fail, but there’s also the spoof ‘Erwin’s Grumpy Cat’ on eeerik.com.

Erwin's Grumpy Cat

We’ve also quietly seen widespread use of sweet IRC-style bots, such as Slack or Twitch or Discord bots. These act like incredibly niche search engines, in a way. My friend’s own bot is for a game—looking up stats, storing screenshots, sifting through game logs and such.

So, yeah, we are using a lot of ‘one-line languages’—you can use words like ‘queries’ or ‘commands’ or whatever—but search terms aren’t really a command and something called a ‘query’ can be much more than a single line—think of ‘advanced search’ pages that provide all kinds of buttons and boxes.


Almost everything has a one-line language of some kind:

  • Sites like Facebook, Twitter, Wikipedia and YouTube all have search boxes on nearly all of their pages—a single line interface for querying the entire text. (Even general services like text messaging and e-mail have this prominently in their interface.)
  • Issuing short commands to voice-recognition machines like Alexa and Siri.
  • UNIX tools usually act individually.
  • Spreadsheet math done in the fx bar.
  • The browser address bar.
  • One of my favorites is Pinboard’s URLs, which can be used to find related things using whatever ingenuity you can muster.
  • Microwave cook commands.

Humans push the limits of these simple tools—think of hashtags, which added categorical querying to otherwise bland search engines. Or @-mentions, which allow user queries on top of that. (Similar to early-Web words, such as ‘warez’ and ‘pr0n’ that allowed queries to circumvent filtering for a time.)

It’s very interesting to me that misspellings and symbolic characters became a source of innovation in the limited world of one-liners. (Perhaps similar to micro.blog’s use of tagmoji.)


It seems that these ‘languages’ are designed to approach the material—the text, the tags, the animated GIFs—in the most succinct way.

I wonder, though, if ‘search’ is the most impotent form of the one-liner. It’s clearly the most accessible on the surface: it has no ‘commands’, you just run a few searches and figure out which ‘commands’ work until they succeed. (If they do?)

Feeling Lucky BBS

It also seems relevant that less than 1% of Google traffic uses the I’m Feeling Lucky button. Is this an indication that people are happy to have the raw data? Is it mistrust? Is this just a desire to just have more? Well, yeah, that’s for sure. We seem to make the trade of options over time.[1]

Observations:

  • The more generic the data (the Web as a whole vs. a creepypasta chat), the more generic the language seems to be.
  • Could the Web be viewed as something other than a giant container that we have to randomly access?
  • For example, many chatbots work like a conversation—they have a memory, such as for storing quotes/memes, and they can be used as Bayesian filters (for kicking spammers).
  • Is it possible to build a meta-bot that uses all the niche bots?
  • What one-line language could be extrapolated from micro.blog or Pinboard?
  • To what degree can cars, Christmas tree lights, video splicing, disc jockeying, playing video games—be driven by one-liners?
  • What would it take to get to two lines?

Some sites—such as yubnub and goosh—play with this, as do most browsers, which let you add various shortcut prefixes.


Oh, one other MAJOR point about chatbots—there is definitely something performative about using a chatbot. Using a Discord chatbot is a helluva lot more fun than using Google. And part of it is that people are often doing it together—idly pulling up conversation pieces and surprising bot responses.

Part of the lameness of chatbots isn’t just the AI. I think it’s also being alone with the bot. It feels pointless.

I think that’s why we tend to anthropomorphize the ‘one-line language’ once we’re using it as a group—it is a medium between us at that point and I think we want to identify it as another being in the group. (Even in chats, like Minecraft, where responses don’t come from a particular name—the voice of the response has an omniscience and a memory.)


  1. It’s also amusing that Google keeps the button—despite the fact that it apparently loses them money. Another related footnote: the variations on I’m Feeling Lucky that Google has had in the past. Almost like a directory attached to a search. ↩︎

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

02 Oct 2018

Taming Outlandish TiddlyWikis

A prototype for the time being.

I’m sorry to be very ‘projecty’ today—I will get back to linking and surfing straightway. But, first, I need to share a prototype that I’ve been working on.

Our friend h0p3[1] has now filled his personal, public TiddlyWiki to the brim—a whopping 21 MEGAbyte file full of, oh, words. Phrases. Dark-triadic memetic, for instance. And I’m not eager for him to abandon this wiki to another system—and I’m not sure he can.

So, I’ve fashioned a doorway.

This is not a permanent mirror yet. Please don’t link to it.

Screenshot of the h0p3 archive page.

Yes, there is also an archive page. I took these from his Github repo, which appears to go all the way back to the beginning.

Ok, yes, so it does have one other feature: it works with the browser cache. This means that if you load snapshot #623 and then load #624, it will not reload the entire wiki all over again—just the changes. This is because they are both based on the same snapshot (which is #618, to be precise.) So—if you are reading over the course of a month, you should only load the snapshot once.

Snapshots are taken once the changes go beyond 2 MB—though this can be tuned, of course.

  • Total size of the raw archive: 6.2 gigs.
  • Size of my kicksnap’d archive: 736 megs.

Shrunk to 11% of its original size. This is done through the use of judicious diffs (or deltas). The code is in my TiddlyWiki-loader repository.

A Few Lessons I Picked Up

I picked up this project last week and kind of got sucked into it. I tried a number of approaches—both in snapshotting the thing and in loading the HTML.

I ended up with an IFRAME in the end. It was just so much faster to push a 21 MB string through IFRAME’s srcdoc property than to use stuff like innerHTML or parseHTML or all the other strategies.

Also: document.write (and document.open and document.close) seems immensely slow and unreliable. Perhaps I was doing it wrong? (You can look through the commit log on Github to find my old work.)

On the Snapshot Technique

I originally thought I’d settled on splitting the wiki up into ~200 pieces that would be updated with changes each time the wiki gets synchronized. I got a fair bit into the algorithm here (and, again, this can be seen in the commit log—the kicksplit.py script.)

But two-hundred chunks of 21 MB is still 10k per chunk. And usually a single day of edits would result in twenty chunks being updated. This meant a single snapshot would be two megs. In a few days, we’re up to eight megs.

Once I went back to diffs and saw that a single day usually only comprised 20-50k of changes (and that this stayed consistent over the entire life of h0p3’s wiki,) I was convinced. The use of diffs also made it very simple to add an archives page.

In addition, this will help with TiddlyWikis that are shared on the Dat network[2]. Right now, if you have a Dat with a TiddlyWiki in it, it will grow in size just like the 6 gig folder I talked about in the last box. If you use this script, you can be down to a reasonable size. (I also believe I can get this to work directly from TiddlyWiki from inside of Beaker.)

And, so, yeah, here is a dat link you can enjoy: dat://38c211…a3/

I think that’s all that I’ll discuss here, for further technical details (and how to actually use it), see the README. I just want to offer help to my friends out there that are doing this kind of work and encourage anyone else who might be worried that hosting a public TiddlyWiki might drain too much bandwidth.


  1. philosopher.life, dontchakno? I’m not going to type it in for ya. ↩︎

  2. The network used by the Beaker Browser, which is one of my tultywits. ↩︎

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

Fake HTML Includes (for Beaker)

My personal strategy for handling HTML on the distributed Web.

So, HTML is a bit different on the distributed Web (the Dat network which the Beaker Browser uses, IPFS and so on) because your file history sticks around there. Normally on the Web, you upload your new website and it replaces the old one. With all of these other ‘webs’, it’s not that way—you add your new changes on top of the old site.

Things tend to pile up. You’re filing these networks with files. So, with a blog, for instance, there are these concerns:

  • I want common things like headers and footers to be in separate files—because they bloat every one of my pages.
  • I also want them in separate files so that when I change something in my header it doesn’t change EVERY PAGE in my site—pushing lots of changes onto the network.
  • The trend with Dat seems to be that websites are delivered more as applications—where you could potentially access the underlying posts in a format like JSON, rather than just having a raw HTML dump.

Ultimately, I might end up delivering a pure JavaScript site on the Dat network. It seems very efficient to do that actually—this site weighs in at 19 MB normally, but a pure JavaScript version should be around 7 MB (with 5 MB of that being images.)

My interim solution is to mimick HTML includes. My tags look like this:

<link rel="include" href="/includes/header.html">

The code to load these is this:

document.addEventListener('DOMContentLoaded', function() {
  let eles = document.querySelectorAll("link[rel='include']");
  for (let i = 0; i < eles.length; i++) {
    let ele = eles[i];
    let xhr = new XMLHttpRequest()
    xhr.onload = function() {
      let frag = document.createRange().
        createContextualFragment(this.responseText)
      let seq = function () {
        while (frag.children.length > 0) {
          let c = frag.children[0]
          if (c.tagName == "SCRIPT" && c.src) {
            c.onload = seq
            c.onerror = seq
          }
          ele.parentNode.insertBefore(c, ele);
          if (c.onload == seq) {
            break
          }
        }
      }
      seq()
    }
    xhr.open('GET', ele.href);
    xhr.send();
  }
})

You can put this anywhere on the page you want—in the <head> tags, in a script that gets loaded. It will also load any scripts inside the HTML fragment that gets loaded.

This change saved me 4 MB immediately. But, in the long run, the savings are much greater because my whole site doesn’t rebuild when I add a single tag (which shows up in the ‘archives’ box on the left-hand side of this site.)

I would have used ‘HTML imports’—but they aren’t supported by Firefox and are a bit weird for this (because they don’t actally put the HTML inside into the page.)

I am happy to anyone for improvements that can be made to this.

  1. Reply: Strategy: Minimize

    Tim Swast

    Neat idea. My strategy has been to minimize the amount of shared headers and footers. Your method seems much more flexible.

    Took a look at your blog—it’s sweet! I will be sure to include it in my next href hunt. I enjoyed the article about Dat and am interested in finding others who write about practical uses of the ‘dweb’—unfortunately, many of the links on Tara Vancil’s directory are ‘broken’ (perhaps ‘vanished’ is more correct?) and I’m not sure how to discover more.

    At any rate, good to meet you!

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

01 Aug 2018

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

c0d3.attorney

I ran across this site while out link hunting. Since I’m not planning to include software-related links in my directory—since business and software already have many directories—I will post it here. There is a discussion of this site on a blog called esoteric.codes, which has been a second fascinating discovery!

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

24 Jul 2018

The Awesome Directories

Continuing my discussion from Foundations of a Tiny Directory, I discuss the recent trend in ‘awesome’ directories.

All this recent discussion about link directories and one of the biggest innovations was sitting under my nose! The awesome-style directory, which I was reminded of by the Dat Project’s Awesome list.

An “awesome” list is—well, it isn’t described very well on the about page, which simply says: only awesome is awesome. I think the description here is a bit better:

Curated lists of awesome links around a specific topic.

The “awesome” part to me: these independently-managed directories are then brought together into a single, larger directory. Both at the master repo and at stylized versions of the master repo, such as AwesomeSearch.


In a way, there’s nothing more to say. You create a list of links. Make sure they are all awesome. Organize them under subtopics. And, for extra credit, write a sentence about each one.

Dat Project's Awesome

Generally, awesome lists are hosted on Github. They are plain Markdown READMEs. They use h2 and h3 headers for topics; ul tags for the link lists. They are unstyled, reminiscent of a wiki.

This plain presentation is possibly to its benefit—you don’t stare at the directory, you move through it. It’s a conduit, designed to take you to the awesome things.

Hierarchical But Flat in Display

Awesome lists do not use tags; they are hierarchical. But they never nest too deeply. (Take the Testing Frameworks section under the JavaScript awesome list—it has a second level with topics like Frameworks annd Coverage.)

Sometimes the actual ul list of links will go down three or four levels.

But they’ve solved one of the major problems with hierarchical directories: needing to click too much to get down through the levels. The entire list is displayed on a single page. This is great.

Curation Not Collection

The emphasis on “awesome” implies that this is not just a complete directory of the world’s links—just a list of those the editor finds value in. It also means that, in defense of each link, there’s usually a bit of explanatory text for that link. I think this is great too!!

Wiki-Style But Moderated

The reason why most awesome lists use Github is because it allows people to submit links to the directory without having direct access to modify it. To submit, you make a copy of the directory, make your changes, then send back a pull request. The JavaScript awesome list has received 477 pull requests, with 224 approved for inclusion.

So this is starting to seem like a rebirth of the old “expert” pages (on sites like About.com). Except that there is no photo or bio of the expert.

About.com screenshot.

As I’ve been browsing these lists, I’m starting to see that there is a wide variety of quality. In fact, one of the worst lists is the master list!! (It’s also the most difficult list to curate.)

I also think the lack of styling can be a detriment to these lists. Compare the Static Web Site awesome list with staticgen.com. The awesome list is definitely easier to scan. But the rich metadata gathered by the StaticGen site can be very helpful! Not the Twitter follower count—that is pointless. But it is interesting to see the popularity, because that can be very helpful sign of the community’s robustness around that software.

Anyway, I’m interested to see how these sites survive linkrot. I have a feeling we’re going to be left with a whole lot of broken awesome lists. But they’ve been very successful in bringing back small, niche directories. So perhaps we can expect some further innovations.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

16 Jul 2018

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

30 Jun 2018

The Rundown on Mentioning

It seems that Indieweb is made of these loosely connected pieces that follow as much of the protocol as they individually want to. While this is supposed to make it approachable—I mean you don’t need to adopt any of it to participate—it can be tough to know how much of it you’re obeying. (The whole thing actually reminds me a lot of HTML itself: elaborate, idealistic, but hellbent on leaving all that behind in order to be practical.)

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

12 Jun 2018

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

02 May 2018

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

01 May 2018

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

The World of JSON Exposed

An incredibly thorough review of JSON specifications and parsers. Fantastic criticism of the RFC, but beyond that: the benchmarking and concise bug hunting here is something every parser project should count themselves lucky to have.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

F.A.T. Lab is Dead

Geez I was really hoping the ending would reveal that they were all dead the whole time. Now we’re going to need to band together, in order to resist this intoxicating urge to deify F.A.T.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

24 Jan 2017

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

31 Jan 2016

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

13 Jan 2016

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

12 Jan 2016

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

08 Jan 2016

Makey Makey No Longer Supports Arduino

While trying to get JoyLabz Makey Makey 1.2 to work with an iPad, I discovered there is no way to reprogram it.

It seems like this information hasn’t been disclosed quite enough as it should: Makey Makey’s version 1.2, produced by JoyLabz, cannot be reprogrammed with the Arduino software. In previous versions, you could customize the firmware — remap the keys, access the AVR chip directly — using an Arduino sketch.

🙌 NOTE: Dedokta on Reddit demonstrates how to make a Makey Makey.

Now, this isn’t necessarily bad: version 1.2 has a very nice way to remap the keys. This page here. You use alligator clips to connect the up and down arrows of the Makey Makey, as well as the left and right arrows, then plug it into the USB port. The remapping page then communicates with the Makey Makey through keyboard events. (See Communication.js.)

This is all very neat, but it might be nice to see warnings on firmware projects like this one that they only support pre-1.2 versions of the Makey Makey. (I realize the page refers to “Sparkfun’s version” but it might not be clear that there are two Makey Makeys floating about—it wasn’t to me.)

UPDATE: The text on the chip of the version 1.2 appears to read: PIC18F25K50. That would be this.

Some Notes About Connecting to iPads

Now, how I came upon this problem was while experimenting with connecting the Makey Makey to an iPad. Instructions for doing this with the pre-1.2 Makey Makey are here in the forums—by one of the creators of the MM.

Observe the iPad jealously guarding its precious battery juices.

With the 1.2 version, it appears that the power draw is too great. I received this message with both an iPad Air and an original iPad Mini.

Obviously a Makey Makey isn’t quite as interesting with an iPad — but I was messing with potentially communicating through a custom app.

Anyway, without being able to recompile the firmware, the iPad seems no longer an option. (The forum post should note this as well, no?)

Interfacing the Sparkfun Makey Makey with Arduino 1.6.7

If you do end up trying to get a pre-1.2 Makey Makey working with the latest Arduino, I ran into many problems just getting the settings right. The github repos for the various Makey Makey firmwares are quite dated.

One of the first problems is getting boards.txt to find my avr compiler. I had this problem both on Linux and Windows. Here’s my boards.txt that finally clicked for me:

############################################################################
menu.cpu=Processor
############################################################################
################################ Makey Makey ###############################
############################################################################
makeymakey.name=SparkFun Makey Makey
makeymakey.build.board=AVR_MAKEYMAKEY
makeymakey.build.vid.0=0x1B4F
makeymakey.build.pid.0=0x2B74
makeymakey.build.vid.1=0x1B4F
makeymakey.build.pid.1=0x2B75
makeymakey.upload.tool=avrdude
makeymakey.upload.protocol=avr109
makeymakey.upload.maximum_size=28672
makeymakey.upload.speed=57600
makeymakey.upload.disable_flushing=true
makeymakey.upload.use_1200bps_touch=true
makeymakey.upload.wait_for_upload_port=true
makeymakey.bootloader.low_fuses=0xFF
makeymakey.bootloader.high_fuses=0xD8
makeymakey.bootloader.extended_fuses=0xF8
makeymakey.bootloader.file=caterina/Caterina-makeymakey.hex
makeymakey.bootloader.unlock_bits=0x3F
makeymakey.bootloader.lock_bits=0x2F
makeymakey.bootloader.tool=avrdude
makeymakey.build.mcu=atmega32u4
makeymakey.build.f_cpu=16000000L
makeymakey.build.vid=0x1B4F
makeymakey.build.pid=0x2B75
makeymakey.build.usb_product="SparkFun Makey Makey"
makeymakey.build.core=arduino
makeymakey.build.variant=MaKeyMaKey
makeymakey.build.extra_flags={build.usb_flags}

I also ended up copying the main Arduino platform.txt straight over.

Debugging this was difficult: arduino-builder was crashing (“panic: invalid memory address”) in create_build_options_map.go. This turned out to be a misspelled “arudino” in boards.txt. I later got null pointer exceptions coming from SerialUploader.java:78 — this was also due to using “arduino:avrdude” instead of just “avrdude” in platforms.txt.

I really need to start taking a look at using Ino to work with sketches instead of the Arduino software.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.

31 Dec 2015

Switching PWM to Another Pin

Sometimes your PWM pin is tied up doing SPI. You can still salvage the PWM timer itself, though.

Right now the spotlight is stolen by lovely chips like the ESP8266 and the BCM2835 (the chip powering the new Raspberry Pi Zero). However, personally, I still find myself spending a lot of time with the ATtiny44a. With 14 pins, it’s not as restrictive as the ATtiny85. Yet it’s still just a sliver of a chip. (And I confess to being a sucker for its numbering.)

My current project involves an RF circuit (the nRF24l01+) and an RGB LED. But the LED needed some of the same pins that the RF module needs. Can I use this chip?

The Rise and Fall of PWM

The LED is controlled using PWM — pulse-width modulation — a technique for creating an analog signal from code. PWM creates a wave — a rise and a fall.

PWM Wave

This involves a hardware timer — you toggle a few settings in the chip and it begins counting. When the timer crosses a certain threshold, it can cut the voltage. Change the threshold (the OCR) and you change the length of the wave. So, basically, if I set the OCR longer, I can get a higher voltage. If I set a lower OCR, I get a lower voltage.

I can have the PWM send voltage to the green pin on my RGB LED. And that pin can be either up at 3V (from the two AA batteries powering the ATtiny44a) or it can be down at zero — or PWM can do about anything in between.

My problem, though, was that the SPI pins — which I use to communicate with the RF chip — overlap my second set of PWM pins.

ATtiny24/44 Pinout

You see — pin 7 has multiple roles. It can be OC1A and it can also be DI. I’m already using its DI mode to communicate with the RF module. The OC1B pin is similarly tied up acting as DO.

I’m already using OC0A and OC0B for my green and blue pins. These pins correspond to TIMER0 — the 8-bit timer used to control those two PWM channels on OC0A and OC0B. To get this timer working, I followed a few steps:

// LED pins
#define  RED_PIN   PA0
#define  GREEN_PIN PB2
#define  BLUE_PIN  PA7

Okay, here are the three pins I want to use. PB2 and PA7 are the TIMER0 pins I was just talking about. I’m going to use another one of the free pins (PA0) for the red pin if I can.

DDRA |= (1<<RED_PIN) | (1<<BLUE_PIN);
DDRB |= (1<<GREEN_PIN);

Obviously I need these pins to be outputs — they are going to be sending out this PWM wave. This code informs the Data Direction Register (DDR) that these pins are outputs. DDRA for PA0 and PA7. DDRB for PB2.

// Configure timer0 for fast PWM on PB2 and PA7.
TCCR0A = 3<<COM0A0 | 3<<COM0B0 // set on compare match, clear at BOTTOM
       | 3<<WGM00; // mode 3: TOP is 0xFF, update at BOTTOM, overflow at MAX
TCCR0B = 0<<WGM02 | 3<<CS00; // Prescaler 0 /64

Alright. Yeah, so these are TIMER0’s PWM settings. We’re turning on mode 3 (fast PWM) and setting the frequency (the line about the prescaler.) I’m not going to go into any detail here. Suffice to say: it’s on.

// Set the green pin to 30% or so.
OCR0A = 0x1F;
// Set the blue pin to almost the max.
OCR0B = 0xFC;

And now I can just use OCR0A and OCR0B to the analog levels I need.

TIMER1, 16-bit is Better, Right?

Most of these AVR chips have multiple timers and the ATtiny44a is no different — TIMER1 is a 16-bit timer with hardware PWM. Somehow I need to use this second timer to power th PWM on my red pin.

I could use software to kind of emulate what the hardware PWM does. Like using delays or something like that. The Make: AVR Programming book mentions using a timer’s interrupt to handcraft a hardware-based PWM.

This is problematic with a 16-bit timer, though. An 8-bit timer maxes out at 255. But a 16-bit timer maxes out at 65535. So it’ll take too long for the timer to overflow. I could lower the prescaler, but — I tried that, it’s still too slow.

Then I stumbled on mode 5. An 8-bit PWM for the 16-bit timer. What I can do is to run the 8-bit PWM on TIMER1 and not hook it up to the actual pin.

// Setup timer1 for handmade PWM on PA0.
TCCR1A = 1<<WGM10; // Fast PWM mode (8-bit)
                   // TOP is 0xFF, update at TOP, overflow at TOP
TCCR1B = 1<<WGM12  // + hi bits
        | 3<<CS10;  // Prescaler /64

Okay, now we have a second PWM that runs at the same speed as our first PWM.

What we’re going to do now is to hijaak the interrupts from TIMER1.

TIMSK1 |= 1<<OCIE1A | 1<<TOIE1;

Good, good. OCIE1A gives us an interrupt that will go off when we hit our threshold — same as OCR0A and OCR0B from earlier.

And TOIE1 supplies an interrupt for when the thing overflows — when it hits 255.

Now we manually change the voltage on the red pin.

ISR(TIM1_COMPA_vect) {
    sbi(PORTA, RED_PIN);
}
ISR(TIM1_OVF_vect) {
    cbi(PORTA, RED_PIN);
}

And we control red. It’s not going to be as fast as pure PWM, but it’s not a software PWM either.

Why Not Use Another Chip?

I probably would have been better off to use the ATtiny2313 (which has PWM channels on separate pins from the SPI used by the RF) but I needed to lower cost as much as possible — 60¢ for the ATtiny44a was just right. This is a project funded by a small afterschool club stipend. I am trying to come up with some alternatives to the Makey Makey — which the kids enjoyed at first, but which alienated at least half of them by the end. So we’re going to play with radio frequencies instead.

I imagine there are better other solutions — probably even for this same chip — but I’m happy with the discovery that the PWM’s interrupts can be messed with. Moving away from Arduino’s analogWrite and toward manipulating registers directly is very freeing — in that I can exploit the chip’s full potential. It does come with the trade off that my code won’t run on another chip without a bunch of renaming — and perhaps rethinking everything.

Whatever the case, understanding the chip’s internals can only help out in the long run.

If you’d like to see the code in its full context, take a look through the Blippydot project.

This post accepts webmentions. Do you have the URL to your post?

You may also leave an anonymous comment. All comments are moderated.