More Windows (8) Update Woes

August 11, 2019 at 10:09 am (computers) (, , , )

That really nice Acer Iconia W510 tablet that I had such fun with before has started playing up again.  It isn’t clear from the wisdom of the Internet if I could put Windows 10 on it or not, but I did wonder if it was worth seeing if the free update was still working or not.  I haven’t yet, but the Windows 8.1 updates seem to have stopped again and I get a range of errors popping up, 0x800F0831 seems a favourite this time.  Apparently this isn’t in the list of common corruption errors, but, well, this is Windows, so who knows!?  It seems to be related to some kind of mismatch in applying updates.

I did wonder if it was getting too full (there is only 32GB onboard storage, and only around 1GB free) and so managed to get itself in a mess.  This post is by way of documenting some of the more useful suggestions I’ve found online for dealing with Windows update issues as I’ve tried to sort my issues out.

There does seem a ‘standard’ but complicated procedure for resetting Windows update (assuming the built-in troubleshooting doesn’t do any good).  There are two helpful Powershell scripts available here that can do all this for you, alongside details of all the manual steps involved too.  The only issue I found was that I had to temporarily change the signed execution policy to allow them to run.

In a “run as administrator” Powershell prompt, I had to do:

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process

Before running the script.  The slacking of policy should only be temporary (unlike some other suggestions I’ve seen which change it permanently).  Once the script has run, a reboot is required to kick everything off again.

Still no go for me though. Next up is some advice about using the tools sfc and dism – that’s the “system file checker” and “deployment image servicing and management” tools.  Full details of what they do can be found here and from Microsoft here, but the summary is:

sfc /scannow
dism.exe /Online /Cleanup-image /Scanhealth
dism.exe /Online /Cleanup-image /Restorehealth

That will do some basic checks of the running system image (sfc); check the health of the  running instance (dism /Scanhealth) and then repair it if required (/Restorehealth) using the online Windows Update servers as the reference source material. Nothing says this, but I assume you need to run sfc again after the two uses of dism, otherwise I’m not sure what the actual point is!  The /Online means “target the running operating system” rather than an actual file or other partition containing a non-running Windows image.

By the way if dism gets stuck at 20% or 40% apparently this is quite common – you’ll have to wait it out.  Eventually it will jump to 100% complete.

If your system is too corrupt then it looks like you can use dism from a working Windows installation to repair the image of a broken one or specify an alternative source of known good files if the link to Windows Update isn’t doing it for you.  I downloaded the 32-bit Windows 8.1 installation ISO from the MS download site and then dropped it onto a USB memory stick so it can be mounted from the tablet.

To specify a new reference source, use the switches /Online /Cleanup-image /Restorehealth /Source to specify a known good source of files.  You need to point to \sources\install.wim from the mounted ISO image.  It is also worth using /LimitAccess to stop it phoning home to Windows Update and using the Windows Update client.  More details again here.

It may be that this would have helped my Windows 10 boot problems I described before.

Kevin

 

Advertisements

Permalink Leave a Comment

3U 8HP 4 Channel Panning Mixer

July 14, 2019 at 7:01 pm (maker, music) (, , , )

As I mentioned in my last post, I used an off-the-shelf 4 channel mixer board in my synth-in-a-box, but I wanted it to be accessible as a eurorack modular panel.  I also wanted it to take mono inputs and be able to set the panning as required to the L or R channels of the mixer.  I managed to squeeze it into one of my 3U, 8HP panels.

Now I didn’t need an on/off switch, and I wanted some space to add a stereo output jack, so I removed the switch and soldered a couple of links in its place as can be seen in the bottom left of this photo.  The plan was to pass the pots through the panel and use leads to connect sockets to the inputs and output.

2019-07-09 19.17.12

The panning circuit was quite simple.  I found it in the book “Make: Analog Synthesizers” by Ray Wilson from MFOS.  In chapter 7 he describes a simple circuit to allow you to hook up your (mono) sound output to a (stereo) PC sound card. It involves a 10k pot and four 2k resistors, with the wiper of the pot connected to ground.  Full details can be found in the book.

For me, I was planning to just solder the resistors directly onto the pots and sockets and then use a short stereo cable to connect to the input sockets of the mixer.  This is all shown in the following photos (complete with my dodgy machining skills).

The four input sockets are mono of course, with the stereo input signal coming off the resistor network.  The output socket is stereo. I soldered the four resistors for each channel together first then “applied” them to the pot and socket.

Then it was just a case of adding the mixer itself and making a simple power cable from the 16-pin eurorack connector to the DC barrel jack.

I used the four knobs that came with the mixer as the pan-pot knobs, as they were nice and small.  Then I used some generic ebay knobs for the volume controls.

When it came to fixing into the rack, I ended up soldering on an additional stereo lead to the output so it can be routed internally straight to the amp.  So in normal use, the output socket isn’t needed, but I can power off the amp and use the output if I wanted to send the audio off to an external amp.

I’m really pleased with how it came out. Not bad for a $15 board and a handful of components.

Kevin

Permalink 1 Comment

Modular Synth in a Box

July 14, 2019 at 2:30 pm (maker, music) (, , , )

Inspired by Morocco Dave who built a small “almost 5U” modular synth case out of a plastic storage box, I have created one of my own.  My goal was to build something that could take Eurorack modules, so looking at around 3U high modules, so for me the best layout was a dual-rack layout with the box standing vertically as follows.

