Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .arduino-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
- leonardo
- due
- zero
# - due
# - zero
# - leonardo
- m4
- esp32
# - esp8266
# - mega2560
# Declaring Dependent Arduino Libraries (to be installed via the Arduino Library Manager)
libraries:
- "MCP4725"
- "MCP4725"
10 changes: 7 additions & 3 deletions .github/workflows/arduino_test_runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ name: Arduino CI
on: [push, pull_request]

jobs:
arduino_ci:
runTest:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: Arduino-CI/action@master
# Arduino-CI/action@v0.1.1
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- run: |
gem install arduino_ci
arduino_ci.rb
137 changes: 106 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,62 @@

[![Arduino CI](https://github.com/RobTillaart/FunctionGenerator/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/FunctionGenerator/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/FunctionGenerator/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/FunctionGenerator/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/FunctionGenerator/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/FunctionGenerator/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/FunctionGenerator.svg?maxAge=3600)](https://github.com/RobTillaart/FunctionGenerator/releases)


# FunctionGenerator

Arduino library to generate wave forms (nummeric) for a DAC
Arduino library to generate (numeric) wave forms for a DAC


## Description

TODO.
This library presents a class for a function generator in software.
It is typical used to control one or more DAC's.
To maximize signal quality one has to apply all (or most) processor power
to calculate new values over and over again to get enough resolution.
In practice the generator is useful for low frequencies,
0.01 - 25 Hz, depending on waveform and processor and number of DAC's.
(see indication below).

Note: this class generates float values, performance wise this can be optimized,
to achieve higher speeds at cost of accuracy / precision.


## Performance

Indication of what performance can be expected (based upon 0.2.1 version).
Note that the values need to be transported to a DAC or serial port too.
Numbers based on performance example, for one single signal.

| Processor | Clock | Waveform | usec/calls | max freq |
|:-------------|---------:|:---------|-----------:|---------:|
| Arduino UNO | 16 MHz | sawtooth | 62 | 60 Hz |
| Arduino UNO | 16 MHz | triangle | 74 | 50 Hz |
| Arduino UNO | 16 MHz | square | 53 | 1000 Hz |
| Arduino UNO | 16 MHz | sinus | 164 | 25 Hz |
| Arduino UNO | 16 MHz | stair | 81 | 50 Hz |
| Arduino UNO | 16 MHz | random | 37 | 1000 Hz |
| | | | | |
| ESP32 | 240 MHz | sawtooth | 3.8 | 1000 Hz |
| ESP32 | 240 MHz | triangle | 3.9 | 1000 Hz |
| ESP32 | 240 MHz | square | 2.8 | 1000 Hz |
| ESP32 | 240 MHz | sinus | 13.6 | 250 Hz |
| ESP32 | 240 MHz | stair | 4.8 | 800 Hz |
| ESP32 | 240 MHz | random | 1.3 | 1000 Hz |


- assumption minimal 250 samples per period to get a smooth signal.
if a rougher signal is OK, higher frequencies are possible.
- ESP32 can do more calculations however 1000 Hz seems to be a nice
upper limit for a software based function generator.
- if one wants to control multiple DAC's one need to divide the numbers.


Note: hardware function generator https://github.com/RobTillaart/AD985X


## Interface

Expand All @@ -18,48 +65,76 @@ TODO.
- **funcgen(float period = 1.0, float amplitude = 1.0, float phase = 0.0, float yShift = 0.0)**
All parameters can be set in the constructor but also later in configuration.


### Configuration

- **void setPeriod(float period = 1.0)** // seconds
- **float getPeriod**
- **void setFrequency(float freq = 1.0)** // Hertz
- **float getFrequency()**
- **void setAmplitude(float ampl = 1.0)** // -
- **float getAmplitude()**
- **void setPhase(float phase = 0.0)** // phase of period
- **float getPhase()**
- **void setYShift(float yShift = 0.0)** // shift in amplitude, zero point.
- **float getYShift()**
- **void setPeriod(float period = 1.0)** set the period of the wave in seconds.
- **float getPeriod()** returns the set period.
- **void setFrequency(float frequency = 1.0)** set the frequency of the wave in Hertz (1/s).
- **float getFrequency()** returns the set frequency.
- **void setAmplitude(float amplitude = 1.0)** sets the amplitude of the wave. TODO point to point?
Setting the amplitude to 0 gives ?what?
- **float getAmplitude()** returns the set amplitude.
- **void setPhase(float phase = 0.0)** shifts the phase of the wave. Will only be noticeable when
compared with other waves.
- **float getPhase()** returns the set phase.
- **void setYShift(float yShift = 0.0)** sets an Y-shift in amplitude, allows to set some zero point.
- **float getYShift()** returns the set Y-shift.


### Wave forms

t is time in seconds
- **float sawtooth(float t)**
- **float triangle(float t)**
- **float square(float t)**
- **float sinus(float t)**
- **float stair(float t, uint16_t steps = 8)**
- **float random()**
- **float line()**
- **float zero()**

Line() and zero() are functions that can be used
to drive a constant voltage from a DAC and can be
used to calibrate the generator / DAC combination.

- **float sawtooth(float t, uint8_t mode = 0)** mode == 0 (default) ==> sawtooth /|. mode == 1 ==> sawtooth |\.
- **float triangle(float t)** triangle form, duty cycle 50%.
- **float square(float t)** square wave with duty cycle 50%.
- **float sinus(float t)** sinus wave, has no duty cycle.
- **float stair(float t, uint16_t steps = 8, uint8_t mode = 0)** mode = 0 ==> steps up, mode = 1 steps down.
- **float random()** noise generation.
- **float line()** constant voltage line
- **float zero()** constant zero.

Line() and zero() are functions that can be used to drive a constant voltage from a DAC
and can be used to calibrate the generator / DAC combination.


## Operational

See examples.

## TODO

ideas for the future...
## Future


#### waveforms

- square duty-cycle (will be slower!)
- triangle duty-cycle (makes sawtooth a special triangle)
- trapezium wave (would merge square and triangle and sawtooth)

#### investigate

- duty-cycle for sinus what does it mean. move peak.
- white noise, pink noise etc.
- investigate algorithms for performance gains (DAC specific values 10-12-16 bit)
- Amplitude modulation ?
- external clock to synchronize two or more sw function generators.
- RC function curve.
- heartbeat curve?
- record a signal and play back

#### misc

- stand-alone functions in separate .h?
- mapping to voltage function.
- check for synergy with https://github.com/RobTillaart/AD985X

#### examples

- example ESP32 version as separate task...
- example with DAC. 8 12 16 bit.
- example with potmeters for 4 parameters
- RC function
- Trapezium
- Sawtooth reverse?
- play "recording"
- example with potentiometers for 4 parameters



8 changes: 7 additions & 1 deletion examples/functionGenerator/functionGenerator.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
// URL: https://github.com/RobTillaart/FunctionGenerator
//


#include "functionGenerator.h"


funcgen gen;

uint32_t lastTime = 0;
char choice = '0';


void setup()
{
Serial.begin(500000);
Expand All @@ -24,6 +27,7 @@ void setup()
gen.setAmplitude(50);
}


void loop()
{
if (Serial.available())
Expand Down Expand Up @@ -54,4 +58,6 @@ void loop()
}
}

// END OF FILE

// -- END OF FILE --

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
funcgen gen1;
funcgen gen2;


void setup()
{
Serial.begin(115200);
Expand All @@ -31,6 +32,7 @@ void setup()
gen2.setYShift(25);
}


void loop()
{
float t = millis() * 0.001;
Expand All @@ -44,4 +46,6 @@ void loop()
Serial.println();
}

// END OF FILE

// -- END OF FILE --

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// URL: https://github.com/RobTillaart/FunctionGenerator
//


#include "functionGenerator.h"

uint32_t start;
Expand All @@ -17,6 +18,7 @@ volatile float y;

funcgen gen;


void setup()
{
Serial.begin(115200);
Expand Down Expand Up @@ -87,6 +89,7 @@ void test_square()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void test_sawtooth()
{
start = micros();
Expand All @@ -102,6 +105,7 @@ void test_sawtooth()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void test_triangle()
{
start = micros();
Expand All @@ -117,6 +121,7 @@ void test_triangle()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void test_sinus()
{
start = micros();
Expand All @@ -132,6 +137,7 @@ void test_sinus()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void test_stair()
{
start = micros();
Expand All @@ -147,6 +153,7 @@ void test_stair()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void test_random()
{
start = micros();
Expand All @@ -162,6 +169,7 @@ void test_random()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void test_line()
{
start = micros();
Expand All @@ -177,6 +185,7 @@ void test_line()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void test_zero()
{
start = micros();
Expand All @@ -192,8 +201,11 @@ void test_zero()
Serial.println(1000000.0 / ((stop - start) / 10000.0));
}


void loop()
{
}

// END OF FILE

// -- END OF FILE --

Loading