Hello and Noob/Lurker alert
I am trying to implement Bjorklund's algorithm, which aims to:
"distribute n pulses over m timing slots in the most even way possible, even though n may not necessarily be an even divisor of m."
I swiped the algorithm from the paper and modified it so it would run on Arduino, also referencing this (unresolved) post: Euclid, Bjorklund algorithm - Programming Questions - Arduino Forum
However, I am experiencing some problems with the code and I need some fresh eyes and guidance. I would be extremely grateful.
Here is what is currently running:
//Bjorklund's Algorithm
// see: https://ics-web.sns.ornl.gov/timing/Rep-Rate%20Tech%20Note.pdf
int count[16];
int divisor;
int i;
int pattern[16];
void setup() {
Serial.begin(9600);
}
void loop() {
delay(3000); //Give enough time to open the serial window and study the output....
Serial.println(); //Blank line
compute_bitmap (16,4); //e.g. Compute for 4 Pulses in 16 steps
}
void compute_bitmap(int num_slots, int num_pulses) {
int remainder[16]; // Should this be declared as a global????
divisor = (num_slots - num_pulses);
remainder[0] = num_pulses;
int newLength;
int level = 0;
int cycleLength = 1;
int remLength = 1;
do {
count[level] = (divisor / remainder[level]);
remainder[level+1] = (divisor % remainder[level]);
divisor = remainder[level];
newLength = (cycleLength * count[level]) + remLength;
remLength = cycleLength;
cycleLength = newLength;
level = level + 1;
//Debug
//Serial.println(newLength);
//Serial.println("---");
//delay(200); //debug
}
while (remainder[level] > 1);
count[level] = divisor;
if (remainder[level] > 0)
cycleLength = (cycleLength * count[level]) + remLength;
build_string(level);
}
void build_string(int level) {
if (level == -1) {
//append a “0” to the end of the bitmap;
Serial.println("0"); //debug
delay(500);
}
else if (level == -2) {
//append a “1” to the end of the bitmap;
Serial.println("1"); //debug
delay(500);
}
else {
for (i=0; i < count[level]; i++)
build_string(level-1);
if (remainder[level] != 0)
build_string(level-2);
}
}
Firstly, if I declare int remainder[16] as a global variable at the top of the file, I receive the following error:
error: invalid conversion from 'double (*)(double, double)' to 'int' [-fpermissive]
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
But if I instead declare it within the build_string() function, it compiles and runs.
Why is this so?
Secondly, when the algorithm does run, I get very mixed results. For example,
18/6 (001001001001001001) looks OK, as does 12/5 (010010100101), 16/4 etc.
However, 16/6 (0101010101010101) is definitely wrong, and sometimes I just get a stream of 1's and 0's.
It seems to be breaking-down somewhere and I having trouble debugging it. Can anyone spot where I've gone wrong?
Many kind thanks in advance for any nuggets of help.