Arduino HID Pushbuttons in a Harmonica Case; New Workshop (and) Moving Sucks

Over the past several weeks I had to pack up my entire bench, all parts, all tools, and everything else I own, and move them to a rental place across town while my psychiatrist wife's house gets a new foundation. 

Moving, especially when you are older and fully set in your ways, is stressful and generally not recommended.

We've moved in. Sort of.

To shake out my temporary workshop I built a simple USB-HID keyboard using perf, Arduino IDE, Claude Code, a DS3231 RTC (realtime clock) breakout board and an RP2040 MCU--specifically the Seeed XIAO-RP2040.  


Press a button, the current date and time are displayed on whatever PC you have the widget plugged into.  Press the other 2 and 2 pre-programmed strings appear.

Worked first time, here's what the finished thingy looks like--I may put labels and dumb decals on it, but good enough for now.

Hohner harp cases -- great for small projects.


PCBLESS

I hadn't built anything with perf in a long time, it was--fun?

Parts are mostly from the junk box....


The jury is still out.

The DS3231 I2C RTC breakout board is a no-name-o from Amazon. Without it, the RP2040 loses track of internal time during a power outage.

If you want this BoB check the link here, but the link may break after a few months....whatever; this is a common BoB and is probably available from your favorite tariff-ingesting retailer; match the photo:










Wiring: the upper IC is the SEEED MCU, bottom 4 pins (SCL, SDA, Vcc, GND) are the wirepads of the RTC breakout board.  Two views--from the top and bottom--are in one drawing. I have found with perf projects, if I don't create a guide like this, very likely I will make wiring mistakes....



THE CODE

....centers on the incredible C/C++ RP2040 SDK to Arduino port from Earle Philhower III, check out the extensive documentation here, Swiss accent guy's video here

Wow, Earle worked super hard so we don't have to--we owe Earle our gratitude!

Being an employable up-to-date tech (also intellectually disinterested?) I used Claude Code to generate sketches for the project.

Claude code is amazing and terrifying....the damn thing got most of what is below right in one pass, making a few stupid (but major) mistakes--whatever, easily fixed.....quicker to get things close with Claude and fix bugs by hand vs. code by hand and fix bugs by hand.

This first sketch sets the RTC to current time. Modify the rtc.adjust line, compile, and upload.



#include 
#include 

RTC_DS3231 rtc;

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

  if (!rtc.begin()) {
    Serial.println("DS3231 not found!");
    while (true);
  }

  // >>> SET YOUR CURRENT TIME HERE <<<
  // Format: DateTime(YYYY, MM, DD, HH, MM, SS)  — 24-hour time
  rtc.adjust(DateTime(2026, 3, 15, 18, 50, 0));

  Serial.println("RTC time has been set!");

  // Verify by reading it back
  DateTime now = rtc.now();
  Serial.print("Time is now: ");
  Serial.print(now.month());   Serial.print("/");
  Serial.print(now.day());     Serial.print("/");
  Serial.print(now.year());    Serial.print(" ");
  Serial.print(now.hour());    Serial.print(":");
  if (now.minute() < 10) Serial.print("0");
  Serial.print(now.minute());  Serial.print(":");
  if (now.second() < 10) Serial.print("0");
  Serial.println(now.second());
}

void loop() {
  // Nothing — time is set, job done.
}


The second sketch makes pushing the buttons display current date/time as well as a couple of strings--replace string1 and string2 values with your own:




#include 
#include 
#include 

/* Board manager:
   https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
   Board: Seeed XIAO RP2040
   USB Stack: PICO SDK

   Library required: RTClib by Adafruit (Library Manager)

   DS3231 Wiring:
     VCC -> 3.3V
     GND -> GND
     SDA -> D4 (GPIO 6)
     SCL -> D5 (GPIO 7)

   NOTE: Button 3 (Email 2) moved from D4 to D6 to free up I2C SDA.
*/

RTC_DS3231 rtc;

// Button pins
const int buttonD1 = D1; // Date/Time
const int buttonD3 = D3; // Email 1
const int buttonD6 = D6; // Email 2 — moved from D4 to avoid I2C conflict

// Button states
bool lastStateD1 = HIGH;
bool lastStateD3 = HIGH;
bool lastStateD6 = HIGH;

void setup() {
  pinMode(buttonD1, INPUT_PULLUP);
  pinMode(buttonD3, INPUT_PULLUP);
  pinMode(buttonD6, INPUT_PULLUP);

  Keyboard.begin();
  Wire.begin();

  if (!rtc.begin()) {
    // RTC not found — flash onboard LED as error indicator
    pinMode(LED_BUILTIN, OUTPUT);
    while (true) {
      digitalWrite(LED_BUILTIN, HIGH); delay(200);
      digitalWrite(LED_BUILTIN, LOW);  delay(200);
    }
  }

  // If the RTC lost power (dead/missing battery), set it to compile time.
  // Once the coin cell is installed this will not overwrite a valid time.
 // if (rtc.lostPower()) {
  //  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 // }
}

void loop() {
  bool currentStateD1 = digitalRead(buttonD1);
  bool currentStateD3 = digitalRead(buttonD3);
  bool currentStateD6 = digitalRead(buttonD6);

  if (currentStateD1 == LOW && lastStateD1 == HIGH) {
    delay(50);
    printRTCTime();
    delay(300);
  }

  if (currentStateD3 == LOW && lastStateD3 == HIGH) {
    delay(50);
    Keyboard.print("string1");
    delay(300);
  }

  if (currentStateD6 == LOW && lastStateD6 == HIGH) {
    delay(50);
    Keyboard.print("string2");
    delay(300);
  }

  lastStateD1 = currentStateD1;
  lastStateD3 = currentStateD3;
  lastStateD6 = currentStateD6;
}

void printRTCTime() {
  DateTime now = rtc.now();

  Keyboard.print(now.month());
  Keyboard.print("/");
  Keyboard.print(now.day());
  Keyboard.print("/");
  Keyboard.print(now.year());
  Keyboard.print(" ");

  if (now.hour() < 10) Keyboard.print("0");
  Keyboard.print(now.hour());
  Keyboard.print(":");
  if (now.minute() < 10) Keyboard.print("0");
  Keyboard.print(now.minute());
  Keyboard.print(":");
  if (now.second() < 10) Keyboard.print("0");
  Keyboard.print(now.second());
}

THE PLUG 


I will need a PCB for the next one of these I build, and maybe a more durable case.  For this, this blog's sponsor, PCBWAY, can fabricate the PCB's, the case, and everything else.
In addition to top shelf PCB fabrication they also do fantastic work with assembly, 3D printing, injection molding, and much more.  
As always--you can help this blog by checking out the PCBWAY site.  Thank you!

BENCHED MACH II

Here's the new bench setup. 

We are getting moved in and simple things like getting cold water from the kitchen sink is driving us nuts.  

I am told the foundation work, including lifting the house, redoing the French drains, fixing the roof line, bringing electrical up to code, and everything else needed in Earthquake Country, will take a year to a year and a half.

So we are here. For now.

What you see below works--sorta.



Good enough to perf....

See you next time.

No comments:

Post a Comment