Skip to content

Instantly share code, notes, and snippets.

@colrichie
Last active April 29, 2026 04:21
Show Gist options
  • Select an option

  • Save colrichie/59ad9ce9b2f54b600f58eae2c39e49c7 to your computer and use it in GitHub Desktop.

Select an option

Save colrichie/59ad9ce9b2f54b600f58eae2c39e49c7 to your computer and use it in GitHub Desktop.
A Test Sketch to Evaluate delayMecroseconds() on UNO Rev3 and R4
//////////////////////////////////////////////////////////////////////
//
// A Test Sketch to Evaluate delayMecroseconds() on UNO R3, R4, and Q
//
// Try this sketch running on the above Arduino UNO series by the
// following steps.
//
// 1) Connect the GPIO #12 pin on your Arduino R3/R4/Q to a piezo
// buzzer to listen to the signal from the GPIO pin.
// (If you have "EK JAPAN SU-1204", just attach it to the Arduino
// UNO series.)
// 2) Connect the Arduino to your PC.
// 3) Run the Arduino IDE and make it recognize the Arduino.
// 4) Write the following sketch into the IDE and run it on the
// Arduino.
// 5) Listen to the sound from the buzzer. The sketch plays "Do-Re-Me"
// continuously. However, when running it on UNO R4 and Q, you can
// hear a higher sound of "Do-Re-Me" and a lower sound alternately,
// whereas the same tone of "Do-Re-Mi" is played on UNO R3 (and
// other boards, like Raspberry Pi Pico).
//
// I AM THINKING THAT THE "delayMecroseconds()" ON UNO R4 AND Q OVERSLEEPS
// A LITTLE MORE THAN THE SPECIFIED DURATION. IN PARTICULAR, THE PRECISION
// OF THE "delayMecroseconds()" AND "tone()" ON Q IS F*CKING TERRIBLE!!
// THE TIME RESOLUTIONS OF THEM SEEM TO BE 100us. FOR THESE FUNCTIONS,
// THE CHART OF THE SETTING WAITING TIME VERSUS THE ACTUAL WAITING TIME
// LOOKS LIKE A STAIRCASE AT 100us INTERVALS.
//
// To make this sketch, I adopted some codes written on the text book
// of "EK JAPAN SU-1204."
//
// Written by @colrichie on 2026-04-29
//
//////////////////////////////////////////////////////////////////////
#define BUZZER_PIN 12
//#define BUSY_LOOP_VERSION
#ifdef BUSY_LOOP_VERSION
#define delayMicroseconds Delay_us
#endif
void Delay_us(unsigned int us) {
#ifdef ARDUINO_UNO_Q
if (us <= 2) return;
uint32_t start = micros();
while (micros() - start < (us - 3)); // Hardware cycle counter
#else
if (us == 0) return;
uint32_t start = micros();
while (micros() - start < us ); // Hardware cycle counter
#endif
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(BUZZER_PIN , OUTPUT);
}
void loop() {
// Buzzing with delayMecroseconds()
digitalWrite(LED_BUILTIN, HIGH);
for (int i=0; i<528; i++) { // Do
digitalWrite(BUZZER_PIN, HIGH);
delayMicroseconds(473);
digitalWrite(BUZZER_PIN, LOW );
delayMicroseconds(473);
}
digitalWrite(LED_BUILTIN, LOW );
for (int i=0; i<588; i++) { // Re
digitalWrite(BUZZER_PIN, HIGH);
delayMicroseconds(425);
digitalWrite(BUZZER_PIN, LOW );
delayMicroseconds(425);
}
digitalWrite(LED_BUILTIN, HIGH);
for (int i=0; i<660; i++) { // Mi
digitalWrite(BUZZER_PIN, HIGH);
delayMicroseconds(379);
digitalWrite(BUZZER_PIN, LOW );
delayMicroseconds(379);
}
// Buzzing with tone()
digitalWrite(LED_BUILTIN, LOW );
tone(BUZZER_PIN,1056); delay(500); // Do
noTone(BUZZER_PIN);
digitalWrite(LED_BUILTIN, HIGH);
tone(BUZZER_PIN,1176); delay(500); // Re
noTone(BUZZER_PIN);
digitalWrite(LED_BUILTIN, LOW );
tone(BUZZER_PIN,1320); delay(500); // Mi
noTone(BUZZER_PIN);
// Rest for 1s
delay(1000);
}
//////////////////////////////////////////////////////////////////////
//
// A Test Sketch to Evaluate waitill_*() on UNO R3, R4, and Q
//
// Try this sketch running on the above Arduino UNO series by the
// following steps.
//
// 1) Connect the GPIO #12 pin on your Arduino R3/R4/Q to a piezo
// buzzer to listen to the signal from the GPIO pin.
// (If you have "EK JAPAN SU-1204", just attach it to the Arduino
// UNO series.)
// 2) Connect the Arduino to your PC.
// 3) Run the Arduino IDE and make it recognize the Arduino.
// 4) Write the following sketch into the IDE and run it on the
// Arduino.
// 5) Listen to the sound from the buzzer. The sketch plays "Do-Re-Mi"
// continuously. And you can make sure that the sketch makes the
// pitch of the buzzer sound better than the sound by the sketch
// using the "delayMicroseconds()."
//
// Surveying the time by "millis()" and "micros()" is the actual way to
// get the precious timing, especially on UNO R4 and Q. And we advocate
// the "waitill_*()" functions instead of "delay*()." The "waitill_*()"
// functions could cancel the running time to perform any tasks except
// delay functions by measuring the absolute time provided by the
// "millis()" and "micros()" functions.
//
// To make this sketch, I adopted some codes written on the text book
// of "EK JAPAN SU-1204."
//
// Written by @colrichie on 2026-04-28
//
//////////////////////////////////////////////////////////////////////
#define BUZZER_PIN 12
unsigned long WT_EPOCH_M; // Reference time (epoch time) in ms
unsigned long WT_EPOCH_U; // Reference time (epoch time) in us
void waitill_ms(unsigned long time_to_ret) {
unsigned long dt = millis() - WT_EPOCH_M;
if (time_to_ret > dt) {delay(time_to_ret-dt);}
}
void waitill_us(unsigned long time_to_ret) {
#ifdef ARDUINO_UNO_Q
while (time_to_ret - 3 > micros() - WT_EPOCH_U);
#else
while (time_to_ret > micros() - WT_EPOCH_U);
#endif
}
void setup() {
WT_EPOCH_U = micros();
WT_EPOCH_M = millis();
pinMode(LED_BUILTIN, OUTPUT);
pinMode(BUZZER_PIN , OUTPUT);
}
void loop() {
static unsigned long tp_u = 0;
unsigned long tp_u_buzzend = tp_u;
// Buzzing with waitill_us()
digitalWrite(LED_BUILTIN, HIGH);
tp_u_buzzend += 500*1000UL;
while (tp_u < tp_u_buzzend) { // Do
digitalWrite(BUZZER_PIN, HIGH);
tp_u += 473;
waitill_us(tp_u);
digitalWrite(BUZZER_PIN, LOW );
tp_u += 473;
waitill_us(tp_u);
}
digitalWrite(LED_BUILTIN, LOW );
tp_u_buzzend += 500*1000UL;
while (tp_u < tp_u_buzzend) { // Re
digitalWrite(BUZZER_PIN, HIGH);
tp_u += 425;
waitill_us(tp_u);
digitalWrite(BUZZER_PIN, LOW );
tp_u += 425;
waitill_us(tp_u);
}
digitalWrite(LED_BUILTIN, HIGH);
tp_u_buzzend += 500*1000UL;
while (tp_u < tp_u_buzzend) { // Mi
digitalWrite(BUZZER_PIN, HIGH);
tp_u += 379;
waitill_us(tp_u);
digitalWrite(BUZZER_PIN, LOW );
tp_u += 379;
waitill_us(tp_u);
}
// Buzzing with tone()
digitalWrite(LED_BUILTIN, LOW );
tone(BUZZER_PIN,1056); // Do
tp_u_buzzend += 500*1000UL;
waitill_us(tp_u_buzzend);
noTone(BUZZER_PIN);
digitalWrite(LED_BUILTIN, HIGH);
tone(BUZZER_PIN,1176); // Re
tp_u_buzzend += 500*1000UL;
waitill_us(tp_u_buzzend);
noTone(BUZZER_PIN);
digitalWrite(LED_BUILTIN, LOW );
tone(BUZZER_PIN,1320); // Mi
tp_u_buzzend += 500*1000UL;
waitill_us(tp_u_buzzend);
noTone(BUZZER_PIN);
// Rest for 1s
tp_u = tp_u_buzzend + 1000*1000UL;
waitill_us(tp_u);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment