Lecture Sample Code

This collection of short Arduino sketches introduces a variety of programming concepts.

scale

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 1. generate chromatic tones on a speaker on pin 5
// 2. demonstrate for loops, int and float variables

void setup()
{
}

void loop()
{
  float freq = 440.0;
  for (int i = 0; i < 24; i = i + 1) {
    tone(5, freq);
    delay(200);
    freq = freq * 1.0595;
  }
  noTone(5);
  delay(1000);
}

ringfilter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/****************************************************************/
void setup(void)
{
  Serial.begin(115200);
}

/****************************************************************/
void loop(void)
{
  static unsigned long last_update_clock = 0;

  unsigned long now = micros();
  unsigned long interval = now - last_update_clock;
  last_update_clock = now;

  const long sample_interval = 10000;   // 10 msec, 100 Hz sampling
  static long sample_timer = 0;
  
  sample_timer -= interval;
  if (sample_timer <= 0) {
    sample_timer += sample_interval;

    int raw_value = analogRead(0);
    float calibrated = ((float)raw_value) / 1024.0;

    ringfilter_put(calibrated);

    float velocity = ringfilter_deriv(0.01);
    
    float quadratic_params[3];
    ringfilter_fit_quadratic(quadratic_params);

    Serial.print("v: "); Serial.print(velocity);
    Serial.print(" q: "); Serial.print(quadratic_params[0]);
    Serial.print(" "); Serial.print(quadratic_params[1]);
    Serial.print(" "); Serial.println(quadratic_params[2]);
  }
}

state-machine

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
// 1. Simultaneous blink the onboard Arduino LED on pin 13 and play a melody in pin 5.
// 2. Demonstrate a non-blocking event loop with multiple tasks.
// 3. Demonstrate micros() and timing calculations.
// 4. Demonstrate switch-case state machine structure.

void setup(void)
{
  pinMode(LED_BUILTIN, OUTPUT);
}

/****************************************************************/
void loop(void)
{
  static unsigned long last_update_clock = 0;

  unsigned long now = micros();
  unsigned long interval = now - last_update_clock;
  last_update_clock = now;

  // simultaneously run several independent tasks
  poll_led(interval);
  poll_melody(interval);
}

/****************************************************************/
// State variables for the LED blinker.
long led_blink_timer = 0;
bool led_blink_state = false;
const long led_blink_interval = 500000;

void poll_led(unsigned long interval)
{
  // This task uses the decrementing timer idiom (led_blink_timer).
  
  led_blink_timer -= interval;
  if (led_blink_timer <= 0) {
    // Reset the LED timer.
    led_blink_timer += led_blink_interval;

    // Toggle the LED to blink it.
    led_blink_state = !led_blink_state;
    digitalWrite(LED_BUILTIN, led_blink_state);
  }
}

/****************************************************************/
// State variables for the melody player.
int  melody_index = 0;
long melody_elapsed = 0;

const int SPEAKER_PIN = 5;
const int NOTE_FS4 = 370;
const int NOTE_C4 = 262;

void poll_melody(unsigned long interval)
{
  // This task uses the incrementing timer idiom (melody_elapsed).  The elapsed
  // time value is increased on each cycle, then reset at state transitions.
  melody_elapsed += interval;

  // Following is a state machine implemented using switch-case.  This example
  // executes state 0-5 in sequence then remains in state 5.  Each state
  // transition is conditioned purely on elapsed time; transitions have the side
  // effect of changing the speaker pitch.  Note that in a more general case
  // each state could transition to any other state or be conditioned on sensor
  // values.
  
  switch(melody_index) {
  case 0:
    // Initialization state: start the speaker tone and immediately transition to state 1.
    melody_elapsed = 0;
    melody_index += 1;
    tone(SPEAKER_PIN, NOTE_FS4);
    break;

  case 1:
  case 3:
    // Allow a tone to play for an interval, then change the tone and advance.
    if (melody_elapsed > 1000000) {
      melody_elapsed = 0;      
      melody_index += 1;
      tone(SPEAKER_PIN, NOTE_C4);
    }
    break;

  case 2:
  case 4:
    // Allow a tone to play for an interval, then change the tone and advance.    
    if (melody_elapsed > 1000000) {
      melody_elapsed = 0;      
      melody_index += 1;
      tone(SPEAKER_PIN, NOTE_FS4);
    }
    break;

  case 5:
  default:
    // terminal state: script is done
    noTone(SPEAKER_PIN);
    break;
  }
}

responsive-delay

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
const int SWITCH_PIN = 8;
const int BEEPER_PIN = 7;