2019-06-16 15.33.08

The box is a common “9 litre” box, with rough external dimensions of approximately 40x25x15 cm.  Mine came from a local discount store.

I’ve just used a few pieces of wood for the cross-bars and covered them with some of that aluminium tape you can buy for patching up cars.  The measurements are taken from the Eurorack standards and based on the instructions from the Synth-DIY Modular Synth Cabinet Howto from MFOS, gives me around 44HP of module space.  Each module has around 10cm height of usable clearance for electronics and

I created two bus-bars following the 16-pin Eurorack power standard out of stripboard and build and connected up a PSU from Frequency Central (£10 for the PCB).  The whole thing is powered using a 12AC “wallwart” power supply via a barrel jack socket on the side.  I drilled out a grid of holes top and bottom to allow air to circulate.

In addition I created a set of USB sockets hanging off the +5V line from the PSU as some of the modules I’m using will be Arduino and similar based, being to power directly from USB will be really useful.  The PSU is probably not powerful enough for an entire rack full of modules, but the idea is to have a platform that allows experimenting and playing around with designs, so that isn’t a major issue right now.

In terms of power bus cabling, I have a whole pile of old IDE cables so I picked up a bulk set of 16-pin IDC connectors and can now make my own bus cables.  The first one was the connector shown in the first photos, linking the PSU to the two stripboard buses.

I wanted a cheap way to make panels for modules, and in the end opted for a supplier on ebay who provides 2m lengths of 2x40mm wide flat aluminium bars.  This particular supplier also included some basic cutting, so for less than £25 I’ve ended up with a whole pile of approx. 260x40x2mm aluminium panels I can cut further as required.

I just use a wire brush to give a “brushed aluminium” finish.  If you want to follow this path, look up “aluminium flat bar” on ebay, and be warned that a cheap supplier will not be giving you accurate dimensions if cutting them for you!  I know 40mm wide isn’t a standard “HP” module width, but as it is almost 8HP, its fine for me.

One thing I was particularly keen to do was have a complete “synth in a box” and by that I wanted to include some basic amplification and speakers.  I had some speakers from an old CRT TV set that seemed pretty good for their size, so then looked around for means of amplification and mixing.  Again basic modules on ebay solved this for me, and I ended up with a cheap 4-way mixer board ($14) and amplifier ($5).  The mixer is based on a NJM3414 low-voltage, high-current op-amp and the amplifier is based on a TDA7297.  Both can be powered from a 12v supply and the amplifier claims 2x15W output.

I’ve built the mixer into a panel and added some simple panning “front ends” to each input, but I’ll leave details of how I did that for another time.  For now, here is the basic case with built-in stereo speakers and amp.

Being able to just unplug the power and pick the whole thing up is great.

My physical construction skills are not particularly great.  I don’t have the patience to do a really good job, and don’t have the skills, tools or experience for anything approaching any kind of professional finish.  But for a homemade “just for me” project,  I’m really please with the results.

Kevin

 

 

Permalink 1 Comment

Surfing on Entropy

March 21, 2019 at 10:28 am (art, computers, music) (, , , )

I was passed a link to this interesting comment from Brian Eno: “There is not enough Africa in computers” (thanks Richard).

I’ve now read this a couple of times and was still left wondering quite what lay behind the comment.  So I tried to find the original interview between Kevin Kelly (then editor of Wired I believe) and Brian Eno so I could read it in full.  Unfortunately it isn’t on the same link anymore, but with some googling, you can find it in the Wired archive here.

There are a number of really fascinating discussion points – I really recommend reading the whole article – and it provides the context for that isolated quote. I did find some of the answers a little contradictory at times though.

A disclaimer, to date the music and views of Brian Eno seems to have passed me by, so these comments start with this interview in isolation. I look forward to seeing what he would say now and finding more about his ideas of generative music.

On the one hand I believe he is saying he doesn’t like the “set it in motion and it will perform predictably” aspect of computers – he likes the idea of providing inspiration and guiding principles that may or may not produce something depending on the live inputs of the viewer/reader/listener – he appears to like the serendipity of it all … but later on he talks of “black boxes for music” where he has set the rules and the box produces the music according to those rules, with some input from the listener depending on their mood.  The box become some combination of player and instrument if I understand his view correctly.

Right near the start of the interview, he suggests that the orchestral tradition is too constraining, but I see it as a (more limited admittedly) set of programmable components ready to do the composer’s bidding.

When you look at how the orchestra developed from Mozart’s time through the Romantic period, contrasting those early Classical period works with Beethoven, Brahms and then the later large scale deployments of Mahler, there is quite a lot of scope for variability there and the basic “machine” evolved enormously through that time. Then when you look at what Stravinsky did in his ballet music or what Debussy did with his completely alternative view of harmony through to the likes of Messiaen recreating birdsong in his Turangalia symphony (including incorporating the electronic Ondes Martinot), then as a “programmable box” an orchestra is actually quite a versatile person/machine system in action.

I guess he doesn’t like the idea that a composer sets the rules and the orchestra is then condemned to just reproduce them.  But I wonder what he thinks about jazz and improvisation? Good jazz still follows rules, but every performance is different. But it isn’t random. Is a jazz ensemble “more Africa” than an orchestra?  Or maybe it is a matter of the illusion on unpredictability.  When I look at something like the Long Player – that is a key set of rules, and you exactly determine what the music will be at any point – but the cycle is so long (designed to last a thousand years) that every time you dip into it, you don’t really know what you will hear.  Or at the other end, is John Cage’s As Slow as Possible where you can go back after several months and the music is still exactly the same.

