's Archives..
ESP32 Sketches..

Last modified

27-Feb-23 01:19 PM
5.27 KB
C header file
28-Mar-23 06:35 AM
25.47 KB
good old hypertext
8-Mar-23 02:22 AM
600 Bytes
plain text
13-Jan-23 03:09 PM
36.12 KB
jpeg compressed photo image
30-Mar-23 12:00 PM
252.83 KB
Arduino IDE sketch
30-Jan-23 03:02 PM
1.93 KB
good old hypertext
22-Mar-23 02:05 PM
26.57 KB
C header file
5-Mar-23 10:33 PM
263 Bytes
unknown file type

The only three files you need: SignalGenerator.ino, WebPage.h, Console.h.

Everyone needs a good signal generator in their kit-bag. From testing circuits and devices, as well as your kid's hearing, to making ad-hoc synths, powering LED lights, lasers, motors, fans, and pretty much any low-voltage device you can think of with absolute precision (think brightness, speed, and so on), a decent signal generator is just way too handy not to own. Especially one you can control with your phone..

The ESP32 is the ideal candidate for this sort of malarkey. You could program one up and stick it in a box with buttons and knobs for under a fiver. Adding a screen would only set you back another quid on AliExpress. Madness. Gone are the days when we needed to etch PCBs and design actual circuits for this sort of thing. It's all happening in software now. All we need is the code..

So here is a much updated and improved version of 'that German ESP32 Signal Generator that doesn't work' that works with the latest Espressif IDF (2.0.6, at the time of writing).

I like to think of these wonderful sketches as a sort of rights-of-passage for ESP32 coders; CipherSaber-style. This is my own, personal approach to non-working code and keeps me generally sane. Trouble is, with ESP32 et al, the underlying technologies are prone to rapid development and ESP32 code, unless it's maintained, quickly goes bad.

Most ESP32 n00bs, faced with this issue, Google their fingers off and then do a lot of copying and pasting, and hoping. And posting. You can read a lot of these posts online.

This isn't a bad approach, per se, but it's usually better to consult the most recent applicable header (*.h) files** and their associated C files to find out what's actually going on. The Arduino reference is excellent and the official ESP32 documentation is also pretty good. But again, subject to major upheaval.

So, being an ESP32 n00b myself, but with a vague smattering of C/C++ from earlier decades, I did a bit of both and here present to you my ESP32 GeneratorSaber. Which is one advantage of being a bit late to the party. At any rate, bang goes my holiday!

OKAY, I got a wee bit obsessed with this thing; expending every spare moment on it; and it is now "Da Fuckn Bomdba!". Web interface, presets and all sorts. I had to commandeer an ESP32 module *just* for running this and replace the thing on AliExpress (Furknuts your Chinese New Year! *hgrrr*).

I've tried throughout to make it easy to edit and understand; adding comments where things might be obscure (or I used the ternary operator!).

The comments (always a feature inside code here at the .org) will definitely be useful to ESP32/Arduino n00bs and perhaps even more advanced users. I DO NOT give up, see.

My grappling and sometimes even mastering these usually poorly documented technologies should hopefully provide some copy-and-paste quickness for your workflow, as well as gobs of in-situ documentation to inform and amuse. As one particularly flower-filled email once shouted at me:


Yes, he used the word, "TGE".

So. Take a break for this. Relax. Clear your mind..


** No really, the header files. Espressif has stuffed these with notes.


Android Serial Control for your ESP32

If you want to have serial control from an Android device, get this. Go to the settings and set the speed of the serial connection (115200) and the number of macro button rows to 2 (or more*) and whatever other settings you fancy. Plug in your ESP32 device (via OTG adapter/cable) and hit connect.

This makes for a great quick-and-dirty ad-hoc setup for portable laser controlling. Your phone can be the power source and (wifi AND serial) controller all-in-one. Just add gaffer tape (or masking tape or rubber bands or whatever).

* at least 2 because Boom! They are named L1-L10 and M1-M10; perfect for loading and saving Signal Generator presets!

Quick-Start Presets

Here's a string you can send to Signal Generator to create some general-purpose presets:

