badger-hardware
Hardware integration for Badger 2350 including GPIO, I2C sensors, SPI devices, and electronic components. Use when connecting external hardware, working with sensors, controlling LEDs, reading buttons, or interfacing with I2C/SPI devices on Badger 2350.
What this skill does
# Badger 2350 Hardware Integration
Interface with GPIO pins, sensors, and external hardware on the Badger 2350 badge using I2C, SPI, and digital I/O.
## GPIO Basics
### Pin Configuration
```python
from machine import Pin
# Configure pin as output (LED, relay, etc.)
led = Pin(25, Pin.OUT)
led.value(1) # Turn on (HIGH)
led.value(0) # Turn off (LOW)
led.toggle() # Toggle state
# Configure pin as input (button, switch, etc.)
button = Pin(15, Pin.IN, Pin.PULL_UP)
if button.value() == 0: # Button pressed (pulled to ground)
print("Button pressed!")
# Configure pin as input with pull-down
sensor = Pin(16, Pin.IN, Pin.PULL_DOWN)
```
### PWM (Pulse Width Modulation)
```python
from machine import Pin, PWM
# Control LED brightness or servo motor
pwm = PWM(Pin(25))
pwm.freq(1000) # Set frequency to 1kHz
# Set duty cycle (0-65535, where 65535 is 100%)
pwm.duty_u16(32768) # 50% brightness
pwm.duty_u16(16384) # 25% brightness
pwm.duty_u16(65535) # 100% brightness
# Cleanup
pwm.deinit()
```
### Interrupts
```python
from machine import Pin
button = Pin(15, Pin.IN, Pin.PULL_UP)
def button_callback(pin):
print(f"Button pressed! Pin: {pin}")
# Trigger on falling edge (button press)
button.irq(trigger=Pin.IRQ_FALLING, handler=button_callback)
# Trigger on rising edge (button release)
button.irq(trigger=Pin.IRQ_RISING, handler=button_callback)
# Trigger on both edges
button.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=button_callback)
```
## I2C Communication
### I2C Setup
```python
from machine import I2C, Pin
# Initialize I2C (QWIIC connector uses specific pins)
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
# Scan for connected devices
devices = i2c.scan()
print(f"Found {len(devices)} I2C devices:")
for device in devices:
print(f" Address: 0x{device:02x}")
```
### Reading from I2C Device
```python
# Read data from I2C device
address = 0x48 # Example: Temperature sensor
data = i2c.readfrom(address, 2) # Read 2 bytes
print(f"Raw data: {data}")
# Read from specific register
register = 0x00
i2c.writeto(address, bytes([register])) # Select register
data = i2c.readfrom(address, 2) # Read data
```
### Writing to I2C Device
```python
# Write single byte
address = 0x48
data = bytes([0x01, 0xA0])
i2c.writeto(address, data)
# Write to specific register
register = 0x01
value = 0xFF
i2c.writeto(address, bytes([register, value]))
```
## Common I2C Sensors
### BME280 (Temperature, Humidity, Pressure)
```python
from machine import I2C, Pin
import time
class BME280:
def __init__(self, i2c, address=0x76):
self.i2c = i2c
self.address = address
def read_temp(self):
# Read temperature register
data = self.i2c.readfrom_mem(self.address, 0xFA, 3)
temp_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
# Apply calibration (simplified)
temp_c = temp_raw / 100.0
return temp_c
def read_humidity(self):
# Read humidity register
data = self.i2c.readfrom_mem(self.address, 0xFD, 2)
hum_raw = (data[0] << 8) | data[1]
humidity = hum_raw / 1024.0
return humidity
# Usage
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
sensor = BME280(i2c)
temp = sensor.read_temp()
humidity = sensor.read_humidity()
print(f"Temp: {temp:.1f}°C, Humidity: {humidity:.1f}%")
```
### APDS9960 (Gesture, Proximity, Color Sensor)
```python
class APDS9960:
def __init__(self, i2c, address=0x39):
self.i2c = i2c
self.address = address
self._init_sensor()
def _init_sensor(self):
# Enable device
self.i2c.writeto_mem(self.address, 0x80, bytes([0x01]))
# Enable gesture mode
self.i2c.writeto_mem(self.address, 0x93, bytes([0x01]))
def read_gesture(self):
# Read gesture FIFO
fifo_level = self.i2c.readfrom_mem(self.address, 0xAE, 1)[0]
if fifo_level > 0:
data = self.i2c.readfrom_mem(self.address, 0xFC, 4)
# Process gesture data
return self._detect_gesture(data)
return None
def _detect_gesture(self, data):
# Simplified gesture detection
if data[0] > data[2]:
return "UP"
elif data[0] < data[2]:
return "DOWN"
elif data[1] > data[3]:
return "LEFT"
else:
return "RIGHT"
# Usage
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
gesture_sensor = APDS9960(i2c)
gesture = gesture_sensor.read_gesture()
if gesture:
print(f"Gesture detected: {gesture}")
```
### VL53L0X (Time-of-Flight Distance Sensor)
```python
class VL53L0X:
def __init__(self, i2c, address=0x29):
self.i2c = i2c
self.address = address
def read_distance(self):
# Start measurement
self.i2c.writeto_mem(self.address, 0x00, bytes([0x01]))
# Wait for measurement
time.sleep(0.05)
# Read distance (mm)
data = self.i2c.readfrom_mem(self.address, 0x14, 2)
distance = (data[0] << 8) | data[1]
return distance
# Usage
i2c = I2C(0, scl=Pin(5), sda=Pin(4), freq=400000)
tof = VL53L0X(i2c)
distance = tof.read_distance()
print(f"Distance: {distance}mm")
```
## SPI Communication
### SPI Setup
```python
from machine import SPI, Pin
# Initialize SPI
spi = SPI(0, baudrate=1000000, polarity=0, phase=0,
sck=Pin(2), mosi=Pin(3), miso=Pin(4))
# Chip select pin
cs = Pin(5, Pin.OUT)
cs.value(1) # Deselect initially
# Read/write data
cs.value(0) # Select device
spi.write(bytes([0x01, 0x02, 0x03])) # Write data
data = spi.read(3) # Read 3 bytes
cs.value(1) # Deselect device
print(f"Received: {data}")
```
### SD Card Reader (SPI)
```python
from machine import SPI, Pin
import sdcard
import os
# Initialize SPI and SD card
spi = SPI(0, baudrate=1000000, sck=Pin(2), mosi=Pin(3), miso=Pin(4))
cs = Pin(5, Pin.OUT)
sd = sdcard.SDCard(spi, cs)
# Mount SD card
os.mount(sd, '/sd')
# Write file
with open('/sd/data.txt', 'w') as f:
f.write('Hello from Badger!')
# Read file
with open('/sd/data.txt', 'r') as f:
print(f.read())
# Unmount
os.umount('/sd')
```
## Analog Input (ADC)
```python
from machine import ADC, Pin
# Initialize ADC on GPIO pin
adc = ADC(Pin(26))
# Read raw value (0-65535 for 16-bit ADC)
raw_value = adc.read_u16()
print(f"Raw ADC: {raw_value}")
# Convert to voltage (assuming 3.3V reference)
voltage = (raw_value / 65535) * 3.3
print(f"Voltage: {voltage:.2f}V")
# Example: Read potentiometer
while True:
value = adc.read_u16()
percentage = (value / 65535) * 100
print(f"Pot: {percentage:.1f}%")
time.sleep(0.1)
```
## NeoPixel (WS2812B) LEDs
```python
from machine import Pin
import neopixel
import time
# Initialize NeoPixel strip (8 LEDs on pin 25)
num_leds = 8
np = neopixel.NeoPixel(Pin(25), num_leds)
# Set individual LED color (R, G, B)
np[0] = (255, 0, 0) # Red
np[1] = (0, 255, 0) # Green
np[2] = (0, 0, 255) # Blue
np[3] = (255, 255, 0) # Yellow
np.write() # Update LEDs
# Rainbow effect
def rainbow_cycle(wait):
for j in range(255):
for i in range(num_leds):
pixel_index = (i * 256 // num_leds) + j
np[i] = wheel(pixel_index & 255)
np.write()
time.sleep(wait)
def wheel(pos):
"""Generate rainbow colors across 0-255 positions"""
if pos < 85:
return (pos * 3, 255 - pos * 3, 0)
elif pos < 170:
pos -= 85
return (255 - pos * 3, 0, pos * 3)
else:
pos -= 170
return (0, pos * 3, 255 - pos * 3)
rainbow_cycle(0.001)
```
## Servo Motor Control
```python
from machine import Pin, PWM
import time
class Servo:
def __init__(self, pin):
self.pwm = PWM(Pin(pin))
self.pwm.freq(50) # 50Hz for servo
def angle(self, degrees):
"""Set servo angle (0-180 degrees)"""
# Convert angle to duty cycle
# 0° = 1ms (3.2% duty)
# 90° = 1.5ms (7.5% duty)
# 180° = 2ms (10% duty)
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.