I am writing to ask for help on the arduino uno programming on the high frequency PWM adjusting.
In my project, I am thinking to first receive high frequency PWM input, and read it, then reproduce a new pwm with adjusted duty cycle. The factor adjusting the new PWM duty cycle is based on the Photovaristor value.
The operating freuency is about 150kHz.
below is the program with adjusting duty cycle from input of the photovaristor value, it already able dim the led lamp in 150kHZ.
const byte LED = 3; // Timer 2 "B" output: OC2B
int divider =10;
const long frequency = 150000L; // Hz (eg:150000=150khz)
int inputPin = 2; // set the analog input at pin2
int val = 0; // create variable
void setup()
{ Serial.begin(9600);
pinMode (LED, OUTPUT);
TCCR2A = _BV (WGM20) | _BV (WGM21) | _BV (COM2B1); // fast PWM, clear OC2B on compare
TCCR2B = _BV (WGM22) | _BV (CS21); // fast PWM, prescaler of 8
OCR2A = ((F_CPU / 8) / frequency) - 1; // zero relative
//OCR2B = ((OCR2A + 1) / 2) - 1; // 50% duty cycle
} // end of setup
void loop()
{
//divider=1 100% val<500 dark val>500 normal light
//divider=2 50%
//divider=3 33%
//divider=4 25%
//divider=10 10%
val = analogRead(inputPin);
Serial.write("val: ");
Serial.print(val); //print the received input data to serialmonitor
Serial.write(" divider: ");
if (val>10 && val<=200 ){ divider =1; }
if (val>200 && val<=400 ){ divider =2; }
if (val>400 && val<=600 ){ divider =3; }
if (val>600 && val<=800 ){ divider =4; }
if (val>800 && val<=1000 ){ divider =10; }
delay(50);
Serial.print(divider);
Serial.println("");
OCR2B = ((OCR2A + 1) / divider) - 1;
// do other stuff here
}
But the problem now is how can I able to read the high frequency PWM.
The input PWM will be 10V at frequency 150kHZ(may change a bit)
In the post problem, the key problem is how to get the digital pulse in PWM form( square wave),150kHz( may vary +- 10%), 10V into the Arduino Uno and successfully read the PWM. I also want to know the duty cycle of the input PWM signal.
I can’t help but think there’s got to be many cheap/easy hardware solutions. The number 5 keeps running through my mind. 5 - 5 - 5, for some reason 5! And the word ‘crystal’…
Run the input through a RC filter that gives an analog voltage proportional to the duty cycle. Read that with analogRead. Then do a PWM output with parameters suitably adjusted.
Once again, I modified the program above to generate a high frequency 150kHz PWM square wave in Pwm output pin.
Then I connect the circuit as shown below, the output of circuit connect back to the analog-in pin 3 and use analogRead to read it.
I found out the the serial monitor show the value of analogRead vary a lot. Is it because the circuit parameter are not correct?( As I am new with RC filter.) Or it is because the program run too slow?...confused.
Below is the program.
const byte LED = 3; // Timer 2 "B" output: OC2B
const long frequency = 150000L; // Hz (eg:150000=150khz)
int PWMinputPin = 3;
int PWMinputvalue = 0;// set the analog input at pin2
void setup()
{ Serial.begin(9600);
pinMode (LED, OUTPUT);
TCCR2A = _BV (WGM20) | _BV (WGM21) | _BV (COM2B1); // fast PWM, clear OC2B on compare
TCCR2B = _BV (WGM22) | _BV (CS21); // fast PWM, prescaler of 8
OCR2A = ((F_CPU / 8) / frequency) - 1; // zero relative
OCR2B = ((OCR2A + 1) / 3) - 1;
} // end of setup
void loop()
{ PWMinputvalue = analogRead(PWMinputPin);
Serial. println(PWMinputvalue);
delay(500);
}
Apart from the RC filter problem, I also concern on the program of PWM output in post 1.
As shown in the program below, the code " OCR2B = ((OCR2A + 1) / divider) - 1;" is placed in the void loop() rather than in the void setup(). I want to ask is it ok and wont damage the arduino board.
qq11011:
As shown in the program below, the code " OCR2B = ((OCR2A + 1) / divider) - 1;" is placed in the void loop() rather than in the void setup(). I want to ask is it ok and wont damage the arduino board.
It won't damage anything. I think it would be best to change it only if necessary. Writing to the register all the time might change the way the timer counts, however if you test if the new value is different to the old one, and only change OCR2B then, it should be OK.
As I am constructing my new program, I still have some questions want to ask,
(Below code is first detect the Photovaristor value then futher analysis PWM input to generate new PWM)
Questions:
[1] Is it ok to change the equation of register in different math calculation?The important issue is OCR2B need not to higher than OCR2A,right?
[2] As shown in the above code, I just divided the range of 0-1023 of PWMinputvalue into ten group and generate new PWM signal with ten duty cycle group, I want to know how to be more precise on the proportional PWM average voltage to PWMinputvalue (analogRead).
[3]As these code will place in void loop(), I also concern on is it necessary to add delay(xx);?
I think you can change OCR2A and OCR2B. Yes, OCR2B should not be higher than OCR2A or it cannot PWM as it never reaches the count.
What numbers are you coming up with? The higher the frequency the lower the available resolution because you are dealing in smaller numbers. Say for example OCR2A is 10, then OCR2B can only be 0 to 9 thus giving you only 10% increments.
I don't see any need for delay unless you want to slow down serial prints or something.
For the frequency set to 150kHz,
Is it possible to change the prescaler of 8 to 1 such that the OCR2A become106.667 ,(((16000000/1)/150000)+1)-1
then I can adjust the equation of OCR2B to have more increments, relatively more precise.