Raspberry Pi Family Tree

December 8, 2018 at 10:44 pm (computers) ()

There are a number of pages around listing the history of the various models of Raspberry Pi, and a few photo galleries of all models, but so far I haven’t been able to find an actual evolutionary family tree of the various boards produced to date.  So I’ve created one which will do until I find a better one.

Sources:

And the images themselves were picked out from Alex of Raspi.tv’s Raspberry Pi Family photo from March 2018:

(with the manual addition of the 3A+)

I think I’ve got the right linkages, but if not let me know.  Anything with a line across to the right hand side is still listed (at the time of writing) as a live product on raspberrypi.org as far as I can see.

Kevin

Raspberry Pi Family Tree.png

Advertisements

Permalink Leave a Comment

8×7 LED Array and MCP23017

December 7, 2018 at 8:21 pm (computers) (, , , , , , )

I can’t resist playing with an LED array, especially a surface mount one, so when I stumbled across some cheap (<$2) surface mount 8×7 LED arrays, charlieplexed onto 8 IO pins on ebay, I had to grab some.

Now I should say, I can’t really imagine why anyone would bother doing what I’m about to describe, as you already have many other options, including:

But as I say, I can’t resist a surface mount LED board, so I started to play.  When these arrived and I started poking around, I soon found out they were actually a cheap knock-off of the Sparkfun 8×7 LED Array, something I didn’t even know existed!  Apologies to Sparkfun for not getting an official board, but many thanks to them for open sourcing the design.

Initially they are fairly easy to hook-up and drive.  I used an Arduino Uno for my first experiments, as they could be paired straight away with pins 2-9 and then driven directly using the Arduino Charlieplex library (the Sparkfun Tutorial uses the Chaplex library and a special Sparkfun library for the board, but I was just doing fairly simple things for now).

With the neat serial interface to the Pi-Lite in the back of my mind, I wanted a better way to connect to the board.  Ideally, something that could be soldered onto the back to make it a single unit.  Some options I explored were:

  • Using an IO expander – such as the MCP23017 (the subject of this post).
  • Using an Arduino Mini Pro – to provide a serial interface (bit more on that later).
  • Using an LED driver module.

For this first experiment, I thought having an I2C addressable LED module would be quite neat (I didn’t know about the IS31FL3731 used on the Adafruit and Pimoroni boards at this time – that is an experiment for another day), so I grabbed some cheap MCP23017 breakout boards and after breadboarding it, ended up simply soldering one on the back.  It overlaps ever so slightly, but I think I could still place a few of these side by side to chain them.

2018-12-01-16-06-19.jpg2018-12-01-16-04-34.jpg2018-12-01-16-04-20.jpg

Link-up wise, this ties the 8 IO pins of the matrix to port A pins 0 to 7 on the MCP23017.  The 7 pins with header connections are (in order top to bottom):

  • VCC
  • GND
  • SCL/SCK
  • SDA/SI
  • NC/CS
  • NC/SO
  • RESET

And the three connections with no header pins are the three address encoding pins.  As I’m using I2C I only need four connections: VCC, GND, SCL and SDA (I could have left off the other three header pins really).

In terms of the code, there are libraries for the MCP23017, Charlieplexing and even the aforementioned Sparkfun library for this module, but to link them all together is quite inefficient.  The simple approach would be to replace the low-level pin setting/clearing code in the charlieplex library with commands for the MCP23017.  But as every setting of a single LED, even when triggered as part of a ‘scan’ managing a display buffer, requires I2C commands to be sent over the bus, and each command requires bit manipulation to process the IO pins individually, this is massively inefficient.

However, the MCP23017 is really only be driven by two registers: GPIOA to set the IO pins HIGH or LOW, and IODIRA to set the pins to INPUT or OUTPUT.  Recall that for Charlieplexing, all three states of pins are significant: INPUT, OUTPUT+HIGH, OUTPUT+LOW.

To work out which pins do what, we need to refer to the wiring layout of the LEDs on the board, for which the Sparkfun schematic is key (my thanks again for the open source design).  Here is an annotated version showing which IO pins (numbered 1 to 8 on the schematic) are connected to which LED in the matrix.

2018-12-07-19-29-34.jpg

The key thing to notice is how for every column listed, there is, naturally, a gap in the numbering of the rows (you can’t have an LED connected with both leads to the same IO pin).

So a more efficient scanning algorithm would thus run something like this:

// IODIRA = INPUT (1) or OUTPUT (0)
// GPIOA  = HIGH (1) or LOW (0)

FOREACH col (0 to 7)  // scan one column at a time
  gpiomask = (1<<col) // only pin that is HIGH in the col pin
  dirmask = 0         // default to all OUTPUTS
  FOREACH iopin (0 to 7)
    led = iopin
    IF (iopin == col) SKIP
    IF (iopin > col) THEN
       // led we want is one less than iopin due to charlieplex mapping
    IF (led for col is OFF) THEN
       dirmask |= (1<<iopin)  // set this one to an INPUT i.e. OFF
  NEXT iopin
  IODIRA = dirmask
  GPIOA  = gpiomask
