I’m having trouble finding the documentation for the Lua interface. It would be great with a few examples too. Sorry if I’m missing something obvious.
Best,
Henrik
I’m having trouble finding the documentation for the Lua interface. It would be great with a few examples too. Sorry if I’m missing something obvious.
Best,
Henrik
Hi Henrik,
for reference, most lua built-in functions are available in Grid’s lua runtime.
https://www.lua.org/docs.html
Our own APIs are available here:
On the wiki, most entries have a “reference manual” flag, which can be flicked to see what’s under the hood.
Sorry for the slow response, but thanks for the answer! This will help!
Hello, while searching for helpful tips, tricks, examples, and more documentation, I came across this topic:
I’m having trouble understanding some functions and examples – it often feels like reverse engineering, but perhaps I’m taking the wrong approach?
For example: I understand the basic use of the display in the VSN1 example. However, when I want to delve deeper:
There’s self.eventrx_cb = function(self, hdr, e, v, n)
When trying to find out more about it, I hit a dead end. If I try to figure out what self, hdr, e, v, and n are, I can only find out that n is the triggering control element (e.g., Button5) using a simple print("Event: ", self, hdr, e, v, n).
For all the others, I only get the display ‘table’.
How can I find out which is a Button down or a Button up? What could I find out using the encoder?
So many questions, not all of which I’ve (yet) found answers to on https://docs.intech.studio/
This was mostly necessary because we were very limited on memory on the patch when VSN1 released. We could only write code for 390+390 characters for the screen to make it all work, this is why so many variable names are abbreviated.
Now with the new 899 character limit (just released on FW v1.5.0), a much more legible code would be possible, we just didn’t have the time to update it yet.
OK, understood.
Meanwhile I figured out some contents while proceeding, can you confirm/add my findings:
elf.eventrx_cb = function(self, hdr, e, v, n)
self.v = v
print("hdr: " .. hdr[1] .. ", " .. hdr[2] .. ", " .. hdr[3])
print("e: " .. e[1] .. ", " .. e[2] .. ", " .. e[3])
print("v: " .. v[1] .. ", " .. v[2] .. ", " .. v[3])
print("n: " .. n)
if #n == 0 then
n = d[e[3]] .. e[2]
end
self.id = string.sub(n, 1, (self:screen_width() / (s / 2) - 1) // 1)
self.f = 1
end
So the code for the screen default is the following:
--CODE FOR THE SETUP EVENT OF THE SCREEN ELEMENT
lcd_set_backlight(255)
pi =math.pi --this is just so that pi is a variable
s=64 --a SCALE variable that's an exponent of 2 with a minimum of 8
c={
{0, 0, 0},
{255, 255, 255},
{led_default_red(), led_default_green(), led_default_blue()}
} --c is an array of COLORS which we use for every color on the screen
self.f = 1 --is for pacing the screen, to not make it refresh every single time
self.v = {27, 0, 100} --default array of VALUES for incoming values, {current, minimum, maximum}
self.id = 'VSN1' --a default ID or name for the displayed element
d = {[1] = 'Linear', [2] = 'Encoder', [3] = 'Button', [7] = 'Endless'}
--these are the default IDs if the element has no name
xc=160 --horizontal center
yc=120 --vertical center
p = s * 5 / 8 --this is for POSITIONING stuff on the screen
self.eventrx_cb = function(self, hdr, e, v, n)
self.v = v
if #n == 0 then
n = d[e[3]] .. e[2]
end
self.id = string.sub(n, 1, (self:screen_width() / (s / 2) - 1) // 1)
self.f = 1
end
--"hdr" is actually there for an array of HEADER variables that are received for every triggered event
--hdr={message type (this is not very important to us), horizontal module position, vertical module position}
--"e" is for the ELEMENT DESCRIPTORS e={page number, index of element, type of event}
--"v" is a VALUE array, where v={current, minimum, maximum}
--"n" is a NAME string, if it exists, otherwise nil
self:draw_area_filled(0, 0, 319, 239, c[1])
self:draw_rectangle_rounded(3, 3, 317, 237, 10, c[2])
--CODE FOR THE DRAW EVENT OF THE SCREEN ELEMENT
if self.f > 0 then --counts down from F to trigger a render cycle, this is used so that idle does not render constantly
self.f = self.f - 1
local a, xo =
map_saturate(self.v[1], self.v[2], self.v[3], 0.1, 1),
#tostring(self.v[1]) / 2 * s / 2 - #tostring(self.v[1]) - s // 32
self:draw_area_filled(10, 10, 310, 230, c[1])
self:draw_rectangle_rounded(xc - p // 1 - 1, yc - p // 1 - 1, xc + p // 1 + 1, yc + p // 1 + 1, s, c[2])
self:draw_rectangle_rounded_filled(xc - p * a // 1, yc - p * a // 1, xc + p * a // 1, yc + p * a // 1, s, c[3])
self:draw_text_fast(self.v[1], xc - xo, yc + s, s / 2, c[2])
local xn = (#self.id * (s / 2)) / 2 - s // 32
self:draw_text_fast(self.id, xc - xn, yc - 1.5 * s, s / 2, c[2])
self:draw_swap()
end
Okay, this is it for now, but I can expand on this if you still have questions.