Hi all. I'd like to quickly start by saying I am not a programmer. I've never taken a class or read a book so please excuse my poor methods, organization, and lack of comments. My code below was developed somewhat of necessity for a problem at work.
Goal: Use digital write to generate my own "PWM" output at a lower frequency to increase resolution (lower frequency means longer on/off time and more discrete states than at the standard 490Hz of the analog write function). Ultimately, I would like 10-bit resolution @ 200Hz. This output is then passed through an RC filter to another analog device with 10-bit resolution. (I used this guide for high-speed digital writing: http://www.instructables.com/id/Arduino-is-Slow-and-how-to-fix-it/?ALLSTEPS)
What happens: On an oscilloscope, pulse width is fine but the frequency is approximately 216Hz when a 10k analog input pot is at 0v, 226Hz from 0.005v to 4.995v, and 240Hz when input is at 5v.
What I've checked:
- Removed code that's not shown. This code and the larger, original program behave the same way
- Changed the on and off time of the digital output to finite values rather than a variable
- Used a previous version of my program to verify this problem isn't present using analog write and the same device (Mega)
- Changed the output pin from D2 to D11.
Any ideas? Unless I'm missing something, the analog read actually has no impact on digital write...there's no code that should be connecting the two. Does analog read generate different amounts of load on the CPU when the input is at 0v, 0<x<5v, and 5v?
int Loadpin = 0; // Physical pin number of the Load potentiometer
int Loadval = 0; // Raw 10-bit value of the Load potentiometer analog pin
float Loadpct = 0; // Scaled value of the Load pin (0.0 - 100.0%)
int Loadint = 0; // Converted integer value of the float "Loadpct"
int Load = 0; // Load value aftering being descretized into 5% increments
const long screenrefresh = 150;
unsigned long previousMillis = 0;
const long PWMperiod = 4095;
unsigned long previousMicros = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
unsigned long currentMillis = millis();
unsigned long currentMicros = micros();
Loadval = analogRead(Loadpin); // read the Load potentiometer input
Loadpct = Loadval/1023.0*100.0; // Scale the value from 0-1023 to 0.0-100.0
Loadint = Loadpct; // Convert float back to integer for if/else statement
if (Loadint >= 0 && Loadint <7)
{Load = 5;}
else if (Loadint >= 7 && Loadint <12)
{Load = 10;}
else if (Loadint >= 12 && Loadint <17)
{Load = 15;}
else if (Loadint >= 17 && Loadint <22)
{Load = 20;}
else if (Loadint >= 22 && Loadint <27)
{Load = 25;}
else if (Loadint >= 27 && Loadint <32)
{Load = 30;}
else if (Loadint >= 32 && Loadint <37)
{Load = 35;}
else if (Loadint >= 37 && Loadint <42)
{Load = 40;}
else if (Loadint >= 42 && Loadint <47)
{Load = 45;}
else if (Loadint >= 47 && Loadint <52)
{Load = 50;}
else if (Loadint >= 52 && Loadint <57)
{Load = 55;}
else if (Loadint >= 57 && Loadint <62)
{Load = 60;}
else if (Loadint >= 62 && Loadint <67)
{Load = 65;}
else if (Loadint >= 67 && Loadint <72)
{Load = 70;}
else if (Loadint >= 72 && Loadint <77)
{Load = 75;}
else if (Loadint >= 77 && Loadint <82)
{Load = 80;}
else if (Loadint >= 82 && Loadint <87)
{Load = 85;}
else if (Loadint >= 87 && Loadint <92)
{Load = 90;}
else if (Loadint >= 92 && Loadint <97)
{Load = 95;}
else
{Load = 100;}
if (currentMicros - previousMicros >= 4096) {
PORTB |= _BV(PB5);
previousMicros = currentMicros;
}
if (currentMicros - previousMicros >= 2048) {
PORTB &= ~_BV(PB5);
}
Serial.print(Load);
Serial.print(" | ");
Serial.println(Load);
}
Thank you very much for any assistance!