Categories
Projects

Back in the swing of things

I’m not sure how but over the past few months the subscriptions have shot up on my youtube channel. It’s motivated me to get back into making. A young viewer asked if it’s possible to make robot arms so I dusted off the bricks and made a little tutorial.

This is not really one of my arts projects but I’m putting it on the front page just because I’ve been out of the loop for ages and I want to keep busy.

Categories
Blog Code

Designing clean API for AVR round-robin ADC – part 1

softpotSeveral of my recent 8 bit microcontroller projects need multiple analogue inputs. I want a nice API that allows me to have different interfaces for getting analogue values, for example reading a straightforward pot as 0-255 or 0-1023, or a SoftPot membrane potentiometer where I may also want to track whether or not it’s
currently pressed.

adc_simple

Reading analogue inputs on AVR chips takes time and the lazy approach to reading an analogue value is to set up the registers to read a value and simply wait for it to come in.  You do something like this:

    ADMUX |= _BV(MUX0);
    ADMUX |= _BV(ADLAR);
    ADCSRA |= _BV(ADPS1) | _BV(ADPS0) | _BV(ADEN);
    while (ADCSRA & _BV(ADSC));	// !

That while loop is just eating cycles whilst we’re waiting for the ADC to return a result.

adc_interruptThe best way to avoid this wait is to set up the ADC to start reading a value and when it’s ready send an interrupt to get the result.

The interrupt can either use the value immediately or stash it away in a stored value so it can be picked up later on in the main loop.

This approach saves wasting cycles but still has a problem: the ADC can only read one value at a time and I need multiple inputs.

adc_roundrobin

The workaround for this is to make the interrupt run continually and constantly read each ADC value in turn.

The poll requests requests a value for a certain analogue input and when the ADC interrupt is fired off, it re-polls for the next one.  This runs perpetually whilst interrupts are enabled.

The interrupt can act on the values immediately or – if we’re not concerned about keeping everything perfectly in sync – the values can simply be stored in data so it can be picked up in the main thread.

In the next post I’ll explain how I iterated this round-robin in building a fast and clean API for AVR chips.

Categories
Blog

Brain/Project Bootstrap

Since my PhD collapsed I’ve was out of action on the making front. I’ve taken some time to clear my head and now I’m getting the urge to create things again. It’s coming on strong and the problem is when this happens I get dozens of ideas at once, and then I start them all at once, so it all falls apart pretty quickly!

To get past this I’ve resolved to take the path of the the self-indulgent project dev blog. Whatever happens on dev days gets written, the good bits and the bad bits – and there are a lot of bad bits. I’m hoping that this will give me a healthier perspective on ‘failure’ days where I’m going in circles making an API that it turns out I didn’t need, or when I get one of those days where Windows/installers failing seems to waste a whole day *

So for starters, here’s what went well today. I drove up to Nottingham to get myself a signal generator I can gut to make a music interface.  Here’s whats I gots:

marconi-panel

It will anger radio hams that I’m gutting such a beautiful thing but it’s bought more as spares and I’d probably fry myself if I tried to wire it up to the mains. I’m aiming to make this into an exploratory audience-based music interface, largely focused on rhythm. This is exactly the sort of thing my PhD was focused on – dammit – but putting frustrations aside I’m going to just going to build what I can an see where it takes me.

The unit is a Marconi CT452A and it weighs 65lbs. The insides are incredible, I was expecting straightforward vernier potentiometers on the controls but it is heavily mechanical with springs, chains and gears.  I’ve not opened the main electronics section but there are a number of exposed valves and massively enlarged transformer, caps and bridge rectifier.  It’s an old selenium one from General Electric:

marconi-super-diode

So the first part of this project – the pick up – is done. Next I need to strip back the innards and see how easily I can interact with those controls.

What didn’t go so well today was I was planning to do a bit of sight-seeing in Nottingham, but I got there so late I missed the castle. I made it the famous pub ‘Ye Olde Trip To Jerusalem’ though and the contemporary arts gallery, which was typically pretentious, but in the foyer I found an awesome book on Kubrick by Tashen. Actually one good thing there was a dark corridor with sound in the walls, I’d love to have been in a bigger version of it:

dsc_0326

I drove today to ‘Black Box Thinking’ by Matthew Syed on audible, which is part of the motivation for me getting into writing this. It’s really good.  Another good thing was this morning I managed to squeeze one more desk into the workshop which is a hugs win as every other surface is covered in half-finished projects.

* Footnote: on failed APIs and Windows-waste days. I will blog a little about these later because despite being an annoyance it’s wrong to consider them a fail or waste; I learn a lot from these things, the problem is just I don’t write it down anywhere so I forget!  I’ll aim to post about the API experiments tomorrow, it’s an interface for reading Pots and SoftPots on AVRs.

Categories
Blog Code

Self-generating C++ from embedded Ruby

Disclaimer to protect my CV: this is not something I do professionally!

I often need to generate pitch or sample lookup tables for my AVR projects. I usually generate these C++ headers with little ruby scripts.  An evil thought struck me during a long drive… I don’t like these separate little scripts, I want the script inside the header, so if you #include it you get the data, but if you run it with ruby it rebuilds itself.

The thought preoccupied me for the journey.  Preprocessor macros start with a hash, and ruby uses hashes as comments, so you can hide ruby code in a #if 0 block.

The problem was then how to stop ruby from parsing the C++ the file contains. That’s simple enough, you can hide =begin and =end in #if blocks.

The file reading and writing itself is handled using gsub() and some careful regexing. It searches for the tailing end of the table declaration and the hash of the #if that trails it, and the replaces that block with generated values.

Just to be a swine I’ve condensed the Ruby to be borderline unreadable. Save this as ‘notes.h’ and run it through ruby:

#if 0
# Run 'ruby notes.h' and this rebuilds itself.
i=IO.read($0);IO.write($0,i.gsub(/(\]\s=\s{).+?#/m,"\\1 \n #{1024.times.collect{|n|(((44100.0*64.0)/(2.0**(n.to_f/(12*16))*110.0))).to_i}.join(",\n ")}\n};\n#"))
=begin
#endif
uint16_t freq[1024] = {
  25658,
  25565,
  // ... the rest here will be regenerated
  641,
  638
};
#if 0
=end
#endif

Note the regex can’t just search for the ‘] = {‘ verbatim because it would pick up the first instance of that expression in the gsub itself; this code is reading its own text and it would replace the regex! I bypass this by swapping spaces for \s ‘]\s=\s‘.

Here the evil ends.  #include "notes.h" works fine and you can rebuild any time – and risk trashing everything if you have made the tiniest typo :)  Not a good way to approach development but a fun puzzle.  The next challenge is to do this with compile-time table generation using variadic templates.

Categories
2016

Berlin TBC

Featuring miniature music machines this December.

Categories
2015

AARC

Diverge @ ORT Birmingham

Ryan and I getting into our polyrhythmic headspace with LEGO sequencers and synths.  The full performance is on youtube or a you can see a snippet on vimeo.

Categories
2015

Mechanical Calculator Workshop

Innovative Learning Week @ Edinburgh University

Demonstrating how machines do maths, and building LEGO adders in a workshop.  My designs for this workshop are available on github.

 

Categories
2014

Wired Next Generation

Talking at Tobacco Dock exploring ideas in playful ways can help develop new insights and creative tools.  The presentation is available at WIRED UK.

Categories
2014

Hong Kong Contemporary 14

Running from 16th to the 19th, featuring Missing Link and videos of my work.

Categories
2014

ITV Big Think

An opportunity to see Play House again as part of ITV’s event focusing on popular culture in society.