NEXT col

The basic principle being that for a single scan, set one pin HIGH/OUTPUT (for one column in the matrix) and then work out which other LEDs need to be active by setting the direction of the pins accordingly – LOW/OUTPUT will light the LED for that pin combination; INPUT will mean the led for that combination is off.  Then on the next scan, do the same for the next column.

The following is some basic code, based on a whole range of sources (and to be honest, not particularly well structured in terms of functional separation) to provide an I2C optimised scanning function for the MCP23017 and LED array combination.

Usual caveats apply – I’m not really a cpp person, use at your own risk, etc, etc.

Key gotchas from doing this:

  • You can set the I2C bus to run at a higher speed, which is well worth doing in this case.  Note that I don’t know what happens if you have lots of things on the bus – this was working with just this LED array and nothing else.  See Wire.SetClock() in the Arduino Wire library.
  • You can’t do I2C from an interrupt routine.  I wanted the scanning routine to run off a timer interrupt, but nothing works if you try to do that – in fact, everything actually completely locks up.

So that’s it for now.  It scans quite well and with not a bad refresh rate, but as I said right at the start, with so many options of LED array available, not quite sure why anyone would want to do this.

Next, I’ll see if I can get the Pi-Lite firmware onto an Arduino Pro Mini and solder that on the back of one of these too.  That will create a standalone, drivable over serial port, module similar to the original Pi-Lite (ish).  Not really sure why anyone would want to do that either.

Kevin

I2CCharlieExample.ino

/*
 * Charlieplex Example for the Sparkfun LED Array board connected
 * to an MCP23017 IO expander chip and accessed via I2C.
 */
#include "I2CCharlieplex.h"
#include "Wire.h" // required for I2CCharlieplex.h

#define MCPADDR  0   // 0 to 7 for 0x20 to 0x27 for MCP23017 expander

// Define the pins in the order you want to address them.
//
// Note: for the MCP23017, pin numbers are as follows:
//         Port A pins 0 to 7 = pins 0 to 7
//         Port B pins 0 to 7 = pins 8 to 15
//
#define NUMBER_OF_PINS 8
byte pins[] = {0,1,2,3,4,5,6,7};

I2CCharlieplex charlieplex = I2CCharlieplex(MCPADDR, pins, NUMBER_OF_PINS);

void setup(){
  charlieplex.init();
  charlieplex.clr();
  charlieplex.scan();
}

int x=0;
int y=0;
int scan=0;
int clr=0;

void loop(){
  delay(1);
  charlieplex.scan();

  // Update the LED pattern from time to time
  if (scan > 200) {
    scan = 0;

    if (clr) {
      charlieplex.clr();
      clr=0;
    } else {
      charlieplex.led (x, y, HIGH);
      x++;
      if (x>=8) {
        x=0;
        y++;
        if (y>=7) {
          y=0;
          clr=1;
        }
      }
    }
  }
  scan++;
}

I2CCharliePlex.cpp

/*
 * I2C MCP23017 I2C IO Expander Charlieplex
 * Based on elements of MCP23017 Library from Adafruit and
 * the Charlieplex library by Alexander Brevig
 *
 * Pins are numbered as follows:
 *   0-7  Port A 0-7
 *   8-15 Port B 0-7
 */

#include "I2CCharlieplex.h"
#include "Wire.h"

// Default address
#define MCP23017_ADDRESS 0x20

// registers (using same definitions as Adafruit_MCP23017.h)
// Note: MCP23017 can be configured for interleaving registers or
//       sequential, depending on the setting of IOCON[AB].BANK.
//       By default on power up IOCON.BANK = 0; i.e. interleaved
//       as defined below..
#define MCP23017_IODIRA 0x00
#define MCP23017_IPOLA 0x02
#define MCP23017_GPINTENA 0x04
#define MCP23017_DEFVALA 0x06
#define MCP23017_INTCONA 0x08
#define MCP23017_IOCONA 0x0A
#define MCP23017_GPPUA 0x0C
#define MCP23017_INTFA 0x0E
#define MCP23017_INTCAPA 0x10
#define MCP23017_GPIOA 0x12
#define MCP23017_OLATA 0x14

#define MCP23017_IODIRB 0x01
#define MCP23017_IPOLB 0x03
#define MCP23017_GPINTENB 0x05
#define MCP23017_DEFVALB 0x07
#define MCP23017_INTCONB 0x09
#define MCP23017_IOCONB 0x0B
#define MCP23017_GPPUB 0x0D
#define MCP23017_INTFB 0x0F
#define MCP23017_INTCAPB 0x11
#define MCP23017_GPIOB 0x13
#define MCP23017_OLATB 0x15

#define MCP23017_INT_ERR 255

// Address in range 0 to 7.  MCP23017 address set in the range
//  0x20 to 0x27 using the A0, A1, A2 pins
I2CCharlieplex::I2CCharlieplex(uint8_t address, byte* userPins, byte numberOfUserPins){
  pins = userPins;
  numberOfPins = numberOfUserPins;

  // Initialise the MCP23017 IO Expander using I2C
  if (address > 7) {
    addr = MCP23017_ADDRESS;  // default to first address if not sure
  } else {
    addr = MCP23017_ADDRESS + address;
  }
}

