Hello all,
the code below synthesizes 6 PWM signals: each can be offset and frequency modulated, The frequency modulation can be sinusoid, triangular or sawtooth ascending or descending. (target mbed LPC1768)
I’m having trouble assigning the mode class variable, the compiler reports:
Error: A value of type “float (Channel::)()" cannot be assigned to an entity of type "float ()()” in “main.cpp”, Line: 63, Col: 15
syntactically it should be correct, what am I missing? The error occurs in both class constructors.
Any help is appreciated, thank-you.
Giancarlo
#include "mbed.h"
#define SCHUMANN 7.83 // Base frequency
#define CHANNELS 6
#define SAMPLING_RATE 10000.0 // Samples per second
DigitalOut out[CHANNELS] = { LED1, LED2, LED3, LED4, p25, p26 };
Ticker counter;
unsigned int ticks = 0;
void tick()
{
++ticks;
}
enum MODE { None, Sine, Triangle, SawAsc, SawDesc };
class Channel
{
float frequency; // Base frequency (Hz)
inline float modeNone()
{
return 0.0;
}
inline float modeSine()
{
float df = (float) (ticks % sweep_period) - (float) sweep_period / 2.0;
return sweep_range * df * (ticks % sweep_period < sweep_period / 2) ? 1.0 : -1.0;
}
inline float modeTriangle()
{
float df = (float) (ticks % sweep_period) - (float) sweep_period / 2.0;
return sweep_range * df * (ticks % sweep_period < sweep_period / 2) ? 1.0 : -1.0;
}
inline float modeSawAsc()
{
return sweep_range * (float) (ticks % sweep_period - sweep_period / 2);
}
inline float modeSawDesc()
{
return -sweep_range * (float) (ticks % sweep_period - sweep_period / 2);
}
public:
bool enabled;
unsigned int period; // ms
unsigned int offset; // ms
unsigned int duty; // ms
float (*mode)();
float sweep_range; // Hz
unsigned int sweep_period; // ms
Channel()
{
enabled = false;
period = SAMPLING_RATE / SCHUMANN;
offset = 0;
duty = period * 0.5; // 50%
mode = &Channel::modeNone;
sweep_range = 0.0;
sweep_period = 0;
}
Channel(float Frequency, unsigned short Duty, unsigned short Phase = 0, MODE SweepMode = None, float SweepRange = 0.0, float SweepFrequency = 0.0)
{
enabled = true;
frequency = abs(Frequency);
period = Frequency == 0 ? (unsigned int) ~0 : SAMPLING_RATE / frequency;
offset = period * Phase / 100.0;
duty = period * Duty / 100.0;
if (SweepMode == Sine)
mode = &Channel::modeSine;
else if (SweepMode == Triangle)
mode = &Channel::modeTriangle;
else if (SweepMode == SawAsc)
mode = &Channel::modeSawAsc;
else if (SweepMode == SawDesc)
mode = &Channel::modeSawDesc;
else
mode = &Channel::modeNone;
sweep_range = abs(SweepRange) > frequency ? frequency : abs(SweepRange);
sweep_period = SweepFrequency <= 0 ? (unsigned int) ~0 : SAMPLING_RATE / SweepFrequency;
}
bool State()
{
if (enabled) {
float df = mode(); // Determine frequency offset from base frequency
unsigned int dp = -df / frequency * (frequency + df);
if ((ticks - offset) % (period + dp) < (duty * frequency / (frequency + df)))
return true;
}
return false;
}
}
int main()
{
// Initialize channels
Channel channels[CHANNELS] = {
Channel(), //SCHUMANN / 2.0, 10),
Channel(), //SCHUMANN / 2.0, 10, 50),
Channel(30.0, 10, 0, Sine, 15.0, 0.01),
Channel(),
Channel(),
Channel()
};
/*
for (int i = 0; i < CHANNELS; ++i) {
printf("Channel %d: freq (Hz) %2.2f, offset (ms): %d, duty: %d%%\n", i+1, SAMPLING_RATE / channels[i].period, channels[i].offset, channels[i].duty);
}
*/
counter.attach_us(&tick, (unsigned int) 1000000.0 / SAMPLING_RATE);
int i = 0;
while (1) {
out[i] = channels[i].State();
i = ++i % CHANNELS;
}
}