void setup(void)
{
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(SWITCH_PIN, INPUT);
  pinMode(BEEPER_PIN, OUTPUT);
  digitalWrite(BEEPER_PIN, LOW);
}

/****************************************************************/
int responsive_delay_and_poll(long microseconds)
{
  unsigned long last_update_clock = micros();
  
  while (microseconds > 0) {
    unsigned long now = micros();
    unsigned long interval = now - last_update_clock;
    last_update_clock = now;
    microseconds -= interval;

    static long led_blink_timer = 0;
    static bool led_blink_state = false;
    const long led_blink_interval = 500000;

    led_blink_timer -= interval;
    if (led_blink_timer <= 0) {
      led_blink_timer += led_blink_interval;
      led_blink_state = !led_blink_state;
      digitalWrite(LED_BUILTIN, led_blink_state);
    }

    if (digitalRead(SWITCH_PIN)) return 1;
  }
  return 0;
}

/****************************************************************/
void loop(void)
{
  // entering state 0
  if (responsive_delay_and_poll(1000000)) goto react;

  // entering state 1
  if (responsive_delay_and_poll(1000000)) goto react;

  // entering state 2
  if (responsive_delay_and_poll(1000000)) goto react;

  // entering state 3
  while (true) responsive_delay_and_poll(1000000);

 react:
  digitalWrite(BEEPER_PIN, HIGH);
  while (responsive_delay_and_poll(1000));

  responsive_delay_and_poll(500000);
  digitalWrite(BEEPER_PIN, LOW);
}

sine-metronome

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// demo use of a trajectory generator function
#include <Servo.h> 

const int SERVO_PIN = 9;
Servo wiggling_servo;

void setup(void)
{
  Serial.begin(115200);
  wiggling_servo.attach(SERVO_PIN);
}


void loop(void)
{
  // Perform a smooth movement around the center several times.
  for (int i = 0; i < 4; i = i+1) {

    // Define a few constants governing the motion.  Note that this example
    // uses a C++ style of declaration which looks more like a normal variable
    // declaration, but whose value cannot be changed.
    const float center    = 90.0;     // in degrees
    const float magnitude = 30.0;     // in degrees
    const float period    =  4.0;     // in seconds, duration of cycle
    const float interval  =  0.020;   // in seconds, duration of each step

    int cycle_steps = period / interval;
    
    for (int step = 0; step < cycle_steps; step++) {
      // Compute the 'phase angle' for the sine function.  Note that the sin()
      // function requires an angle in radians.
      float phase = step * (2*M_PI/cycle_steps);
      
      // Compute the angle to send to the servo.
      float angle = center + magnitude * sin(phase);
      wiggling_servo.write(angle);

      // Wait for one sampling period.
      delay(1000*interval);
    }
  }
  Serial.println("cycle done.");
}

clocks

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 1. measure execution time
// 2. demonstrate the firmware clock
// 3. demonstrate debugging on the serial port

void setup()
{
  Serial.begin(115200);
}

long last_time = 0;

void loop()
{
  long now = micros();

  Serial.print(millis());
  Serial.print(" ");  

  Serial.print(micros());
  Serial.print(" ");

  Serial.println(now - last_time);

  last_time = now;
}

smoothing

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/****************************************************************/
void setup(void)
{
  Serial.begin(115200);
}

/****************************************************************/
void loop(void)
{
  static unsigned long last_update_clock = 0;

  unsigned long now = micros();
  unsigned long interval = now - last_update_clock;
  last_update_clock = now;

  const long sample_interval = 10000;   // 10 msec, 100 Hz sampling
  static long sample_timer = 0;
  
  sample_timer -= interval;
  if (sample_timer <= 0) {
    sample_timer += sample_interval;

    int raw_value = analogRead(0);                       // read the current input 
    float calibrated = ((float)raw_value) / 1024.0;      // scale to normalized units 

    static float smoothed_value = 0.0;                   // filtered value of the input
    float difference   =  calibrated - smoothed_value;   // compute the 'error'
    smoothed_value     += 0.1 * difference;              // apply a constant gain to move the smoothed value toward the reading

    Serial.println(smoothed_value);
  }
}

melody

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 1. generate tones on a speaker on pin 5
// 2. demonstrate table lookup
// 3. demonstrate Serial debugging

void setup()
{
    Serial.begin(115200);
    Serial.println("Hello!");
}

const float note_table[] = { 440.0, 523.25, 659.26, 523.25, 659.26, 523.25/2, 440.0, 659.26, 659.26*2, 523.25, -1 };

