Norns: studies

I have the same issue; external midi sync doesnt seem to work (tried Arturia Keystep and Squarp Pyramid)

1 Like

using the mallet to stop the feedback bloom was unexpectedly (and inordinately) amusing

excellent performance @tehn !


Fun hack. I found a Kindle Fire (gen 5) tablet that I forgot about. It’s some weird fake Android without Google Play app store but…TouchOSC is in the Amazon App Store (is that even the same thing?).

The tablet cost $40 new. Kinda rad as a wireless general purpose controller.


Have you checked if it works? If it does it would be AWESOME.

try it, you’ll like it

1 Like

Update for future readers: I didn’t note it below, but I was on the 181002 firmware. The relevant syntax was changed with that firmware. @tehn explains in detail here:



Looks like there’s a code example typo in study part 3, in the parameters section:



Should be?


thanks for the mention. i’m mostly done updating the study… will get it posted in a bit!

1 Like

So I finally updated to update 181002 to learn the new way to access grid keys, and stumbled over this:

According to study 4 “physical” this is how to make use of grid key presses:
g.event = function(x,y,z)

But according to the new version of “awake” in update 181002, this is how to make use of grid key presses:
function g.event(x, y, z)

Both seem to work. Is there any difference between the 2, or can both be used interchangably? From my real bloody novice user experience, this format
function g.event(x, y, z)
blends in better with how functions have been introduced & used in previous studies.

On a slightly related note, there seems to be a bug in study 4 “physical” in the code for the “complete step sequencer”. When I enter the code as described… = 'PolyPerc'
steps = {}
position = 1
counter = metro.alloc() 
counter.time = 0.1 
counter.count = -1
counter.callback = count

function init()
  for i=1,16 do 

g = grid.connect()

g.event = function(x,y,z)
  if z == 1 then
    steps[x] = y

function grid_redraw() 
  for i=1,16 do
    g.led(i,steps[i],i==position and 15 or 4)

function count()
  position = (position % 16) + 1 

…nothing happens, i.e. the sequencer does not run.

After experimenting I found that
counter.callback = count
needs to be inside
function init()
in order to make the sequencer run.

Is there a way to explain to a novice user why only this counter.callback needs to be in the function init(), but not the other expressions?

Thanks much in advance!

1 Like

these statements mean the same thing in lua. (lua functions are first order objects, but the second form is provided as syntactic sugar - it looks more natural if you’re coming from c-like languages.)

just a guess, but i think the problem is simply that you say counter.callback = count before you define count. so you are really saying counter.callback = nil.

whereas init() is executed later by a callback (when engine is done loading), so the count function has already been defined there.

my guess is it would also work if you define count and then assign it to counter.callback, even without doing the assignment in init.


i’ll fix the study, thanks for the heads up

1 Like

Strange error with renaming @tehn s awake script in 181002


In maiden…

  • open tehn > awake and copy the lua script to clipboard
  • create a new empty script ("untitled.lua" is created)
  • paste clipboard content in “untitled.lua
  • press play (awake runs flawlessly)
  • rename “untitled.lua” to “new.lua
  • press play


  • awake plays
  • REPL shows this error message over and over:

stack traceback:
/home/we/dust/scripts/jhh/untitled.lua:123: in field 'on_step'
/home/we/dust/lib/lua/beatclock.lua:66: in function 'beatclock.advance_step'
/home/we/dust/lib/lua/beatclock.lua:72: in function 'beatclock.tick'
/home/we/dust/lib/lua/beatclock.lua:22: in field 'callback'
/home/we/norns/lua/metro.lua:155: in function </home/we/norns/lua/metro.lua:152>
/home/we/dust/scripts/jhh/untitled.lua:123: attempt to call a nil value (global 'gridredraw')

Moving function step() after function gridredraw() doesn’t help. And the odd thing is, this behavior only occurs after renaming.


  • although the file “new.lua” is shown in maiden’s script list, Cyberduck (after a refresh) still shows “untitled.lua”, and after a refresh in maiden, maiden also shows “untitled.lua” (and “new.lua” is gone)


  • The new awake script still uses g:refresh() instead of g.refresh(), but the behavior mentioned above can also occur with g.refresh()

Is this a bug or am I missing something? Thanks in advance!

g:refresh() is incorrect. it should be g.refresh(). i’ll fix this in the repo.

the renaming issue sounds like a maiden bug. i’ll try to reproduce it.

the repeated error is confusing, however. try to load a different script, then come back to your work in progress.

I tried loading a different script, but after renaming the renamed script always gives the repeated error.

I’m trying study 1 tonight and running into this when starting with the section on the key function:

lua: /home/we/norns/lua/paramset.lua:177: attempt to index a nil value (field '?')
stack traceback:
	/home/we/norns/lua/paramset.lua:177: in function 'paramset.t'
	/home/we/norns/lua/menu.lua:690: in field 'key'
	/home/we/norns/lua/menu.lua:144: in function </home/we/norns/lua/menu.lua:121>

Is this due to the syntax change mentioned earlier or am I doing something wrong?

does the script still work? i believe this is a harmless error message from the param system (which i’ll fix in the next release)

No, the script is odd. I also tried loading Study 1 from the Study folder and also pressing key 2 takes me back to the script browser as if I didn’t load it. Other scripts seem to load and work normally.

I did a little more testing, loading other scripts as well from maiden. The odd thing is that when I go back to my test script, the error I get for an encoder shows the path for the last script I ran:

lua: /home/we/norns/lua/paramset.lua:166: attempt to index a nil value (local 'param')
stack traceback:
/home/we/norns/lua/paramset.lua:166: in function ''
/home/we/dust/scripts/mhetrick/easygrain.lua:113: in function 'encoders.callback'
/home/we/norns/lua/encoders.lua:56: in function 'encoders.process'

The script I was running to test was this:

-- many tomorrows
-- norns study 1 = "TestSine"

function init()
  print("the end and the beginning they are the same.")

function key(n,z)
  print("key " .. n .. " == " .. z)

function enc(n,d)
  print("encoder " .. n .. " == " .. d)

Looking at the developer tools, I see a 404 error for http://norns.local/maiden/snippets/text.js which makes me believe there is something wrong with maiden maybe?

My suspicion is that it may actually be normal behavior - unfortunately I don’t have a device handy to check. I believe @ppqq had enabled some support for snippets in the editor, my guess is it’s looking snippet text which may not have been added to the build or was intended to be provided by an enterprising individual.

1 Like

what’s happening is there was a “feature” added to lockout PLAY screen for scripts not defining redraw() which is of course a bug for study 1.

the “feature” has been removed, so the next update will have study 1 working fine. in the meantime you can define a blank function for redraw and it’ll work as expected.

1 Like

Thanks, that fixes it!

confirmed. not great though and definitely something to track down…