I am trying to make a VCO based on voltmeter and generator programs, what I need is control Overflow of the timer by voltage applied to PA7.
pwmtimer3.setOverflow(1000 - 1);
Cheers, E.
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
HardwareTimer pwmtimer3(3);
int i;
int volt;
void setup() {
pinMode(PA6, INPUT_ANALOG);
lcd.begin(16, 2);
pinMode(PB0, PWM);
/*
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(1000 - 1);
pwmtimer3.setCompare(TIMER_CH3, 500); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
*/
}
void loop() {
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(i);
pwmtimer3.setCompare(TIMER_CH3, i / 2); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
i == volt;
float volt = analogRead(PA6);
volt = (volt * 3.3) / 4095.0;
lcd.setCursor(0, 0);
lcd.print(volt);
delay(100);
}
I can’t remember if PB0 even has a timer attached to it, but I’d double check that first
Then just to an AnalogWrite to PB0 and check you get some PWM
After thats working, try setting up your own PWM at one frequency
When thats working and you can set various initial frequencies and check that works
Then in your main(), try setting an initial freq, waiting 250ms and then set a new freq
If at any stage things arent working as you expect, examine what you are doing and bug fix
Then in your main(), try setting an initial freq, waiting 250ms and then set a new freq
If at any stage things arent working as you expect, examine what you are doing and bug fix
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
HardwareTimer pwmtimer3(3);
//int i ;
void setup() {
pinMode(PA6, INPUT_ANALOG);
lcd.begin(16, 2);
pinMode(PB0, PWM);
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(1000 - 1);
pwmtimer3.setCompare(TIMER_CH3, 500); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
delay(10);
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(100 - 1);
pwmtimer3.setCompare(TIMER_CH3, 50); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
}
void loop() {
/*
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(1000 - 1);
pwmtimer3.setCompare(TIMER_CH3, 500); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
delay(10);
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(100 - 1);
pwmtimer3.setCompare(TIMER_CH3, 50); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
*/
/*
float volt = analogRead(PA6);
volt = (volt * 3.3) / 4095.0;
lcd.setCursor(0, 0);
lcd.print(volt);
delay(100);
*/
}
pwmtimer3.setOverflow(100 - 1);#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
HardwareTimer pwmtimer3(3);
//int i ;
void setup() {
pinMode(PA6, INPUT_ANALOG);
lcd.begin(16, 2);
pinMode(PB0, PWM);
}
void loop() {
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(1000 - 1);
pwmtimer3.setCompare(TIMER_CH3, 500); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
delay(1000);
pwmtimer3.pause();
pwmtimer3.setPrescaleFactor(72); // Timer input clock Prescaler = 1MHz 72MHz
pwmtimer3.setOverflow(100 - 1);
pwmtimer3.setCompare(TIMER_CH3, 50); // PWM High Pulse width is 50% duty (1:1)
pwmtimer3.refresh();
pwmtimer3.resume();
delay(1000);
}
So replace in your code pwmtimer3 with Timer3.
Furthermore, you don’t need to stop and restart the timer each time you change the compare value.
You don’t have to set the prescale factor each time.
It is enough to set it once in the setup
//HardwareTimer pwmtimer3(3); // - not needed
// in setup:
Timer3.setPrescaleFactor(72);
...
// in loop, when you want to change the frequency and/or duty cycle.
...
Timer3.pause();
Timer3.setOverflow(TIMER_CH3, <2*value-1>);
Timer3.setCompare(TIMER_CH3, <value>);
Timer3.refresh();
Timer3.resume();
...
It is working, two frequencies are switching every 1 sec.
blinking LED = blinking generator.
How this can be used for VCO ?
I did, like that, and have some errors. Your approach is similar to my in the first post, you changed “i” to “value”, I think will work after removing the errors.
The errors
vco_dc_-stevestrong:16: error: expected initializer before 'void'
void loop() {
^
C:\Users\OWNER\Desktop\vco_dc_-stevestrong\vco_dc_-stevestrong.ino: In function 'void loop()':
vco_dc_-stevestrong:23: error: 'value' was not declared in this scope
value == volt;
^
vco_dc_-stevestrong:26: error: expected primary-expression before '<' token
Timer3.setOverflow(TIMER_CH3, <2*value-1>);
^
vco_dc_-stevestrong:26: error: expected primary-expression before ')' token
Timer3.setOverflow(TIMER_CH3, <2*value-1>);
^
vco_dc_-stevestrong:27: error: expected primary-expression before '<' token
Timer3.setCompare(TIMER_CH3, <value>);
^
vco_dc_-stevestrong:27: error: expected primary-expression before ')' token
Timer3.setCompare(TIMER_CH3, <value>);
^
Multiple libraries were found for "LiquidCrystal.h"
Used: C:\Users\OWNER\AppData\Local\Arduino15\packages\stm32duino\hardware\STM32F1\2018.1.3\libraries\LiquidCrystal
Not used: C:\Users\OWNER\Documents\Arduino\libraries\Newliquidcrystal_1.3.5
Not used: C:\Users\OWNER\Desktop\183\arduino-1.8.3\libraries\LiquidCrystal
Using library LiquidCrystal in folder: C:\Users\OWNER\AppData\Local\Arduino15\packages\stm32duino\hardware\STM32F1\2018.1.3\libraries\LiquidCrystal (legacy)
exit status 1
expected initializer before 'void'
[stevestrong – Thu Sep 06, 2018 11:38 am] –
how do you verify the resulting frequency on PB0? With a scope?
Yes.
//int i ;
int value // --- missing ";" -----//http://www.stm32duino.com/viewtopic.php?f=19&t=4082
//edogaldo
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
int ain;
int ovfDiv2;
float volt;
void setup() {
pinMode(PA6, INPUT_ANALOG);
lcd.begin(16, 2);
pinMode(PB0, PWM);
Timer3.setPrescaleFactor(72);
}
void loop() {
ain = analogRead(PA6);
ovfDiv2 = map(ain,0,4095,50,5000); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHz
Timer3.pause();
Timer3.setOverflow(2*ovfDiv2-1);
Timer3.setCompare(TIMER_CH3, ovfDiv2);
Timer3.refresh();
Timer3.resume();
volt = (ain * 3.3) / 4095.0;
lcd.setCursor(0, 0);
lcd.print(volt);
delay(100);
}
0V – 1.2V = 120Hz-30Hz.
1.2V – 2.7V = no pulses
2.7V – 2.8V = toy music -on speaker
2.8V -3.3V = 200 Hz – 40 Hz
//ovfDiv2 = map(ain,0,50,4095,5000); // freq between 10KHz and 100Hz
ovfDiv2 = ain; // freq between 10KHz and 100Hz ovfDiv2 = map(ain,0,4095,50,5000); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHz
ovfDiv2 = map(ain,0,4095,5000,50); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHzFrequency is not much changing for input 0V to 2.5V
Thanks
I play with the numbers and looks I can get proper response however the sound is not that pure as using VCO build on NE555.
Probably I need averaging “ain”.
You should use this one:
ovfDiv2 = 5050 - map(ain,0,4095,50,5000); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHz//http://www.stm32duino.com/viewtopic.php?f=19&t=4082
//edogaldo
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
int ain;
int ovfDiv2;
float volt;
unsigned int total; // can hold max 64 readings
void setup() {
pinMode(PA6, INPUT_ANALOG);
lcd.begin(16, 2);
pinMode(PB0, PWM);
Timer3.setPrescaleFactor(72);
}
void loop() {
////////////////////
for (int x = 0; x < 64; x++) { // multiple analogue readings for averaging
total = total + analogRead(PA6); // add each value to a total
}
volt = (total / 64.0) * 3.3; // convert readings to volt
//////////////////////
ain = analogRead(PA6);
//ovfDiv2 = map(ain,0,50,4095,5000); // freq between 10KHz and 100Hz
//ovfDiv2 = map(ain,0,1000,10000,0); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHz
// ovfDiv2 = map(total,0,1000,10000,0);
// ovfDiv2 = ain/5; // freq between 10KHz and 100Hz
ovfDiv2 = map( total,0,50,4095,5000); // freq between 10KHz and 100Hz
Timer3.pause();
Timer3.setOverflow(2*ovfDiv2-1);
Timer3.setCompare(TIMER_CH3, ovfDiv2);
Timer3.refresh();
Timer3.resume();
// volt = (ain * 3.3) / 4095.0;
volt = (total /64.0)* 3.3 / 4095.0;
lcd.setCursor(0, 0);
lcd.print(volt);
total = 0; // reset value
delay(10);
}
//http://www.stm32duino.com/viewtopic.php?f=19&t=4082
//edogaldo
#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);
int ain;
int ovfDiv2;
float volt;
void setup() {
pinMode(PA6, INPUT_ANALOG);
lcd.begin(16, 2);
pinMode(PB0, PWM);
Timer3.setPrescaleFactor(72);
}
void loop() {
ain = analogRead(PA6);
// ovfDiv2 = map(ain,0,4095,50,5000); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHz
ovfDiv2 = 5050 - map(ain,0,4095,50,5000); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHz
Timer3.pause();
Timer3.setOverflow(2*ovfDiv2-1);
Timer3.setCompare(TIMER_CH3, ovfDiv2);
Timer3.refresh();
Timer3.resume();
volt = (ain * 3.3) / 4095.0;
lcd.setCursor(0, 0);
lcd.print(volt);
delay(10);
}
100Hz all the time, pulse duty is changing smoothly from 50% to 0%, nice and stable signal, now I need to change this to make frequency changes not the width ?
[edogaldo – Thu Sep 06, 2018 4:41 pm] –
Try to explain the relationship you would expect between the voltage and the frequency.
smooth frequency changes
int ovfDiv = 5050 - ain;
Timer3.pause();
Timer3.setOverflow(ovfDiv-1);
Timer3.setCompare(TIMER_CH3, ovfDiv/2);
Timer3.refresh();
Timer3.resume();
ovfDiv2 = 500000/map(ain,0,4095,100,10000); // freq between 100Hz and 10kHz: ain=0 -> freq=100Hz - ain=4095 -> freq=10kHz
Timer3.pause();
Timer3.setOverflow(2*ovfDiv2-1);
Timer3.setCompare(TIMER_CH3, ovfDiv2);
Timer3.refresh();
Timer3.resume();
Perfect, 100Hz-10 000Hz, starts responding @ 0.05V = very sensitive and accurate.
@ 0.05V , the first pulse is stable, next 3 pulses are shaking a little bit and the 4th is again stable, for another voltages similar, this is giving sound not very pure bat acceptable.
thanks guys for helping.

