Thursday, May 15, 2025

Material Master

 Material Measurement Device


Materials




Display will need 2(3)/5 of the pinouts. "SDA on pad 0 and SCL on pad 1." Since we are going for low power, I'll need a transistor to control the power. This drawing is wrong: 
    "Unique pad capabilities Digital #0 / A2  - this is connected to PA08 on the ATSAMD21. This pin can be used as a digital I/O with selectable pullup or pulldown, analog input (use 'A2'),  PWM output, and is also used for I2C data (SDA) Digital #1 / A0  - this is connected to PA02 on the ATSAMD21. This pin can be used as a digital I/O with selectable pullup or pulldown, capacitive touch, analog input (use 'A0'),  and true analog (10-bit DAC) output. It cannot be used as PWM output. Digital #2 / A1  - this is connected to PA09 on the ATSAMD21. This pin can be used as a digital I/O with selectable pullup or pulldown, analog input (use 'A1'),  PWM output, and is also used for I2C clock (SCL), and hardware SPI MISO Digital #3 / A3  - this is connected to PA07 on the ATSAMD21. This pin can be used as a digital I/O with selectable pullup or pulldown, analog input (use 'A3'),  capacitive touch, PWM output, and is also used for UART RX (Serial1 in Arduino), and hardware SPI SCK Digital #4 / A4  - this is connected to PA06 on the ATSAMD21. This pin can be used as a digital I/O with selectable pullup or pulldown, analog input (use 'A4'),  capacitive touch, PWM output, and is also used for UART TX (Serial1 in Arduino), and hardware SPI MOSI"

Battery display:
I'll need to create a voltage divider that scales down the battery's max 4.2V:
Battery + (4.2V max) ---- R1 (100k) ----+---- R2 (330k) ---- GND
                                        |
                                        +----> Trinket analog input pin (e.g., A1(Pad 2)
This will result in a max battery reading of 3.22V. It will use minimal current:
I=430k4.29.8μA
"All of the I/O pins can be used for 12-bit analog input" means I'll get values from 0 to 4095. The voltage divider reduced the reading to 76.7% of the actual voltage:
Vout=Vbat×R1+R2R2=Vbat×100k+330k330k=Vbat×0.767

Pseudocode, but insert real values of R1 & R2 from DMM:
const int analogPin = A1;  // ADC pin
const float R1 = 100000.0; // 100k nominal 
const float R2 = 330000.0; // 330k nominal
const float ADC_MAX = 4095.0;
const float V_REF = 3.3;

void setup() {
  Serial.begin(115200);
  analogReadResolution(12);  // 12-bit resolution for Trinket M0
}

void loop() {
  int adcValue = analogRead(analogPin);
  
  // Convert ADC to voltage at divider output
  float V_out = (adcValue / ADC_MAX) * V_REF;

  // Calculate battery voltage
  float V_bat = V_out * (R1 + R2) / R2;

  Serial.print("ADC: ");
  Serial.print(adcValue);
  Serial.print("  V_out: ");
  Serial.print(V_out, 3);
  Serial.print(" V  Battery Voltage: ");
  Serial.print(V_bat, 3);
  Serial.println(" V");

  delay(1000);
}

Hall Effect Sensor:
Testing with 5V, I got a sense distance of around 2.5mm. This might have to be embedded in the wall of a main body with magnets very near in the outer ring. Although it looks like I was testing it incorrectly. From the datasheet: "The UA package is south pole active: Applying a south magnetic pole greater than BOP facing the branded side of the package switches the output low."

Sunday, May 11, 2025

Carson's Bowling Ball

Project Log: Building a Motorized Neopixel Light Ring with Sparkle Dynamics

Like many projects, this one started by looking at my parts bin and asking, "What can I make with this?" I had an ESP32, a ULN2003 28BYJ-48 4-Phase Stepper Motor, a handful of WS2812B neopixels (5V 3MM x 10MM), a salvaged lithium battery, a charging IC, a USB-C breakout board, and a couple of old skate bearings rolling around my drawer. Good ingredients for something kinetic and glowy.

The Vision

My goal was to build a dynamic light ring with a rich, flowing animation—something alive, not just blinking lights. I wanted motion not just in the light but physically: a rotating ring with synchronized color effects. And if I was going to make it spin, why not use herringbone gears and embed magnets for snap-on ease?

The Build

The project required a few custom 3D-printed parts:

  • A replica mounting piece embedded with magnets for quick attachment.

  • A base plate to house the core electronics and battery.

  • A ring holder to mount the neopixels in a perfect arc.

  • Internal and external herringbone gears to give it that sweet mechanical motion and hold alignment under load.

  • A sleek main body shell to hold it all together.

The skate bearings found new life supporting the rotating parts, and the gear train was driven by a small motor tucked inside the shell.

The Electronics

The ESP32 handles everything:

  • Motor control

  • Animation logic

  • Battery monitoring

  • LED timing

The LEDs (WS2812Bs) are powered directly from the 5V rail and mounted in a fixed ring. Their brightness and color are dynamically adjusted based on motor speed and position.

The Sparkle Effect

One of the standout features is the speed-reactive sparkle.

  • At low speeds, the sparkle is deeper and more frequent, adding a dreamy shimmer.

  • At high speeds, the sparkle becomes subtle and sparse, giving way to smoother transitions.

This isn't just random flickering. Each LED has a base brightness and a per-frame “target offset” that modulates its value. A bit of easing logic ensures the sparkles fade in and out smoothly, rather than flicking abruptly.

Here's the gist:

cpp

// Randomly assign a new brightness target if (abs(current - target) < 0.01) { if (chance < 15%) { target = base ± deeper sparkle } else { target = base ± mild flicker } } // Ease toward the target current += (target - current) * 0.1;

Outcome

The result? A beautifully fluid light pattern that feels like it’s responding to motion. The hues chase each other around the ring, fading seamlessly from one to the next, while sparkles add depth—like watching starlight reflect off a moving surface.

What's Next?

I'm considering:

  • Adding BLE control to change modes or colors. Update 5/11/25: The ESP32 creates a WIFI hotspot. When connected, it forces a captive portal serving a page with Java controls.

  • Making the ring modular so it can snap onto different bases (a helmet, a sculpture, etc.).

  • Porting the project into a self-contained, rechargeable kinetic sculpture.


Want a visual walkthrough or code breakdown? Drop a comment or check out the GitHub repo (coming soon!).