Mercurial > hg > beaglert
changeset 542:3016638b4da2 prerelease
Analog examples updated
author | Robert Jack <robert.h.jack@gmail.com> |
---|---|
date | Fri, 24 Jun 2016 13:00:31 +0100 |
parents | c301cc07ae11 |
children | 8f8809c77dda |
files | examples/03-Analog/analog-input/render.cpp examples/03-Analog/analog-output/render.cpp examples/03-Analog/scope-analog/render.cpp |
diffstat | 3 files changed, 70 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/03-Analog/analog-input/render.cpp Fri Jun 24 02:29:05 2016 +0100 +++ b/examples/03-Analog/analog-input/render.cpp Fri Jun 24 13:00:31 2016 +0100 @@ -23,27 +23,33 @@ #include <Bela.h> -#include <rtdk.h> #include <cmath> float gPhase; float gInverseSampleRate; int gAudioFramesPerAnalogFrame; -// These settings are carried over from main.cpp -// Setting global variables is an alternative approach -// to passing a structure to userData in setup() - -extern int gSensorInputFrequency; -extern int gSensorInputAmplitude; +// Set the analog channels to read from +int gSensorInputFrequency = 0; +int gSensorInputAmplitude = 1; bool setup(BelaContext *context, void *userData) { + + // Check if analog channels are enabled if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) { rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n"); return false; } + // Check that we have the same number of inputs and outputs. + if(context->audioInChannels != context->audioOutChannels || + context->analogInChannels != context-> analogOutChannels){ + printf("Error: for this project, you need the same number of input and output channels.\n"); + return false; + } + + // Useful calculations gAudioFramesPerAnalogFrame = context->audioFrames / context->analogFrames; gInverseSampleRate = 1.0 / context->audioSampleRate; gPhase = 0.0; @@ -61,16 +67,18 @@ for(unsigned int n = 0; n < context->audioFrames; n++) { if(!(n % gAudioFramesPerAnalogFrame)) { - // Even audio samples: update frequency and amplitude from the matrix + // On even audio samples: read analog inputs and update frequency and amplitude frequency = map(analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputFrequency), 0, 1, 100, 1000); amplitude = analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputAmplitude); } float out = amplitude * sinf(gPhase); - for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = out; + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) { + audioWrite(context, n, channel, out); + } + // Update and wrap phase of sine tone gPhase += 2.0 * M_PI * frequency * gInverseSampleRate; if(gPhase > 2.0 * M_PI) gPhase -= 2.0 * M_PI; @@ -90,10 +98,10 @@ ------------------------- This sketch produces a sine tone, the frequency and amplitude of which are -affected by data received on the analog pins. Before looping through each audio -frame, we declare a value for the frequency and amplitude of our sine tone -(line 55); we adjust these values by taking in data from analog sensors -(for example potentiometers) with `analogRead()`. +modulated by data received on the analog input pins. Before looping through each audio +frame, we declare a value for the `frequency` and `amplitude` of our sine tone; +we adjust these values by taking in data from analog sensors (for example potentiometers) +with `analogRead()`. - connect a 10K pot to 3.3V and GND on its 1st and 3rd pins. - connect the 2nd middle pin of the pot to analogIn 0. @@ -113,8 +121,4 @@ } ```` -Note that the pin numbers are stored in the variables `gAnalogInputFrequency` and -`gAnalogInputAmplitude`. These are declared in the main.cpp file; if you look in -that file you will see that they have the values of 0 and 1. Bear in mind that -these are analog input pins which is a specific header! */
--- a/examples/03-Analog/analog-output/render.cpp Fri Jun 24 02:29:05 2016 +0100 +++ b/examples/03-Analog/analog-output/render.cpp Fri Jun 24 13:00:31 2016 +0100 @@ -23,24 +23,29 @@ #include <Bela.h> -#include <rtdk.h> #include <cmath> // Set range for analog outputs designed for driving LEDs const float kMinimumAmplitude = (1.5 / 5.0); const float kAmplitudeRange = 1.0 - kMinimumAmplitude; -float gFrequency; +float gFrequency = 3.0; float gPhase; float gInverseSampleRate; bool setup(BelaContext *context, void *userData) { - // Retrieve a parameter passed in from the initAudio() call - gFrequency = *(float *)userData; - if(context->analogFrames == 0) { - rt_printf("Error: this example needs the matrix enabled\n"); + // Check if analog channels are enabled + if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) { + rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n"); + return false; + } + + // Check that we have the same number of inputs and outputs. + if(context->audioInChannels != context->audioOutChannels || + context->analogInChannels != context-> analogOutChannels){ + printf("Error: for this project, you need the same number of input and output channels.\n"); return false; } @@ -55,7 +60,7 @@ for(unsigned int n = 0; n < context->analogFrames; n++) { // Set LED to different phase for each matrix channel float relativePhase = 0.0; - for(unsigned int channel = 0; channel < context->analogChannels; channel++) { + for(unsigned int channel = 0; channel < context->analogOutChannels; channel++) { float out = kMinimumAmplitude + kAmplitudeRange * 0.5f * (1.0f + sinf(gPhase + relativePhase)); analogWrite(context, n, channel, out); @@ -64,6 +69,7 @@ relativePhase += M_PI * 0.25; } + // Update and wrap phase of sine tone gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; if(gPhase > 2.0 * M_PI) gPhase -= 2.0 * M_PI; @@ -99,7 +105,7 @@ arguments as follows `analogWrite(context, n, channel, out)`. Channel is where the you give the address of the analog output pin (in this case we cycle through each pin address in the for loop), out is the variable that holds the -desired output (in this case set by the sine wave). +desired output (in this case set by the sine wave) and `n` is the frame number. Notice that the phase of the brightness cycle for each led is different. This is achieved by updating a variable that stores a relative phase value. This
--- a/examples/03-Analog/scope-analog/render.cpp Fri Jun 24 02:29:05 2016 +0100 +++ b/examples/03-Analog/scope-analog/render.cpp Fri Jun 24 13:00:31 2016 +0100 @@ -37,6 +37,19 @@ // setup the scope with 3 channels at the audio sample rate scope.setup(3, context->audioSampleRate); + // Check if analog channels are enabled + if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) { + rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n"); + return false; + } + + // Check that we have the same number of inputs and outputs. + if(context->audioInChannels != context->audioOutChannels || + context->analogInChannels != context-> analogOutChannels){ + printf("Error: for this project, you need the same number of input and output channels.\n"); + return false; + } + gInverseSampleRate = 1.0 / context->audioSampleRate; gPhase = 0.0; @@ -66,8 +79,10 @@ scope.log(out, in1, in2); // pass the sine wave to the audio outputs - for(unsigned int channel = 0; channel < context->audioChannels; channel++) - context->audioOut[n * context->audioChannels + channel] = out; + for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) { + audioWrite(context, n, channel, out); + } + } } @@ -81,10 +96,10 @@ /** \example scope-analog/render.cpp -Connecting potentiometers +Scoping sensor input ------------------------- -This example reads from analogue inputs 0 and 1 via `analogReadFrame()` and +This example reads from analogue inputs 0 and 1 via `analogRead()` and generates a sine wave with amplitude and frequency determined by their values. It's best to connect a 10K potentiometer to each of these analog inputs. Far left and far right pins of the pot go to 3.3V and GND, the middle should be @@ -92,7 +107,21 @@ The sine wave is then plotted on the oscilloscope. Click the Open Scope button to view the results. As you turn the potentiometers you will see the amplitude and -frequency of the sine wave change. +frequency of the sine wave change. You can also see the two sensor readings plotted +on the oscilloscope. + +The scope is initialised in `setup()` where the number of channels and sampling rate +are set. + +````` +scope.setup(3, context->audioSampleRate); +````` + +We can then pass signals to the scope in `render()` using: + +`````` +scope.log(out, in1, in2); +`````` This project also shows as example of `map()` which allows you to re-scale a number from one range to another. Note that `map()` does not constrain your variable