I guess some of this relates to the difference between analogue and digital.  Digital is obsessed with chopping up the analogue reality into small measurable chunks – be that discrete frequencies that we call semitones in Western music, pixels on a computer screen, or even the digitising of the end results as a digital bit stream to be played back via audio hardware off a CD or MP3.  But even when digital and in theory part of a finite space, that space is so vast as to approximate to the entire musical repertoire or pictorial output of any artist, composer or musician (as least as far as human senses are concerned).

I’ve always been fascinated with the idea of the computer screen representing an unimaginably large single number and that counting through them all would show every possible image that screen could display.

In theory the digitisation of music could be represented the same way – if every note on the piano keyboard had a number 1 to 88, then a piece of music (forgetting rhythm for the moment) is essentially one very long base 88 number.  That’s not too dissimilar to how a pianola worked, although physical layout of the cut-outs are key here, or even MIDI in today’s world, when linked with a sense of the flow of time of course.  I remember my school having a dictionary of musical themes and it basically worked on those lines (although it only worried about a single octave, so it was essentially a 5-10 digit “base 7” number).  I’ve always wanted that book, but so far have never seen one since.

So just because things can be reduced to number and handled by computer, is that any less “Africa” than a free-flowing analogue equivalent?  I guess a key distinction is not necessarily digital vs analogue, but more pre-determined vs unpredictable.

In a weird way, fast forward these last 20 years and computers have become so complex as to be largely unpredictable to many.  Now that these already complex machines are hooked up to the even more complex global machine that is “the Internet” (by whichever definition to choose to use – remember it is just a series of tubes), then most of us would be hard pushed to be convinced by the argument that computers are things that always behave the same way based on the same inputs.

I am reminded here of Bjarne Stroustrup when he said (I believe): “I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone.”

I’m also reminded of the fact that computers may soon be able to pass the Turing Test, not because they’ve become as smart as humans, but possible because there is a real possibility that humans are becoming as dumb as computers…

Back to Brian Eno:

“What people are going to be selling more of in the future is not pieces of music, but systems by which people can customize listening experiences for themselves.  Change some of the parameters and see what you get.”

He was after unfinished pieces of musical ideas to be combined in a new form as the listener experiments.  Of course, in a sense he was overestimating the listeners – today listeners want “customized listening experiences” but at the granularity of the song, the tune, not the musical extract or idea or concept.  And they don’t really want the effort of having to produce it themselves.  Of course they have it in droves with on-demand streaming where algorithms are “changing the parameters” on your behalf.

His ideas for evolutionary music and art may still come about, but again probably more by presaging the idea of algorithms creating music and art. But does that make the algorithms the composers and painters?  The jury is still out on that one, but he may well get his “furniture music” this way – his “ubiquitous 24 hours a day” music “infiltrating every waking moment of our lives”.

It is interesting his view on the use of machines.  He suggest we all need to be “surfing on entropy” – to be able to ride the wave of unpredictability and complexity becoming apparent.  I think that is very, very apt today, but the huge irony here being that this unpredictability and complexity has come about by the very components he considered too constrained, “not enough Africa”, now being let loose as they’ve grown more powerful and complex, on the world.

Machines are no longer doing “predictable, boring and repetitive things” – they are the very instruments of uncertainty.  We can still exert influence – by surfing the wave of complexity:

“When you surf, there is a powerful complicated system, but you’re riding on it, you’re going somewhere on it, and you can make some choices about it.”  You either ride it an use it with skill to get your own direction, or you give up and go with the flow.

There is an interesting section discussing the difference between art and science.  Art “doesn’t make a difference” – in that he means that whilst art will stimulate emotions, create large emotional experiences (e.g. watching a film) then end when the experience ends.  Of course, with today’s blended and mixed reality, is that still the case?

A fascinating read, especially with the benefit of 20 years passing in the mean time. The context might be slightly different, but many of the thoughts are still amazingly apt for today.  I’d love to know what he thinks about these thoughts again today.

Kevin

 

Permalink Leave a Comment

ATtiny85 MIDI to CV

March 2, 2019 at 4:07 pm (maker, music) (, , , )

There are a number of projects out there that provide a MIDI to CV function utilising some flavour of the ATtiny family of microcontrollers.  But most of them go from USB MIDI to CV but I wanted a genuine 5-pin DIN MIDI to CV.  This was the result.

It has taken a basic MIDI in circuit from the Internet (Google will find a few of these kicking around) and pairs it with the ATtiny85 CV out section of Jan Ostman’s cheap USB MIDI 2 CV design.

Update: Jan Ostman has now written a tutorial on how to do this directly using the USI on the ATtiny85. Read it directly from the expert here http://blog.dspsynth.eu/diy-good-ol-midi-to-cv/

The result is as follows (excuse the poor representation in Fritzing, it served its purpose). Note that the 6N138 only had 5 active pins in the Fritzing part, so the extra dodgy link shown below is a fudged link for pin 7 to GND via a 4.7k resistor.

MIDItoCV2_schem

I also have a version for the ATtiny2313, but the main changes are as you’d expect.  Basically I was having problems with the ATtiny85 missing MIDI messages and wondered if a hardware UART would be better.  Turned out it was just my dodgy code with no real error checking getting out of sync with the MIDI stream.  But it took trying it on a 2313 to highlight the real issue, so back to the ATtiny85 and now all is well.

