Hello everyone,
I wasn’t happy with the original Chapter 7 buzzer, so I went a bit overboard and gave it the full treatment!
The result is a proper wailing police siren with a smooth rotating red-and-blue light bar on a NeoPixel ring — all running beautifully across both cores of the RP2040 using the Jorvik profile.
Three tasks, one protected object, clean synchronisation, instant button response, full exception logging, and modular arithmetic magic for the light pattern. Zero mutex headaches, of course — Ada just makes it feel natural.
Full tutorial, complete source, Alire crate and GNATdoc are now live:
Chapter 7 Reloaded: Police Siren with Flashing Lights · Pi Ada Tutorial
It was enormous fun to write. If you fancy building your own miniature police car for the desk, give it a go and let me know how you get on!
Cheers,
Martin
10 Likes
Thanks for that, I found it very nicely written. 
Just curious, what would the benefit of the Debug pragma be when used outside a declarative section? I.e. in my understanding this pragma is useful when some declarative-scope data needs to be printed but I can see you’re using it in subprogram/entry bodies too (e.g. pragma Debug (Pico.UART_IO.Put_Line ("= Wait_For_System_Ready")); inside Wait_For_System_Ready)
So was wondering what the reason for that is rather than simply doing (for the above example) Pico.UART_IO.Put_Line ("= Wait_For_System_Ready")?
Thanks
The main reason why you use pragma Debug: It’s not added to the release build. None of the pragma Debug statements are in the code when you use alr build --release increasing performance and in the case of the Pico decrease energy use.
My Desktop applications are factor 5 faster in release. Partially because all the logs are removed. And I have lots of logs.
Apart from that I use „+“ and „-“ track the entry and exit of a procedure:
pragma Debug (Pico.UART_IO.Put_Line ("+ Buzz_And_Blink.Main"));
.
.
.
pragma Debug (Pico.UART_IO.Put_Line ("- Buzz_And_Blink.Main"));
So I put the „+“ before any statements and „-“ after every statement. This also means the subprograms need to be organised in such a way that there is only one return.
However „Wait_For_System_Ready“ entry and exit is basically the same as there is only the guard condition.
entry Wait_For_System_Ready when System_Ready is
begin
pragma Debug (Pico.UART_IO.Put_Line ("= Wait_For_System_Ready"));
end Wait_For_System_Ready;
On Desktop I would use „±“ but that’s a Unicode character which might mot work with serial terminals.
To recap those are the prefixes I use:
- „+“ – Subprogram begin
- „-“ – Subprogram end
- „>“ – Information
- „?“ – Warning
- „!“ – Error
- „±“, „=“ – null function
- „⟲“ – Tail recursion.
1 Like