BEEP is a loud piezoelectric buzzer coupled with an I²C controller. By sending a single a single I²C command it generates a note of a given duration. Notes can be interrupted at any time by sendin a new command. BEEP uses a straightforward write-only protocol with one command to trigger audio:

<dur>
<pitch>

Where <dur> is the note duration in milliseconds, and <pitch> is the MIDI note number. By sending a series of notes, the module can generate a variety of tones and alarms. Short notes, under 5 ms, produce loud clicks suitable for keypresses and other interations.

import sys
import serial
import time
import struct
import random

from i2cdriver import I2CDriver, EDS

if __name__ == '__main__':
    i2 = I2CDriver(sys.argv[1], True)

    d = EDS.Beep(i2)

    for note in range(55, 127):
        print("MIDI note %d" % note)
        d.beep(100, note)
        time.sleep(.100)
#include <Wire.h>

void beep(byte dur, byte note)
{
  Wire.beginTransmission(0x30);
  Wire.write(dur);
  Wire.write(note);
  Wire.endTransmission();
}

void setup() {
  Wire.begin();
}

void loop() {
  for (int note = 55; note < 127; note++) {
    beep(100, note);
    delay(100);
  }
}
from machine import I2C
import time

class Beep:
    """ BEEP is a beeper """
    def __init__(self, i2, a = 0x30):
        self.i2 = i2
        self.a = a

    def beep(self, dur, note):
        """
        Play a note. 
        dur is the duration in milliseconds, 0-255.
        note is a MIDI note in the range 21-127 inclusive.
        """
        self.i2.writeto(self.a, bytes((dur, note)))

def main():
    i2 = I2C(1, freq = 100000)

    d = Beep(i2)

    for note in range(55, 127):
        print("MIDI note %d" % note)
        d.beep(100, note)
        time.sleep(.100)

Default I²C address 0x30 (0b0110000)
Current consumption (typ.) 5 mA
Vcc 2.2 - 3.6 V