Drum machine. It's not quite a Roland or a Korg, but not bad for few hours effort.

Buzby

Senior Member

Prompted by Chris' virtual buffer thread, and my recent acquisition of an AXE134 OLED, I decided to build a ( somewhat limited ) drum machine.
Most of the code is for the user interface.
Two buttons move the cursor to select the buffer position, and a third toggles the data at that point.
Holding a cursor key down for longer will extend or shorten the buffer, and a fourth button switches between 'Prog' and 'Run'.
In 'Run' mode the cursor keys adjust the tempo, and setting a tempo of zero causes the system to use an external clock.
The code is posted here really to show how a user interface can be built, not as an example of how to build a drum machine !.

Cheers,

Buzby

Code:
#picaxe 28X2
#no_data
#no_table

' Drum machine #1

symbol CurLftPin        = pinC.0    ' Cursor left
symbol CurRgtPin        = pinC.1    ' Cursor right
symbol TglDat           = pinC.2    ' Toggle data, or set buffer length
symbol DelPin           = pinC.3    ' Select mode
symbol ClkPin           = pinC.4    ' Clock in

symbol OLEDpin         = A.1
symbol OutPin           = A.3       ' Data out pin

symbol pinsmem           = b1        ' memory for pins
symbol oneshots          = b2        ' oneshots for all pins in bits 16 to 23


symbol os_C0        = bit16    ' Oneshot from C.0
symbol os_C1        = bit17    ' Oneshot from C.1
symbol os_C2        = bit18    ' Oneshot from C.2
symbol os_C3        = bit19    ' Oneshot from C.3
symbol os_C4        = bit20    ' Oneshot from C.4
symbol os_C5        = bit21    ' Oneshot from C.5
symbol os_C6        = bit22    ' Oneshot from C.6
symbol os_C7        = bit23    ' Oneshot from C.7

symbol mode            = bit24     ' mode flag, 0 = Prog, 1 = Run
symbol PushTimed        = bit25    ' Left or right pressed for long time
symbol RunTimed        = bit26    ' Run timer expired
symbol clockbit        = bit27    ' Current clock, from internal or external

symbol BufLen           = b4        ' Used to hold length of buffer
symbol BufEnd           = b5        ' Used to hold address of last byte of buffer
symbol PushTimer        = b6        ' Timer for long pushes
symbol RunTimer         = b7        ' Timer for interal clock
symbol RunSpeedLim      = b8        ' Setting for internal clock
symbol pincopies         = b9        ' copy of full byte of port C
symbol disploop        = b10
symbol temp1        = b11
symbol curpos        = b12

symbol BufStart         = 32        ' Buffer Start address
                                    ' (  )

#define OLEDbaud N2400_8        
#define PushTimeLim 60           

#define Prog 0
#define Runn 1

' Code starts here
' ----------------

pause 1000
serout OLEDpin, OLEDbaud, (254,1) : pause 30    ' Clear screen
serout OLEDpin, OLEDbaud, (254,130)            ' line 1 pos 2
serout OLEDpin, OLEDbaud, ("Drum Machine #1")
serout OLEDpin, OLEDbaud, (254,192)            ' line 2 pos 1
serout OLEDpin, OLEDbaud, ("--------------------")
serout OLEDpin, OLEDbaud, (254,148,"Prog")
serout OLEDpin, OLEDbaud, (254,14)            ' Cursor ON   

BufLen = 20                         ' Buffer length ( Fixed at 20 at the moment )
BufEnd = BufStart + BufLen - 1      ' Calculate the end of the buffer
bptr   = BufStart                   ' Set byte ptr to start of buffer
curpos = BufStart                ' Set cursor same
RunSpeedLim = 25                ' Set initial run speed limit

temp1 = 192 - BufStart + curpos
serout OLEDpin, OLEDbaud, (254, temp1) ' Move cursor    