void I2CCharlieplex::init () {
  Wire.begin();  // We are the bus master

  // Note on I2C clock speed - as a synchronous comms, the clock is set
  // by the master and the slave will be triggered by it.
  // The default is 100kbit/s (standard); many devices will also support 400kbit/s (full speed).
  // Some might support 1Mbit/s (fast mode) or 3.2Mbit/s (high speed).
  // See https://www.i2c-bus.org/speed/
  //
  // 400000 bps is 400000/8 = 50 KB/s
  Wire.setClock(400000); // Use I2C in full speed mode

  // Clear all leds (set all pins to INPUT)
  mcpAllInputs();
}

// LED Buffer access routines
void I2CCharlieplex::led(uint8_t x, uint8_t y, bool state) {
  if ((x<NUMXLEDS) && (y<NUMYLEDS)) {
    if (state == HIGH) {
      leds[y] |= (1<<x);
    } else {
      leds[y] &= ~(1<<x);
    }
  }
}

void I2CCharlieplex::clr() {
  for (uint8_t i=0; i<NUMYLEDS; i++) {
    leds[i] = 0;
  }
}

// WARNING: This cannot be called from an ISR if it is using I2C
//          (everything locks up if you do)
void I2CCharlieplex::scan() {
  // Only scan one column at a time

  // Scan according to the following algorithm:
  //  IODIRA = INPUT (1) or OUTPUT (0)
  //  GPIOA  = HIGH (1) or LOW (0)
  //  
  //  FOREACH col (0 to 7)  // scan one column at a time
  //    gpiomask = (1<<col) // only pin that is HIGH in the col led
  //    dirmask = 0         // default to all OUTPUTS
  //    FOREACH iopin (0 to 7)
  //      IF (iopin == col) SKIP
  //      IF (iopin > col) THEN
  //         led we want is one less than iopin due to charlieplex mapping
  //      IF (led for col is OFF) THEN
  //         dirmask |= (1<<iopin)  // set this one to an INPUT i.e. OFF
  //    NEXT iopin
  //    IODIRA = dirmask
  //    GPIOA  = gpiomask
  //  NEXT col

  // First kill all LEDS
  mcpWrite(MCP23017_IODIRA,0xff);

  uint8_t ledmask = (1<<col);
  uint8_t dirmask = 0;
  for (uint8_t p=0; p<NUMPINS; p++) {
    uint8_t y = p;
    if (p == col) {
      // skip this one
      continue;
    } else if (p > col) {
      // LED index will be one less than pin value due to charlieplex pattern
      y--;
    }
    // check the 'col'th LED in each 'y' row to see if pin 'p' is IN or OUT
    if ((leds[y] & (1<<col)) == 0) {
      // Want IO pin to be low to illuminate the LED
      // So only set IO pin if LED is OFF
      dirmask |= (1<<p);
    }
  }
  // Always need "col" pin as an OUTPUT (low) though
  dirmask &= ~(1<<col);
  
  // Only High pin will be the col being scanned
  mcpWrite (MCP23017_GPIOA, ledmask);
  // All other pins are low, so direction will determine if they are
  // a low OUTPUT or INPUT (which will disable that LED)
  mcpWrite (MCP23017_IODIRA, dirmask);
  // next column
  col++;
  if (col >= NUMXLEDS) {
    col = 0;
  }
}

// I2C MCP23017 IO Handling
// Not: No DigitalRead as yet

void I2CCharlieplex::mcpPinMode (uint8_t p, uint8_t mode) {
  if (mode == INPUT) {
    // Set appropriate bit in register
    mcpBitUpdate(p, 1, pin2reg(p, MCP23017_IODIRA, MCP23017_IODIRB));
  } else {
    // Clear appropriate bit in register
    mcpBitUpdate(p, 0, pin2reg(p, MCP23017_IODIRA, MCP23017_IODIRB));
  }
}

void I2CCharlieplex::mcpAllInputs () {
    // Set all pins to INPUT at once
    // (makes a full clear much quicker than setting individual bits)
    mcpWrite(MCP23017_IODIRA,0xff);
    mcpWrite(MCP23017_IODIRB,0xff);
}

void I2CCharlieplex::mcpDigitalWrite (uint8_t p, uint8_t val) {
  // Need to read current I/O states from the latch,
  // set/clear the appropriate bit and
  // write it back to the GPIO register
  uint8_t io;
  io = mcpRead(pin2reg(p, MCP23017_OLATA, MCP23017_OLATB));
  bitWrite(io, pin2bit(p), val);
  mcpWrite(pin2reg(p, MCP23017_GPIOA, MCP23017_GPIOB), io);
}

//
// I2C MCP23017 Register Handling
//

void I2CCharlieplex::mcpWrite(uint8_t reg, uint8_t val) {
  // Write sequence:
  //    Send register address to write
  //    Send the byte of data
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.write(val);
  Wire.endTransmission();
}