Design wise, its fairly simple ATtiny85 wise with the pin usage as follows:

  • SoftwareSerial receive on D3 (PB3) which is physical pin 2.
  • Gate output on D2 (PB2) which is physical pin 7.
  • CV output using the PWM signal tied to OC1A triggered off timer 1, which is D1 (PB1) on physical pin 6.

The code uses the same trick that Jan Ostman used in his code – if the top compare value for PWM operation is 239 then there are 240 graduations for PWM.  To cover a MIDI range of C2 (note 36) to C7 (note 96) is 60, so the PWM compare value required for a linear CV voltage output is basically (note-36)*4.

In terms of timer control registers, this all translates over to (refer to the ATtiny85 data sheet):

  • Set PWM1A i.e. PWM based on OCR1A
  • Set COM1A1 i.e. Clear OC1A (PB1) output line
  • Set CS10 i.e. Prescaler = PCK/CK i.e. run at Clock speed
  • Clear PWM1B is not enabled (GTCCR = 0)

The value for the PWM cycle is set in OCR1C to 239, and the compare value is set in OCR1A between 0 and 239, thus representing a range of 0 to 5v giving 1v per octave, assuming a 5v power supply.

When porting to the ATtiny2313, a similar scheme was used, but timer 1 is a 16 bit timer, and the control registers were slightly different, but I still used the 0-239 range.

Reading around the different modes, I ended opting for the use of Fast PWM with the compare value in OCR1A and the maximum PWM cycle value (239) in ICR1.  The timer register settings were thus as follows:

Timer 1 Control Register A (TCCR1A):

  • 7 COM1A1 = 1 COM1A1(1); COM1A0(0) = Clear OC1A on compare match; set at TOP
  • 6 COM1A0 = 0
  • 5 COM1B1 = 0
  • 4 COM1B0 = 0
  • 3 Resv = 0
  • 2 Resv = 0
  • 1 WGM11 = 1 WGM11(1); WGM10(0) = PWM from OCR1A based on TOP=ICR1
  • 0 WGM10 = 0

Timer 1 Control register B (TCCR1B):

  • 7 ICNC1 = 0
  • 6 ICES1 = 0
  • 5 Resv = 0
  • 4 WGM13 = 1 WGM13(1); WGM12(1) = PWM from OCR1A based on TOP=ICR1
  • 3 WGM12 = 1
  • 2 CS12 = 0 CS12(0); CS11(0); CS10(1) = Prescaler = PCK/CK i.e. run at Clock speed
  • 1 CS11 = 0
  • 0 CS10 = 1

Timer 1 Control Register C left all zeros.

I don’t know if it was the version of the ATtinyCore I was using, but the bit and register definitions for Timer1 for the ATtiny2313 didn’t seem to match the datasheet, so I just used the bit codes directly.

In terms of ATtiny2313 pin definitions, the following were used:

  • Hardware serial receive on D0 (PD0) which is physical pin 2.
  • Gate output on D11 (PB2) which is physical pin 14.
  • CV output using the PWM signal tied to OC1A triggered off timer 1, which is D12 (PB3) on physical pin 15.

A quick note on the MIDI serial handling.  My first code was very lazy and basically said:

Loop:
  IF (serial data received) THEN
    read MIDI command value
    IF (MIDI note on received) THEN
      read MIDI note value
      read MIDI velocity value
      set CV out value based on MIDI note value
      set Gate signal HIGH
    ELSE IF (MIDI note off received) THEN
      read MIDI note value
      read MIDI velocity value
      set CV out value based on MIDI note value
      set Gate signal LOW
    ELSE
      ignore and go round again waiting for serial data
    ENDIF
  ENDIF
END Loop

This generated a very quirky set of issues.  Basically when there was serial data available and a MIDI note on or off command detected, the read of the note and velocity data was returning and error (-1) which I never bothered checking.  Basically the code was running too fast and the next MIDI byte hadn’t registered yet.  So when (-1) was passed on as the MIDI note, it was resulting in a note on code thinking the MIDI note was 255, which was rounded up to the highest note (96).

The result was that I could see the gate pulsing in response to MIDI note on and off messages, but the CV voltage went high as soon as the first MIDI message was received.

The next version used test that said

IF (at least three bytes of serial data received) THEN

which means that if things get out of sync, eventually bytes are skipped until there are three bytes that equate to a note on/off message.  Crude, but it worked enough to show the principle.

The final code includes proper handling of the “Running Status” of MIDI, as described here: http://midi.teragonaudio.com/tech/midispec/run.htm

I used the 8MHz internal clock for the ATtiny85.

To test all of it together, I used my ATtiny85 MIDI Tester.

I might add some kind of selection for the MIDI channel.  Right now its hard-coded in a #define.  One option might be using an analogue input and a multi-position switch with a resistor network.  Or maybe a “tap to increase the channel” digital input switch.  Or if I use the 2313 version, I could use more pins and use a BCD or hex rotary switch or DIP switches.

2019-03-02 16.00.27

Here is the full code for the ATtiny85 version, which can be loaded up from the Arduino environment using the ATtiny85 core by Spence Konde. 

