I am trying to build a simple pulse generator to clock analog gear from Norns.

The norns global clock sends midi clock messages which I can pick up without issue but getting the two clocks to align properly is proving difficult. My script is counting midi 1/4 notes i.e. counting to 24 clock ticks, so it stays in time with what is going on in norns, but not necessarily in sync: pulses might be produced half way though each 1/4 note for example.

The clock reset function on Norns (through the parameters menu) does not seem to send a midi start or continue message. Is there some other way to force that to happen globally? If not should it just be done via a script?

hi hi!

if you can share your script, that’d help identify where things are getting wonky. otherwise, is your script beginning the count with clock.sync(1)? that should start the counter directly on a quarter note, to stay in sync with the global clock which is driving the midi clock messages.

1 Like

Thanks for the reply. I must have been unclear in my question — sorry.

I’m trying to keep an external device in sync with norns global clock. For proof of concept I’m just coding for a teensy in arduino IDE.

I can receive the clock signals from norns over usb midi but I can’t tell when norns is on a 1/4 note or whole note boundary for example. So whatever is running on norns (eg awake) is nicely synced with norns clock via its own clock.sync calls, and my external device keeps time — because it gets the midi 248 messages — but can be misaligned because it didn’t necessarily start counting when norns did.

Ideally I’d like my device to be able to pick up the clock regardless of what script is running. Clock reset would be one way to do that but as far as I can tell no midi message is sent from norns to indicate the reset has taken place.

I hope that made the issue clearer! Thanks again.

Edit: here’s a bit of code extracted from my clock handler so you can see what is going on.

void myClock() { // handle MIDI clock tick

  if (count > 3) {
    digitalWrite(LED,LOW); 
  }
 count++; 
  
  if(count > 23) {
    count = 0;
    digitalWrite(LED,HIGH); 
  }
}

The issue is that my device’s count from 0 - 23 may not be aligned with norns 1/4 notes, i.e. the count variable above may not be reset to 0 on a multiple of 24 ticks according to norns.

Have you considered a forward/backward “nudge” for “course correction” that just increments/decrements the counter? These could maybe be mapped to buttons on the arduino device

If all else falls I could definitely implement the nudge on the external device — good idea.

(Implementing it on norns would be per-script which would make things less clean I guess.)

Good call about adding it to the slower-moving target. Although if you created some kind of clock protocol for your own norns apps, you could maybe get more expressive/precise.

ah gotcha, thank you for the additional detail! hopefully i’m understanding the scope correctly now :slight_smile:

norns can send midi start, stop and continue messages, but you’re correct that the clock reset function doesn’t call any of them.

you could roll this type of reset into a norns script’s initialization – if your arduino code is able to reset its counter with a stop message, then you can execute whatever_var_you_initialize_midi_as:stop() from norns. whatever_var_you_initialize_midi_as:start() and whatever_var_you_initialize_midi_as:continue() will execute the other messages.

for awake, midi is initialized as midi_out_device. i’m curious if you run awake and execute midi_out_device:stop() from the maiden REPL if that helps reset the arduino? and then either midi_out_device:start() or midi_out_device:continue(), depending?

if those do what you need, then we’ll want to get those clock synced to the rest of the script — excited to find out if the functions work tho!

2 Likes

I can’t access Awake’s midi_out_device from the REPL, I guess because of its local scope, but never mind!

Dropping midi_out_device:continue() into the Awake script at a strategic point gets things lined up nicely. The Teensy resets its count to 0 when it receives the message and everything stays in beat alignment. I’ve set it up in Awake so that the continue message is sent when the loop restarts. An alternative would be to send a start when the app initialises but I fear alignment would drift if you adjust tempo.

This gives a nice per-script workaround. The spec I am working to here – doing this for a friend – is “can I clock my Buchla from norns apps?” so a global solution would be preferable to modifying individual scripts, because I think there are multiple apps under consideration.

For quick-n-dirty this is great so far though. Thanks.

1 Like

FWIW I use something like the following with my TR-09 because it has a STOP/CONTINUE button

and you could throw something into the clock.transport.reset function to stop/start or continue (or whatever behaviour works for you - maybe the clock.sync(1) or similar there?)

function clock.transport.start()
  print("transport.start")
  running = true
end

function clock.transport.stop()
  print("transport.stop")
  running = false
end

function clock.transport.reset()
  --print("transport.reset")
end

function midi_event(data)
  msg = midi.to_msg(data)
  if msg.type == "start" then
      clock.transport.reset()
      clock.transport.start()
  elseif msg.type == "continue" then
    if running then 
      clock.transport.stop()
    else 
      clock.transport.start()
    end
  end 
  if msg.type == "stop" then
    clock.transport.stop()
  end 
-- etc...
3 Likes

Thanks.

As I understand more the architecture of the norns clocks it becomes clear that there won’t be a way to do this once and for all, but on the other hand it is pretty easy to bake the appropriate alignment in to a given norns script. Looks like I need to get my friend to specify his use cases a bit more precisely and then this is going to be a simple thing to achieve. Thanks again.

2 Likes