uint8_t I2CCharlieplex::mcpRead(uint8_t reg) {
  // Read sequence:
  //    Send register address to read
  //    Request 1 byte of data from the device
  //    Read the byte of data
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(addr, (uint8_t)1);
  return Wire.read();
}

void I2CCharlieplex::mcpBitUpdate (uint8_t bit, uint8_t val, uint8_t reg) {
  uint8_t regval;
  regval = mcpRead(reg);
  bitWrite(regval,bit, val);
  mcpWrite(reg, regval);
}

// Register and pin helper functions
uint8_t I2CCharlieplex::pin2bit(uint8_t pin){
  // Returns bit 0 to 7 for range of pins 0 to 7 and pins 8 to 15
  return pin%8;
}
uint8_t I2CCharlieplex::pin2reg(uint8_t pin, uint8_t portAaddr, uint8_t portBaddr){
  if (pin < 8) {
    return portAaddr;
  } else {
    return portBaddr;
  }
}

I2CCharlieplex.h

#ifndef I2CCHARLIEPLEX_H
#define I2CCHARLIEPLEX_H

#include <Arduino.h>

class I2CCharlieplex {

// LED matrix is 8 across by 7 deep
// Wired up in a charlieplex mode to map to 8 IO pins
#define NUMXLEDS 8
#define NUMYLEDS 7
#define NUMPINS  8

public:
  I2CCharlieplex(uint8_t address, byte* userPins,byte numberOfUserPins);
  void init ();

  // LED buffer handler functions
  void led(uint8_t x, uint8_t y, bool state);
  void clr();
  void scan();

  // MCP23017 handler functions
  void    mcpPinMode(uint8_t p, uint8_t mode);
  void    mcpAllInputs();
  void    mcpDigitalWrite(uint8_t p, uint8_t val);
  void    mcpWrite(uint8_t reg, uint8_t val);
  uint8_t mcpRead(uint8_t reg);
  void    mcpBitUpdate (uint8_t bit, uint8_t val, uint8_t reg);
  uint8_t pin2bit(uint8_t pin);
  uint8_t pin2reg(uint8_t pin, uint8_t portAaddr, uint8_t portBaddr);

private:
  byte    numberOfPins;
  byte*   pins;
  uint8_t addr;
  uint8_t leds[NUMYLEDS];
  uint8_t col;
};

#endif

Permalink Leave a Comment

Extractivism and the Anatomy of AI

November 6, 2018 at 10:20 pm (computers, interesting, science) (, , , )

I found this fascinating website – the Anatomy of an AI System – which takes an Amazon Echo and attempts to map out the behind the scenes costs in terms of manual labour, material resources, and data required to power the ecosystem.

It is particularly telling how much it focuses on the raw material impact of our modern lifestyles, which when all said and done is not unique to the Echo, but a symptom of our continued fascination with electronic gadgetry in its totality.  It has a word, that was new to me, for the way much of the impact is continually hidden from end consumers by large companies – extractivism – and attempts to bring to the fore the continued extractivism going on in support of the huge technology base being created (and in some cases just as quickly obsoleted) by large technology companies.

It uses as one example, The Salar, which is a high plateau in Bolivia that apparently contains the majority of the world’s source for Lithium, becoming increasingly important of course in our desire for mobile power (both smartphones and electric vehicles).

Another interesting example is the metaphor of “the cloud”:

Vincent Mosco has shown how the ethereal metaphor of ‘the cloud’ for offsite data management and processing is in complete contradiction with the physical realities of the extraction of minerals from the Earth’s crust and dispossession of human populations that sustain its existence.

We think of putting our data in “the cloud”, of using services in “the cloud” and all the mechanics are abstracted away, out of sight, out of mind. It is rarely that the physical realities of “the cloud” surface, expect in exceptional circumstances, usually where something goes wrong.

I would be interested in reading an update to Andrew Blum’s Tubes, updating it to make “the cloud” real in the same way he did for the also ethereal Internet itself.

Another interesting observation to come out of the study is the importance of the multiple roles of the end user:

When a human engages with an Echo, or another voice-enabled AI device, they are acting as much more than just an end-product consumer. It is difficult to place the human user of an AI system into a single category: rather, they deserve to be considered as a hybrid case. Just as the Greek chimera was a mythological animal that was part lion, goat, snake and monster, the Echo user is simultaneously a consumer, a resource, a worker, and a product.

(emphasis in the original paper).

This also comes out in the scale of income distributions – with Jeff Bezos at the top (apparently earning $275 million a day) – through US developers and workers, through overseas developers and workers – right down to “unpaid user labour” at the bottom generating the data that feeds the system and continually improves it.

The study rightly points out the fractal nature of attempting to display any of this in a linear manner on a single diagram.  Of course, each supply chain is supported by components each with their own supply chain.  Its supply chains all the way down until you reach the raw elements.

In summary I am minded simultaneously of Carl Sagan:

“We live in a society exquisitely dependent on science and technology, in which hardly anyone knows anything about science and technology.”

But seeing this complication laid bare, somewhat in defence of humanity, also of Douglas Adams (from “Mostly Harmless”):

