In principle, this approach works, but it's not very dependable. You're better off using a Timer to generate a waveform like this. There are many tutorials out there about configuring Timers for waveform generation.
A partial solution for this was to use noInterrupts(); and I have I better results, but no perfect. I will search how to use timer for this. thank you.
The waveform that is displayed on the first trace is not a true representation of what is actually happening.
You are generating a frequency of 1kHz.
The oscilloscope is on a slow timebase, and is only taking 500 samples per second.
This means that it is only taking one sample for every two cycles of the actual waveform.
The only reason that the waveform looks like a square wave is that the frequency generated is not exactly 1kHz, and that each sample gets taken earlier (or later) on in the cycle.
The waveform displayed is an artifact of sampling below the Nyquist frequency.
That is also the reason why the frequency is displayed as 12.2Hz, and not 1kHz.
Is there some setting on the oscilloscope that can increase the sampling rate?
The timebase is on 100ms/division, try increasing the timebase to say 1ms/division to see the true waveform - that's turn the timebase knob 6 clicks clockwise.
I tried turning down the memory depth on my oscilloscope to see if I could recreate what you were seeing.
I couldn't get anywhere near 500 samples per second, with the timebase on 100ms/division.
The lowest my oscilloscope would do was 10kSa/s.
Then I had an idea - use a second Arduino to make an oscilloscope.
500 samples per second is easy to achieve, and the serial plotter displays 500 points.
This should be exactly the same as victorioroque1's oscilloscope settings.
Here is the sketch that I came up with:
int inputPin = A0;
unsigned int raw = 0 ;
unsigned long previousMicros = 0;
const long interval = 2000; // sampling period in microseconds
void setup() {
Serial.begin(115200);
}
void loop() {
unsigned long currentMicros = micros();
if (currentMicros - previousMicros >= interval) {
previousMicros = previousMicros + interval;
raw = analogRead(inputPin);
Serial.print(raw);
Serial.print(", ");
Serial.print(1200); // prevents serial plotter autoscaling
Serial.print(", ");
Serial.println(-400); // sets y axis scale
}
}
I used this second Arduino Uno R3 to monitor the output of a Uno R3 running victorioroque1's code.
Here are the results on the serial plotter:
This code has the additional limitation that the execution time of the code is not accounted for; each delay would need to be tuned to more closely arrive at 500 us per pulse width, high and low.
It could be improved significantly by simply using fastDigitalPin library, available through the IDE Library Manager.