// MIDI to CV using ATTiny85
// NB: Use Sparkfun USB ATTiny85 Programmer
//     Set Arduino env to USBTinyISP
//     Set to 8MHz Internal Clock (required for MIDI baud)
#include <SoftwareSerial.h>

#define MIDIRX 3  // 3=PB3/D3 in Arduino terms = Pin 2 for ATTiny85
#define MIDITX 4  // 4=PB4/D4 in Arduino terms = Pin 3 for ATTiny85
#define MIDICH 2
#define MIDILONOTE 36
#define MIDIHINOTE 96

// Output:
//  PB2 (Ardiuno) = Pin 7 = Gate Output
//  PB1 (Arduino) = Pin 6 = Pitch CV Output
//
// PB5 set as digital output
// PB1 used as PWM output for Timer 1 compare OC1A
#define GATE    2  // PB2 (Pin 7) Gate
#define PITCHCV 1  // PB1 (Pin 6) Pitch CV

SoftwareSerial midiSerial(MIDIRX, MIDITX);

void setup() {
  // put your setup code here, to run once:
  midiSerial.begin (31250); // MIDI Baud rate

  pinMode (GATE, OUTPUT);
  pinMode (PITCHCV, OUTPUT);

  // Use Timer 1 for PWM output based on Compare Register A
  // However, set max compare value to 239 in Compare Register C
  // This means that output continually swings between 0 and 239
  // MIDI note ranges accepted are as follows:
  //    Lowest note = 36 (C2)
  //    Highest note = 96 (C7)
  // So there are 60 notes that can be received, thus making each
  // PWM compare value 240/60 i.e. steps of 4.
  //
  // So, for each note received, PWM Compare value = (note-36)*4.
  //
  // Timer 1 Control Register:
  //   PWM1A = PWM based on OCR1A
  //   COM1A1 = Clear OC1A (PB1) output line
  //   CS10 = Prescaler = PCK/CK i.e. run at Clock speed
  //   PWM1B is not enabled (GTCCR = 0)
  //
  TCCR1 = _BV(PWM1A)|_BV(COM1A1)|_BV(CS10);
  GTCCR = 0;
  OCR1C = 239;
  OCR1A = 0; // Initial Pitch CV = 0 (equivalent to note C2)
  digitalWrite(GATE,LOW); // Initial Gate = low
}

void setTimerPWM (uint16_t value) {
  OCR1A = value;
}

void loop() {
  if (midiSerial.available()) {
    // pass any data off to the MIDI handler a byte at a time
    doMIDI (midiSerial.read());
  }
}

uint8_t MIDIRunningStatus=0;
uint8_t MIDINote=0;
uint8_t MIDILevel=0;
void doMIDI (uint8_t midibyte) {
  // MIDI supports the idea of Running Status.
  // If the command is the same as the previous one, 
  // then the status (command) byte doesn't need to be sent again.
  //
  // The basis for handling this can be found here:
  //  http://midi.teragonaudio.com/tech/midispec/run.htm
  //
  // copied below:
  //   Buffer is cleared (ie, set to 0) at power up.
  //   Buffer stores the status when a Voice Category Status (ie, 0x80 to 0xEF) is received.
  //   Buffer is cleared when a System Common Category Status (ie, 0xF0 to 0xF7) is received.
  //   Nothing is done to the buffer when a RealTime Category message is received.
  //   Any data bytes are ignored when the buffer is 0.
  //

  if ((midibyte >= 0x80) && (midibyte <= 0xEF)) {
    //
    // MIDI Voice category message
    //
    // Start handling the RunningStatus
    if ((midibyte & 0x0F) == (MIDICH-1)) {
      // Store, but remove channel information now we know its for us
      MIDIRunningStatus = midibyte & 0xF0;
      MIDINote = 0;
      MIDILevel = 0;
    } else {
      // Not on our channel, so ignore
    }
  }
  else if ((midibyte >= 0xF0) && (midibyte <= 0xF7)) {
    //
    // MIDI System Common Category message
    //
    // Reset RunningStatus
    MIDIRunningStatus = 0;
  }
  else if ((midibyte >= 0xF8) && (midibyte <= 0xFF)) {
    //
    // System real-time message
    //
    // Ignore these and no effect on the RunningStatus
  } else {
    //
    // MIDI Data
    //
    if (MIDIRunningStatus == 0) {
      // No record of state, so not something we can
      // process right now, so ignore until we've picked
      // up a command to process
      return;
    }
    // Note: Channel handling has already been performed
    //       (and removed) above, so only need consider
    //       ourselves with the basic commands here.
    if (MIDIRunningStatus == 0x80) {
      // First find the note
      if (MIDINote == 0) {
        MIDINote = midibyte;
      } else {
        // If we already have a note, assume its the level
        MIDILevel = midibyte;

        // Now we have a note/velocity pair, act on it
        midiNoteOff (MIDINote, MIDILevel);
        MIDINote = 0;
        MIDILevel = 0;
      }
    } else if (MIDIRunningStatus == 0x90) {
      if (MIDINote == 0) {
        MIDINote = midibyte;
      } else {
        // If we already have a note, assume its the level
        MIDILevel = midibyte;
        
        // Now we have a note/velocity pair, act on it
        if (MIDILevel == 0) {
          midiNoteOff (MIDINote, MIDILevel);
        } else {
          midiNoteOn (MIDINote, MIDILevel);
        }
        MIDINote = 0;
        MIDILevel = 0;
      }
    } else {
      // MIDI command we don't process
    }
  }
}

