Skip to content

Instantly share code, notes, and snippets.

@futureshocked
Last active August 22, 2024 01:07
Show Gist options
  • Save futureshocked/2658d5b902039bc72d201caa00038649 to your computer and use it in GitHub Desktop.
Save futureshocked/2658d5b902039bc72d201caa00038649 to your computer and use it in GitHub Desktop.
09_ESP32 Signal generator (Oscilloscopes for Busy People)
// With this program, you can use the ESP32 as an ultra-low cost signal generator.
// To learn more, see https://techexplorations.com/courses/oscilloscopes/
#include <Arduino.h>
#include "waveforms.h"
int i = 0;
int sample_delay = 0;
const byte POT_GPIO = 35; // Potentiometer
int t_sample;
const byte output_pin = 25;
const byte buttonPin = 14;
int waveformID = 0;
volatile int interruptCounter = 0;
// Debouncing parameters
long debouncing_time = 1000; //Debouncing Time in Milliseconds
volatile unsigned long last_micros;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR handleInterrupt() {
portENTER_CRITICAL_ISR(&mux);
if((long)(micros() - last_micros) >= debouncing_time * 1000) {
interruptCounter++;
}
last_micros = micros();
portEXIT_CRITICAL_ISR(&mux);
}
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP); // Using an extarnal pull up instead of internal
attachInterrupt(digitalPinToInterrupt(buttonPin), handleInterrupt, FALLING);
}
void loop() {
if(interruptCounter>0){
portENTER_CRITICAL(&mux);
interruptCounter--;
portEXIT_CRITICAL(&mux);
waveformID++;
if (waveformID == maxWaveform)
waveformID = 0;
// sample_delay = map(analogRead(POT_GPIO), 0, 4095, 0, 100);
Serial.print("Waveform ID: ");
Serial.print(waveformID);
Serial.print(", delay: ");
Serial.println(sample_delay);
}
dacWrite(output_pin, waveformsTable[waveformID][i]);
i++;
if (i == maxSamplesNum) // Reset the counter to repeat the wave
i = 0;
// sample_delay = map(analogRead(POT_GPIO), 0, 4095, 0, 100);
// delayMicroseconds(sample_delay); // Hold the sample value for the sample time
delayMicroseconds(map(analogRead(POT_GPIO), 0, 4095, 0, 100)); // Hold the sample value for the sample time
}
;PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
; Custom Serial Monitor port
monitor_port = /dev/cu.SLAB_USBtoUART
; Custom Serial Monitor speed (baud rate)
monitor_speed = 115200
lib_deps =
#ifndef _Waveforms_h_
#define _Waveforms_h_
#define maxWaveform 6
#define maxSamplesNum 240
static int waveformsTable[maxWaveform][maxSamplesNum] = {
// Sin wave, calculated with https://daycounter.com/Calculators/Sine-Generator-Calculator.phtml
{
0x80,0x83,0x86,0x8a,0x8d,0x90,0x93,0x97,
0x9a,0x9d,0xa0,0xa4,0xa7,0xaa,0xad,0xb0,
0xb3,0xb6,0xb9,0xbc,0xbf,0xc2,0xc5,0xc8,
0xca,0xcd,0xd0,0xd2,0xd5,0xd7,0xda,0xdc,
0xde,0xe0,0xe3,0xe5,0xe7,0xe9,0xea,0xec,
0xee,0xf0,0xf1,0xf3,0xf4,0xf5,0xf7,0xf8,
0xf9,0xfa,0xfb,0xfb,0xfc,0xfd,0xfd,0xfe,
0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xfe,0xfe,0xfd,0xfd,0xfc,0xfb,0xfb,0xfa,
0xf9,0xf8,0xf7,0xf5,0xf4,0xf3,0xf1,0xf0,
0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe0,
0xde,0xdc,0xda,0xd7,0xd5,0xd2,0xd0,0xcd,
0xca,0xc8,0xc5,0xc2,0xbf,0xbc,0xb9,0xb6,
0xb3,0xb0,0xad,0xaa,0xa7,0xa4,0xa0,0x9d,
0x9a,0x97,0x93,0x90,0x8d,0x8a,0x86,0x83,
0x80,0x7c,0x79,0x75,0x72,0x6f,0x6c,0x68,
0x65,0x62,0x5f,0x5b,0x58,0x55,0x52,0x4f,
0x4c,0x49,0x46,0x43,0x40,0x3d,0x3a,0x37,
0x35,0x32,0x2f,0x2d,0x2a,0x28,0x25,0x23,
0x21,0x1f,0x1c,0x1a,0x18,0x16,0x15,0x13,
0x11,0xf,0xe,0xc,0xb,0xa,0x8,0x7,
0x6,0x5,0x4,0x4,0x3,0x2,0x2,0x1,
0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x1,0x1,0x2,0x2,0x3,0x4,0x4,0x5,
0x6,0x7,0x8,0xa,0xb,0xc,0xe,0xf,
0x11,0x13,0x15,0x16,0x18,0x1a,0x1c,0x1f,
0x21,0x23,0x25,0x28,0x2a,0x2d,0x2f,0x32,
0x35,0x37,0x3a,0x3d,0x40,0x43,0x46,0x49,
0x4c,0x4f,0x52,0x55,0x58,0x5b,0x5f,0x62,
0x65,0x68,0x6c,0x6f,0x72,0x75,0x79,0x7c
}
,
// Triangular wave calculated with https://daycounter.com/Calculators/Triangle-Wave-Generator-Calculator.phtml
{
0x2,0x4,0x6,0x9,0xb,0xd,0xf,0x11,
0x13,0x15,0x17,0x1a,0x1c,0x1e,0x20,0x22,
0x24,0x26,0x28,0x2b,0x2d,0x2f,0x31,0x33,
0x35,0x37,0x39,0x3c,0x3e,0x40,0x42,0x44,
0x46,0x48,0x4a,0x4d,0x4f,0x51,0x53,0x55,
0x57,0x59,0x5b,0x5e,0x60,0x62,0x64,0x66,
0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,0x77,
0x79,0x7b,0x7d,0x80,0x82,0x84,0x86,0x88,
0x8a,0x8c,0x8e,0x91,0x93,0x95,0x97,0x99,
0x9b,0x9d,0x9f,0xa2,0xa4,0xa6,0xa8,0xaa,
0xac,0xae,0xb0,0xb3,0xb5,0xb7,0xb9,0xbb,
0xbd,0xbf,0xc1,0xc4,0xc6,0xc8,0xca,0xcc,
0xce,0xd0,0xd2,0xd5,0xd7,0xd9,0xdb,0xdd,
0xdf,0xe1,0xe3,0xe6,0xe8,0xea,0xec,0xee,
0xf0,0xf2,0xf4,0xf7,0xf9,0xfb,0xfd,0xff,
0xfd,0xfb,0xf9,0xf7,0xf4,0xf2,0xf0,0xee,
0xec,0xea,0xe8,0xe6,0xe3,0xe1,0xdf,0xdd,
0xdb,0xd9,0xd7,0xd5,0xd2,0xd0,0xce,0xcc,
0xca,0xc8,0xc6,0xc4,0xc1,0xbf,0xbd,0xbb,
0xb9,0xb7,0xb5,0xb3,0xb0,0xae,0xac,0xaa,
0xa8,0xa6,0xa4,0xa2,0x9f,0x9d,0x9b,0x99,
0x97,0x95,0x93,0x91,0x8e,0x8c,0x8a,0x88,
0x86,0x84,0x82,0x80,0x7d,0x7b,0x79,0x77,
0x75,0x73,0x71,0x6f,0x6c,0x6a,0x68,0x66,
0x64,0x62,0x60,0x5e,0x5b,0x59,0x57,0x55,
0x53,0x51,0x4f,0x4d,0x4a,0x48,0x46,0x44,
0x42,0x40,0x3e,0x3c,0x39,0x37,0x35,0x33,
0x31,0x2f,0x2d,0x2b,0x28,0x26,0x24,0x22,
0x20,0x1e,0x1c,0x1a,0x17,0x15,0x13,0x11,
0xf,0xd,0xb,0x9,0x6,0x4,0x2,0x0
}
,
// Sawtooth wave
{
0x2,0x4,0x6,0x9,0xb,0xd,0xf,0x11,
0x13,0x15,0x17,0x1a,0x1c,0x1e,0x20,0x22,
0x24,0x26,0x28,0x2b,0x2d,0x2f,0x31,0x33,
0x35,0x37,0x39,0x3c,0x3e,0x40,0x42,0x44,
0x46,0x48,0x4a,0x4d,0x4f,0x51,0x53,0x55,
0x57,0x59,0x5b,0x5e,0x60,0x62,0x64,0x66,
0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,0x77,
0x79,0x7b,0x7d,0x80,0x82,0x84,0x86,0x88,
0x8a,0x8c,0x8e,0x91,0x93,0x95,0x97,0x99,
0x9b,0x9d,0x9f,0xa2,0xa4,0xa6,0xa8,0xaa,
0xac,0xae,0xb0,0xb3,0xb5,0xb7,0xb9,0xbb,
0xbd,0xbf,0xc1,0xc4,0xc6,0xc8,0xca,0xcc,
0xce,0xd0,0xd2,0xd5,0xd7,0xd9,0xdb,0xdd,
0xdf,0xe1,0xe3,0xe6,0xe8,0xea,0xec,0xee,
0xf0,0xf2,0xf4,0xf7,0xf9,0xfb,0xfd,0xff,
0x2,0x4,0x6,0x9,0xb,0xd,0xf,0x11,
0x13,0x15,0x17,0x1a,0x1c,0x1e,0x20,0x22,
0x24,0x26,0x28,0x2b,0x2d,0x2f,0x31,0x33,
0x35,0x37,0x39,0x3c,0x3e,0x40,0x42,0x44,
0x46,0x48,0x4a,0x4d,0x4f,0x51,0x53,0x55,
0x57,0x59,0x5b,0x5e,0x60,0x62,0x64,0x66,
0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,0x77,
0x79,0x7b,0x7d,0x80,0x82,0x84,0x86,0x88,
0x8a,0x8c,0x8e,0x91,0x93,0x95,0x97,0x99,
0x9b,0x9d,0x9f,0xa2,0xa4,0xa6,0xa8,0xaa,
0xac,0xae,0xb0,0xb3,0xb5,0xb7,0xb9,0xbb,
0xbd,0xbf,0xc1,0xc4,0xc6,0xc8,0xca,0xcc,
0xce,0xd0,0xd2,0xd5,0xd7,0xd9,0xdb,0xdd,
0xdf,0xe1,0xe3,0xe6,0xe8,0xea,0xec,0xee,
0xf0,0xf2,0xf4,0xf7,0xf9,0xfb,0xfd,0xff
}
,
// Square wave
{
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
},
//Decaying Wave from https://daycounter.com/Calculators/Decaying-Wave-Generator-Calculator.phtml
{
0x0,0x4,0x8,0xc,0x10,0x14,0x18,0x1c,
0x20,0x24,0x27,0x2b,0x2e,0x32,0x35,0x38,
0x3c,0x3f,0x42,0x45,0x48,0x4b,0x4e,0x51,
0x54,0x57,0x5a,0x5c,0x5f,0x62,0x64,0x67,
0x69,0x6c,0x6e,0x71,0x73,0x75,0x78,0x7a,
0x7c,0x7e,0x80,0x82,0x85,0x87,0x89,0x8a,
0x8c,0x8e,0x90,0x92,0x94,0x96,0x97,0x99,
0x9b,0x9c,0x9e,0xa0,0xa1,0xa3,0xa4,0xa6,
0xa7,0xa9,0xaa,0xac,0xad,0xae,0xb0,0xb1,
0xb2,0xb3,0xb5,0xb6,0xb7,0xb8,0xba,0xbb,
0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,
0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,
0xcc,0xcc,0xcd,0xce,0xcf,0xd0,0xd0,0xd1,
0xd2,0xd3,0xd3,0xd4,0xd5,0xd6,0xd6,0xd7,
0xd8,0xd8,0xd9,0xd9,0xda,0xdb,0xdb,0xdc,
0xdc,0xdd,0xde,0xde,0xdf,0xdf,0xe0,0xe0,
0xe1,0xe1,0xe2,0xe2,0xe3,0xe3,0xe4,0xe4,
0xe5,0xe5,0xe5,0xe6,0xe6,0xe7,0xe7,0xe7,
0xe8,0xe8,0xe9,0xe9,0xe9,0xea,0xea,0xea,
0xeb,0xeb,0xeb,0xec,0xec,0xec,0xed,0xed,
0xed,0xee,0xee,0xee,0xee,0xef,0xef,0xef,
0xef,0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,
0xf1,0xf2,0xf2,0xf2,0xf2,0xf3,0xf3,0xf3,
0xf3,0xf3,0xf4,0xf4,0xf4,0xf4,0xf4,0xf4,
0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf6,0xf6,
0xf6,0xf6,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
0xf7,0xf7,0xf7,0xf7,0xf8,0xf8,0xf8,0xf8,
0xf8,0xf8,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,
0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,
0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa
},
// Runt wave
{
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, // I'll use this level for the trigger
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
},
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment