SevIQ systems • tooling • infrastructure

SevIQ

systems • tooling • infrastructure
UTC
3-phase Δ (delta) • cos φ = 0.70 (lag)
φ (phase angle)
Apparent power S
Real power P = S·cosφ
Reactive power Q = S·sinφ
Δ system shown as line-to-line voltages VAB, VBC, VCA (120° apart). Current lags voltage by φ where cos φ = 0.7. This is a placeholder, but it's also a confession. Learn more about phasors →
Need realtime thermals, fan traces, and power envelopes? Open the telemetry console →
Ready for hands-on builds? The Arduino field notebook catalogs guided labs with wiring tables, code, and troubleshooting playbooks.

Learning resources

Move from DC fundamentals to AC intuition and hands-on builds with these focused guides.

DC foundation

Electronics fundamentals

Work through KVL, KCL, Ohm's Law, power math, and practical motor control wiring with visuals and worked examples.

Open guide
AC + phasors

Phasors & complex power

Build intuition for impedance, RMS, power factor, and three-phase geometry with annotated diagrams and callouts.

Read chapter
Hands-on

Arduino field notebook

Follow lab-style walkthroughs with BOMs, wiring tables, and debug checkpoints to recreate and remix the builds.

Browse labs
What to add next:
  • Three-phase lab: Δ vs Y wiring with simulated meters and safety notes
  • Power factor correction walkthrough: capacitor sizing calculator + pitfalls
  • Instrumentation quickstart: choosing probes, scopes, and isolation for mains

IR detector → XOR LED halo

Break the virtual beam to flip alternating LEDs with mask ^= 0b101010101010. The register stays high for whatever hold time you dial in, emulating a halo installation triggered by an IR detector.

Duration: 2.00s
Status: Idle
mask ^= pattern → 0b000000000000

Hard stop: bare-metal AVR, no Arduino sugar

Direct register hits on ATmega-class MCUs, efficient branching, and mask-flip patterns that mirror the UI demo. Nothing here drags in frameworks—just <avr/io.h>, <util/delay.h>, and discipline.

1 · 12-bit halo register

XOR the even LEDs into a ring mask, map straight into PORTB/PORTA, and keep JTAG off our pins.

/* Ledblink v.2 — bare metal */
#include <avr/io.h>
#include <util/delay.h>

#define HALO_PATTERN 0b101010101010

static inline void drive_ring(uint16_t mask) {
    PORTB = mask & 0xFF;          // PB0..PB7
    PORTA = (mask >> 8) & 0x0F;   // PA0..PA3
}

int main(void) {
    MCUSR |= (1 << JTD);
    MCUSR |= (1 << JTD);        // disable JTAG reliably
    DDRB = 0xFF;
    DDRA = 0x0F;
    DDRD = 0xFF;

    uint16_t ring_mask = 0;
    for (;;) {
        ring_mask ^= HALO_PATTERN;
        drive_ring(ring_mask);
        _delay_ms(300);
    }
}

2 · IR latch without extras

A beam break stores the XOR pattern, holds it for N cycles, then drops. No interrupts, no Arduino core.

#include <avr/io.h>
      #include <util/delay.h>

      #define HALO_PATTERN 0b101010101010
      #define HOLD_TICKS   12

      static inline void setup_ports(void) {
        MCUSR |= (1 << JTD);
        MCUSR |= (1 << JTD);
        DDRB = 0xFF;
        DDRA = 0x0F;
        DDRC &= ~(1 << PC0);   // IR input on PC0
        PORTC |= (1 << PC0);   // enable pull-up
      }

      static inline uint8_t ir_triggered(void) {
        return !(PINC & (1 << PC0));
      }

      static inline void pulse(uint16_t *mask) {
        *mask ^= HALO_PATTERN;
        PORTB = *mask & 0xFF;
        PORTA = (*mask >> 8) & 0x0F;
      }

      int main(void) {
        uint16_t ring_mask = 0;
        uint8_t hold = 0;
        setup_ports();

        for (;;) {
          if (ir_triggered()) {
            pulse(&ring_mask);
            hold = HOLD_TICKS;
          }

          if (hold) {
            _delay_ms(50);
            if (--hold == 0) {
              pulse(&ring_mask); // drop pattern back to zeroed state
            }
          }
        }
      }

3 · Minimal XOR pulse

Strip everything to a single toggled bit—this is the portion many “examples” comment out.

int main(void) {
    DDRB = 0xFF;
    uint8_t idx = 0;

    for (;;) {
        PORTB ^= (1 << idx);
        _delay_ms(200);
        if (++idx > 7) idx = 0;
    }
}

Fine. Arduino time.

Same XOR mask, but in the friendlier setup()/loop() world so workshops can follow along. Still lean—no dynamic allocation, no mystery libraries.

1 · Halo mask with pins

Map 12 GPIOs, flip the alternating bits with XOR, and blast them out with plain digitalWrite().

const uint8_t ringPins[] = {2,3,4,5,6,7,8,9,10,11,12,13};
const uint8_t RING_COUNT = sizeof(ringPins) / sizeof(ringPins[0]);
const uint16_t HALO_PATTERN = 0b101010101010;

uint16_t ringMask = 0;

void setup() {
  for (uint8_t i = 0; i < RING_COUNT; ++i) {
    pinMode(ringPins[i], OUTPUT);
    digitalWrite(ringPins[i], LOW);
  }
}

void writeRing(uint16_t mask) {
  for (uint8_t i = 0; i < RING_COUNT; ++i) {
    digitalWrite(ringPins[i], (mask >> i) & 0x01);
  }
}

void loop() {
  ringMask ^= HALO_PATTERN;
  writeRing(ringMask);
  delay(300);
}

2 · IR hold with millis()

Debounce the IR detector, latch the pattern for a fixed dwell, and drop back when time expires.

const uint8_t irPin = A0;
const uint16_t HALO_PATTERN = 0b101010101010;
const uint16_t HOLD_MS = 600;

uint16_t ringMask = 0;
unsigned long holdUntil = 0;

void setup() {
  pinMode(irPin, INPUT_PULLUP);
  for (uint8_t pin : ringPins) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);
  }
}

bool irTriggered() {
  return digitalRead(irPin) == LOW;
}

void pulse() {
  ringMask ^= HALO_PATTERN;
  writeRing(ringMask);
}

void loop() {
  const unsigned long now = millis();

  if (irTriggered()) {
    pulse();
    holdUntil = now + HOLD_MS;
    delay(30); // tiny debounce so we do not re-trigger instantly
  }

  if (holdUntil && now > holdUntil) {
    pulse();        // clear pattern
    holdUntil = 0;
  }
}

3 · Truly basic blink

If they only need a single LED proving ground, this is the entire story.

const uint8_t ledPin = LED_BUILTIN;
bool state = false;

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

void loop() {
  state = !state;       // XOR with 1
  digitalWrite(ledPin, state);
  delay(200);
}