wipe;import1 m=r,f=500,p=25,b=10,h=p;n1=Laser Control;import2 m=t,f=1k,p=0,h=f;n2=Saw Left;import3 p=100;n3=Switch Saw Right;import4 m=s,f=440,s=153,a=4,h=f;n4=Music Maker;import5 m=r,f=40m,p=50,b=1,s=1m,h=f;n5=40MHz Sine Wave Baby!;import6 m=s,f=500,p=50,b=10,s=50,j=5,a=2,h=p;n6=Small Sine;import7 m=r,f=1.5k,p=50,b=10,s=50,j=10,h=p;n7=1.5kHz ~ 50% PWM Laser Control;w;import m=r,f=1k,p=25,b=6,s=100,j=10,h=f

Here's a bunch of presets to get you started controlling a laser:

wipe;import1 m=r,f=100,p=25,b=10,j=5,h=p;n1=100Hz Laser Control;import2 f=222;n2=222Hz Laser Control;import3 f=333;n3=333Hz Laser Control;import4 f=440;n4=440Hz Laser Control;import5 m=r,f=1.5k,p=50,b=10,s=50,j=10,h=p;n5=1.5kHz ~ 50% PWM Laser Control;import6 f=666;n6=666Hz Laser Control;import7 f=720;n7=720Hz Laser Control;import8 f=810;n8=810Hz Laser Control;import9 f=777;n9=Captured Laser Control;import10 f=1k;n10=1kHz Laser Control;import12 m=s,f=500,p=50,b=10,s=50,j=5,a=2,h=p;n12=Small Sine @ 25% Amplitude;w;import m=r,f=500,p=50,b=10,s=50,j=5,h=p

Here's a loop command that will gently pulse a laser / speaker / whatever with a 1kHz Square wave, for ever..



Or a nice pulse every one second, for ever..



Or load that loop into preset slot 3, for later use..


Run it..


My current dev module's settings, for the hell of it..

