I've done some tests to verify or disprove Barito's findings.
I've got some ATtiny85s somewhere, but I couldn't find them, so I used an Arduino Uno R3 instead.
I used Barito's code, modified to use pins that were convenient to me, and used digitalWrite() instead of analogWrite().
Code Used
const int potPin = A0; // Input to set waveform period delta
const int outPin = 12; // wave out
unsigned long lastUpdate = 0;
unsigned int sampleInterval = 0; // waveform (half) period
byte waveValue = 0; // instant wave value
int potVal;
void setup() {
pinMode(outPin, OUTPUT);
Serial.begin(115200);
}
void loop() {
potVal = analogRead(potPin);
sampleInterval = 2080 + potVal; //we toy with (half) period directly
if (micros() - lastUpdate >= sampleInterval) {
lastUpdate = micros();
digitalWrite(outPin, waveValue); // send the new wave value
if (waveValue == 0) {
waveValue = 1;
}
else {
waveValue = 0;
}
}
}
Rather than using a potentiometer, I used a function generator to apply a slowly ramping voltage to analogue input A0, at a frequency of 1mHz.
I monitored the ramp voltage and the pulse generated on an oscilloscope:
I've got two of the oscilloscope's automatic measurements turned on - the mean value of the input voltage, and the period of the square wave.
I programmed an Arduino MKR WiFi 1010 with Ethernet Shield to read the measurements off the oscilloscope at one second intervals, and display them on the Serial Monitor.
MKR WiFi 1010 Code
#include <SPI.h>
#include <Ethernet.h>
unsigned long previousMillis = 0;
const long interval = 1000;
int outPin = 9;
byte outVal = 0;
// Enter a MAC address and IP address for your Arduino
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0x0B, 0xB5 };
IPAddress ip(192, 168, 0, 10); // desired Arduino IP address
IPAddress server(192, 168, 0, 3); // IP address of the Oscilloscope
EthernetClient client;
void setup() {
// Start the Ethernet connection:
Ethernet.begin(mac, ip);
// Open serial communications and wait for port to open:
Serial.begin(9600);
// Give the Ethernet shield a second to initialize + additional time to open Serial Monitor:
delay(10000);
Serial.println("connecting...");
// Connect to the DMM:
if (client.connect(server, 5025)) { // Port 5025 is commonly used for SCPI
Serial.println("connected");
// Send an SCPI command to the instrument:
client.println("*IDN?");
} else if (client.connect(server, 5555)) { // Port 5555 is used for SCPI by Rigol
Serial.println("connected");
// Send an SCPI command to the instrument:
client.println("*IDN?");
} else {
// If you didn't get a connection to the server:
Serial.println("connection failed");
}
// delay(1000);
while (client.available()) {
char c = client.read();
Serial.print(c);
delay(100);
}
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
client.println("PAVA? CUSTALL"); // SCPI command to read all measurements
// If there are incoming bytes available from the Oscilloscope:
while (client.available()) {
char c = client.read();
Serial.print(c);
}
// If the server disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// Do nothing more:
while (true);
}
}
}
Here is what the results on the Serial Monitor look like:
I've arrowed the columns with the mean voltage and period measurements in.
I left the test to run for one whole cycle of the 1mHz swept voltage (1000 seconds).
I copied the results from the serial Monitor into a .CSV file, and opened them in Excel.
Using the Excel TEXTBEFORE( ) function I was able to extract the numerical value of the measurements taken.
I converted the mean voltage into milliVolts, and the square wave period into microseconds so they could be displayed on the same graph.
The results were as follows:
Exactly as Barito had described.