void midiNoteOn (byte midi_note, byte midi_level) {
  // check note in the correct range of 36 (C2) to 90 (C7)
  if (midi_note < MIDILONOTE) midi_note = MIDILONOTE;
  if (midi_note > MIDIHINOTE) midi_note = MIDIHINOTE;

  // Scale to range 0 to 239, with 1 note = 4 steps
  midi_note = midi_note - MIDILONOTE;

  // Set the voltage of the Pitch CV and Enable the Gate
  digitalWrite (GATE, HIGH);
  setTimerPWM(midi_note*4);
}

void midiNoteOff (byte midi_note, byte midi_level) {
  // check note in the correct range of 36 (C2) to 90 (C7)
  if (midi_note < MIDILONOTE) midi_note = MIDILONOTE;
  if (midi_note > MIDIHINOTE) midi_note = MIDIHINOTE;

  // Scale to range 0 to 239, with 1 note = 4 steps
  midi_note = midi_note - MIDILONOTE;

  // Set the voltage of the Pitch CV and Enable the Gate
  digitalWrite (GATE, LOW);
  setTimerPWM(midi_note*4);
}

 

Permalink Leave a Comment

ATtiny85 MIDI Tester

January 25, 2019 at 10:28 pm (maker, music) (, , )

Having spent some time messing about with building simple synthesizer circuits, I’m putting together a simple MIDI to CV converter.  I have one using an ATtiny85 but think I’m struggling from the fact it is only using SoftwareSerial, so I plan to have another go with an ATtiny231w pretty soon now.

One thing I was missing though was a simple “hands free” MIDI tester.  Now it would be fairly simple to hook up my laptop or a keyboard to a MIDI cable and use that, but I wanted something I could just plug in and leave sending MIDI data out to whatever I was building.  So the idea of using a simple USB-powered ATTiny85 to creating a continuous set of MIDI note on and not off messages was born.

I’m using one of those cheap Digispark USB clones you can buy. I had no luck ever getting the USB programming side of it to work, (its supposed to be able to have the nucleus boot loader installed to provide a software USB implementation), but its easy to programme if you have an 8-pin DIL test clip, in my cased hooked up to a sparkfun tiny programmer.

2019-01-25 21.22.26

Basic design notes for the board:

  • P1 (equivalent to Arduino D1 and the ATtiny85 pin 6) has the built-in LED.
  • I’m using P2 as MIDI TX and P3 as (unused) MIDI RX (D2 and D3, mapped to ATtiny85 pins 7 and 2).
  • P0 (ATtiny85 pin 5) as a digital input with internal pull-up resistors enabled.

I’m using a simple MIDI out circuit from the Internet that shows:

  • DIN pin 5 – MIDI OUT signal directly connected to P2.
  • DIN pin 2 – MIDI ground.
  • DIN pin 4 – MIDI +5v via a 220R resistor.

The resistor was soldered inside an in-line female MIDI DIN socket.

2019-01-25 21.36.522019-01-25 21.42.10

A switch was soldered across from P0 to GND on the Digispark board.  The code will flash the LED when the switch is registered so you know you’ve done something.

That is pretty much it.

2019-01-25 21.51.47

2019-01-25 21.51.56

In terms of code, I just tested it with an increasing scale of a few octaves, with the switch being used to increase the tempo (by reducing the delay between notes). Of course, you can use whatever test pattern works for you.

My initial (simple) code below.

Important: You must “set the fuses” to use the internal 16MHz clock in order to get the MIDI baud rates for the SoftwareSerial implementation.

Kevin

// MIDI Code Test Generator using ATtiny85
// NB: Use Sparkfun USB ATtiny85 Programmer
//     Set Arduino env to USBTinyISP
//     Set 16MHz Internal Clock (required for MIDI baud)
#include <SoftwareSerial.h>

// Pin Mapping for DigiSpark USB/ATtiny85
//  P0 = PB0/D0 = Pin 5 Attiny85
//  P1 = PB1/D1 = Pin 6 - built-in LED
//  P2 = PB2/D2 = Pin 7
//  P3 = PB3/D3 = Pin 2 - wired to USB+
//  P4 = PB4/D4 = Pin 3 - wired to USB-
//  P5 = PB5/D5 = Pin 1 - wired to RESET
//
// Use the Arduino D numbers below (which are the same as Digispark P numbers)
#define MIDITX   2
#define MIDIRX   3
#define BUTTON   0
#define BLTINLED 1

// MIDI Parameters for testing
#define MIDI_CHANNEL     1
#define MIDI_LOWNOTE     36
#define MIDI_HIGHNOTE    90
#define MIDI_VELOCITY    64
#define MIDI_DELAYMAX    550
#define MIDI_DELAYMIN    50
#define MIDI_DELAYSTEP   100

#define MIDI_NOTEON      0x90
#define MIDI_NOTEOFF     0x80

SoftwareSerial midiSerial(MIDIRX, MIDITX);

int delayRate;
int buttonState;
int lastButtonState;
byte midiNote;

void setup() {
  // Switch will trigger HIGH->LOW
  pinMode (BUTTON, INPUT_PULLUP);
  pinMode (BLTINLED, OUTPUT);
  digitalWrite (BLTINLED, LOW);
  buttonState = HIGH;
  lastButtonState = HIGH;
  
  midiSerial.begin (31250); // MIDI Baud rate

  delayRate = MIDI_DELAYMAX;
  midiNote  = MIDI_LOWNOTE;
}