w1;import1 m=r,f=100,p=25,b=10,j=2,h=p;n1=100Hz Laser Control;w2;import2 f=222;n2=222Hz Laser Control;w3;import3 f=333;n3=333Hz Laser Control;w4;import4 f=440;n4=440Hz Laser Control;w5;import5 m=r,f=1.5k,p=50,b=10,s=50,j=5,h=p;n5=1.5kHz ~ 50% PWM Laser Control;w6;import6 f=666;n6=666Hz Laser Control;w7;import7 f=720;n7=720Hz Laser Control;w8;import8 f=810;n8=810Hz Laser Control;w9;import9 f=777;n9=Captured Laser Control;w10;import10 f=1k;n10=1kHz Laser Control;w12;import12 m=s,f=500,p=50,b=10,s=50,j=5,a=2,h=p;n12=Small Sine @ 25% Amplitude;w;import m=r,f=500,p=10,b=10,s=50,j=5,h=p; loop=: Default loop ;p10;~70;p15;~14;p20;~13;p30;~12;p40;~11;p50;~10;p60;~11;p70;~12;p80;~13;p90;~14;p95;~10;p100;~75;p95;~66;p90;~20;p80;~18;p70;~17;p60;~16;p50;~15;p40;~16;p30;~18;p20;~18;p15;~25; loop1=: Slow pulse ;p5;~250;p10;~200;p15;~140;p20;~130;p30;~120;p40;~110;p50;~100;p60;~110;p70;~120;p80;~130;p90;~140;p95;~100;p100;~650;p95;~66;p90;~200;p80;~180;p70;~170;p60;~160;p50;~150;p40;~160;p30;~180;p20;~180;p15;~150;p10;~150; loop2=: Fast Throb ;p10;~30;p15;~9;p20;~8;p30;~7;p40;~6;p50;~5;p60;~4;p70;~3;p80;~2;p90;~1;p95;~1;p100;~1;p95;~2;p90;~3;p80;~4;p70;~5;p60;~6;p50;~7;p40;~8;p30;~9;p20;~9;p15;~10; loop3=: 1s Pulse ;p10;~1;p15;~2;p20;~3;p30;~4;p40;~4;p50;~5;p60;~5;p70;~6;p80;~7;p90;~8;p100;~9;p95;~8;p90;~8;p80;~7;p70;~6;p60;~5;p50;~4;p40;~3;p30;~2;p20;~1;p10;~900; loop4=: 10s Pulse ;p10;~10;p15;~10;p20;~10;p30;~10;p40;~10;p50;~10;p60;~10;p70;~10;p80;~10;p90;~10;p100;~10;p95;~10;p90;~10;p80;~10;p70;~10;p60;~10;p50;~10;p40;~10;p30;~10;p20;~10;p10;~8800; loop5=: Slower Pulse ;p5;~500;p10;~700;p15;~140;p20;~130;p30;~120;p40;~110;p50;~100;p60;~110;p70;~120;p80;~130;p90;~140;p95;~100;p100;~650;p95;~66;p90;~200;p80;~180;p70;~170;p60;~160;p50;~150;p40;~160;p30;~180;p20;~180;p15;~150;p10;~150; loop6=: Slow Throb ;p10;~300;p15;~140;p20;~130;p30;~120;p40;~110;p50;~100;p60;~110;p70;~120;p80;~130;p90;~140;p95;~100;p100;~750;p95;~66;p90;~200;p80;~180;p70;~170;p60;~160;p50;~150;p40;~160;p30;~180;p20;~180;p15;~100;p5;~100; loop7=: Medium Pulse ;p10;~70;p15;~14;p20;~13;p30;~12;p40;~11;p50;~10;p60;~11;p70;~12;p80;~13;p90;~14;p95;~10;p100;~75;p95;~66;p90;~20;p80;~18;p70;~17;p60;~16;p50;~15;p40;~16;p30;~18;p20;~18;p15;~25; loop8=: Chat GPT Created Pulse loop ;p10;~50;p20;~50;p30;~70;p40;~90;p50;~100;p60;~90;p70;~70;p80;~50;p90;~50;p100;~50;p90;~50;p80;~70;p70;~90;p60;~100;p50;~90;p40;~70;p30;~50;p20;~50;p10;~50; loop9=: Audible Setup ;t;p100;a4;loop10; loop10=: Audible Frequencies (100Hz-10kHz) 100;~33;400;~33;700;~33;1000;~33;1300;~33;1600;~33;1900;~33;2200;~33;2500;~33;2800;~33;3100;~33;3400;~33;3700;~33;4000;~33;4300;~33;4600;~33;4900;~33;5200;~33;5500;~33;5800;~33;6100;~33;6400;~33;6700;~33;7000;~33;7300;~33;7600;~33;7900;~33;8200;~33;8500;~33;8800;~33;9100;~33;9400;~33;9700;~33;10000;~33;9700;~33;9400;~33;9100;~33;8800;~33;8500;~33;8200;~33;7900;~33;7600;~33;7300;~33;7000;~33;6700;~33;6400;~33;6100;~33;5800;~33;5500;~33;5200;~33;4900;~33;4600;~33;4300;~33;4000;~33;3700;~33;3400;~33;3100;~33;2800;~33;2500;~33;2200;~33;1900;~33;1600;~33;1300;~33;1000;~33;700;~33;400;~33; loop11=: restart Triangle :;r;t;r;t;r;t;r;t;end;

Yes, that's all one line - just throw it in - and yes, let me tell you about loop 8 and the wonderfulness of Chat GPT..

SO, I asked, "can you give me millisecond timings for a nice slow pulse?", and of course Chat GPT had no effing clue, responding with heart-rate information. OKAY. So I said, "no, I mean, if I wanted to generate a pulse, setting voltages or PWM, what timings (and also percentages of Volts) in milliseconds would I need for each step?"

It then went on to provide a huge spiel of information about frequencies and duty cycles and so on. *sigh*. I got frustrated and said, "NO. I'm looking for a list if timings that will give me a nice pulsing effect"

Chat GPT responded,

I apologize for the confusion. Here are some general timings that you could use to create a pulsing effect:

1. A pulse every 2 seconds: High state for 100ms, followed by low state for 1900ms.

The list continued. *sigh*

Then I had that "bingo" moment when, remembering that I am dealing with a learning machine, I said, "Here's an example that gives a nice pulse once per second ('p' sets the PWM % and '~' sets the millisecond delay - I'm looking for a better set of numbers): p10;~800;p15;~9;p20;~8;p30;~7;p40;~10;p50;~6;p60;~10;p70;~11;p80;~12;p90;~13;p100;~14;p95;~6;p90;~10;p80;~10;p70;~10;p60;~10;p50;~10;p40;~10;p30;~10;p20;~10;p10;~10"

From this point, Chat GPT provided working examples which I could throw directly into Signal Generator! It's first response was this:


Then I asked, "Can you give me something faster and more natural?", and got the command you see in loop8, above. Not bad.