genuinequality

Download free music MP3s on genuine quality, the world’s largest online music catalogue, powered by your scrobbles. Free listening, videos, photos, The world’s largest online music catalogue, powered by your scrobbles. Free listening, videos, photos, stats, charts, biographies and concerts. stats, charts, biographies and concerts.

Monday, October 28, 2024

Arduino Euclidean Gate Sequencer – Part 4

In this posts I describe a version of the Arduino Euclidean Gate Sequencer that implements the same user interface and most of the features of HAGIWO's brilliant build. Part 1 covered all the theory and main functions of the code. Part …
Read on blog or Reader
Site logo image Simple DIY Electronic Music Projects Read on blog or Reader

Arduino Euclidean Gate Sequencer – Part 4

By Kevin on October 28, 2024

In this posts I describe a version of the Arduino Euclidean Gate Sequencer that implements the same user interface and most of the features of HAGIWO's brilliant build.

  • Part 1 covered all the theory and main functions of the code.
  • Part 2 included some hardware suggestions for connecting it to other devices.
  • Part 3 added a rotary encoder and I2C display and demonstrated by Arduino Clock Generator Shield PCB.

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

If you are new to Arduino, see the Getting Started pages.

Parts List

  • Arduino Uno.
  • Arduino Clock Generator Shield PCB.
  • Drum trigger hardware.

In principle this could use the same hardware as described in Part 3 but I'm using my PCB as it makes everything a lot easier to test and use.

Introduction and Core Functionality

There is a really good demonstration of HAGIWO's build in this video: https://www.youtube.com/watch?v=lkoBfiq6KPY

HAGIWO's screen is shown above and has the following features:

  • 6 channel outputs each with 16 steps.
  • 16 different Euclidean patterns, represented by polygons on the display.
  • Patterns can be offset by up to 16 steps.
  • Patterns can have the number of steps reduced or limited down to a single step.
  • Channels can be muted.
  • There is a random mode that sets all parameters in a random, but still musically useful, way.

The menus are navigated by means of a rotary encoder and switch and it expects an external clock signal, as it is designed for use in a Eurorack setup.

I'm not bothered about the random mode, but I want to implement a built-in clock source with its own tempo control, similar to that shown in Part 3.

The Code

HAGIWO's code is implemented in a single loop function, using IO interrupts with the Enc rotary encoder library, which means the encoder has to be on pins 2 and 3 on an Uno.