“The available worlds looked pretty grim. They had little to offer him because he had little to offer them. He had been extremely chastened to realize that although he originally came from a world which had cars and computers and ballet and Armagnac, he didn’t, by himself, know how any of it worked. He couldn’t do it. Left to his own devices he couldn’t build a toaster. He could just about make a sandwich and that was it.”

Kevin

Permalink 2 Comments

ESP01 and SSD1306 OLED from myiot

September 30, 2018 at 9:59 am (computers) (, , , )

Not sure where I found the link to these, but this is a neat little board from Ian Sexton – see http://myiot.co.uk/ESP_OLED/.  I ordered four of these and sourced all the parts from ebay.

Here are a few notes on getting them up and running.

  1. You have to be able to hand solder the two capacitors and power regulator SMT devices.  I’d not done this before, so it was a little tricky at first.  No real tips to offer I’m afraid, other than it was worth it, these are really neat boards!
  2. As Ian mentioned, be sure to find an OLED screen labelled VCC-GND-SCL-SDA.  When I was looking, pretty much all of the ones I found were GND-VCC-SCL-SDA.
  3. My displays came with headers pre-soldered, so I couldn’t follow the build order exactly.  Instead using straight 4-pin female headers rather than right angle headers, and then bending them over after solder the OLED on last.
  4. I also found that the ESP01 modules worked best with a small header spacer rather than no spacer as described in Ian’s instructions.  And I added an additional header space to the OLED headers too and used a bit of insulating tape between the OLED and ESP module.
  5. I also found that if I didn’t trim off the ESP 01 module pins, there was still enough of them sticking out that I could still plug them into the 8-pin header of my USB programmer, so actually didn’t need the 5 programming pins included on the board.

The end result for me wasn’t quite as thin as in Ian’s photos, but I is quite a nice compromise between my skills, future usability and utility of the boards.

When it comes to use, you can use the standard ESP/OLED libraries as described in this blog: https://randomnerdtutorials.com/esp8266-0-96-inch-oled-display-with-arduino-ide/

Note however, that this board is wired as follows (which is written on the PCB diagram on Ian’s blog, but it took me a while to find it!):

SCL = GPIO2 (D3 for many ESP boards)
SDA = GPIO0 (D5 for many ESP boards)

These are the opposite way around to most examples in the ssd1306 library.  Also, as I was building for a generic ESP8266, D3 and D5 were not defined anyway, so the example code in, for example, the SSD1306ClockDemo, to initialise the run on the boards was as follows:

// Include the correct display library
// For a connection via I2C using Wire include
#include   // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy include: #include "SSD1306.h"​ #define SDA 0 // D5 = GPIO0 #define SCL 2 // D3 = GPIO2 // Initialize the OLED display using Wire library SSD1306Wire display(0x3c, SDA, SCL);

In summary, these are really great little boards and the resulting modules I think have a lot of applications.

Kevin.

 

Permalink Leave a Comment

Fixing Windows 10 Boot Problems

June 29, 2018 at 9:19 pm (computers) (, , , )

Had an issue with a Windows 10 laptop where it stopped booting.  It was failing at the flashing cursor on a black screen, which to me looked like either a disk failure or some odd boot loop.  It wasn’t registering that there wasn’t an OS and it wasn’t trying to boot an OS and finding errors.

Booting off a Windows repair CD didn’t get anywhere with startup repair either, so into the command line I had to go.

There are a number of Windows commands that relate to boot that came into play:

diskpart – to look at disks and partitions to work out how it is configured (using the commands “list disk”, “select disk 0”, “list partition”, “list volume”, etc)

bootsect – to fix the boot sector (in this case, I used “bootsect /nt60 sys”)

bootrec – to fix various boot and boot record issues – “bootrec /fixmbr”, “bootrec /fixboot”, and finally “bootrec /rebuildbcd”.

Unfortunately rebuildbcd (bcd = boot configuration data) generated an error, “the file or directory is corrupted and unreadable”.  So after a bit of Googling, then also found bcdboot.  This is supposed to setup the boot environment by copying the relevant files form the Windows installation over to the boot area.  Running that though, came up with more errors, so poking around in the two areas, the PC had a boot partition on C: and the system drive was D:.  It was attempting to copy from d:\windows\boot\pcat to c:\boot and failing for some reason.

So at this point, I thought a chkdsk might have been in order – so “chkdsk /f c:” came up with a load of index errors related to all the language files which it seemed to fix.  bcdboot was still struggling, so I manually copied the rest of the files over.

At this point bcdboot largely succeeded, but still had one error, so running it in verbose mode highlighted a problem accessing the bcd catalogue from the d:/windows/system32/config area.  But not really knowing what it was trying to do with it, in the end I just ran “bootrec /rebuildbcd” and that seemed to work fine this time.

At this point, we felt it worth attempting a boot again, and thankfully at this point.  It all worked.  Windows did its own chkdsk again whilst starting up and we were finally in once again.

Kevin

 

 

Permalink Leave a Comment

John Stump 1944-2006

May 28, 2018 at 8:03 pm (interesting, music) (, )

