Lua Pi Question - Timers
Sheldon Jay (9031) 5 posts |
I can’t find this info quickly, so I thought I’d ask the gurus: Can the RISC OS – Raspberry Pi – Lua combination achieve finer timing graduations than using BBC Basic? I understand BASIC reasonably well, but have never learned any other programming languages. My application is a program to run music sequencers. These accept a clock pulse and step through preset musical notes. The clock pulse comes from a master clock, running at about 200 pulses per minute. The program needs to output multiple duplicates of the clock pulse to defined GPIO pins, within 10ms jitter or less. The output pulses need to be delayed under program control. I have written this program on GW-Basic running on an old PC, and GW-Basic can provide timing functions (Fasttimer) that meet the criteria, but PCs are big, heavy, and need monitors. I’d love to be able to run an equivalent on a Pi. I have written a version using BBC on a Pi Zero, but can’t get below the 10ms threshold using Timer. I can do it using a dummy FOR – NEXT loop, but it’s not very clean and it’s hard to change the timing on the fly. So: I’ve been told to learn Lua as being a relatively easy jump from Basic? Thanks for any and all suggestions |
GavinWraith (26) 1563 posts |
Lua is written in C99 ANSI C, but can be compiled with different sorts of integers and/or floating point numbers to suit the platform. For RISC OS everything depends on the platform. For the oldies, Iyonix, RiscPC and earlier, there is no floating point support in hardware. For them RiscLua tends to have 32-bit numbers. For the newer platforms there is VFP. For them RiscLua has 64-bit numbers, whether integers or floating point. The standard Lua function os.clock() returns in seconds the time since the program started, as a floating point number. I think 64-bits gives higher precision than BBC BASIC, but I am not completely sure. Maybe it depends on which BASIC. Lua has functions os.clock(), os.time(), os.difftime(). I think os.clock() is the one you are after.
This is a drum I have been beating for nearly two decades :). Go on. You will love it. |
Stuart Swales (8827) 1357 posts |
Alas, lua’s os.clock has a CLOCKS_PER_SEC granularity, which is 100Hz. RISC OS isn’t a realtime system; background processes could still interfere if you try to create delays using loops in the foreground task. |
Paolo Fabio Zaino (28) 1882 posts |
As others have said, you can use os.clock.
They both supports the timers offered by the OS. They both could be extended. To extend both beyond the possibilities offered by the languages themselves, you’ll need to learn more complex languages (ARM Assembly to extend BBC BASIC and C or C++ to extend Lua).
Yes, Lua is fundamentally a modern form of “BASIC”. It has a lot of advantages over traditional BASIC, for example Lua has a much more cleaner semantics, so it’s more easy to read and has a much better way of handling libraries as well as a more advanced and powerful procedural paradigm. So, learning Lua from BASIC is definitely not a waste of time and it’s very easy.
On the matter of the specific software you are porting/writing for RISC OS. Is it a single task program? In other words does it runs without the WIMP (Window Manager)? If so, you should be ok, but if you are writing an application that has to run in multi-tasking, RISC OS can be hard to program when the application is time sensitive. So, in that case, I would start from something simpler than a music sequencer. Music software is generally highly sensitive to timing and, in a cooperative multi-tasking OS, there is not warrantee of when your application will get back control. As Stuart has mentioned, it depends by what the other apps are doing and if there is any I/O going on. Hope this helps, good luck! :) |
Sheldon Jay (9031) 5 posts |
I’ve cobbled together two version of my software. One version is written in GW-Basic compiled to run on a DOS 6.22 machine. It waits for a pulse on a sense line in the parallel printer port, adjusts timing, then produces pulse outputs by toggling output lines of the same parallel port. A serious kludge, it works fine but needs a big and old PC with a huge monitor.Second version is run on an Arduino. Nice tight timing, cheap, small, but the user interface is a 16×2 LCD and has minimal control input capabilities. I’m using four analog inputs with pots to adjust timing. Arduino can’t support USB keyboards, so I can’t just punch in keystrokes to make changes. Arduino is physically small, accurate, but too fussy to be useable. Changing the software is a real pain. I kind of think RISC OS / Pi Zero could meet all the criteria – fast, cheap, small, easy to interface to real-world using GPIO, accepts USB keyboard input, can be programmed in a language I understand (or can muddle through well enough to write what I want). The Pi Zero is small enough to fit inside a 7” LCD monitor, so no big bulky PC & monitor. And when I muck up the wiring and fry a Zero I can get another one for $19 The sequencer program will be the only thing running, when I’m using the sequencers nothing else is needed. |
Steve Drain (222) 1620 posts |
Have you looked at druck’s TimerMod ? I used it to provide a TIMER keyword and TRACE timing in Basalt with microsecond precision. |
Stuart Swales (8827) 1357 posts |
@Gavin – is your copy of the RISC OS lua source modified from the upstream version with RISC OS-specifics? If so, we could easily modify its os.clock() routine to support druck’s TimerMod if that module is loaded, falling back to the current method if not. |
GavinWraith (26) 1563 posts |
@Stuart I have just put a link from my RiscLua page to instructions on how to build RiscLua for yourself. I wrote these originally for RiscLua 600 but they are now updated to the current version. In summary, access to RISC OS (SWI calls) is provided by the
So the RiscLua binary understands plain Lua, but also has these extra features. See the DIY instructions for the full details. We can probably package Druck’s TimerMod as a dynamically loadable module that overrides |
Stuart Swales (8827) 1357 posts |
Thanks Gavin – I shall take a look! |
GavinWraith (26) 1563 posts |
Not much difference between the two. If I RMLoad TimerMod and then run this RiscLua program in a taskwindow then the output is
That is on an Rpi4 with RO5.28. You can see that TimerMod gives more millisecond detail. My previous remarks about packaging TimerMod were nonsense. As it is a relocatable module nothing further is required, as you see from the example use. |
Stuart Swales (8827) 1357 posts |
That’s good! The increased precision though should allow for (sub-10ms) timing that’s needed for applications like sequencers. |
Paolo Fabio Zaino (28) 1882 posts |
@ Stuart
Can we share the changes on github? I have already added the RiscPkg packaging to RiscLua and also working on some extensions library for GPIO access and git support. If it’s ok for Gavin, I’ll upload the sources to GitHub. P.S. also working on changes to make it work fine when Iris is installed, just got latest Iris updates and testing |
David J. Ruck (33) 1635 posts |
I’m not sure I understand exactly what is needed, 200 pulses per minute is one every 3cs, which the OS timer should be able to do. If you wanted one every 3ms or 300us, then you could sit in a polling loop reading TimerMod’s microsecond clock value. |
Paolo Fabio Zaino (28) 1882 posts |
@ Sheldon
Ok then you’re totally fine. |
Stuart Swales (8827) 1357 posts |
I think that he’s trying to introduce different millisecond-ish delays between the various outputs, and that if it’s just one in a net of sequencers, it might be important to read the input pulses faster than cs to achieve overall synchronisation. |
GavinWraith (26) 1563 posts |
Sure. I do not know how old Paolo is, but I am pretty sure he is a lot younger than me. As I may have hinted before, I am very pleased to leave such burdens to younger and more competent hands. |
Stuart Swales (8827) 1357 posts |
It doesn’t matter how old we are; we could all go under a bus! And where would valuable stuff be then… |
Paolo Fabio Zaino (28) 1882 posts |
Yup!
Thanks Gavin, uploading sources after Doctor Who new episode is over :) |
Paolo Fabio Zaino (28) 1882 posts |
Ok, all done. https://github.com/RISC-OS-Community/RiscLua Tomorrow I’ll start re-organising the sources as per our standards there (so github will also syntax colouring the sources), and run few build tests. Thanks a lot Gavin and looking forward to work together to make Lua even better on RISC OS :) |