void loop()
{
  
  for (int i = 0; note_table[i] > 0.0 ; i = i + 1) {
    Serial.print("Note: ");
    Serial.println(note_table[i]);
    
    tone(5, note_table[i]);
    delay(200);
  }
  noTone(5);
  delay(500);
}

arpeggio

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 1. generate tones on a speaker on pin 5
// 2. demonstrate functional abstraction
// 3. demonstrate MIDI notes and equal temperament scales
// 4. demonstrate for loop with multiple expressions
// 5. demonstate global constants with 'const float' and 'const int'

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  arpeggio(60, 1, 4);  // 60 is the MIDI number for note C4
  silence();
  arpeggio(60, 2, 10);
  arpeggio(72, -2, 8);
  silence();
  silence();
}

void arpeggio(int start, int interval, int length)
{

  for (int note = start, count = 0; count < length; note = note + interval, count = count + 1) {
    float freq = midi_to_freq(note);
    Serial.println(freq);
    tone(5, freq);
    delay(200);
  }
}

const int   MIDI_A0 = 21;
const float freq_A0 = 27.5;
  
float midi_to_freq(int midi_note)
{
  return freq_A0 * pow(2.0, ((float)(midi_note - MIDI_A0)) / 12.0);
}

void silence(void)
{
  noTone(5);
  delay(500);
}

feedback

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// 1. apply proportional feedback using a dual H-bridge driver and analog position sensor
// 2. demonstrate non-blocking event-loop structure
// 3. demonstrate DRV8833 motor driver pulse width modulation
// 4. demonstrate a smoothing filter on an analog input

// Define DRV8833 control pin wiring as per CKS-1 shield board.
const int MOT_A1_PIN = 5;
const int MOT_A2_PIN = 6;
const int MOT_B1_PIN = 10;
const int MOT_B2_PIN = 9;

const int POS_SENSOR_PIN = A0;

/****************************************************************/
void setup(void)
{
  // Configure the four DRV8833 control lines and set them to a quiescent state.
  pinMode(MOT_A1_PIN, OUTPUT);
  pinMode(MOT_A2_PIN, OUTPUT);
  pinMode(MOT_B1_PIN, OUTPUT);
  pinMode(MOT_B2_PIN, OUTPUT);

  digitalWrite(MOT_A1_PIN, LOW);
  digitalWrite(MOT_A2_PIN, LOW);
  digitalWrite(MOT_B1_PIN, LOW);
  digitalWrite(MOT_B2_PIN, LOW);

  // Start the serial port for the console.
  Serial.begin(115200);
}

/****************************************************************/
void loop(void)
{
  static unsigned long last_update_clock = 0;

  unsigned long now = micros();
  unsigned long interval = now - last_update_clock;
  last_update_clock = now;

  poll_feedback_loop(interval);
}

/****************************************************************/
// Polling function for the feedback process: reads an analog position sensor at
// regular sampling intervals, calculates a new motor speed and configures the
// DRV8833 motor driver PWM outputs.

const long sample_interval = 10000;  // 10 msec, 100 Hz sampling
long sample_timer = 0;

float position = 0.0;     // filtered value of the input (unit normalization)
float target = 0.5;       // target position (unit normalization)

void poll_feedback_loop(unsigned long interval)
{
  sample_timer -= interval;
  if (sample_timer <= 0) {
    sample_timer += sample_interval;

    int raw_value = analogRead(POS_SENSOR_PIN);          // read the current input 
    float calibrated = ((float)raw_value) / 1024.0;      // scale to normalized units 

    // first-order smoothing filter to reduce noise in the position estimate
    float difference = calibrated - position;  // compute the 'error' in the sensor reading
    position += 0.2 * difference;              // apply a constant gain to move the smoothed value toward the reading

    // calculate a proportional position control update
    float position_error = target - position;     // compute the position error
    float control_output = 2.0 * position_error;  // apply a proportional position gain

    int control_pwm = constrain((int)(256.0 * control_output), -255, 255);
    set_motor_pwm(control_pwm, MOT_A1_PIN, MOT_A2_PIN);
  }
}

/****************************************************************/
// Set the current speed and direction for either of the DRV8833 channels.
//
// Parameters:
//  pwm     : integer velocity ranging from -255 to 255.
//  IN1_PIN : either MOT_A1_PIN or MOT_B1_PIN
//  IN2_PIN : either MOT_A2_PIN or MOT_B2_PIN
//
// (Note: uses 'fast-decay' mode: coast not brake.)