Whilst scanning  back through old posts, I found Adagio Cantabile with a rock tempo feel … describing a parody piece of music, designed to be unplayable, by John Stump.  However on following the links, it turns out that the Wikipedia page describing the work was deleted, with the deletion log effectively concluding:

Delete There is absolutely nothing to suggest this classical music spoof is notable enough for inclusion in an international encyclopedia.

Knowing what I know of music, human nature, parody and general good fun (and also some of what is included in said international encyclopedia), I couldn’t disagree more!  There are countless classrooms around the world with this piece of music on a poster on the wall and many a music student will know of it.  For that reason alone it should be included and a little of its history ought to be recorded.

Thankfully, where Wikipedia fails, a nephew of John Stump comes to the rescue.  You can read about the mischievous composer here on Greg’s Lost in the Clouds blog:

He had worked in the field of “music engraving” for most of his life, beginning in 1967, and I remember looking with fascination at his “music typewriter” in his office in my grandmother’s garage, so it didn’t surprise me that Uncle John would have created something like this fake musical piece.

Turns out he wrote two other satirical pieces, all three of which are preserved on the web site of  Bryan Higgins.  Here you can find:

Along with two other works in a similar vein by others:

(the rest of Bryan’s collection is worth a browse too – a bit of an eclectic collection)

Greg and Bryan, thank you for going where Wikipedia appears not to have the collective imagine to tread.  The Internet is a better place for it.

Kevin

Permalink Leave a Comment

Repeating Number IP Addresses

April 30, 2018 at 10:40 am (interesting, internet) (, )

Google started a bit of a trend when it released its own DNS service on IP address 8.8.8.8.

The thing about a DNS service, is that when you want someone to be able to use it, they need to know how to configure it.  But you can’t use a nice memorable name, as the whole point of a DNS service is to translate names into IP addresses.  So you have to configure your DNS service using the IP address alone, hence Google finding a way to secure ownership of the 8.8.8.8 address for use with DNS, landing them a nice, easy to remember address.

Now, more recently, the Quad9 DNS service has been launched, promising more privacy and performance, on, you guessed it, 9.9.9.9.  And in the last month or so Cloudflare and APNIC have teamed up to bring you the 1.1.1.1 DNS service, again promising privacy and performance.

So this got me wondering – who might be next?  Well if you’re after memorable IP addresses, then repeated numbers is definitely the way to go, so after a quick bit of typing into an IP address lookup tool, how about some of these?

  • 2.2.2.2 – Orange Telecom
  • 3.3.3.3 – Amazon
  • 4.4.4.4 – Level 3 Communications
  • 5.5.5.5 – E-Plus Mobilfunk GmbH & Co KG
  • 6.6.6.6 – USAISC – looks like US Army
  • 7.7.7.7 – Dept of Defense

And of course we know about 1, 8 and 9.  I’m not interested really in 10, but going for other repeats:

  • 11.11.11.11 – US DoD again
  • 22.22.22.22 – And this one too …
  • 33.33.33.33 – And this one …
  • 44.44.44.44 – US Amateur Radio Digital Communications
  • 55.55.55.55 – USAISC again
  • 66.66.66.66 – Time Warner Cable Internet LLC
  • 77.77.77.77 – Dadeh Gostar Asr Novin P.J.S. Co. (with an address in Iran)
  • 88.88.88.88 – Telenor Business Solutions AS (Norway)
  • 99.99.99.99 – AT&T
  • 111.111.111.111 – KDDI (Japan)
  • 222.222.222.222 – China Telecom

So the US military certainly has ownership of the largest number of repeated number addresses.  But there are also a fair number of telcos and large Internet companies in there too (will we eventually see an Amazon DNS service on 3.3.3.3 I wonder?).

Of course if you were running a universal query answering service, then the best address would have to be 42.42.42.42, which appears to be owned by South Korea Telecom.

But I dread to think what running a single service on any of these specific public addresses would do to the global routing table.

Of course you need to beware of hidden meaning in all this … although taken to extremes it reminds me of the interesting number paradox.

I quite like this idea:

When you see the number 111 stop and look around yourself. Take a note of where you are, what you are doing and who you are with! 111 is a wakeup call from the Universe, telling you to pay attention to what is happening around you.

That’s not a bad premise for a DNS service – as a reminder to pay attention to the real world.

Kevin

 

Permalink Leave a Comment

Arduino, ATtiny85, and Timers

April 29, 2018 at 2:57 pm (computers) (, )

I’m still playing around with using the ATtiny85 as the basis for a synthesizer, using a range of code and circuits from the Internet, but had an irritating problem today with some open code.  The author describes complete build instructions for their code and circuit for v1.5.7 of the Arduino environment and the arduino-tiny library, which as far as I can see was last updated in 2013 from its google code repository.