do ' Main loop

    ' Make oneshots for all 8 pins of port C
    ' --------------------------------------
      pincopies = pinsC                   ' Only read pin once, to avoid glitches
      oneshots  = pinsmem &/ pincopies    ' Make one-shot
      pinsmem   = pincopies               ' Update pin memory


    ' Make pin timer, detect long presses
    '------------------------------------
    if CurLftPin = 0 or CurRgtPin = 0 then
         inc PushTimer
    else
        PushTimer = 0
    endif

    if PushTimer > PushTimeLim then
        PushTimed = 1            ' Long press detected
        PushTimer = 0
    endif


    ' Mode selection
    '---------------
    if os_C3 = 1 then  
        Mode = not Mode
        if mode = 0 then
            serout OLEDpin, OLEDbaud, (254,148,"Prog   ")
        else
            serout OLEDpin, OLEDbaud, (254,148,"Run ", #RunSpeedLim, "  ")   
        endif
        temp1 = 192 - BufStart + curpos
        serout OLEDpin, OLEDbaud, (254, temp1) ' Restore cursor

        PushTimed = 0    ' Reset long press detect when mode changes
        PushTimer = 0  
    endif
       
       
    ' Programming mode
    ' ----------------
    if mode = Prog then           
               
        ' Cursor left         
          if os_C0 = 1 then               
              dec curpos                      '     Decrement cursor address
              if curpos < BufStart then         '     If before first byte ...
                    curpos = BufEnd         '           ... reset cursor
            endif      
            temp1 = 192 - BufStart + curpos
              serout OLEDpin, OLEDbaud, (254, temp1) ' Move cursor
        endif      
        
         ' Cursor right  
         if os_C1 = 1 then                    
              inc curpos                      '     Increment cursor address
              if curpos > BufEnd then         '     If after last  byte ...
                    curpos = BufStart         '           ... reset cursor
            endif   
            temp1 = 192 - BufStart + curpos
              serout OLEDpin, OLEDbaud, (254, temp1) ' Move cursor
        endif             
       
        ' Toggle memory  
        if os_C2 = 1 then  
            bptr = curpos
            temp1 = not @bptr
            @bptr = temp1

            if temp1 > 0 then
               serout OLEDpin, OLEDbaud, ("+")
            else
               serout OLEDpin, OLEDbaud, ("-")
            endif
            temp1 = 192 - BufStart + curpos
            serout OLEDpin, OLEDbaud, (254, temp1) ' Restore cursor
        endif 
   
        ' Shrink buffer
        if PushTimed = 1 and CurLftPin = 0 then
            PushTimed = 0
            BufEnd = BufEnd - 1 min BufStart   
            serout OLEDpin, OLEDbaud, (254,192)            ' line 2 pos 1
            serout OLEDpin, OLEDbaud, ("                    ")
            for curpos = BufStart to BufEnd
                bptr = curpos
                temp1 = 192 - BufStart + curpos
                serout OLEDpin, OLEDbaud, (254, temp1) ' Position cursor
                if @bptr > 0 then
                   serout OLEDpin, OLEDbaud, ("+")
                else
                   serout OLEDpin, OLEDbaud, ("-")
                endif   
            next   
            curpos = BufStart
            temp1 = 192 - BufStart + curpos
            serout OLEDpin, OLEDbaud, (254, temp1) ' Restore cursor
        endif
           
        ' Expand buffer
        if PushTimed = 1 and CurRgtPin = 0 then
            PushTimed = 0
            BufEnd = BufEnd + 1 max 51   
            serout OLEDpin, OLEDbaud, (254,192)            ' line 2 pos 1
            serout OLEDpin, OLEDbaud, ("                    ")
            for curpos = BufStart to BufEnd
                bptr = curpos
                temp1 = 192 - BufStart + curpos
                serout OLEDpin, OLEDbaud, (254, temp1) ' Position cursor
                if @bptr > 0 then
                   serout OLEDpin, OLEDbaud, ("+")
                else
                   serout OLEDpin, OLEDbaud, ("-")
                endif   
            next   
            curpos = BufEnd
            temp1 = 192 - BufStart + curpos
            serout OLEDpin, OLEDbaud, (254, temp1) ' Restore cursor
        endif
   
    endif     ' end Prog mode


    ' Run mode
    ' --------
    if mode = Runn then

          ' Go faster
        if PushTimed = 1 and CurRgtPin = 0 then
            PushTimed = 0
            If RunSpeedLim > 0 then ' only try if not already at zero
                RunSpeedLim = RunSpeedLim - 1 min 0    ' Reduce interval
                serout OLEDpin, OLEDbaud, (254,148,"Run ", #RunSpeedLim, "  ") 
               
                temp1 = 192 - BufStart + curpos
                serout OLEDpin, OLEDbaud, (254, temp1) ' Restore cursor
            endif
        endif   

          ' Go slower
        if PushTimed = 1 and CurLftPin = 0 then
            PushTimed = 0
            RunSpeedLim = RunSpeedLim + 1 max 50    ' Increase interval
            serout OLEDpin, OLEDbaud, (254,148,"Run ", #RunSpeedLim, "  ") 
           
            temp1 = 192 - BufStart + curpos
            serout OLEDpin, OLEDbaud, (254, temp1) ' Restore cursor
        endif   

        ' Update run timer   
        inc RunTimer
        if RunTimer >= RunSpeedLim then ' Timer expired
            RunTimer = 0        ' reset timer
            RunTimed = 1       ' set timed bit, use to clock data out
        endif
       
        ' use internal or external clock
        if RunSpeedLim = 0 then    
            clockbit = os_C4         ' Use external clock
        else
            clockbit = RunTimed     ' Use internal clock
            RunTimed = 0
        endif

        ' Clock data out
        if clockbit = 1 then  
              inc curpos                      '     Increment cursor address
              if curpos > BufEnd then         '     If after last  byte ...
                    curpos = BufStart         '           ... reset cursor
            endif   
           
            temp1 = 192 - BufStart + curpos
              serout OLEDpin, OLEDbaud, (254, temp1) ' Move cursor   
               
            bptr = curpos

                if @bptr > 0 then            ' Output data from current bptr address,
                          pulsout OutPin, 500         
                endif
        endif

    endif   ' end Runn mode  


loop 'Main loop
 
Last edited:

erco

Senior Member
LOVE IT! I have often thought about making a drum machine with servos & drumsticks. Thank you for sharing this awesomeness.
 

Chris Kelly

Well-known member
Hi Buzby

In your code you reference using an internal clock for timing. Could you explain how you access this or manage it?
 

Buzby

Senior Member
The code runs through the 'main loop' continuously. Each time round the loop a variable is incremented. This is one 'tick'. When the variable reaches the required value the 'clock' is set .

This method give a fairly rough 'system clock', as the time to execute one loop changes if keys are pressed, but it's fairly stable when in 'Run' mode.

The section of code that performs this is here :

Code:
        ' Update run timer  
        inc RunTimer
        if RunTimer >= RunSpeedLim then ' Timer expired
            RunTimer = 0        ' reset timer
            RunTimed = 1       ' set timed bit, use to clock data out
        endif
It's much better to use a hardware clock, like an interrupt from one of the PICAXE timers, but I didn't do that for this rough demo.

Cheers,

Buzby
 

Buzby

Senior Member
Well, it took some doing, but I finally got a PICAXE to sound like a drum set.

I used an old Yamaha DTxpress drum trigger module that my son had on his first drumkit. He's moved on to real drums now, ( and moved out thank goodness ! )

My intention was to send MIDI from the PICAXE to the DTxpress, but it wasn't that easy. The PICAXE wouldn't drive the DTxpress, even though the current loop was fine. Tweaking the baudrate didn't do any good, but the DTexpress did occasionally show a 'Framing Error' message, so I knew I was on the right track.

I bought a USB-MIDI interface for the laptop to use as a diagnostic tool. I also downloaded a piece of software called MIDI-OX which is a low-level MIDI toolbox.

Very soon I found that piping the MIDI from the PICAXE through MIDI-OX then to the DTxpress let the music play. The software must be 'cleaning up' the PICAXE MIDI somehow, but I've not delved further to find out more.

The PICAXE code is just an expansion of the one from a few weeks ago, but this time storing bytes to represent drums. I had to select just a few of the many sounds the DTxpress has stored, so they may not be the best choices for a 'real' drum kit.

The video was shot in a hotel room, and I only had headphones for sound, so apologies for that.

I'm not sure if I'll take this any further. After playing with a 'real' MIDI-editor I think a PICAXE version would need a big LCD, more buttons, and a more complex MIDI sequencer than the simple one coded here.

Anyway, it was fun.

Cheers,

Buzby

 

Attachments

Last edited:

hippy

Technical Support
Staff member
Looking good. With a 16x2 OLED display used in graphics mode it would be possible to create a more traditional drum track matrix display, allow 8 or more drums to be sequenced with multiple drums per tick ...

DRUMS.gif

It would probably make sense to have 8 vertical buttons, one per drum track, so the drums at each indexed tick can be toggled on and off, a left and right button to select the tick.

It might even be better to use a PC program to create the drum track and then download that into the PICAXE.
 

Buzby

Senior Member
... It might even be better to use a PC program to create the drum track and then download that into the PICAXE.
Now that's something I'd like to work on !.

Chris has not told us if his project uses a MIDI drum thingy ( like the DTxpress ), or a bunch of hardware 'Syndrum' type circuits. Either way it would make sense for the PC program to write MIDI to the PICAXE, and read .mid files from the Internet. This keeps things compatible with commercial software, and as there are so many free MIDI music editors it beggars the question as to if we really need to 'roll your own' for the PC side of things.

I envisage a commercial PC program generating .mid files for download to the PICAXE in the studio. The PICAXE would store a few .mid files. It would not need a fancy display, just a few LEDs and buttons or foot pedals to select the relevant .mid to play on stage.

This turns the PICAXE into a MIDI instrument, even if the actual drum hardware is 'Syndrum'. As a MIDI instrument it would need a more complex memory structure and sequencer, and a MIDI decoder. These are the sort of things I would be interested in getting my teeth into !.

Let's see what Chris wants first.

Cheers,

Buzby
 

Chris Kelly

Well-known member
Hi Buzby

Thank you for you continued interest in my project!

I think the only MIDI idea I could foresee would be a way of triggering each of the drums. There are only 4 drum sounds (all analog circuitry) and a trigger can just be a 5V signal of any length.

Cheers

Chris
 

Buzby

Senior Member
Hi Chris,

The MIDI idea was so that a commercial MIDI editor could generate files for the PICAXE, it does not mean the PICAXE has to output MIDI to the drums themselves.

The PICAXE would receive the .mid file, then play that using 4 pins to trigger the analogue drums. ( Cool idea, analogue drums. I love the sound. )

If MIDI is not your bag, then a 'OLED and buttons' solution would be quite feasible for four drums.

But even that might more than you need, it depends on how this 'instrument' is to be played.

I've seen solo performers playing a guitar, and using foot pedals to add drums which repeated after the note was added, thus building up a more complex drum beat as the song progressed.

Is this more like the type of instrument you are building, rather than a 'stored programme' drum sequencer ?.

Whatever it is, a PICAXE can do it !.

Cheers,

Buzby
 

Chris Kelly

Well-known member
Hi Buzby

I'll probably just need MIDI input capability to trigger the drums using other hardware rather than a PC based MIDI file. The machine is meant really for making up loops on the fly whilst running alongside other bits of hardware.

But it'd also be cool to have a MIDI out so that the internal clock can also clock another device via MIDI.

However, this project is still just a prototype.- in the future I might need to shout for help with getting it to accept .mid files

Cheers
Chris
 

Buzby

Senior Member
..The machine is meant really for making up loops on the fly whilst running alongside other bits of hardware. ...
That doesn't look like too difficult a challenge. The first task is to define what switches and lights it needs. We know it needs 4 outputs for the drums, so when the interface is specified we'll know how many I/O the PICAXE will need.

Regarding MIDI, my idea was to receive the stuff, not send it. Although simple 'Note On/Off' is easy to send, I've not tried anything which includes the MIDI clock. I'll have to read up on that. ( My knowledge of MIDI was minimal when I started learning to drive the DTxpress, it's slightly less now I've seen how complex MIDI can be. )

Mentioning clocks, you are definatley going to need a better timebase than the rough one in the demo. If you want, I'll code an accurate interrupt driven one to get you started.

I'm interested in this project, partly because I've been exposed to drums for years. My son started with that DTxpress and some mesh drums ten years ago, now he's playing for real, big stuff !

Cheers,

Buzby
 

Chris Kelly

Well-known member
Hi Buzby

I've decided just to use a 555 timer for my internal clock. When I discovered PICaxe's I hoped that I could introduce 'swing' into a rhythm; this is where every other 16th note can be slightly delayed, and gives a drum beat more 'funk'. Most drum machines have this feature. But on further consideration, with my aim to have up to 8 sub divisions per note, I realised that this feature isn't possible, and is redundant anyway 😄.

So my plan is:
4 x 20M2's - one for each drum sound. This gives enough i/o capability and RAM to store patterns. If the speed needs increasing I'll opt for an X2 version and push for 32MHz.

1 x 14M2 - for muting/unmuting each drum, and also 'solo'ing the drum (i.e muting the other 3 drums). I wrote code for this which works great. This feature is independent of any internal/external clocks.

The PICaxes can then just send 5V signals to the CMOS chips in my drum machine to interact with everything. I'll use either transistor or op-amp buffers where needed.

Since my clock has up to 8 steps per 'beat' then I'll divide down the clock signal 3 times using flip flops to get a 5V clock signal that I can export (hopefully via midi) to say, a Korg ESX machine. The two machines will then run in unison: my drum machine will have an 8 count for every 1 count of the Korg.

If MIDI doesn't come to fruition then I can find another way around this (but its a bit messier)

Cheers

Chris
 

hippy

Technical Support
Staff member
When I discovered PICaxe's I hoped that I could introduce 'swing' into a rhythm; this is where every other 16th note can be slightly delayed, and gives a drum beat more 'funk'. Most drum machines have this feature. But on further consideration, with my aim to have up to 8 sub divisions per note, I realised that this feature isn't possible, and is redundant anyway 😄.
It should be possible to do that in a PICAXE, 'put some funk' into the timing, no matter how many sub-divisions there are, and fairly easily whether driven from an internal or external clock. All the PICAXE needs to do is keep count of the notes, then determine which should come slightly later, and that could in fact be another marker or two held as one of the drum tracks.

Doing that would mean you could 'funk-up' any drum hit anywhere within the 128 step pattern, not just for every beat.
 

Buzby

Senior Member
Hi Chris,

I'm fairly certain you don't need five PICAXE chips to do this. ( When I built my orrey, I first thought I would need nine chips, but with a bit of thought I got it down to one. )

I you use one chip per drum, then the first thing you are going to need is the system-wide clock. How else are you going to keep them in sync ?

Much easier to use one big chip, 28 or 40 pin, and put the effort into code, not hardware.


The idea of 'swinging' the timing to produce a more 'human' beat is something that would be easier to find the optimum setting by using software, after all, that's how the big boys do it.

A PICAXE can easily handle at least 100 events per second. ( I've done 1000 per second on a 20X2, but they were very simple events. )

If we were aiming for a maximum of 120 bpm, that makes each beat 500mS, and a 1/16 beat would be ~31mS, meaning we would need a clock of ~32 Hz, easy for a PICAXE to handle.

If we set the PICAXE to clock at, say, 128Hz, then simple dividing will give us fractions of a beat timing markers down to 1/64 of a beat. If these bits for the markers are stored in a single byte then simple pattern matching will tell us when to 'swing' a note.

Using four 'pattern matching' logics, one for each drum, means each drum could be 'swung' differently, if that is needed. ( I'm not a musician, so I don't know what you need ! )

I'm not sure how you would do 'on the fly' adjustments in a performance scenario. Is the aim of this to be a studio instrument, or an 'on stage' device ?.

Whatever you decide, the forum will always be here to help.

Cheers,

Buzby
 

hippy

Technical Support
Staff member
This is the earlier code, using tighter timing ( but still slightly out ) and funked-up.
Code:
#Picaxe 18M2
#No_Data

; #Define MAKE_IT_FUNKY

Symbol POT_PIN    = C.1
Symbol PIEZO_PIN  = C.2

Symbol adcValue   = b0
Symbol bpm        = b1
Symbol tempoPause = w1 ; b3:b2
Symbol funkDelay  = w2 ; b5:b4

Init:
  Gosub PreProgramRiff

MainLoop:
  Do
    For bPtr = 128 To 255
      If @bPtr <> 0 Then
        #IfDef MAKE_IT_FUNKY
          If @bPtr > $80 Then
            funkDelay = tempoPause / 2
            PauseUs funkDelay		
          End If
        #EndIf
        Sound PIEZO_PIN, ( 100, 1 )
      Else
        Sound PIEZO_PIN, (   0, 1 )
      End If
      Gosub Delay
    Next
  Loop

Delay:
  ReadAdc POT_PIN, adcValue       ;  0 .. 255
  bpm = adcValue * 120 / 255 + 60 ; 60 .. 180 BPM
  tempoPause = 37500 / bpm * 20 - funkDelay
  PauseUs tempoPause
  funkDelay = 0
  Return

; ***************************
; * Pre-program a drum riff *
; ***************************

#Macro Strike( bar, index, length )
  bPtr  = bar - 1 * 32 + index + 128
  @bPtr = length
#EndMacro

#Macro FunkThisUp
  @bPtr = @bPtr | $80
#EndMacro

PreProgramRiff:
  
  For bPtr = 128 To 255
    @bPtr = 0
  Next

  ;     Bar 1
  ; 4 ||---------------------------------|
  ; - ||-O-------O-------O-------O-------|
  ; 4 ||-:-------:-------:-------:-------|
  ;      :       : 1111111111222222222233
  ;      01234567890123456789012345678901

  ;       .---------- Bar Number
  ;       |   .------ Where in the bar
  ;       |   |  .--- Length of note
  ;       |   |  |
  Strike( 1,  0, 8 )
  Strike( 1,  8, 8 )
  Strike( 1, 16, 8 )
  Strike( 1, 24, 8 )

  ;     Bar 2
  ; 4  |---------------------------------|
  ; -  |-O---O-O-O-------O---O-O-O-------|
  ; 4  |-:---:-:-:-------:---:-:-:-------|
  ;      :   : : : 1111111111222222222233
  ;      01234567890123456789012345678901

  Strike( 2,  0, 4 )
  Strike( 2,  4, 2 )
  Strike( 2,  6, 2 ) FunkThisUp
  Strike( 2,  8, 8 )
  Strike( 2, 16, 4 )
  Strike( 2, 20, 2 )
  Strike( 2, 22, 2 ) FunkThisUp
  Strike( 2, 24, 8 )

  ;     Bar 3
  ; 4  |---------------------------------|
  ; -  |-O-------O---O---O-------O-------|
  ; 4  |-:-------:---:---:-------:-------|
  ;      :       : 1111111111222222222233
  ;      01234567890123456789012345678901

  Strike( 3,  0, 8 )
  Strike( 3,  8, 4 )
  Strike( 3, 12, 4 )
  Strike( 3, 16, 8 )
  Strike( 3, 24, 8 )

  ;     Bar 4
  ; 4  |---------------------------------||
  ; -  |-OOOOOOOO--------OOOOOOOO--------||
  ; 4  |-::::::::--------::::::::--------||
  ;      ::::::::  1111111111222222222233
  ;      01234567890123456789012345678901

  Strike( 4,  0, 1 )
  Strike( 4,  1, 1 ) FunkThisUp
  Strike( 4,  2, 1 )
  Strike( 4,  3, 1 ) FunkThisUp
  Strike( 4,  4, 1 )
  Strike( 4,  5, 1 ) FunkThisUp
  Strike( 4,  6, 1 )
  Strike( 4,  7, 1 ) FunkThisUp

  Strike( 4, 16, 1 )
  Strike( 4, 17, 1 )
  Strike( 4, 18, 1 )
  Strike( 4, 19, 1 )
  Strike( 4, 20, 1 )
  Strike( 4, 21, 1 )
  Strike( 4, 22, 1 )
  Strike( 4, 23, 1 )

  Return
Uncomment the "#Define MAKE_IT_FUNKY" and it delays those notes marked with "FunkThisUp", the third note of each beat in Bar 2 and the run at the start of Bar 4.

The delay is fixed at 1/16th of a beat, 1/64th of a 4/4 bar. The delay could be determined from another pot.
 

Chris Kelly

Well-known member
I you use one chip per drum, then the first thing you are going to need is the system-wide clock. How else are you going to keep them in sync ?
That's how I'd planned it - one 555 timer producing a clock signal that can be sent to the 4No main 20M2's. The fan-out capability of a 555 is pretty good, so it should easily handle clocking all 4 PICaxes.

Using four 'pattern matching' logics, one for each drum, means each drum could be 'swung' differently, if that is needed. ( I'm not a musician, so I don't know what you need ! )
That's actually what I'd hoped to be able to do! But after thinking about it, I realised that within each of the drum 16 steps, I was sub-dividing each step into 8 slices, which means that you could actually re-create the swing manually by just tapping out the rhythm yourself.

I'm not sure how you would do 'on the fly' adjustments in a performance scenario. Is the aim of this to be a studio instrument, or an 'on stage' device ?.
This is more of a studio instrument (i.e - in my garage! 😂) The idea really is to tap out and 'record' a rhythm into a pattern of any length (up to the 16 beat limit) and have it playing back over and over. Then you can layer the other drums over the loop, and add/subtract from the loops, or tweak the lengths of the loops etc to make interesting polyrhythms. This is kind of why I've shyed away from building something that you pre-program. I guess I wanted it to be more 'organic' in that way.

Much easier to use one big chip, 28 or 40 pin, and put the effort into code, not hardware.
I can totally appreciate that - my last project was packed full of CMOS chips to control the functionality, whereas I could have replicated it all with one PICaxe microcontroller!

So far, the 20M2 for each drum will have every pin in use (except the serial in/out pins):

- CLOCK INPUT
- DATA INPUT
- DATA DELETION
- 'RECORD BUTTON'
- a RESET pin to send the bptr back to the start of the sequence
- INCREASE LOOP LENGTH
- DECREASE LOOP LENGTH
- 'FIDELITY' (using an ADC input pin)
- 5 x LED driver pins
- 2 x other pins for select
- 1 x OUTPUT for the DRUM TRIGGER

Hippy - thanks for the above code! I'm definitely learning alot from you guys, and from browsing other posts on this forum.

Cheers

Chris
 

Buzby

Senior Member
While Googling around for analog drum circuits, I came across this : https://delptronics.com/ldb1se.php

There is a link to the full circuit diagram on the page, and it has some interesting points, such as the Charlieplexing to drive the LEDs.

Even better, there is a blog page talking about how this machine was designed : http://mickeydelp.com/blog/anatomy-of-a-drum-machine?

So no excuse now for not playing about with Bridged-T oscillators and a PICAXE !.

Merry Christmas.

Buzby
 

Chris Kelly

Well-known member
Wow great stuff guys!

Buzby - the LDB is an awesome piece of kit! The analog circuits on my own project have a couple of bridged-t oscillators too, although mine use transistors instead of op-amps. (2 of my sounds came from the Korg Monotron).

Erco - that Knock Box is fantastic! You can get really long recordings on it. Very cool
 
Top