* ======================================================================= * AR-Autopilot — IMU BNO085: Alimentacion, Reset e I2C * Archivo: 6_bno085_imu.cir * Tarjeta: Modulo compacto ESP32+CAN (CIRCUITO GIRO) * * CIRCUITO: * * 3.3V ──[C=10uF + C=100nF]──── BNO085 VDD (alimentacion principal) * 3.3V ──[C=100nF]────────────── BNO085 VDDIO (nivel logico I2C = 3.3V) * * 3.3V ──[R=10K]──── NRST (BNO085 RESET, activo bajo) * └── [C=1uF] ── GND → reset POR: NRST sube lento * * 3.3V ──[R=4.7K]──── SCL (I2C clock, 400 kHz Fast Mode) * 3.3V ──[R=4.7K]──── SDA (I2C data, open-drain) * 3.3V ──[R=10K] ──── INT (interrupcion data-ready, activo bajo OD) * * SA0 ── GND → direccion I2C = 0x4A * BOOT ── GND → modo operacion normal (no bootloader USB) * * BNO085 (CEVA/Hillcrest BNO085): * Alimentacion: VDD = 3.3V, VDDIO = 1.8V a 3.3V * Corriente tipica: 6.5 mA (todos los sensores activos, 100 Hz) * Reset: NRST activo bajo, minimo 10 us, startup: 50 ms tipico * I2C: 100 kHz o 400 kHz (Fast Mode), max 1 MHz (Fast Mode Plus) * Reportes configurables: Rotation Vector, Gyroscope, Accelerometer... * Sensor Fusion DSP interno: 500 Hz internal fusion rate * Giroscopio: ruido ~0.014 deg/s RMS, bias < 1 deg/s * Magnetometro: compensacion hard/soft iron automatica * Rango de temperatura operacion: -40 a +85 C (marino OK) * * REPORTES USADOS PARA EL AUTOPILOTO: * ARVR Stabilized Rotation Vector → Heading (0-360°) a 100 Hz * Gyroscope Calibrated → Yaw rate (°/s) a 250 Hz * Linear Acceleration → para deteccion de impactos * * COMO USAR EN LTSPICE: * Ver: V(nrst) → curva de reset POR (debe superar 0.7×VDD = 2.31V en ~12ms) * V(vdd_bno) → tension de alimentacion BNO085 con decoupling * V(scl) → reloj I2C 400 kHz con tiempos de subida correctos * V(sda) → datos I2C con open-drain y pull-up * V(int_pin) → interrupcion data-ready * ======================================================================= .title AR-Autopilot BNO085 IMU Power, Reset and I2C Interface * ----------------------------------------------------------------------- * ALIMENTACION 3.3V * ----------------------------------------------------------------------- V33 V33 GND 3.3V * ----------------------------------------------------------------------- * DESACOPLO DE ALIMENTACION BNO085 * ----------------------------------------------------------------------- * BNO085 datasheet recomienda: 10uF (bulk) + 100nF (HF) en VDD * y 100nF adicional en VDDIO, lo mas cerca posible del IC. * A 22mm del inductor L2 del buck: el ruido de switching es bajo * pero el decoupling sigue siendo critico para el magnetometro. Cbulk V33 VDD_BNO 10u ; capacitor bulk 10uF ceramico (X5R) Cdec1 VDD_BNO GND 100n ; 100nF ceramico junto al pin VDD del BNO085 Cdec2 V33 GND 100n ; 100nF en VDDIO (misma tension 3.3V) * Inductancia del trace PCB entre condensador bulk y IC (~10mm de traza) * L_trace a 1.4MHz (MP2338): XL = 2*pi*1.4e6*1e-9 = 8.8mOhm → despreciable Rtrace V33 VDD_BNO 0.05 ; resistencia de traza PCB (~50mOhm para 10mm) * Consumo del BNO085 (todos sensores + fusion a 100Hz) Ibno085 VDD_BNO GND DC 6.5m ; 6.5 mA tipico (datasheet tabla 4.3) * ----------------------------------------------------------------------- * CIRCUITO DE RESET (Power-On Reset) * ----------------------------------------------------------------------- * NRST activo bajo: cuando VDD sube, NRST debe permanecer bajo * hasta que VDD este estable, luego sube lentamente via RC. * El BNO085 sale de reset cuando NRST > 0.7 * VDDIO = 2.31V * Con R=10K, C=1uF: τ = 10ms → NRST cruza 2.31V en ~12ms * * Simulamos encendido: VDD sube en 1ms (soft-start del buck converter) * Despues NRST sube lentamente → BNO085 en reset durante ~12ms ✓ * Resistencia de pull-up del RESET Rrst V33 NRST_NODE 10k * Condensador de reset (define el tiempo de reset) Crst NRST_NODE GND 1u IC=0 * Diodo de descarga rapida (para re-reset rapido si VDD cae) Drst GND NRST_NODE DRST_FAST .model DRST_FAST D(Is=1e-12 N=1 Rs=1 Cjo=5p) * Modelo del umbral de reset del BNO085 (schmitt trigger interno) * NRST < 2.31V → en reset; NRST > 2.31V → operativo Eres RESET_STATUS GND VALUE={IF(V(NRST_NODE) > 2.31, 3.3, 0)} * ----------------------------------------------------------------------- * BUS I2C — RESISTENCIAS DE PULL-UP * ----------------------------------------------------------------------- * Fast Mode (400 kHz): Rpullup maximo = Vcc/(3mA) = 3.3/0.003 = 1.1k * Rpullup minimo = (Vcc - Voh)/(bus cap × slew rate) ≈ 1k * Valor estandar: 4.7k (funciona bien hasta 300kHz con Cbus < 100pF) * Para 400kHz con Cbus=50pF: tr = 0.8473 * 4700 * 50e-12 = 199ns OK (limite es 300ns) * * Si necesitas 400kHz garantizado con cable largo (Cbus > 100pF): * Reducir a 2.2k → tr = 93ns ✓ (pero mayor consumo: 3.3/2.2k = 1.5mA por linea) Rpull_scl V33 SCL 4.7k ; pull-up SCL Rpull_sda V33 SDA 4.7k ; pull-up SDA * Capacidad de bus (trazas PCB ~10cm + pines I2C de ESP32 y BNO085) * ESP32 I2C input cap: ~5pF, BNO085 I2C input cap: ~5pF, traza: ~10pF/cm × 10cm = 100pF Cbus_scl SCL GND 50p ; capacidad de bus SCL (solo 10cm de traza en PCB compacto) Cbus_sda SDA GND 50p ; capacidad de bus SDA * ----------------------------------------------------------------------- * ESP32 MASTER I2C — Genera transaccion I2C (direccion 0x4A, lectura) * ----------------------------------------------------------------------- * Protocolo I2C 400kHz (Fast Mode): * Periodo = 2.5us * SCL alto = 0.6us min (spec), SCL bajo = 1.3us min * Usamos: SCL alto = 0.9us, SCL bajo = 1.6us (simétrico aproximado) * * Secuencia simulada: * t=0: Bus idle (SDA=HIGH, SCL=HIGH) * t=5us: START condition (SDA baja mientras SCL alto) * t=7us: SCL baja → comienzo de bits de direccion * t=7-32us: 8 bits: direccion 0x4A + R/W=1 (lectura) * 0x4A = 1001010, con R/W=1 → byte = 10010101 = 0x95 * t=32us: SCL sube → ACK del esclavo (BNO085 baja SDA) * t=37us: SCL baja → BNO085 libera SDA (pull-up sube) * t=40us: BNO085 comienza a enviar dato (primer byte de SHTP) * t=60us: STOP condition * SCL: generado por ESP32 (push-pull internamente, vista del bus = open-drain + pull-up) * Modelamos el SCL como fuente de tension con resistencia baja (driver fuerte) Vscl_drv SCL_DRV GND PWL( + 0 3.3 + 4.9u 3.3 + 5.0u 3.3 ; bus idle + 6.9u 3.3 + 7.0u 0 ; SCL baja → START completado, primer bit + 8.5u 0 + 8.6u 3.3 ; bit 7 (MSB): '1' + 9.9u 3.3 + 10.0u 0 + 11.4u 0 + 11.5u 3.3 ; bit 6: '0' + 12.9u 3.3 + 13.0u 0 + 14.4u 0 + 14.5u 3.3 ; bit 5: '0' + 15.9u 3.3 + 16.0u 0 + 17.4u 0 + 17.5u 3.3 ; bit 4: '1' + 18.9u 3.3 + 19.0u 0 + 20.4u 0 + 20.5u 3.3 ; bit 3: '0' + 21.9u 3.3 + 22.0u 0 + 23.4u 0 + 23.5u 3.3 ; bit 2: '1' + 24.9u 3.3 + 25.0u 0 + 26.4u 0 + 26.5u 3.3 ; bit 1: '0' + 27.9u 3.3 + 28.0u 0 + 29.4u 0 + 29.5u 3.3 ; bit 0 (R/W=1, lectura) + 30.9u 3.3 + 31.0u 0 ; SCL bajo para ACK + 32.4u 0 + 32.5u 3.3 ; SCL sube: BNO085 debe mantener SDA baja (ACK) + 33.9u 3.3 + 34.0u 0 + 59.9u 0 + 60.0u 3.3) ; ultimo SCL bajo → STOP Rscl_drv SCL_DRV SCL 10 ; impedancia del driver I2C del ESP32 * SDA: ESP32 genera START y los bits de direccion * BNO085 genera ACK (baja SDA durante ACK clock) Vsda_drv SDA_DRV GND PWL( + 0 3.3 + 4.9u 3.3 + 5.0u 0 ; START: SDA baja mientras SCL alto + 5.9u 0 + 6.0u 3.3 ; START completado: SDA sube (SCL ya bajo) * bits de direccion 0x95 = 10010101 (MSB first) * bit7=1: SDA alto (pull-up) + 6.9u 3.3 + 7.0u 3.3 ; bit 7 = 1 (recesivo, pull-up mantiene alto) + 9.9u 3.3 + 10.0u 0 ; bit 6 = 0 (ESP32 baja SDA) + 11.4u 0 + 11.5u 0 ; bit 5 = 0 + 13.9u 0 + 14.0u 3.3 ; bit 4 = 1 + 15.9u 3.3 + 16.0u 0 ; bit 3 = 0 + 17.9u 0 + 18.0u 3.3 ; bit 2 = 1 + 19.9u 3.3 + 20.0u 0 ; bit 1 = 0 + 21.9u 0 + 22.0u 3.3 ; bit 0 = 1 (R/W=1) + 29.9u 3.3 + 30.0u 0 ; ACK slot: ESP32 libera SDA (flota) * BNO085 baja SDA para ACK → modelado como fuente separada + 34.0u 0 + 34.1u 3.3 ; ESP32 retoma control del bus (post-ACK) + 59.9u 3.3 + 60.0u 3.3) ; STOP: SDA sube mientras SCL alto Rsda_drv SDA_DRV SDA 10 * ACK del BNO085: baja SDA durante el clock de ACK (t=32.5us a 34us) Vsda_ack SDA_ACK GND PWL( + 0 3.3 + 31.9u 3.3 + 32.0u 0 ; BNO085 ACK: baja SDA + 33.9u 0 + 34.0u 3.3) ; BNO085 libera SDA Rack SDA_ACK SDA 50 ; el driver del BNO085 tiene impedancia finita * ----------------------------------------------------------------------- * LINEA DE INTERRUPCION INT (data-ready, activo bajo, open-drain) * ----------------------------------------------------------------------- * El BNO085 baja INT cuando tiene un reporte listo para leer. * Con heading + yaw rate a 100Hz: INT pulsa cada 10ms * El ESP32 lee el dato cuando detecta INT bajo (GPIO input con pull-up) Rpull_int V33 INT_PIN 10k ; pull-up externo (ESP32 tiene pull-up interno tambien) Cint INT_PIN GND 10p ; capacidad del pin * Simula INT pulsando periodicamente (100 Hz = 10ms periodo, 100us de pulso bajo) Vint_bno INT_DRV GND PULSE(3.3 0 5m 100n 100n 100u 10m) Rint_drv INT_DRV INT_PIN 100 ; open-drain: BNO085 solo puede bajar, no subir * ----------------------------------------------------------------------- * MEDICIONES AUTOMATICAS * ----------------------------------------------------------------------- * Tiempo que tarda NRST en superar el umbral de reset (2.31V) .meas TRAN t_reset_deassert WHEN V(nrst_node)=2.31 RISE=1 * Tension estable de alimentacion del BNO085 .meas TRAN Vvdd_stable AVG V(vdd_bno) FROM 20m TO 50m * Tiempo de subida de SCL (10% → 90% de 3.3V = 0.33V → 2.97V) .meas TRAN t_rise_scl TRIG V(scl)=0.33 RISE=1 TARG V(scl)=2.97 RISE=1 * Tension minima en VDD_BNO durante transient de corriente del BNO085 .meas TRAN Vvdd_min MIN V(vdd_bno) FROM 0 TO 50m * ----------------------------------------------------------------------- * DIRECTIVAS DE SIMULACION * ----------------------------------------------------------------------- * 50ms total: captura arranque completo + transaccion I2C + varios pulsos INT .tran 0 50m 0 10n .options reltol=0.001 * ----------------------------------------------------------------------- * VALORES ESPERADOS * ----------------------------------------------------------------------- * t_reset_deassert ≈ 12ms → BNO085 sale de reset 12ms despues del arranque * Vvdd_stable ≈ 3.28-3.30V → caida de tension por Rtrace=50mOhm + Ibno=6.5mA * ΔV = 6.5mA × 50mOhm = 0.33mV (despreciable) ✓ * t_rise_scl ≈ 150-200ns → con Rpull=4.7k y Cbus=50pF: τ = 235ns * tr(10%-90%) = 2.2τ × (80%) = 200ns < 300ns OK ✓ * (especificacion I2C Fast Mode: tr < 300ns) * * BNO085 en operacion normal: * Corriente a 3.3V: 6.5mA tipico, 12mA maximo (fusion completa) * Tiempo de startup tras reset: 50ms tipico (inicializacion DSP) * Primer reporte disponible: ~100ms tras arranque * * CONEXION TIPICA A ESP32: * GPIO21 → SDA (I2C SDA, con pull-up 4.7k externo) * GPIO22 → SCL (I2C SCL, con pull-up 4.7k externo) * GPIO34 → INT (input only, con pull-up 10k, interrupcion falling edge) * GPIO13 → NRST (output, normalmente alto; pulsa bajo para hard reset) * * CONFIGURACION FIRMWARE: * wire.begin(21, 22) → ESP32 Arduino I2C * Wire.setClock(400000) → Fast Mode 400kHz * BNO08x.begin(0x4A, Wire, GPIO34) → libreria SparkFun BNO08x * * REPORTES PARA AUTOPILOTO: * setReports(ARVR_STABILIZED_RV, 0.01) → heading a 100Hz * setReports(GYROSCOPE_CALIBRATED, 0.004) → yaw rate a 250Hz * getRVheading() → degrees (0-360) con compensacion tilt * getGyroZ() → deg/s (eje Z = yaw rate, positivo = estribor) .backanno .end