void loop() {
  buttonState = digitalRead (BUTTON);
  if ((lastButtonState == HIGH) && (buttonState == LOW)) {
    ledOn();
    delayRate = delayRate - MIDI_DELAYSTEP;
    if (delayRate < MIDI_DELAYMIN) delayRate = MIDI_DELAYMAX;
  }
  lastButtonState = buttonState;

  midiNoteOn (MIDI_CHANNEL, midiNote, MIDI_VELOCITY);
  delay (400); // Need note on long enough to sound
  midiNoteOff (MIDI_CHANNEL, midiNote);
  delay (delayRate);

  midiNote++;
  if (midiNote > MIDI_HIGHNOTE) midiNote = MIDI_LOWNOTE;
  
  ledOff();
}

void midiNoteOn (byte midi_channel, byte midi_note, byte midi_vel) {
  midiSerial.write (midi_channel+MIDI_NOTEON);
  midiSerial.write (midi_note);
  midiSerial.write (midi_vel);
}

void midiNoteOff (byte midi_channel, byte midi_note) {
  midiSerial.write (midi_channel+MIDI_NOTEOFF);
  midiSerial.write (midi_note);
  midiSerial.write ((byte)0);
}

void ledOn () {
  digitalWrite (BLTINLED, HIGH);
}

void ledOff () {
  digitalWrite (BLTINLED, LOW);  
}

Permalink 1 Comment

Arduino Nano “USB Device Not Recognised” Fix

January 19, 2019 at 5:06 pm (maker) (, , , )

I have quite a range of Arduino Nano boards of varying vintage, but I’ve found some always come up with “USB Device Not Recognised” in Windows and wanted to work out why.  Symptoms are:

  • all fine if powered externally or via the ISP header.
  • “USB Device Not Recognised” errors otherwise.

These are Arduino Nano v3.0 boards I believe, and it turns out there is a known issue where the TEST pin of the FTDI chip isn’t correctly grounded, which makes the boards unreliable at best, and constantly failing at worst.

The faulty boards look like this:

arduino nano ftdi - toparduino nano ftdi - bottom

Notice the FTDI chip on the bottom of the board – this is the cause of the issue.  Many of the other cheap clones of the Arduino Nano use the CH340 chip, these don’t seem to have a similar issue.  For reference, they look like something like this instead:

arduino nano ch340 - bottom

The fix for the issue is described here on the Arduino Forums: http://forum.arduino.cc/index.php/topic,23025.0.html

But you will need your soldering iron and a very steady hand (and probably a magnifying glass).  Basically the poster shorted pins 26 (TEST) and 25 (AGND) on the chip and that seems to do the trick.  These pins (3rd and 4th from the top right hand side of the chip) are highlighted below (see the FT232RL datasheet for details).

arduino-nano-ftdi-fix.jpg

ftdi-ft232rl-pinout

Attempt the fix at your own risk of course.  Double check the part number of the chip, the orientation with the spot and the datasheet for the part number you are reading on the chip before you go near the soldering iron.

It worked for me.  YMMV.

Kevin

 

Permalink Leave a Comment

Dual ScrollPhatHD 17×14 LED Array

January 13, 2019 at 12:31 pm (maker) (, , , , , )

Having now had a play with my ScrollPhatHDs with the Arduino I’ve now successfully linked two together via a TCA9548A breakout board (having solved my Weird Multi-I2C Bus Issues as previously described).

The ultimate aim was to make a self-contained unit containing two ScrollPhatHD boards, an Arduino Nano and the TCA9584A.  I’ve now managed that using a square piece of breadboard, various jumper wires and most importantly, the Pimoroni Pogo-a-go-go Solderless header pins – I just didn’t want to spoil the neat look of the ScrollPhatHD’s by soldering to them directly.  The Pogo-pins are just perfect for spring-loaded connections between the ScrollPhatHDs and breadboard.

The one quirk, is that if I wanted all boards nicely sandwiched between the ScrollPhatHDs and the breadboard, but wanted to use the pogo-pins, then the breadboard needs to be strip-side up.

Here is the plan, followed by some photos of the finished item.

scrollphat-breakout_bb

I’ve left the nano and tca breakout off, so I can see the tracks.  This was from a first experiment with the two Phats, so it already had three full height sets of cuts in tracks – hence the few places where there were a couple of bits of patching to do, which were just done with solder links.  There are a few pins added to support the nano, especially at the USB end where I’ll be plugging in and out, which aren’t connected to anything on the stripboard.  And the four pins highlighted for the two ScrollPhat’s themselves weren’t soldered pins – that is the location for the pogo-pins.

In the final board, I put the jumper wires on the underside, and used headers pushed right through from below.  I also added a reset switch (not shown in the plan) wired to the Nano RST and ground on the strip board.

The linking of the two Phats isn’t perfect – the Nano USB port is just a fraction too high to perfectly fit, meaning the two boards bow out slightly in the middle.  Note the use of the pogo-pins.  I could replace them all with a slightly longer stand-off, but this is fine for a prototype.

Also, I made sure to drop some insulating tape on the bottom of both the Nano and the TCA board, to make sure it wouldn’t short anything on the copper of the stripboard.  I also put a bit around the shield of the USB port just in case, but I don’t think there was anything conductive on the back of the Phat.

