I have now written the code to produce pulses to implement the pulse generator mode of the Micro Servo Tester, see the listing below. I have only included the pulse generatong function as that is the only part that has changed.
void pulsegeneratormode(void)
{
int frequency, pulsebit;
long int fdelay;
frequency = 1;
pulsebit = 1;
fdelay = 0;
display.clearDisplay(); // Clear the display so we can refresh
display.setCursor(0,10); // Middle left
display.println("Pulse Generator ");
display.setCursor(0,30); // Middle left
display.println("Frequency ");
display.setCursor(0,40); // Middle left
display.println("Pulse Width ");
display.display(); // This outputs to the screen
frequency = analogRead(adcfreq); //Get the initial frequency value
if (frequency < 1)
frequency = 2;
fdelay = (1000000 / frequency)/2;
while (!buttonpress(button))
{
digitalWrite(pulseop, HIGH);
if (fdelay < 10000) // Pulse delay part
{
delayMicroseconds(fdelay);
}
else
{
delay(fdelay/1000);
delayMicroseconds(fdelay % 10000);
} /* for */
digitalWrite(pulseop, LOW);
if (fdelay < 10000) // Space delay part
{
delayMicroseconds(fdelay);
}
else
{
delay(fdelay/1000);
delayMicroseconds(fdelay % 10000);
} /* for */
frequency = analogRead(adcfreq); //Get the frequency value
if (frequency < 1)
frequency = 2;
fdelay = (1000000 / frequency)/2;
pulsebit = analogRead(adcpulse); //Get the pulse width value
// mydisplaypulse(frequency, pulsebit);
} /* while */
}
It is a relatively simple function as all it does is read the 10 turn pot controlling the frequency and then converts that into a microsecond delay. It does that by dividing 1 million by the measured frequency. So if the frequency is 1 Hz then the delay will be 1000000/1 = 1000000 us which is correct. I then divide this by 2 to produce the pulse part of the delay, and the space part will be the same. At present I have not implemented the capability to vary the pulse width so this will be an even mark to space ration pulse for all pulses.
The Arduino documentation indicates the the delayMicrosecond() function is not that accurate after 16,000 values so I used 10,000 as the cutoff. If any delay is greater than 10,000 us then it is converted into a number of millisecond delays, with a remainder (obtained using modulos) in microseconds. It seems to work. There will be some jitter or variation in frequency as the 10 turn pot is turned due to different length paths through this function, but the variation will be small.
A bigger problem is that the OLED display takes 37 milliseconds to update which is much too long for this use. So, I have deleted that part from the code. Sadly, this means that the OLED display is no longer used when in pulse generator mode. See the video below.
This problem also means that when in Servo Tester mode that the pulse being generated will be much to long. It should be a varying pulse part between 1 - 2 miiliseconds, followed by the 18 millisecond space delay, but with the display taking 37 ms to update, it means the space delay has increased to 53 milliseconds. It is a testament to the flexibility of the servo motors that they work at all!. I will have to have a rethink about all the functions of this system. Ah well, something to do on a rainy day.
Dubbie
Top Comments