Arduino 64 Steps Sequencer with minimum hardware, adapted from the Drum Sequencer

Поделиться
HTML-код
  • Опубликовано: 11 сен 2024
  • Arduino sequencer with minimum hardware, adapted code from the drum sequencer using the same hardware.The interface is composed of two rotary encoders with switch, a 128x64 I2C OLED display and nine or ten LEDs.The display presents a grid with twelve rows and sixteen columns, rows arenotes, columns are steps. The grid represents a measure, each sequence can have a maximum of eight measures. Rotary encoders are used to navigate through the grid coordinates.The encoder X switch selects five modes: Edit, Tempo, Play, Load, and Save.In Edit mode, both X and Y encoders are used to navigate the grid and create or edit a sequence.In Tempo mode the X encoder sets the sequencer BPM (Beats Per Minute).Entering Play mode starts playing the current sequence.Load mode allows the Y encoder to select and load sequences previouslystored in the Arduino internal EEPROM. In Save mode a sequence can be saved to EEPROM. Sequence size is 128 bytes.The Y encoder switch is used to choose between Cursor, Write, Measure and Step modes.In Cursor mode the selected rectangular slot on the grid is highlighted bythicker lines. When the cursor passes over an activated slot (On) the slot iserased (Off).In Write mode a filled square is drawn inside the next selected slot on thegrid, indicating it is On.In Measure mode the Y encoder is used to select which measure will beedited, while the X encoder is used to set the sequence size in measures.Step mode is for setting the last step of the measures (9 - 16), also the beat subdivision ( 3 to 8 steps).The left side of the display shows BPM tempo, values and modes:Top left is BPM value.Below BPM are sequence number, last measure, current measure and last step.Then there is the current mode selected by the X switch:Edit, Tempo, Play, Load, and Save) indicated by the letters E, T, P, L and S, respectively.And finally the Y switch current mode is displayed using letters C, W, M, S and B, for Cursor, Write, Measure, last Step and Beat size.Eight LEDs show gate activity from the eight measures. These LEDs werein place to indicate the rhythmic pattern when this code was for a drumsequencer, a better use for some of these pins now is to control some form of DAC in order to generate 1V/8ª output for analog synthesizer modules. Alternatives are a R2R ladder DAC using seven pins to drive it, or using a shift register like the 74HC595 using three Arduino pins, or dedicated DACs like the DAC0800 using eight pins.Other option is an I2C DAC like the MCP4725, but I am not sure it wouldwork well sharing the I2C lines with the SSD1306 OLED, need to check this.Fow now only MIDI output is implemented. The sequencer sends MIDI notes through Arduino TX pin (channel 1, notes 36 through 47, C - B).I am using the MIDI output to control analog synth modules through a MIDIto CV converter.A dual LED serves as the metronome beat indicator, red when the beatis the first of a measure, green for the remaining beats.In short, each sequence can have a maximum of eight measures, measures can have a maximum of sixteen steps, beats can have three to eight steps.Sequence is arranged in a bi-dimensional array, this time an 8x16 arraycontaining the eight measures with sixteen steps. The main clock usesTimerOne library and seems to work well if the OLED display is not updatedduring Play mode.Libraries do all the hard work: Luni64 Encoder Tool, Adafruit_SSD1306 and GFX, Paul Stoffregen's TimerOne, EEPROM and Wire. I just connected the dots.Hardware:- Arduino Nano.- One 128x64 I2C OLED, connected to Arduino GND, +5V, SCL (A5) and SDA (A4).- Two rotary encoders with switch, the X encoder terminal connections: A to Arduino pin 4, B to pin 2, C to GND, one switch terminal to pin 6, the other to GND. The Y encoder terminal connections: A to Arduino pin 5, B to pin 3, C to GND, one switch terminal to pin 7,- Eight red LEDs, cathode to ground, anode to Arduino pins 8,9,10,11,12, A0,A1,A2 through current limiting resistors (below).- Eight 1K resistors limiting current (5mA) to the red LEDs.- One dual color LED (green and red), common cathode to GND, green to Arduino pin A3 through 680R resistor, red to pin 13 through 200R resistor.- One 680R and one 200R resistor, mentioned above.- Two 220R resistors for the MIDI out connector, next.- One 5 pin DIN female connector (MIDI), pin 5 connected to Arduino TX pin through a 220R resistor, pin 4 to +5V through another 220R resistor. Pin 2 and shield connected to GND.- One 100µF/10V electrolytic capacitor connected to +5V and GND.Power supply can be through USB, or a battery or PSU connected to Vin pinand GND. Voltage connected to Vin should be 7V ~ 12V.
    Join this channel:
    / @unrelatedactivities
    Facebook: / sbranvlztronics
    / batskull.asra
    Thanks for watching.