So I now have a USB-accessible, self-contained, programmable 17×14 LED array.

Software wise, this uses the modified Adafruit IS31FL3731 Library I mentioned before, with the added quirk that one of the boards needs the coordinates reversing.  Coupled with the need to switch boards using the TCA as well, this means the basic idea of using the board is as follows:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <ScrollPhat_IS31FL3731.h>

// ScrollPhats connected using a TCA9548A I2C Multiplexer
// These are the I2C bus numbers used
#define TCAONE       0
#define TCATWO       1

//  HOR = number in horizontal (x) plane
//  VER = number in vertical (y) plane
#define HOR 17
#define VER 14

// Scrollphats have a hardcoded I2C address.
// Assumes connected as follows:
//      ledmatrix1 - using SC0 via the TCA
//      ledmatrix2 - using SC1 via the TCA
ScrollPhat_IS31FL3731 ledmatrix1 = ScrollPhat_IS31FL3731();
ScrollPhat_IS31FL3731 ledmatrix2 = ScrollPhat_IS31FL3731();

#define TCAADDR 0x70
void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

void setup () {
  // Initialse the I2C handling
  Wire.begin();
  
  tcaselect(TCAONE);
  ledmatrix1.begin();
  tcaselect(TCATWO);
  ledmatrix2.begin();
    
  // Do something to initialse your pixel array
}

void loop () {
  // Do stuff on your pixel array
  // Don't forget to write the displayRead(x,y) function
  // used in the scan routine

  ScanDisplay();
}

// Note: you need to implement the displayRead (x,y) function
//      to determine if a pixel is on or off
//
void ScanDisplay () {
  // Scan the first matrix
  tcaselect(TCAONE);
  for (uint8_t x=0; x<HOR; x++) {
    for (uint8_t y=0; y<VER/2; y++) {
      if (displayRead (x, y)) {
        ledmatrix1.drawPixel(x, y, 64);
      } else {
        ledmatrix1.drawPixel(x, y, 0);
      }
    }
  }

  // Scan the second matrix
  // Note this is oriented 180 degrees, so reverse both
  // x and y prior to setting, also of course, only using
  // the second half of the pixel array to display here.
  tcaselect(TCATWO);
  for (uint8_t x=0; x<HOR; x++) {
    for (uint8_t y=0; y<VER/2; y++) {
      if (displayRead (HOR-x-1, VER/2-1-y+VER/2)) {
        ledmatrix2.drawPixel(x, y, 64);
      } else {
        ledmatrix2.drawPixel(x, y, 0);
      }
    }
  }
}

 

Kevin

Permalink Leave a Comment

Weird Multi-I2C Bus Issues

January 11, 2019 at 8:17 pm (maker) (, , , )

This is just a quick post as a future reminder really.  I have two ScrollPhat HD Pimoroni boards that I’m using with an Arduino Nano, but as the I2C address is fixed for the boards, I’m using a TCA9548A I2C multiplexer breakout board to change I2C buses between accessing the two ScrollPhatHD boards.

But I was getting weird bus issues – sometimes only one of the boards came up, sometimes none, very occasionally, they were both fine.  I tried different channels off the TCA, swapping the boards over, I tried linking the RESET line of the TCA to the RESET line of the Arduino.  I even tried connecting the RESET line of the TCA to a digital pin and resetting the TCA manually on power up, but nothing seemed to work.

Then I saw a post somewhere about some weird I2C bus issues and one of the responses was “make sure you are calling Wire.begin();”.  I’d forgotten to put that in.

Once the code was calling Wire.begin() (only once mind), all was well.  It now powers up reliably and no resetting of the TCA is required.  All is good.

Kevin

 

Permalink 1 Comment

Pogo-pin ISP Programming Header

January 9, 2019 at 8:20 pm (maker) (, , , )

I have a batch of Arduino Nanos that have been used on projects but now don’t seem to accept a download unless I burn a new bootloader to them.  I have an excellent USBasp  ISP programmer to do that, but connecting to unpopulated ISP header pads on a nano without taking it out of a project is a bit fiddly, so I wanted a pogo-pin ISP header programmer.

But this is one of those times where I just haven’t seemed to hit on the right search terms to bring one up to buy.  So after a bit of experimenting, I’ve made my own.

Shopping list:

  • Cheap pogo-pins (I grabbed a pack of 50 from China).
  • “Dupont” crimp headers for a 3×2 header block (I got a multi-pack with a range of headers and male and female crimp inserts).
  • Your favourite ISP programmer of course.

2019-01-09 19.39.47

The idea is the solder the pogo-pins into the crimp part of the pins instead of a cable, and end up with a two-sided 3×2 header blog – pins on one side, pogo-pins on the other, as follows:

2019-01-09 19.41.142019-01-09 19.40.002019-01-09 19.55.20

The only thing to watch out for is getting the pins straight enough to make a neat 3×2 grid that will line up with header pads.  This can then be inserted in your ISP adapter header in the usual way.

2019-01-09 19.56.30

The only downside for me is that the pins are a little small still to make a perfect connection to an unpopulated set of header pads with solder holes.  But its more reliable than just poking an unsoldered 3×2 header block in the holes, which is what I was doing before.

Its a pretty simple idea, but I’ve just not seen anything like it around to buy off the shelf, or described in any kind of diy manner.  Let me know if you know of a better (cheap) solution.

Kevin

Permalink Leave a Comment

Next page »