void set_motor_pwm(int pwm, int IN1_PIN, int IN2_PIN)
{
  if (pwm < 0) {  // reverse speeds
    analogWrite(IN1_PIN, -pwm);
    digitalWrite(IN2_PIN, LOW);

  } else { // stop or forward
    digitalWrite(IN1_PIN, LOW);
    analogWrite(IN2_PIN, pwm);
  }
}

/****************************************************************/

non-blocking

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 1. Blink the onboard Arduino LED on pin 13.
// 2. Demonstrate a non-blocking event loop.
// 3. Demonstrate micros() and timing calculations.
// 4. Note the absence of delay().  For comparison, see blink.ino.

void setup(void)
{
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop(void)
{
  static unsigned long last_update_clock = 0;

  unsigned long now = micros();
  unsigned long interval = now - last_update_clock;
  last_update_clock = now;

  static long led_blink_timer = 0;
  static bool led_blink_state = false;
  const long led_blink_interval = 500000;
 
  led_blink_timer -= interval;
  if (led_blink_timer <= 0) {
    led_blink_timer += led_blink_interval;

    led_blink_state = !led_blink_state;
    digitalWrite(LED_BUILTIN, led_blink_state);
  }
}
  

plotting

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 1. use the Arduino IDE plotting utility to visualize an analog signal
// 2. demonstrate analogRead()

void setup()
{
   Serial.begin(115200);
}

void loop()
{
  Serial.println(analogRead(0));
}

shm-metronome

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// demo use of a differential equation generator function
#include <Servo.h> 

const int SERVO_PIN = 9;
Servo svo;

// ================================================================
// Simple Harmonic Motion oscillator, e.g. unit-mass on spring with damping.

const float k    = 4*M_PI*M_PI;   // 1 Hz; freq = (1/2*pi) * sqrt(k/m); k = (freq*2*pi)^2
const float b    = 1.0;           // damping
const float q_d  = 90.0;          // neutral spring position
const float dt   = 0.01;          // integration time step

float q    = 0.0;         // initial position
float qd   = 0.0;         // initial velocity

// ================================================================

void setup(void)
{
  Serial.begin(115200);
  svo.attach(SERVO_PIN);
}

// ================================================================
void loop()
{
  // calculate the derivatives
  float qdd = k * (q_d - q) - b * qd;

  // integrate one time step
  q  += qd  * dt;
  qd += qdd * dt;

  // update the servo
  svo.write(q);

  // logic to reset the oscillator after a cycle has completed
  if (fabs(qd) < 0.1 && fabs(q_d - q) < 0.1) q = 0.0;
      
  // print the output for plotting
  Serial.println(q);

  // delay to control timing
  delay((int)(1000*dt));
}

delay-with-poll

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void setup(void)
{
  pinMode(LED_BUILTIN, OUTPUT);
}

/****************************************************************/
void delay_and_poll(long microseconds)
{
  unsigned long last_update_clock = micros();
  
  while (microseconds > 0) {
    unsigned long now = micros();
    unsigned long interval = now - last_update_clock;
    last_update_clock = now;
    microseconds -= interval;

    static long led_blink_timer = 0;
    static bool led_blink_state = false;
    const long led_blink_interval = 500000;

    led_blink_timer -= interval;
    if (led_blink_timer <= 0) {
      led_blink_timer += led_blink_interval;
      led_blink_state = !led_blink_state;
      digitalWrite(LED_BUILTIN, led_blink_state);
    }
  }
}

/****************************************************************/
void loop(void)
{
  // entering state 0
  delay_and_poll(1000000);

  // entering state 1
  delay_and_poll(1000000);

  // entering state 2
  delay_and_poll(1000000);

  // entering state 3
  while (true) delay_and_poll(1000000);
}

table-metronome

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// demo use of a lookup table
#include <Servo.h> 

const int SERVO_PIN = 9;
Servo svo;

void setup(void)
{
  svo.attach(SERVO_PIN);
}

const int angles[12] = { 45, 0, 135, 0, 90, 0, 90, 45, 135, 90, 180, 0 };

void loop(void)
{
  for (int idx = 0; idx < 12; idx = idx + 1) {
    svo.write(angles[idx]);
    delay(500);
  }
}

tones

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 1. generate tones on a speaker on pin 5
// 2. demonstrate tone(), noTone(), delay()

void setup()
{
  // empty body, tone() configures a pin for output
}
void loop()
{
  tone(5, 440);
  delay(1000);

  noTone(5);
  delay(1000);

  tone(5, 660);
  delay(1000);
}

tonestep

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 1. read a switch input on pin 9
// 2. generate tones on a speaker on pin 5
// 3. demonstrate a simple state machine
// 4. demonstrate Serial debugging

const int SWITCH_PIN  = 9;
const int SPEAKER_PIN = 5;

void setup()
{
  Serial.begin(115200);
  Serial.println("Hello!");
}

const float note_table[] = { 440.0, 523.25, 659.26, 523.25, 659.26, 523.25/2, 440.0, 659.26, 659.26*2, 523.25, -1 };

int nextnote = 0;

/// The loop function is called repeatedly by the Arduino system.  In this
/// example, it executes once per cycle of the switch input.
void loop()
{
  while(digitalRead(SWITCH_PIN) != 0) {
    // Busywait for the switch to be pressed.  Note that the body of the while
    // is empty, this just loops reading the switch input until it goes low.
  }

  // The following is executed once per switch cycle, right after the switch is pressed.
  float freq = note_table[nextnote];
  Serial.print("Note: ");
  Serial.println(freq);
  tone(SPEAKER_PIN, freq);

  // advance to the next note, looping at the end
  nextnote = nextnote + 1;
  if (note_table[nextnote] < 0) nextnote = 0;

  // Busywait for the switch to be released: loop until the switch input goes high.  
  while(digitalRead(SWITCH_PIN) == 0) {  }

  // The following is executed once, right after the switch is released.
  noTone(SPEAKER_PIN);
}

rocker

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 1. rock the toy with a servo
// 2. demonstrate the Servo library

#include <Servo.h>

const int ARDUINO_LED = 13;

const int SERVO1_PIN = 23;  // on the Mega Pinball Shield

const int PHOTO1_PIN = A0;  // on the Mega Pinball Shield

const int TILT_X_PIN = A8;  // on the Mega Pinball Shield
const int TILT_Y_PIN = A9;  // on the Mega Pinball Shield
const int TILT_Z_PIN = A10; // on the Mega Pinball Shield 

Servo rocker_servo;

void setup()
{
  pinMode(ARDUINO_LED, OUTPUT);
  rocker_servo.attach(SERVO1_PIN);
  Serial.begin(115200);
}

int lower = 60;
int upper = 80;
int pause1 = 100;
int pause2 = 500;

void loop()
{
  digitalWrite(ARDUINO_LED, HIGH);

  rocker_servo.write(lower);
  delay(pause1);

  digitalWrite(ARDUINO_LED, LOW);  
  rocker_servo.write(upper);
  delay(pause2);

  int photo1 = analogRead(PHOTO1_PIN);
  int tilt_x = analogRead(TILT_X_PIN);
  int tilt_y = analogRead(TILT_Y_PIN);
  int tilt_z = analogRead(TILT_Z_PIN);

  Serial.print("Photo1: "); Serial.print(photo1); Serial.print(" ");
  
  Serial.print("Servo lower upper pause1 pause2: ");
  Serial.print(lower); Serial.print(" ");
  Serial.print(upper); Serial.print(" ");
  Serial.print(pause1); Serial.print(" ");
  Serial.print(pause2); Serial.print(" ");
      
  Serial.print("Tilt XYZ: ");
  Serial.print(tilt_x); Serial.print(" ");
  Serial.print(tilt_y); Serial.print(" ");
  Serial.println(tilt_z);

  if (Serial.available() > 0) {
    lower = Serial.parseInt();
    upper = Serial.parseInt();
    pause1 = Serial.parseInt();
    pause2 = Serial.parseInt();
    while(Serial.available() > 0) Serial.read();
  } 
}

bit-bang-two-tone

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 1. generate complex waveform on a speaker on pin 5
// 2. demonstrate execution speed, firmware clocks, bit-banging logic

void setup()
{ 
  pinMode(5, OUTPUT);
}
void loop()
{
  long now = micros();
  bool square1 = (now % 2274) < 1136;
  bool square2 = (now % 1516) < 758;
  digitalWrite(5, square1 ^ square2);
}

plots

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 1. demonstrate use of Serial port for debugging output
// 2. demonstrate IDE graphing: see Tools/Serial Plotter
void setup()
{
  Serial.begin(115200);
}
void loop()
{
  Serial.println(sin(4 * 6.28 * 0.001 * millis()));
}

metronome

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// demo use of a library, hobby servo output
#include <Servo.h> 

Servo your_chosen_servo_name;

void setup()
{
  your_chosen_servo_name.attach(9);
}

void loop()
{
  your_chosen_servo_name.write(45);
  delay(500);

  your_chosen_servo_name.write(135);
  delay(500);
}