Комментарии • 14

  • @unrelatedactivities
    @unrelatedactivities  Год назад

    01:
    /*
    * Sbranvlztronics 03/2023
    * Arduino sequencer with minimum hardware, adapted code from the drum
    * sequencer using the same hardware.
    * The interface is composed of two rotary encoders with switch, a 128x64 I2C
    * OLED display and nine or ten LEDs.
    * The display presents a grid with twelve rows and sixteen columns, rows are
    * notes, columns are steps. The grid represents a measure, each sequence can
    * have a maximum of eight measures. Rotary encoders are used to navigate
    * through the grid coordinates.
    * The encoder X switch selects five modes: Edit, Tempo, Play, Load, and Save.
    * In Edit mode, both X and Y encoders are used to navigate the grid and
    * create or edit a sequence.
    * In Tempo mode the X encoder sets the sequencer BPM (Beats Per Minute).
    * Entering Play mode starts playing the current sequence.
    * Load mode allows the Y encoder to select and load sequences previously
    * stored in the Arduino internal EEPROM. In Save mode a sequence can be saved
    * to EEPROM. Sequence size is 128 bytes.
    * The Y encoder switch is used to choose between Cursor, Write, Measure and
    * Step modes.
    * In Cursor mode the selected rectangular slot on the grid is highlighted by
    * thicker lines. When the cursor passes over an actived slot (On) the slot is
    * erased (Off).
    * In Write mode a filled square is drawn inside the next selected slot on the
    * grid, indicating it is On.
    * In Measure mode the Y encoder is used to select which measure will be
    * edited, while the X encoder is used to set the sequence size in measures.
    * Step mode is for setting the last step of the measures (9 - 16), also
    * dictating the beat subdivision (1, 2, 3 or 4 steps).
    *
    * The left side of the display shows BPM tempo, values and modes:
    * Top left is BPM value.
    * Below BPM are sequence number,
    * last measure,
    * current measure
    * and last step
    * Then there is the current mode selected by the X switch:
    * Edit, Tempo, Play, Load, and Save) indicated by the letters
    * E, T, P, L and S, respetively.
    * And finally the Y switch current mode is displayed using letters
    * C, W, M, S and B, for Cursor, Write, Measure, last Step and Beat size.
    *
    * Eight LEDs show gate activity from the eight measures. These LEDs were
    * in place to indicate the rhithmic pattern when this code was for a drum
    * sequencer, a better use for some of these pins now is to control some
    * form of DAC in order to generate 1V/8ª output for analog synthesizer
    * modules. Alternatives are a R2R ladder DAC using seven pins to drive it,
    * or using a shift register like the 74HC595 using three Arduino pins, or
    * dedicated DACs like the DAC0800 using eight pins.
    * Other option is an I2C DAC like the MCP4725, but I am not sure it would
    * work well sharing the I2C lines with the SSD1306 OLED, need to check this.
    *
    * Fow now only MIDI output is implemented. The sequencer sends MIDI notes
    * through Arduino TX pin (channel 1, notes 36 through 47, C - B).
    * I am using the MIDI output to control analog synth modules through a MIDI
    * to CV converter.
    *
    * A dual LED serves as the metronome beat indicator, red when the beat
    * is the first of a measure, green for the remaining beats.
    *
    * In short, each sequence can have a maximum of eight measures, measures can
    * have a maximum of sixteen steps, beats can have one, two, three or four
    * steps depending on the last step setting.
    * Sequence is arranged in a bi-dimensional array, this time an 8x16 array
    * containing the eight measures with sixteen steps. The main clock uses
    * TimerOne library and seems to work well if the OLED display is not updated
    * during Play mode.
    *
    * Libraries do all the hard work: Luni64 Encoder Tool, Adafruit_SSD1306 and GFX,
    * Paul Stoffregen's TimerOne, EEPROM and Wire. I just connected the dots.
    *
    * Hardware:
    * - Arduino Nano.
    * - One 128x64 I2C OLED, connected to Arduino GND, +5V, SCL (A5) and SDA (A4).
    * - Two rotary encoders with switch, the X encoder terminal connections:
    * A to Arduino pin 4, B to pin 2, C to GND, one switch terminal to pin 6,
    * the other to GND. The Y encoder terminal connections:
    * A to Arduino pin 5, B to pin 3, C to GND, one switch terminal to pin 7,
    * - Eight red LEDs, cathode to ground, anode to Arduino pins 8,9,10,11,12,
    * A0,A1,A2 through current limiting resistors (below).
    * - Eight 1K resistors limiting current (5mA) to the red LEDs.
    * - One dual color LED (green and red), common cathode to GND, green to
    * Arduino pin A3 through 680R resistor, red to pin 13 through 200R resistor.
    * - One 680R and one 200R resistor, mentioned above.
    * - Two 220R resistors for the MIDI out connector, next.
    * - One 5 pin DIN female connector (MIDI), pin 5 connected to Arduino TX pin
    * through a 220R resistor, pin 4 to +5V through another 220R resistor. Pin
    * 2 and shield connected to GND.
    * - One 100µF/10V electrolytic capacitor connected to +5V and GND.
    *
    * Power supply can be through USB, or a battery or PSU connected to Vin pin
    * and GND. Voltage connected to Vin should be >= 7V

  • @rubenortiz1787
    @rubenortiz1787 7 месяцев назад +1

    excelente, me encanta. Funciona en UNO, micro, 2560, o cuál ? gracias, muy buenos videos !!

    • @unrelatedactivities
      @unrelatedactivities  7 месяцев назад +1

      Gracias. En el vídeo es un Nano, puede funcionar con Uno o 2560 sin problemas.

  • @davidagner3205
    @davidagner3205 9 месяцев назад

    Nice work. I doing a digital/analog eurorack sequencer. And was thinking of a "editor" to combine it with it's more live performance orientation.
    Mine has Volt/Octave output 0-8V(10+10bits) range Gate, Note On and Off Triggers, MIDI,Internal and External clock. 8-rotary knobs for programing and live performance, a function encoder, 3 buttons, OLED and 8 LED's to show the beat. But still more than 8 GPIO left for Gates and triggers( Drums?)
    Do you have a Git ? I'm copy and pasting from tha comments, well not the best
    //David

  • @user-uy1hi5nq2k
    @user-uy1hi5nq2k Год назад +1

    wow i wanted to try this!
    what you make is awesome!!!😅
    would you explain how to make this?

    • @unrelatedactivities
      @unrelatedactivities  Год назад

      Thank you! If you already use Arduino and read electronic schematics, the code is split in five comments and the schematic is here: ruclips.net/user/postUgkxylUwLuH3vXDGkePjq7A4agulmgRf2Oy4
      If you never used the Arduino platform and can't read electronic schematics, then I think I can make a tutorial video.

    • @user-uy1hi5nq2k
      @user-uy1hi5nq2k Год назад

      @@unrelatedactivities what is text lcd name?
      i wanted to buy this lcd
      and what is x in the schematic?
      i must know before buy this things

    • @unrelatedactivities
      @unrelatedactivities  Год назад

      It is an OLED display, 128x64 pixels, I2C interface, SSD1306 controller. I think you are referring to the connectors after the resistors (-x), as explained in the code (initial comments, hardware) you can connect them to LED indicators (-x-

  • @unrelatedactivities
    @unrelatedactivities  Год назад

    02:
    #include /* this library will provide the main clock */
    #include /* library to access Arduino internal EEPROM */
    #include /* 128x64 I2C OLED display related libraries */
    #include
    #include
    #define SCREEN_WIDTH 128 /* OLED display width, in pixels */
    #define SCREEN_HEIGHT 64 /* OLED display height, in pixels */
    /* SSD1306 display connected to I2C (SDA, SCL pins) */
    #define OLED_RESET -1 /* Reset pin # (or -1 if sharing Arduino reset pin) */
    Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    #include "EncoderTool.h" /* include EncoderTool library */
    using namespace EncoderTool;
    PolledEncoder knobX, knobY; /* two rotary encoders */
    const byte trackPins[8]={A2, A1, A0, 12, 11, 10, 9, 8}; /* measure LED pins */
    const byte metronPin = A3; /* metronome pin, always pulsing at selected BPM */
    const byte beatOnePin = 13; /* beat one pin, turns on only at the first beat of a pattern */
    byte swXstate = 0; /* swX switch state (01234) from X encoder */
    byte swYstate = 0; /* swY switch state (0123) from Y encoder */
    byte patternSize = 0; /* number of measures per pattern */
    byte measure = 0; /* current measure */
    byte oldMeasure = 0; /* previous measure */
    byte scale = 4, oldScale = 4;
    byte lastStep = 16; /* last step of a measure */
    bool clockState = LOW; /* clock pulse state, low or high */
    volatile uint32_t clockCount = 0; /* clock counter, increases when clockState is high */
    uint32_t metron = 0; /* metronome counter */
    uint32_t measurClk = 0; /* measure clock (count steps in a measure */
    uint32_t measurCnt = 0; /* play measure counter related things */
    int noteSlot = 0, noteSlotOld = 0; /* track slots (screen y axis) */
    int stepSlot = 0, stepSlotOld = 0; /* step slots (screen x axis) */
    byte patterNum = 0, oldPatterNum = 0; /* pattern number */
    uint16_t BPM = 120; /* tempo, Beats Per Minute */
    const byte maxSteps = 16; /* maximum number of steps per measure */
    const byte maxMeasures = 8; /* maximum number of measures per pattern */
    byte pattern[maxMeasures][maxSteps]={ /* pattern array */
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 16 steps each measure */
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }};
    const byte patterSize = 128;
    const byte nn[12]={47,46,45,44,43,42,41,40,39,38,37,36}; /* MIDI note numbers */
    /* ------------- The grid is drawn once, during setup() ------------- */
    void drawGrid() /* the matrix grid */
    {
    oled.drawLine(32, 0, 36, 0, WHITE); /* 1st beat, four steps */
    oled.drawLine(56, 0, 60, 0, WHITE); /* 2nd beat, four steps */
    oled.drawLine(80, 0, 84, 0, WHITE); /* 3rd beat, four steps */
    oled.drawLine(104,0,108, 0, WHITE); /* 4th beat, four steps */
    oled.fillRect(26, 3,4, 3, WHITE); /* B */
    oled.fillRect(26,13,4, 3, WHITE); /* A */
    oled.fillRect(26,23,4, 3, WHITE); /* G */
    oled.fillRect(26,33,4, 3, WHITE); /* F */
    oled.fillRect(26,38,4, 3, WHITE); /* E */
    oled.fillRect(26,48,4, 3, WHITE); /* D */
    oled.fillRect(26,58,4, 3, WHITE); /* C */
    for(int i = 0; i < 13; i++) /* from 0 to 12, draw 13 horizontal lines */
    {
    /* drawLine( x0, y0, x1, y1, color); */
    oled.drawLine( 32, 1+i*5, 127, 1+i*5, WHITE); /* horizontal lines */
    }
    for(int i = 0; i < 17; i++) /* from 0 to 16, draw 17 vertical lines */
    {
    /* drawLine( x0, y0, x1, y1, color); */
    oled.drawLine(31+i*6, 1, 31+i*6, 61, WHITE); /* vertical lines */
    }
    oled.setTextColor(WHITE, BLACK); /* white text over black background */
    oled.setTextSize(1); /* font size 1 */
    oled.setCursor(0, 0);
    oled.print(BPM, DEC); /* print the BPM value */
    oled.setCursor(0, 9);
    oled.print(patterNum, DEC); /* print patterNum value */
    oled.setCursor(0, 18);
    oled.print(patternSize+1, DEC); /* print the patternSize value */
    oled.setCursor(13, 18);
    oled.print(scale, DEC); /* print the scale (Beat size) value */
    oled.setCursor(0, 27);
    oled.print(measure+1, DEC); /* print the measure value */
    oled.setCursor(6, 36);
    oled.print(lastStep, DEC); /* print the measure value */
    oled.fillTriangle(30+lastStep*6,63,31+lastStep*6,62,32+lastStep*6,63,WHITE);
    } /* end of drawGrid() */

  • @user-dw6fj1py1o
    @user-dw6fj1py1o Год назад +1

    Great!

  • @unrelatedactivities
    @unrelatedactivities  Год назад

    05:
    /* ------------- read a measure from pattern[][] array and play it ------------- */
    void play(uint32_t tick, uint32_t stepIndx, uint32_t measurIndx, bool rst)
    {
    if(rst) /* if reset is true, zero measurCnt and return */
    {
    measurCnt = 0; /* *** this may have no effect, remember to check */
    return;
    }
    byte rest = tick % 4 == 3 ? 1 : 0; /* last quarter of a step is a pause */
    /* store tracks byte from pattern array in data1 variable: */
    byte data1 = pattern[measurIndx][stepIndx];
    byte play = data1 ? 1 : 0; /* read data1 (note state) */
    if(play && !rest) /* if playing and not rest (boolean)... */
    {
    digitalWrite(trackPins[measurIndx], HIGH); /* correspondent output pin on */
    Serial.write(144); /* note on MIDI channel 1 */
    Serial.write(data1); /* note number */
    Serial.write(127); /* velocity 127 */
    }
    else if(play & rest) /* if playing and there is a rest (bitwise)... */
    {
    digitalWrite(trackPins[measurIndx], LOW); /* correspondent output pin off */
    Serial.write(144); /* note on MIDI channel 1 */
    Serial.write(data1); /* note number */
    Serial.write(0); /* velocity 0 (noteOff) */
    }
    }
    /* ------------- deal with cursor things and create/edit pattern ------------- *
    * arguments y and x are grid coordinates and, together with measure, indexes for
    * data in array pattern[8][16], state is the on-off state of the slot,
    * patternSize is the pattern size in measures. */
    void edit(byte x, byte y, byte state, byte measure)
    {
    if(measure != oldMeasure) /* if variable measure has changed, we need to erase all grid slots, */
    { /* then load the current measure grid slots states */
    oldMeasure = measure; /* update variable oldMeasure value */
    for(byte b=0;b

  • @unrelatedactivities
    @unrelatedactivities  Год назад

    03:
    void mainClock(void) /* called by Timer1.attachInterrupt */
    {
    if (clockState == LOW) /* create the clock and count the high states */
    {
    clockState = HIGH;
    clockCount = clockCount + 1;
    }
    else
    {
    clockState = LOW;
    }
    }
    /* ------------- setup() ------------- */
    void setup()
    {
    Timer1.initialize(500000); /* initialize Timer1 with period 500000 */
    Timer1.attachInterrupt(mainClock); /* call function mainClock every interrupt */
    Serial.begin(57600); /* initialize serial for OLED debug */
    /* SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally */
    if(!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) /* oled I2C address 0x3C */
    { /* if oled failed to iitialize, */
    Serial.println(F("SSD1306 allocation failed")); /* print a warn */
    for(;;); /* Don't proceed, loop forever */
    }
    Serial.end(); /* end serial for OLED debug */
    //delay(200);
    Serial.begin(31250); /* start serial for MIDI with 31250 baud rate */
    oled.clearDisplay(); /* Clear the buffer */
    oled.setTextSize(1); /* 2X-scale text */
    oled.setTextColor(WHITE); /* Draw white text */
    oled.setCursor(0, 0); /* Start at top-left corner */
    oled.println(F(".")); /* Print some text to OLED display */
    /* Show the display buffer on the screen. You MUST call display()
    after drawing commands to make them visible on screen */
    oled.display();
    delay(300); /* wait a little */
    oled.clearDisplay(); /* then clear the display buffer */
    for(byte i=0; i

  • @unrelatedactivities
    @unrelatedactivities  Год назад

    04:
    /* ------------- loop() ------------- */
    void loop(){
    knobX.tick(); /* polled encoder -> call tick() as often as possible */
    knobX.setLimits(-1,1); /* limit encoder counter range to -1 and +1 */
    knobY.tick(); /* polled encoder -> call tick() as often as possible */
    knobY.setLimits(-1,1); /* limit encoder counter range to -1 and +1 */
    /* ------------- encoder X ------------- */
    int newX; /* encoder variables for new readings */
    if(knobX.valueChanged()) /* do we have a new encoder value? */
    {
    newX = knobX.getValue(); /* get its value and store in newX */
    knobX.setValue(0); /* reset the encoder counter */
    if(swXstate == 0 && swYstate 99 ? oled.setCursor(0, 0) : oled.setCursor(5, 0);/* cursor position */
    delay(20);
    oled.print(BPM, DEC); /* print the BPM value */
    }
    else if(swXstate >= 3) /* if (Load or Save), use newX to select a pattern */
    {
    patterNum = constrain(patterNum+newX, 0, 7); /* limit patterNum range to 0 - 7 */
    oled.setCursor(0, 9); /* cursor position */
    oled.print(patterNum, DEC); /* print the pattern number */
    }
    oled.display();
    } /* end of if(knobX.valueChanged()) */
    /* ------------- encoder Y ------------- */
    int newY; /* encoder variable for new readings */
    if(knobY.valueChanged()) /* do we have a new encoder value? */
    {
    newY = knobY.getValue(); /* get its value and store in newY */
    knobY.setValue(0); /* zeroes the encoder counter */
    if(swYstate 9 ? oled.setCursor(6, 36) : oled.setCursor(11,36); /* cursor position */
    delay(20);
    oled.print(lastStep, DEC);
    /* draw the triangle in last Step of the measure, 35 pixels offset */
    oled.fillTriangle(30+lastStep*6,63,31+lastStep*6,62,32+lastStep*6,63,WHITE);
    }
    else if(swYstate == 4)
    {
    scale = constrain(scale+newY, 3, 8);
    oled.setCursor(13, 18);
    oled.print(scale, DEC);
    }
    oled.display();
    allOff(); /* mute */
    }
    /* ------------- switches ------------- */
    if(knobX.buttonChanged()) /* listen to knobY switch */
    {
    knobX.getButton() == LOW ? swXstate++ : 0; /* if pressed, increase swXstate variable value */
    if(swXstate % 5 == 0) swXstate = 0; /* limit swXstate value to 0 - 4 */
    if(swXstate == 0) oled.drawChar( 0, 47, 'E', WHITE, BLACK, 2); /* Edit */
    if(swXstate == 1) oled.drawChar( 0, 47, 'T', WHITE, BLACK, 2); /* Tempo */
    if(swXstate == 2) oled.drawChar( 0, 47, 'P', WHITE, BLACK, 2); /* Play */
    if(swXstate == 3) /* this always comes after Play, use it to also reset it */
    {
    oled.drawChar( 0, 47, 'L', WHITE, BLACK, 2); /* Load */
    play(0, 0, 0, 1); /* call function play() with reset */
    allOff(); /* mute */
    }
    if(swXstate == 4) oled.drawChar( 0, 47, 'S', WHITE, BLACK, 2); /* Save */
    oled.display();
    }
    if(knobY.buttonChanged()) /* listen to knobX switch */
    {
    knobY.getButton() == LOW ? swYstate++ : 0; /* if pressed, increase swYstate variable value */
    if(swYstate % 5 == 0) swYstate = 0; /* limit swYstate value to 0 - 4 */
    if(swYstate == 0) oled.drawChar( 14, 47, 'C', WHITE, BLACK, 2); /* Cursor (edit) */
    if(swYstate == 1) oled.drawChar( 14, 47, 'W', WHITE, BLACK, 2); /* Write (edit) */
    if(swYstate == 2) oled.drawChar( 14, 47, 'M', WHITE, BLACK, 2); /* Measure (edit) */
    if(swYstate == 3) oled.drawChar( 14, 47, 'S', WHITE, BLACK, 2); /* last Step (edit) */
    if(swYstate == 4) oled.drawChar( 14, 47, 'B', WHITE, BLACK, 2); /* scale Beat size (edit)*/
    oled.display();
    allOff(); /* mute */
    }
    if(noteSlot != noteSlotOld || stepSlot != stepSlotOld) /* if coordinates have changed */
    { /* call function edit() to draw the */
    edit(stepSlot, noteSlot, swYstate, measure); /* cursor and write/erase slots */
    noteSlotOld = noteSlot; /* update old coordinates */
    stepSlotOld = stepSlot;
    }
    if(patterNum != oldPatterNum) /* if patterNum changed */
    {
    oldPatterNum = patterNum; /* update oldPatterNum */
    /* if X switch state is 3, call function to load patterns from eeprom, argument is eeprom address, */
    if(swXstate==3) patternLoad(patterNum*patterSize); /* so multiply by the size of each pattern (128) */
    /* if X switch state is 4, and the Y switch is pressed, */
    /* call function to save current pattern to eeprom: */
    if(swXstate==4&&knobY.getButton() == LOW) patternSave(patterNum*patterSize);
    }
    if(scale != oldScale)
    {
    oldScale = scale;
    drawBeat(scale);
    }
    /* ------------- deal with time ------------- */
    Timer1.setPeriod(60000000 / (BPM * scale * 8)); /* set the period of the main clock */
    measurClk = clockCount % (lastStep * 4); /* measurClk counts from 0 to lastStep*4 each measure */
    uint32_t steps = measurClk * 0.25; /* index for the steps in each measure */
    metron = measurClk % (scale * 4); /* metronome counter */
    measurCnt = (clockCount / (lastStep * 4)) % (patternSize+1); /* measure counter */
    /* turn beatOnepin on if measurClk is 0, this is the first beat of a measure: */
    digitalWrite(beatOnePin, !measurClk);
    /* set the metronome state to true at the start of each beat: */
    //bool mtrState = metron==0 ? 1 : 0;
    /* flash green LED each beat, less the first beat of a measure: */
    digitalWrite(metronPin, !metron && measurClk);
    if(swXstate == 2) play(measurClk, steps, measurCnt, 0); /* if set to play call function play() */
    } /* end of loop() */