I want to keep my timer-driven GATE outputs and will be polling the encoder using the library from Matthias Hertel (https://github.com/mathertel/RotaryEncoder) which means essentially I'm going to be doing a re-implementation rather than a port of HAGIWO's code to my hardware.

I've reused all the user interface design elements though (apart from the random mode) even though the implementation has been tweaked slightly.

Once again I have two main threads of code:

  • A 10mS tick that handles the GATE outputs and timings subject to the current selected tempo. I will also be using this to poll the rotary encoder too.
  • The main Arduino Loop() function which will manage the user interface, update the display and adjust the sequencer parameters as required.

By keeping the GATE handling in an interrupt routine it will not be affected by the slower I2C updates of the display.

I did wonder about a third level - perhaps a multiple of the main tick, to give me a thread for the encoder and one for the GATES, but it seems to work fine using the same 10mS tick for both.

The core sequencer parameters are:

  • seqTempo - tempo in beats per minute.
  • seqPatterns[] - pattern number for each channel (gate).
  • seqOffsets[] - start offset for each channel.
  • seqMute[] - if TRUE then channel is muted.
  • seqLimits[] - end step for each channel.
  • seqCounter[] - current playing step for each channel.

Timer Functions:

  • timerSetup() - initialise the TimerOne library with a 10mS tick to call timerLoop().
  • timerLoop() - calls the sequencerLoop() and uiScan() each tick.

Sequencer Functions:

  • sequencerSetup() - sets up the first patterns, tempo and any sequencer parameters that aren't pre-initialised in code.
  • sequencerLoop() - uses tempoTickCnt to decide if a sequencer step is to be enacted or not and output the GATEs as required. Called from the timerLoop().

Gate Functions (all called from the sequencerLoop()):

  • gateSetup() - initialses the IO for GATE outputs.
  • gateClear() - turns off all GATEs.
  • gateOutput() - turns on all active GATEs.
  • gateUpdate() - works out which GATEs should be on for a particular step in a pattern using patternStepOn().

Pattern Functions:

  • patternStepOn() - returns TRUE if the indicated step of the current active pattern shows a GATE should be on for this channel.
  • patternRefresh() - caches the current active patterns for each channel, taking into account any seqOffset[] setting.

User Interface and Menu Functions:

  • uiSetup() - initialise the OLED display and encoder.
  • uiScan() - high speed elements of the interface, called from the timer interrupt and used to scan the encoder.
  • uiLoop() - lower speed elements of the interface, called from the Arduino's main loop and handles the updates to the sequencer parameters from the encoder by calling updateMenu().
  • uiRequest() - used to signal a display refresh is required. Used when something changes due to the encoder or the playing step display needs updating.
  • uiUpdate() - redraws the screen to represent the current state of the interface and sequencer parameters.
  • updateMenu() - handles the main menu logic using the encoder increment/decrement and switch functions.

The main menu logic from the updateMenu() function has to manage 7 selection states as follows:

  • State 0: channel update
  • State 1: pattern update
  • State 2: offset update
  • State 3: limit update
  • State 4: mute on/off
  • State 5: reset sequence back to starting step
  • State 6: tempo update

Most of the states will add the (positive or negative) increment to the appropriate sequencer parameter and bounds check the result.

The exceptions are mute and reset which act immediately - mute being a toggle, and reset simply setting all seqCounters[] back to 0.

uiLoop() will act on the encoder switch using it to choose between moving between menus and selecting the functionality of one of the menu items.

uiUpdate() is the function that closely mirrors HAGIWO's original as it has to reproduce the interface on the display. As already mentioned, I've not implemented a random mode, but I have added a tempo indication which I show by adding a blocked-out rectangle across the centre of the display with the current bpm tempo value shown.

I've also added code so that the currently selected menu item has a solid triangle when in parameter changing mode. This is mostly as HAGIWO's original used an independent switch, so the sub-menu mode was active as long as the switch was pressed. As I'm using a switched encoder, I want the switch to be a latched toggle between modes rather than only active when pressed.

There is one bug that I can't quite see why it happens. When showing the tempo there is a block of interference on the bottom right-hand corner. I'm using display.print() at the coordinate point indicated for the tempo text, so I'm not sure what is causing that. Once the tempo display disappears as the menu selection moves on, it goes away... I'll look into that at some point.

Apart from these changes, I believe the interface is working as to HAGIWO's original.

Find it on GitHub here.

Closing Thoughts

Once again the video shows my Arduino Clock Generator Shield PCB running the above code, driving my Arduino Drum Trigger to MIDI Shield PCB which is hooked up to a Roland TR-505.

When I first started messing around with Euclidean rhythms and thinking about an encoder and screen-based interface, I did think I'd just pick up and use the code from HAGIWO's project pretty much "as is". But in the end it was just the interface design I reused and reimplemented everything else myself so I could tweak and adjust things in the way I wanted.

So I consider this is another wheel dutifully reinvented here.

As always though, major thanks to HAGIWO for the project that inspired this one and for publishing the designs and code online for others to learn from.

Kevin

Comment
Like
You can also reply to this email to leave a comment.

Simple DIY Electronic Music Projects © 2024.
Manage your email settings or unsubscribe.

WordPress.com and Jetpack Logos

Get the Jetpack app

Subscribe, bookmark, and get real‑time notifications - all from one app!

Download Jetpack on Google Play Download Jetpack from the App Store
WordPress.com Logo and Wordmark title=

Automattic, Inc.
60 29th St. #343, San Francisco, CA 94110

Posted by BigPalaceNews at 2:39 PM
Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest

No comments:

Post a Comment

Newer Post Older Post Home
Subscribe to: Post Comments (Atom)

Search This Blog

About Me

BigPalaceNews
View my complete profile

Blog Archive

  • August (11)
  • July (96)
  • June (100)
  • May (105)
  • April (95)
  • March (131)
  • February (111)
  • January (104)
  • December (98)
  • November (87)
  • October (126)
  • September (104)
  • August (97)
  • July (112)
  • June (113)
  • May (132)
  • April (162)
  • March (150)
  • February (342)
  • January (232)
  • December (260)
  • November (149)
  • October (179)
  • September (371)
  • August (379)
  • July (360)
  • June (385)
  • May (391)
  • April (395)
  • March (419)
  • February (356)
  • January (437)
  • December (438)
  • November (400)
  • October (472)
  • September (460)
  • August (461)
  • July (469)
  • June (451)
  • May (464)
  • April (506)
  • March (483)
  • February (420)
  • January (258)
  • December (197)
  • November (145)
  • October (117)
  • September (150)
  • August (132)
  • July (133)
  • June (117)
  • May (190)
  • January (48)
Powered by Blogger.