But I have v1.8.5 and the now easy to use, built-in support for the ATtiny85 from David Mellis (https://github.com/damellis/attiny).

So when it comes to build it on my system I get the following error:

wiring.c.o (symbol from plugin): In function `delayMicroseconds':

(.text+0x0): multiple definition of `__vector_5'

Which is obviously a linker error, but it has proven quite difficult to find a detailed hint as to what the actual problem is.  It says that it has redefined in my .ino file, but wasn’t immediately obvious this related to interrupt routines (although the word vector should have been a clue I guess).

Well it turns out that this is a problem you get if you attempt to defined an interrupt service routine twice.  The code in question had defined

ISR(TIMER0_OVF_vect)

And in any modern Arduino core timer 0 is used for the millisecond timer, as defined in hardware/arduino/avr/cores/arduino/wiring.c.  This is indeed vector 5 (see http://ee-classes.usc.edu/ee459/library/documents/avr_intr_vectors/).  This is defined in wiring.c, but not directly related to the delayMicroseconds function (oh the joys of tracing C linker errors).

I’m skipping over the part where I was attempting to work out where the actual source code being built was stored – not in <program files>\Arduino; not in my own Arduino source area; no it was finding mention of <user>\AppData\Local\Arduino15 that found any ATtiny support in my installation at all.

There seems quite a lot of confusion online (at least from the searching I was doing) about timers on the ATtiny85 and the Arduino environment.  It looks like an earlier version of the Arduino core (although not obviously in the v1.5.7 suggested by the author of the code I was using, so that is still a puzzle) had a method for changing the timer usage for different microcontrollers.

The arduino-tiny library uses a core_build_options.h options file and uses it to set the following:

#if defined( __AVR_ATtiny25__ ) || defined( __AVR_ATtiny45__ ) || defined( __AVR_ATtiny85__ )
#define __AVR_ATtinyX5__
#endif

#if defined( __AVR_ATtinyX5__ )

/*
 For various reasons, Timer 1 is a better choice for the millis timer on the
 '85 processor.
*/
#define TIMER_TO_USE_FOR_MILLIS 1

However, this isn’t in the latest builds of the core or in the version of the ATtiny core support I’m using, which doesn’t seem to have the option to change which timer is used for the delay functions.  In fact, I couldn’t quite pin down when the use of this header file disappeared from the Arduino builds, but to be honest I didn’t spend ages looking.

The code I’m trying to use needs the use of both timers, and as there are only two timers on the attiny85, hence the clash.  I’m not totally clear why it builds when the delay timer is swapped to use timer1 (as in the older arduino-tiny core), but I guess the code isn’t hanging an ISR of the other timer.

Interestingly in other code by the same author, does build ok, but in that case, even though it is installing an ISR for timer0, it is using a different vector, so it doesn’t seem to clash:

ISR(TIMER0_COMPA_vect)

So whilst you can completely mess up the functioning of the timers in your own sketch, by changing the control registers and so on directly, I haven’t found a way to clear and attach a new ISR to the interrupt.

I need to dig around a bit more now into the internals of the ATtiny timers to see how the code might be modified to support timer 1 instead of timer 0, but that will have to be a job for another day now.

Some possible options might include forgoing the use of ‘setup’ and ‘loop’ in the sketch; integrating it better alongside its use with delay; attempting to port over from triggering on overflow to triggering on compare; or I may end up trying to reverse the timer usage in the sketch (but I read somewhere that the two ATtiny85 timers are quite different, so that might not be possible).   I may end up with a special ‘hacked’ core board definition to re-specify the use of timer1 rather than 0 as per the older library, but that would be a bit of a mess…

Anyway, the upshot of all this is that this took quite a lot of untangling and googling and following dead-ends, so if you know of a definitive resource or document that details the history of ATtiny85 support within Arduino and when this changed, I’d like to hear about it!

Update: In my case it turned out that I was pretty much able to replace the use of the Timer 0 overflow interrupt with the Timer 0 compare A interrupt and get largely the same thing.  I don’t know if the two use of the different timers needs to be swapped though, but as far as I can tell right now, changing interrupt does remove the clash.

So in my case, I did this:

#ifdef ORIGINAL_CODE_
 TIMSK = (1 << TOIE0); // Interrupt on overflow
#else
 // Set compare value to same that would trigger overflow
 // of the 8-bit counter (pretty much)
 OCR0A = 0xff;
 TIMSK = (1 << OCIE0A); // Interrupt on compare with OCR0A
#endif

and then later on, when defining the ISR:

#ifdef ORIGINAL_CODE_
ISR(TIMER0_OVF_vect) {
#else
ISR(TIMER0_COMPA_vect) {
#endif

Of course there may still be other side effects, but I need to dig into the details to see.

Kevin

Permalink Leave a Comment

ATtiny85 Synth from Jan Ostman

March 31, 2018 at 3:38 pm (computers, music) (, , , )

I’ve wanted to make a simple synth for a while and stumbled across the excellent DSPSynth site from Jan Ostman, which provides a range of designs for Euro-module compatible synthesizer modules.  One thing that really caught my eye was the CZ1 chip which implements the Casio Phase Distortion method of sound synthesis (I used to have a Casio CZ synth).  The chip is based on an ATtiny85 and the code is available as open source along with a circuit design here: https://janostman.wordpress.com/the-3hp-paperface-euro-modules/

Unfortunately, being a bit of an ATtiny85 novice, it wasn’t totally clear to me quite how to put this together from the bits and pieces I had lying around.  So this is by way of documenting how I got this doing based on the circuits and code from dspsynth.eu.

Note you can buy pre-built modules and kits from the site with proper pcbs and “paperface” front modules which all look very smart.  But as I was just tinkering I wanted to see how much I could get going myself.

And of course massive thanks to Jan Ostman for doing all the hard work and publishing the designs in the first place.

Building the Synth

Parts list for me:

I originally grabbed a couple of very cheap “ATtiny85 devboards” off ebay that include a micro-USB connection, but these turned out just to be a way of powering the boards, not programming them.  I tried using an Arduino as an in-circuit programmer, but in the end the Sparkfun programmer was so easy to use, I just use that now all the time.

dspsynth provides two circuits related to the CZ1 chip.  On the main HP3 paperface module page is a complete euro-module compatible circuit including power regulator and jacks for inputs and outpus.  In the “CZ1 manual” is a much simpler circuit that just shows a simple output stage as follows:

dsp-cz1

So I used this as my output side.  For the inputs, I took two 10k pots connected to the input pins via a 22k resistor each as shown in the full dsp paperface circuit (but without the jack connectors).

The whole thing was powered using the 5v and GND pins from one of those cheap USB “devboards” I mentioned, although I didn’t use that to host the ATtiny85 itself as they aren’t really breadboard friendly.  I did need a simple 8-pin socket adaptor to breadboard adaptor to seat the ATtiny85 nicely though.  Pics below.

2018-03-31 16.04.292018-03-31 16.05.112018-03-31 16.05.17

2018-03-31 16.03.58

Programming the ATTiny85

The source code is provided here: http://www.dspsynth.eu/files/code/pdvco.ino.  The official module uses the TinyAudioBoot system which allows you to upload firmware over one of the audio inputs.  I didn’t bother with that for my tinkering, so I was just loading the pdvco.ino source directly using the Arduino IDE and the Sparkfun programmer.

One thing that had to be done was “set the fuses”.  As I say, as a ATTiny85 novice, this took a bit of googling.  But it turns out all I really needed was to set the internal clock for the device to 16MHz (I uploaded the code without this step and there were some very interesting audio effects coming out of the thing – as you’d expect the digital to analogue conversion was all off sync).

If you select the right parameters in the Arduino IDE (ATtiny85; Clock: Internal 16MHz) and then select “burn bootloader” this has the effect of setting the fuses for the clock speed.  At this point, when the code fired up it all seemed to work and sounded a lot better.

Next Steps

Now I’ve had a bit of a play and an see what the ATtiny85 can do, I plan to explore some more of his designs.  Of particular interest is seeing if I can create a MIDI in to CV module using the principles in his USB MIDI to CV interface. But I want real MIDI so will be experimenting with the serial ports on the ATTIny85 (and worrying about getting MIDI to 5v input levels).

Once again, many thanks to Jan Ostman for publishing these designs and letting people like me have a play with DSP synthesis with such a cheap and available microcontroller from a starting point of relatively little knowledge about such things.

Kevin

 

Permalink Leave a Comment

Repeated iPad Activation Requests

July 30, 2017 at 2:54 pm (computers) (, , , , )

I had a recent problem with an iPad.  It was asking to be activated, yet when you walk through the menus, it wouldn’t connect to the Apple servers and activate, it would only get kicked back into action when connected to a PC running iTunes.

Once activated, all was fine – Internet fine, browsing and apps, fine – apart from iTunes itself.  For some reason it was never able to get in touch with the App Store from the iPad itself.  After a while, it would then get stuck back in the ‘your iPad requires activation’ loop.  This could take a few hours or it might be after a day.

Typical error messages included: “activation error”, “ipad could not contact activation server”, “ipad could not connect to iTunes”.

The one that usually came up once trying to activate the device manually was “Your iPad could not be activated because the activation server is temporarily unavailable. Try connecting your iPad to iTunes to activate it, or try again in a couple of minutes”.

The Internet has various reasons for this – the server really is unavailable, your Internet connection isn’t working, and in some cases there was a report of activation problems after an iOS update.  There are various suggested solutions too – reboot, connect using a PC (which solves it in my case but only temporarily), remove the account from your iPad and add it back in, or even factory reset and restore from backup.  Nothing worked for me.

As I was contemplating a factory reset, I noticed that the clock on the iPad was out.  For some reason automatic updating of the clock from the Internet was turned off and the iPad was a hour out compared to the actual time.  Once the time synchronisation was turned back on and the clock updated, it all worked again.

I know that many cryptographic protocols can be time sensitive – if the clocks are out by too much between the two devices trying to communicate securely then the connection can not be established.  This is a problem I had with a Windows machine once – when the clock out of sync it wouldn’t ever update.  Looks like the same was probably happening here.

So if you are having odd activation errors on your i-device that keep reoccurring, check your clock settings and make sure it is telling the right time and in the right time zone.  This isn’t something I’ve seen mentioned anywhere in response to activation problems.

Kevin.

 

Permalink 2 Comments

Next page »