ActivityPub Viewer

A small tool to view real-world ActivityPub objects as JSON! Enter a URL or username from Mastodon or a similar service below, and we'll send a request with the right Accept header to the server to view the underlying object.

Open in browser →
{ "@context": [ "https://www.w3.org/ns/activitystreams", { "Hashtag": "as:Hashtag", "sensitive": "as:sensitive" } ], "id": "https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/", "type": "Note", "attachment": [ { "type": "Image", "url": "https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=1024", "mediaType": "image/png" }, { "type": "Image", "url": "https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=248", "mediaType": "image/png" }, { "type": "Image", "url": "https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=1024", "mediaType": "image/jpeg" } ], "attributedTo": "https://diyelectromusic.com/@diyelectromusic.com", "content": "<h2>Arduino Euclidean Gate Sequencer &#8211; Part&nbsp;3</h2><p>This is another variant of my <a href=\"https://diyelectromusic.com/2024/10/04/arduino-euclidean-gate-sequencer/\">Arduino Euclidean Gate&nbsp;Sequencer</a> this time using a rotary encoder and I2C display rather than a potentiometer for control.</p><ul class=\"wp-block-list\"><li><a href=\"https://diyelectromusic.com/2024/10/04/arduino-euclidean-gate-sequencer/\">Part 1</a> covered all the theory and main functions of the code.</li><li><a href=\"https://diyelectromusic.com/2024/10/07/arduino-euclidean-gate-sequencer-part-2/\">Part&nbsp;2</a> included some hardware suggestions for connecting it to other devices.</li><li><a href=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/\">Part&nbsp;3</a> added a rotary encoder and I2C display and demonstrated by <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a>.</li><li><a href=\"https://diyelectromusic.com/2024/10/28/arduino-euclidean-gate-sequencer-part-4/\">Part&nbsp;4</a> reimplements HAGIWO&#8217;s original with a few tweaks and updates.</li></ul><p><a href=\"https://makertube.net/w/s1cMmrCzW7tGm16NQQKH9w\">https://makertube.net/w/s1cMmrCzW7tGm16NQQKH9w</a></p><p><em><strong>Warning!</strong> I strongly recommend using old or second hand equipment for your experiments.&nbsp; I am not responsible for any damage to expensive instruments!</em></p><p>If you are new to Arduino, see the&nbsp;<a href=\"https://diyelectromusic.wordpress.com/getting-started/\">Getting Started</a> pages.</p><h3 class=\"wp-block-heading\">Parts List</h3><ul class=\"wp-block-list\"><li>Arduino Uno.</li><li>Switched Rotary Encoder &#8211; either a KY-040 module or an unmounted encoder.</li><li>128&#215;64 OLED I2C SSD1306 display.</li><li>Optional: LEDs and associated (e.g. 220Ω or 1K) resistors.</li><li>Breadboard and jumper wires.</li></ul><h3 class=\"wp-block-heading\">The Circuit</h3><figure class=\"wp-block-image size-large\"><img data-attachment-id=\"14602\" data-permalink=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/arduinoeuclideanclockgen-enc_bb-2/\" data-orig-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png\" data-orig-size=\"1414,944\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ArduinoEuclideanClockGen-Enc_bb\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=300\" data-large-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=1024\" loading=\"lazy\" width=\"1024\" height=\"683\" src=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=1024\" alt=\"\" class=\"wp-image-14602\" srcset=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=1024 1024w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=150 150w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=300 300w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=768 768w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png 1414w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" /></figure><p>The above diagram shows how to connect two variants of rotary encoder. On the left is a common KY-040 switched encoder module. On the right is a common switched encoder directly connected to solderless breadboard. Only one encoder should be connected to D4, D5 with the switch on D6.</p><p>Note if it turns out the encoder is incrementing/decrementing values in the opposite way to what is expected, then usually the simplest thing to do is swap the IO pin assignments for the A and B connections in the code.</p><p>The diagram also shows how to connect a 128&#215;64 I2C OLED display. These are the very common SSD1306 based displays. Note that the pinouts on these can vary with GND/VCC swapped or SCL/SDA swapped, but they must be connected to 5V, GND and A4 (SDA) and A5 (SCL).</p><p>The clock generator outputs are on D8-D13. I&#8217;ve not added an LED to D13 as it is wired to the internal LED, but that can be added too if required.</p><p>I&#8217;ve put together an <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a> which includes buffered outputs, a rotary encoder and I2C display connections.</p><h3 class=\"wp-block-heading\">The Code</h3><p>This expands on the original code that is fully described in <a href=\"https://diyelectromusic.com/2024/10/04/arduino-euclidean-gate-sequencer/\">part 1 here</a>.</p><p>There are two main threads of code as follows:</p><ul class=\"wp-block-list\"><li>10mS &#8220;tick&#8221; interrupt routine to ensure accurate GATE timings.</li><li>Back &#8220;loop&#8221; handling the encoder and display.</li></ul><p>In order to ensure a responsive encoder the display is only updated when something actually needs to change.</p><p>Once again I&#8217;ve opted for Matthias Hertel&#8217;s simple RotaryEncoder library which can be found here: <a href=\"https://github.com/mathertel/RotaryEncoder\">https://github.com/mathertel/RotaryEncoder</a>. A detailed explanation of how it works <a href=\"https://www.mathertel.de/Arduino/RotaryEncoderLibrary.aspx\">can be found here</a>. I&#8217;ve found this seems to work best for me for the cheap encoders I tend to buy. One the correct encoder type has been found I&#8217;ve found this to be very reliable, especially when simply polling IO pins for an encoder. There is a little more on the rationale for choosing this library in a previous project here: <a href=\"https://diyelectromusic.com/2021/09/28/arduino-midi-rotary-encoder-controller/\">Arduino MIDI Rotary Encoder&nbsp;Controller</a>.</p><p>For the I2C display, I&#8217;m using the SSD1306 implementation of the Adafruit GFX library which can be found here:</p><ul class=\"wp-block-list\"><li><a href=\"https://github.com/adafruit/Adafruit_SSD1306\">https://github.com/adafruit/Adafruit_SSD1306</a></li><li><a href=\"https://github.com/adafruit/Adafruit-GFX-Library\">https://github.com/adafruit/Adafruit-GFX-Library</a></li></ul><p>All of these should be installable from the Arduino Library Manager.</p><p>The core principles of operation are as follows:</p><ul class=\"wp-block-list\"><li>The display will show the tempo in beats per minute and which pattern is used for each of the 6 GATE outputs.</li><li>Clicking the encoder will change the focus between tempo and any of the six GATEs allowing them to be changed.</li><li>Note: although the tempo is in bpm the number of GATE pulses is actually running at 4 pulses per beat. This means that every 16-pulse sequence, regardless of pattern, will take 4 beats in time to run through.</li></ul><p>This is the display I have. I&#8217;ve used a larger font for the tempo and underlining to show the active focus of the interface.</p><figure class=\"wp-block-image size-large\"><img data-attachment-id=\"14611\" data-permalink=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/image-46/\" data-orig-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png\" data-orig-size=\"248,153\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=248\" data-large-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=248\" loading=\"lazy\" width=\"248\" height=\"153\" src=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=248\" alt=\"\" class=\"wp-image-14611\" srcset=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png 248w, https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=150 150w\" sizes=\"(max-width: 248px) 100vw, 248px\" /></figure><p>The display is managed by having lists of the coordinate points for &#8220;cursor&#8221; which map what I&#8217;ve used for positioning the text.</p><pre class=\"wp-block-preformatted\">int cursor_x[GATES+1] = {10,30,50,70,90,110,20};<br>int cursor_y[GATES+1] = {60,60,60,60,60,60,35};<br>int cursor_l[GATES+1] = {12,12,12,12,12,12,54};<br><br>display.setTextSize(3);<br>display.setCursor(20,10);<br>display.print(tempo);<br><br>display.setTextSize(1);<br>for (int i=0; i&lt;GATES ; i++) {<br> display.setCursor(10+20*i,50);<br> display.print(gatePatterns[i]);<br>}<br><br>display.writeFastHLine(cursor_x[uiFocus], cursor_y[uiFocus], cursor_l[uiFocus], WHITE);</pre><p>Then when the encoder triggers a change, the main interface code essentially runs the following algorithm:</p><pre class=\"wp-block-preformatted\">IF encoder signals UP THEN<br> IF focus is tempo THEN<br> Increment the tempo<br> ELSE<br> Increment the selected GATE pattern<br>ELSE IF encoder signals DOWN THEN<br> IF focus is tempo THEN<br> Decrement the tempo<br> ELSE<br> Decrement the selected GATE pattern<br><br>IF encoder switch is pressed<br> Move focus on between GATES or over to tempo</pre><p>I did wonder if the encoder should be polled in its own timer-driver routine. For performance, many people might enable hardware pin interrupts, but these are only available on pins 2 and 3 on an ATMega328. But as the interface loop is essentially not doing much else, it will poll the encoder pretty quickly (at least compared to the speed a person can turn it) and performance is further enhanced by only writing out to the display if something has actually changed.</p><p>There are three <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/defines/\">#defines</a> for the encoder IO pins. If the encoder seems to be doing the opposite to what is expected, just swap over the pins for ENC_A and ENC_B.</p><pre class=\"wp-block-preformatted\">#define ENC_A 4<br>#define ENC_B 5<br>#define ENC_SW 6</pre><p>The display is assumed to have an I2C address of 0x3C but that can be changed. It is also built for a 128&#215;64 display but a 128&#215;32 display could also be used if the coordinates for the text and cursors mentioned previously are changed accordingly.</p><pre class=\"wp-block-preformatted\">#define OLED_ADDR 0x3C<br>#define OLED_W 128<br>#define OLED_H 64</pre><p>There are two sets of IO pin definitions in the code. One provides a consecutive set of GATES on D8-D13 and one uses D2,D3,D10-D13 to match the requirements of my <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a>.</p><pre class=\"wp-block-preformatted\">int gatePins[GATES] = {13,12,11,10,3,2}; // PCB variant<br>int gatePins[GATES] = {13,12,11,10,9,8}; // Consecutive pins </pre><p><a href=\"https://github.com/diyelectromusic/sdemp/tree/main/src/SDEMP/ArduinoEuclideanClockGen2\">Find it on GitHub here</a>.</p><h3 class=\"wp-block-heading\">Closing Thoughts</h3><p>The video shows my <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a> running the above code, driving my <a href=\"https://diyelectromusic.com/2024/10/27/arduino-drum-trigger-to-midi-shield-pcb/\">Arduino Drum Trigger to MIDI Shield&nbsp;PCB</a> which is hooked up to a Roland TR-505.</p><p>The only change required is for the GATE pins, which are slightly different for the PCB.</p><p>Kevin</p><figure class=\"wp-block-image size-large\"><img data-attachment-id=\"14635\" data-permalink=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/img_8123/\" data-orig-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg\" data-orig-size=\"2564,1284\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad mini&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1730029072&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;40&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"IMG_8123\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=300\" data-large-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=1024\" loading=\"lazy\" width=\"1024\" height=\"512\" src=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=1024\" alt=\"\" class=\"wp-image-14635\" srcset=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=1022 1022w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=2045 2045w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=150 150w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=300 300w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=768 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" /></figure><p><a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/arduino-uno/\">#arduinoUno</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/define/\">#define</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/defines/\">#defines</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/euclidean/\">#euclidean</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/gate/\">#gate</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/midi/\">#midi</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/oled-display/\">#oledDisplay</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/rotary-encoder/\">#rotaryEncoder</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/ssd1306/\">#ssd1306</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/step-sequence/\">#stepSequence</a></p>", "contentMap": { "en": "<h2>Arduino Euclidean Gate Sequencer &#8211; Part&nbsp;3</h2><p>This is another variant of my <a href=\"https://diyelectromusic.com/2024/10/04/arduino-euclidean-gate-sequencer/\">Arduino Euclidean Gate&nbsp;Sequencer</a> this time using a rotary encoder and I2C display rather than a potentiometer for control.</p><ul class=\"wp-block-list\"><li><a href=\"https://diyelectromusic.com/2024/10/04/arduino-euclidean-gate-sequencer/\">Part 1</a> covered all the theory and main functions of the code.</li><li><a href=\"https://diyelectromusic.com/2024/10/07/arduino-euclidean-gate-sequencer-part-2/\">Part&nbsp;2</a> included some hardware suggestions for connecting it to other devices.</li><li><a href=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/\">Part&nbsp;3</a> added a rotary encoder and I2C display and demonstrated by <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a>.</li><li><a href=\"https://diyelectromusic.com/2024/10/28/arduino-euclidean-gate-sequencer-part-4/\">Part&nbsp;4</a> reimplements HAGIWO&#8217;s original with a few tweaks and updates.</li></ul><p><a href=\"https://makertube.net/w/s1cMmrCzW7tGm16NQQKH9w\">https://makertube.net/w/s1cMmrCzW7tGm16NQQKH9w</a></p><p><em><strong>Warning!</strong> I strongly recommend using old or second hand equipment for your experiments.&nbsp; I am not responsible for any damage to expensive instruments!</em></p><p>If you are new to Arduino, see the&nbsp;<a href=\"https://diyelectromusic.wordpress.com/getting-started/\">Getting Started</a> pages.</p><h3 class=\"wp-block-heading\">Parts List</h3><ul class=\"wp-block-list\"><li>Arduino Uno.</li><li>Switched Rotary Encoder &#8211; either a KY-040 module or an unmounted encoder.</li><li>128&#215;64 OLED I2C SSD1306 display.</li><li>Optional: LEDs and associated (e.g. 220Ω or 1K) resistors.</li><li>Breadboard and jumper wires.</li></ul><h3 class=\"wp-block-heading\">The Circuit</h3><figure class=\"wp-block-image size-large\"><img data-attachment-id=\"14602\" data-permalink=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/arduinoeuclideanclockgen-enc_bb-2/\" data-orig-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png\" data-orig-size=\"1414,944\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ArduinoEuclideanClockGen-Enc_bb\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=300\" data-large-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=1024\" loading=\"lazy\" width=\"1024\" height=\"683\" src=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=1024\" alt=\"\" class=\"wp-image-14602\" srcset=\"https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=1024 1024w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=150 150w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=300 300w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png?w=768 768w, https://diyelectromusic.com/wp-content/uploads/2024/10/arduinoeuclideanclockgen-enc_bb-1.png 1414w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" /></figure><p>The above diagram shows how to connect two variants of rotary encoder. On the left is a common KY-040 switched encoder module. On the right is a common switched encoder directly connected to solderless breadboard. Only one encoder should be connected to D4, D5 with the switch on D6.</p><p>Note if it turns out the encoder is incrementing/decrementing values in the opposite way to what is expected, then usually the simplest thing to do is swap the IO pin assignments for the A and B connections in the code.</p><p>The diagram also shows how to connect a 128&#215;64 I2C OLED display. These are the very common SSD1306 based displays. Note that the pinouts on these can vary with GND/VCC swapped or SCL/SDA swapped, but they must be connected to 5V, GND and A4 (SDA) and A5 (SCL).</p><p>The clock generator outputs are on D8-D13. I&#8217;ve not added an LED to D13 as it is wired to the internal LED, but that can be added too if required.</p><p>I&#8217;ve put together an <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a> which includes buffered outputs, a rotary encoder and I2C display connections.</p><h3 class=\"wp-block-heading\">The Code</h3><p>This expands on the original code that is fully described in <a href=\"https://diyelectromusic.com/2024/10/04/arduino-euclidean-gate-sequencer/\">part 1 here</a>.</p><p>There are two main threads of code as follows:</p><ul class=\"wp-block-list\"><li>10mS &#8220;tick&#8221; interrupt routine to ensure accurate GATE timings.</li><li>Back &#8220;loop&#8221; handling the encoder and display.</li></ul><p>In order to ensure a responsive encoder the display is only updated when something actually needs to change.</p><p>Once again I&#8217;ve opted for Matthias Hertel&#8217;s simple RotaryEncoder library which can be found here: <a href=\"https://github.com/mathertel/RotaryEncoder\">https://github.com/mathertel/RotaryEncoder</a>. A detailed explanation of how it works <a href=\"https://www.mathertel.de/Arduino/RotaryEncoderLibrary.aspx\">can be found here</a>. I&#8217;ve found this seems to work best for me for the cheap encoders I tend to buy. One the correct encoder type has been found I&#8217;ve found this to be very reliable, especially when simply polling IO pins for an encoder. There is a little more on the rationale for choosing this library in a previous project here: <a href=\"https://diyelectromusic.com/2021/09/28/arduino-midi-rotary-encoder-controller/\">Arduino MIDI Rotary Encoder&nbsp;Controller</a>.</p><p>For the I2C display, I&#8217;m using the SSD1306 implementation of the Adafruit GFX library which can be found here:</p><ul class=\"wp-block-list\"><li><a href=\"https://github.com/adafruit/Adafruit_SSD1306\">https://github.com/adafruit/Adafruit_SSD1306</a></li><li><a href=\"https://github.com/adafruit/Adafruit-GFX-Library\">https://github.com/adafruit/Adafruit-GFX-Library</a></li></ul><p>All of these should be installable from the Arduino Library Manager.</p><p>The core principles of operation are as follows:</p><ul class=\"wp-block-list\"><li>The display will show the tempo in beats per minute and which pattern is used for each of the 6 GATE outputs.</li><li>Clicking the encoder will change the focus between tempo and any of the six GATEs allowing them to be changed.</li><li>Note: although the tempo is in bpm the number of GATE pulses is actually running at 4 pulses per beat. This means that every 16-pulse sequence, regardless of pattern, will take 4 beats in time to run through.</li></ul><p>This is the display I have. I&#8217;ve used a larger font for the tempo and underlining to show the active focus of the interface.</p><figure class=\"wp-block-image size-large\"><img data-attachment-id=\"14611\" data-permalink=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/image-46/\" data-orig-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png\" data-orig-size=\"248,153\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=248\" data-large-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=248\" loading=\"lazy\" width=\"248\" height=\"153\" src=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=248\" alt=\"\" class=\"wp-image-14611\" srcset=\"https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png 248w, https://diyelectromusic.com/wp-content/uploads/2024/10/image-13.png?w=150 150w\" sizes=\"(max-width: 248px) 100vw, 248px\" /></figure><p>The display is managed by having lists of the coordinate points for &#8220;cursor&#8221; which map what I&#8217;ve used for positioning the text.</p><pre class=\"wp-block-preformatted\">int cursor_x[GATES+1] = {10,30,50,70,90,110,20};<br>int cursor_y[GATES+1] = {60,60,60,60,60,60,35};<br>int cursor_l[GATES+1] = {12,12,12,12,12,12,54};<br><br>display.setTextSize(3);<br>display.setCursor(20,10);<br>display.print(tempo);<br><br>display.setTextSize(1);<br>for (int i=0; i&lt;GATES ; i++) {<br> display.setCursor(10+20*i,50);<br> display.print(gatePatterns[i]);<br>}<br><br>display.writeFastHLine(cursor_x[uiFocus], cursor_y[uiFocus], cursor_l[uiFocus], WHITE);</pre><p>Then when the encoder triggers a change, the main interface code essentially runs the following algorithm:</p><pre class=\"wp-block-preformatted\">IF encoder signals UP THEN<br> IF focus is tempo THEN<br> Increment the tempo<br> ELSE<br> Increment the selected GATE pattern<br>ELSE IF encoder signals DOWN THEN<br> IF focus is tempo THEN<br> Decrement the tempo<br> ELSE<br> Decrement the selected GATE pattern<br><br>IF encoder switch is pressed<br> Move focus on between GATES or over to tempo</pre><p>I did wonder if the encoder should be polled in its own timer-driver routine. For performance, many people might enable hardware pin interrupts, but these are only available on pins 2 and 3 on an ATMega328. But as the interface loop is essentially not doing much else, it will poll the encoder pretty quickly (at least compared to the speed a person can turn it) and performance is further enhanced by only writing out to the display if something has actually changed.</p><p>There are three <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/defines/\">#defines</a> for the encoder IO pins. If the encoder seems to be doing the opposite to what is expected, just swap over the pins for ENC_A and ENC_B.</p><pre class=\"wp-block-preformatted\">#define ENC_A 4<br>#define ENC_B 5<br>#define ENC_SW 6</pre><p>The display is assumed to have an I2C address of 0x3C but that can be changed. It is also built for a 128&#215;64 display but a 128&#215;32 display could also be used if the coordinates for the text and cursors mentioned previously are changed accordingly.</p><pre class=\"wp-block-preformatted\">#define OLED_ADDR 0x3C<br>#define OLED_W 128<br>#define OLED_H 64</pre><p>There are two sets of IO pin definitions in the code. One provides a consecutive set of GATES on D8-D13 and one uses D2,D3,D10-D13 to match the requirements of my <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a>.</p><pre class=\"wp-block-preformatted\">int gatePins[GATES] = {13,12,11,10,3,2}; // PCB variant<br>int gatePins[GATES] = {13,12,11,10,9,8}; // Consecutive pins </pre><p><a href=\"https://github.com/diyelectromusic/sdemp/tree/main/src/SDEMP/ArduinoEuclideanClockGen2\">Find it on GitHub here</a>.</p><h3 class=\"wp-block-heading\">Closing Thoughts</h3><p>The video shows my <a href=\"https://diyelectromusic.com/2024/10/27/arduino-clock-generator-shield-pcb/\">Arduino Clock Generator Shield&nbsp;PCB</a> running the above code, driving my <a href=\"https://diyelectromusic.com/2024/10/27/arduino-drum-trigger-to-midi-shield-pcb/\">Arduino Drum Trigger to MIDI Shield&nbsp;PCB</a> which is hooked up to a Roland TR-505.</p><p>The only change required is for the GATE pins, which are slightly different for the PCB.</p><p>Kevin</p><figure class=\"wp-block-image size-large\"><img data-attachment-id=\"14635\" data-permalink=\"https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/img_8123/\" data-orig-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg\" data-orig-size=\"2564,1284\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;2.4&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPad mini&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1730029072&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;3.3&quot;,&quot;iso&quot;:&quot;40&quot;,&quot;shutter_speed&quot;:&quot;0.041666666666667&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"IMG_8123\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=300\" data-large-file=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=1024\" loading=\"lazy\" width=\"1024\" height=\"512\" src=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=1024\" alt=\"\" class=\"wp-image-14635\" srcset=\"https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=1022 1022w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=2045 2045w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=150 150w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=300 300w, https://diyelectromusic.com/wp-content/uploads/2024/10/img_8123.jpeg?w=768 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" /></figure><p><a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/arduino-uno/\">#arduinoUno</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/define/\">#define</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/defines/\">#defines</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/euclidean/\">#euclidean</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/gate/\">#gate</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/midi/\">#midi</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/oled-display/\">#oledDisplay</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/rotary-encoder/\">#rotaryEncoder</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/ssd1306/\">#ssd1306</a> <a rel=\"tag\" class=\"hashtag u-tag u-category\" href=\"https://diyelectromusic.com/tag/step-sequence/\">#stepSequence</a></p>" }, "published": "2024-10-27T12:29:43Z", "tag": [ { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/arduino-uno/", "name": "#arduinoUno" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/define/", "name": "#define" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/defines/", "name": "#defines" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/euclidean/", "name": "#euclidean" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/gate/", "name": "#gate" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/midi/", "name": "#midi" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/oled-display/", "name": "#oledDisplay" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/rotary-encoder/", "name": "#rotaryEncoder" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/ssd1306/", "name": "#ssd1306" }, { "type": "Hashtag", "href": "https://diyelectromusic.com/tag/step-sequence/", "name": "#stepSequence" } ], "updated": "2024-10-28T21:40:59Z", "url": "https://diyelectromusic.com/2024/10/27/arduino-euclidean-gate-sequencer-part-3/", "to": [ "https://www.w3.org/ns/activitystreams#Public" ], "cc": [ "https://public-api.wordpress.com/wpcom/activitypub-1.0/sites/177786911/actors/0/followers" ], "replies": { "id": "https://public-api.wordpress.com/wpcom/activitypub-1.0/sites/177786911/posts/14597/replies", "type": "Collection", "first": { "id": "https://public-api.wordpress.com/wpcom/activitypub-1.0/sites/177786911/posts/14597/replies?page=0", "type": "CollectionPage", "partOf": "https://public-api.wordpress.com/wpcom/activitypub-1.0/sites/177786911/posts/14597/replies", "items": [] } }, "sensitive": false }