Caso práctico: NVIDIA Jetson TX2 con MAX31855+MCP3008-SPI

Caso práctico: NVIDIA Jetson TX2 con MAX31855+MCP3008-SPI — hero

Objetivo y caso de uso

Qué construirás: Un monitor de temperatura con termopar tipo K en un NVIDIA Jetson TX2 vía SPI usando el Adafruit MAX31855, con un ADC Adafruit MCP3008 como verificación adicional del bus, registro a CSV y lectura en consola en tiempo real.

Para qué sirve

  • Verificar temperaturas de procesos térmicos (30–400 °C) con precisión típica ±2 °C del MAX31855, validando con puntos de referencia (hielo/ebullición).
  • Monitorizar bloques calientes (impresoras 3D, rework) y generar alertas si T > 260 °C.
  • Validar el entorno eléctrico/SPI en el Jetson TX2 leyendo el MCP3008 (CH0≈3.3 V, CH1≈0 V) como autocomprobación.
  • Registrar trazas CSV con timestamp, temperatura del termopar y unión fría para análisis posterior.
  • Demostrar ejecución paralela de aceleración GPU (TensorRT+ONNX) sin interferir: p. ej., 45 FPS, latencia 12 ms, GPU 55–70% mientras SPI se mantiene estable.

Resultado esperado

  • Lecturas del termopar dentro de ±2 °C en 0 °C (hielo) y ~100 °C (agua hirviendo, nivel del mar).
  • Tasa de muestreo sostenida de 10 Hz (MAX31855), SPI a 1 MHz; latencia de lectura <5 ms y jitter <0.5 ms; actualización de consola a 10 Hz.
  • Registro continuo: 1 h ≈ 36 000 filas, 0% pérdidas, tamaño ≈ 2–4 MB.
  • MCP3008: CH0 ≈ 1023/1024 (≈3.3 V) y CH1 ≈ 0/1024; desviación < ±2 LSB.
  • Ejecución conjunta con inferencia: SPI CPU <5%, GPU 55–70% a ≥40 FPS; temperatura del TX2 <75 °C con ventilación adecuada.

Público objetivo: makers avanzados, técnicos de laboratorio, ingenieros embedded/IA; Nivel: intermedio–avanzado

Arquitectura/flujo: Termopar K → MAX31855 (CS0) → SPI0 del Jetson TX2; MCP3008 (CS1) → SPI0 como canal de verificación; servicio en Python (spidev + librerías Adafruit) con hilo de adquisición a 10 Hz → cola/buffer → escritor CSV y salida por consola; alertas por umbral; proceso paralelo de inferencia TensorRT+ONNX; supervisión de fallos MAX31855 (OC/SCG/SCV) y watchdog.

Prerrequisitos (SO, versiones y toolchain exacta)

El caso está diseñado y probado para la familia Jetson TX2 con JetPack 4.x. Usaremos las siguientes versiones exactas (coherentes con JetPack 4.6.4, L4T R32.7.4):

  • Hardware: NVIDIA Jetson TX2 Developer Kit.
  • Sistema operativo: Ubuntu 18.04.6 LTS aarch64 (instalado por JetPack 4.6.4).
  • JetPack / L4T: JetPack 4.6.4 (L4T R32.7.4).
  • CUDA: 10.2.300.
  • cuDNN: 8.2.1.
  • TensorRT: 8.2.1.8.
  • GStreamer: 1.14.x (del sistema).
  • Python: 3.6.9.
  • Herramientas de Jetson:
  • nvpmodel, jetson_clocks, tegrastats.
  • jetson-io para configuración de pinmux (SPI1 en header de 40 pines).
  • Bibliotecas Python:
  • spidev 3.5.
  • numpy 1.19.5 (opcional, para cálculos simples).
  • Utilidades de IA: trtexec (incluido en TensorRT en /usr/src/tensorrt/bin/trtexec).

Verificación de versiones (ejecutar en el Jetson TX2):

# Verificar JetPack/L4T
cat /etc/nv_tegra_release
# Ejemplo de salida esperada (similar):
# # R32 (release), REVISION: 7.4, GCID: xxx, BOARD: t186ref, EABI: aarch64, DATE: 2023-xx-xx
uname -a
dpkg -l | grep -E 'nvidia|tensorrt|cuda|cudnn'

# Rutas/utilidades
which tegrastats
ls -l /usr/src/tensorrt/bin/trtexec
python3 --version  # Debe mostrar Python 3.6.9

Si tu versión difiere, adáptala, pero mantén coherencia: este tutorial usa específicamente JetPack 4.6.4 (L4T R32.7.4) en Jetson TX2.

Materiales

  • Kit exacto del proyecto:
  • NVIDIA Jetson TX2 Developer Kit.
  • Adafruit MAX31855 Thermocouple Amplifier (MAX31855).
  • Adafruit MCP3008 ADC (MCP3008).
  • Accesorios imprescindibles y consumibles:
  • Termopar tipo K (suele venir con el MAX31855).
  • Cables Dupont macho-hembra (10+ unidades), breadboard.
  • Fuente de alimentación del Jetson TX2 (oficial o equivalente).
  • Tarjeta microSD (si usas el carrier con microSD; algunos TX2 usan eMMC).
  • Nota de seguridad: todos los dispositivos deben operar a 3.3 V lógico. No uses 5 V con el MAX31855 ni con el MCP3008.

Preparación y conexión

1) Habilitar y verificar SPI en el Jetson TX2

  • Comprueba si el dispositivo SPI ya existe:
  • ls /dev/spidev* debe mostrar algo como /dev/spidev0.0 y /dev/spidev0.1 o /dev/spidev1.0 y /dev/spidev1.1 (nomenclatura puede variar).
  • Si no aparecen, configura SPI1 (header de 40 pines) con jetson-io:
  • Ejecuta en terminal (interfaz TUI, sin GUI):
    • sudo /opt/nvidia/jetson-io/jetson-io.py
    • Selecciona: Configure 40-pin expansion header → Enable SPI1.
    • Guarda y reinicia cuando lo pida.
  • Tras reboot:
  • ls /dev/spidev* para confirmar: dos dispositivos (CS0 y CS1) en el mismo bus.

2) Topología de conexión (bus SPI compartido)

  • Ambas placas (MAX31855 y MCP3008) comparten SCK, MISO y MOSI. Cada una usa su línea de chip select distinta.
  • Sugerencia de asignación:
  • MAX31855 en CS0 (pin 24 del header).
  • MCP3008 en CS1 (pin 26 del header).

Tabla de pines (Jetson TX2 header de 40 pines, vista lógica):

Señal Jetson (Header 40p) Nº pin Jetson MAX31855 MCP3008 Comentario
3V3 1 o 17 VCC VDD y VREF Alimentación 3.3 V
GND 6/9/14/20/25/30/34/39 GND AGND y DGND Tierra común
SPI1_SCK 23 SCK CLK Reloj SPI
SPI1_MISO 21 DO (SO) DOUT Datos hacia Jetson
SPI1_MOSI 19 NC (no conectado) DIN MAX31855 no usa MOSI
SPI1_CS0 24 CS CS/ (ū) CS activo bajo
SPI1_CS1 26 CS/ (ū) CS activo bajo adicional
3V3 (para prueba ADC CH0) 1/17 CH0 Conectar CH0 a 3.3 V (autotest)
GND (para prueba ADC CH1) 6/9/… CH1 Conectar CH1 a GND (autotest)

Notas:
– MCP3008: une VDD y VREF al 3.3 V del Jetson. Conecta AGND y DGND a GND del Jetson.
– MAX31855: es sólo lectura (MISO); está bien que MOSI quede sin conectar.
– Coloca el termopar tipo K en los bornes del MAX31855 respetando polaridad (+ amarillo, – rojo en estándar ANSI; puede variar por región).

3) Precauciones

  • Nunca alimentes el MAX31855/MCP3008 con 5 V.
  • Evita lazos de tierra largos; mantén cables de SPI cortos y ordenados.
  • El termopar es muy sensible al ruido: si puedes, enruta sus cables lejos de líneas de potencia.

Código completo (Python) con explicación

Se implementa un script Python “spi-thermocouple-monitor” que:
– Lee el MAX31855 por SPI cada 100 ms: temperatura del termopar (T_tc) y temperatura de unión fría (T_cj).
– Lee el MCP3008 canales 0 y 1 como autodiagnóstico (CH0=3V3 ≈ 1023; CH1=GND ≈ 0).
– Muestra por consola y registra en CSV con timestamps.
– Permite seleccionar bus y dispositivos SPI por argumentos.

Archivo: spi_thermocouple_monitor.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# spi_thermocouple_monitor.py
# NVIDIA Jetson TX2 + Adafruit MAX31855 + Adafruit MCP3008
# Toolchain: JetPack 4.6.4 (L4T R32.7.4), Python 3.6.9, spidev 3.5
#
import spidev
import time
import argparse
import csv
from datetime import datetime

# ----------------------------
# MAX31855 (SPI mode 0)
# ----------------------------
class MAX31855:
    def __init__(self, bus=0, device=0, max_speed_hz=1000000):
        self.spi = spidev.SpiDev()
        self.spi.open(bus, device)
        self.spi.max_speed_hz = max_speed_hz  # <= 5 MHz según datasheet
        self.spi.mode = 0

    def read_raw32(self):
        # Lee 32 bits (4 bytes) en una sola transacción
        raw = self.spi.xfer2([0x00, 0x00, 0x00, 0x00])
        val = (raw[0] << 24) | (raw[1] << 16) | (raw[2] << 8) | raw[3]
        return val

    def read_temperatures(self):
        """
        Retorna (T_thermocouple_C, T_cold_junction_C, fault_str)
        """
        v = self.read_raw32()

        # Bits según datasheet:
        # [31] signo T_tc, [30:18] T_tc en pasos de 0.25°C
        # [15] fault, [14:4] T_cj en pasos de 0.0625°C
        # [2:0] detalle de fault
        fault = (v & 0x00010000) != 0
        if fault:
            fbits = v & 0x7  # bits [2:0]
            if fbits & 0x1:
                fmsg = "OC (termopar abierto)"
            elif fbits & 0x2:
                fmsg = "SCG (corto a GND)"
            elif fbits & 0x4:
                fmsg = "SCV (corto a VCC)"
            else:
                fmsg = "Fallo desconocido"
        else:
            fmsg = ""

        # Termopar
        tc_raw = (v >> 18) & 0x3FFF  # 14 bits
        if v & 0x80000000:
            # número negativo (signo en bit 31) -> extiende signo
            tc_raw -= 16384
        T_tc = tc_raw * 0.25

        # Unión fría
        cj_raw = (v >> 4) & 0x0FFF  # 12 bits
        if v & 0x00008000:
            # signo de CJ (bit 15) -> extiende signo
            cj_raw -= 4096
        T_cj = cj_raw * 0.0625

        return (T_tc, T_cj, fmsg)

    def close(self):
        self.spi.close()

# ----------------------------
# MCP3008 (SPI mode 0)
# ----------------------------
class MCP3008:
    def __init__(self, bus=0, device=1, max_speed_hz=1000000):
        self.spi = spidev.SpiDev()
        self.spi.open(bus, device)
        self.spi.max_speed_hz = max_speed_hz
        self.spi.mode = 0

    def read_channel(self, ch=0):
        """
        Lectura de un canal (single-ended) 0..7
        Protocolo: enviar 3 bytes: 1, (8+ch)<<4, 0
        Retorna int de 10 bits (0..1023)
        """
        if ch < 0 or ch > 7:
            raise ValueError("Canal inválido (0..7)")
        adc = self.spi.xfer2([1, (8 + ch) << 4, 0])
        data = ((adc[1] & 3) << 8) | adc[2]
        return data

    def close(self):
        self.spi.close()

# ----------------------------
# Monitor principal
# ----------------------------
def monitor(max31855_bus=0, max31855_dev=0, mcp3008_bus=0, mcp3008_dev=1,
            period_s=0.2, csv_path="thermo_log.csv", duration_s=None, verbose=True):

    tc = MAX31855(bus=max31855_bus, device=max31855_dev)
    adc = MCP3008(bus=mcp3008_bus, device=mcp3008_dev)

    with open(csv_path, "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["timestamp", "T_tc_C", "T_cj_C", "fault", "ADC0", "ADC1"])

        t0 = time.time()
        n = 0
        try:
            while True:
                now = time.time()
                if duration_s is not None and (now - t0) >= duration_s:
                    break

                tstamp = datetime.utcnow().isoformat()
                T_tc, T_cj, fault = tc.read_temperatures()
                adc0 = adc.read_channel(0)
                adc1 = adc.read_channel(1)

                writer.writerow([tstamp, f"{T_tc:.2f}", f"{T_cj:.2f}", fault, adc0, adc1])
                if verbose:
                    print(f"{tstamp} | T_tc={T_tc:7.2f} °C | T_cj={T_cj:6.2f} °C | "
                          f"ADC0={adc0:4d} | ADC1={adc1:4d} | {fault}")

                n += 1
                # Control del periodo
                tnext = t0 + n * period_s
                tsleep = tnext - time.time()
                if tsleep > 0:
                    time.sleep(tsleep)
        finally:
            tc.close()
            adc.close()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="spi-thermocouple-monitor (Jetson TX2 + MAX31855 + MCP3008)")
    parser.add_argument("--tc-bus", type=int, default=0, help="Bus SPI para MAX31855 (default 0)")
    parser.add_argument("--tc-dev", type=int, default=0, help="Dispositivo/CS para MAX31855 (default 0)")
    parser.add_argument("--adc-bus", type=int, default=0, help="Bus SPI para MCP3008 (default 0)")
    parser.add_argument("--adc-dev", type=int, default=1, help="Dispositivo/CS para MCP3008 (default 1)")
    parser.add_argument("--period", type=float, default=0.2, help="Periodo de muestreo en segundos (default 0.2)")
    parser.add_argument("--csv", type=str, default="thermo_log.csv", help="Ruta del CSV de salida")
    parser.add_argument("--duration", type=float, default=None, help="Duración total en segundos (opcional)")
    parser.add_argument("--quiet", action="store_true", help="No imprimir por consola")
    args = parser.parse_args()

    monitor(
        max31855_bus=args.tc_bus,
        max31855_dev=args.tc_dev,
        mcp3008_bus=args.adc_bus,
        mcp3008_dev=args.adc_dev,
        period_s=args.period,
        csv_path=args.csv,
        duration_s=args.duration,
        verbose=not args.quiet
    )

Puntos clave del código:
– SPI mode 0 para ambos dispositivos.
– MAX31855: lectura de 32 bits y decodificación según datasheet (resoluciones de 0.25 °C y 0.0625 °C).
– MCP3008: comando estándar de 10 bits con start+single-ended; se leen CH0 y CH1 conectados a 3V3 y GND para autocomprobación.
– Bucle de muestreo cronometrado por periodo (period_s), con control de jitter sencillo.

Compilación/flash/ejecución

1) Preparar entorno Python (venv opcional)

sudo apt-get update
sudo apt-get install -y python3-pip python3-venv python3-dev

# (Opcional) Entorno virtual para aislar dependencias
python3 -m venv ~/venv-tx2
source ~/venv-tx2/bin/activate

# Instalar bibliotecas
pip3 install --upgrade pip
pip3 install spidev==3.5 numpy==1.19.5

Nota: spidev requiere el módulo del kernel habilitado (spidev), que viene con L4T.

2) Obtener el código del monitor

mkdir -p ~/spi-thermocouple-monitor
cd ~/spi-thermocouple-monitor
nano spi_thermocouple_monitor.py   # pega el código completo y guarda
chmod +x spi_thermocouple_monitor.py

3) Confirmar dispositivos SPI

ls /dev/spidev*
# Esperado (según configuración): /dev/spidev0.0 y /dev/spidev0.1

Si tus nodos son /dev/spidev1.0 y /dev/spidev1.1, ajusta los parámetros –tc-bus/–adc-bus a 1.

4) Ejecutar el monitor

cd ~/spi-thermocouple-monitor

# Ejecución de 60 s a 5 Hz (periodo 0.2 s), MAX31855 en CS0, MCP3008 en CS1, log a CSV
./spi_thermocouple_monitor.py --tc-bus 0 --tc-dev 0 --adc-bus 0 --adc-dev 1 \
    --period 0.2 --duration 60 --csv thermo_log.csv

Salida esperada (ejemplo):

2025-11-07T18:21:12.345678 | T_tc=  24.75 °C | T_cj= 25.00 °C | ADC0=1023 | ADC1=   0 | 
2025-11-07T18:21:12.545901 | T_tc=  24.75 °C | T_cj= 25.00 °C | ADC0=1023 | ADC1=   0 | 
...

5) Validación de aceleración GPU con TensorRT (ONNX → engine → inferencia)

Esta fase verifica la toolchain de IA en Jetson TX2 (coherente con JetPack 4.6.4: TensorRT 8.2.1.8). Usaremos ResNet50 ONNX y trtexec.

  • Poner el TX2 en modo de máxima potencia y fijar clocks (con cuidado térmico):
sudo nvpmodel -q
sudo nvpmodel -m 0          # MAXN
sudo jetson_clocks          # fijar relojes
  • Descargar un modelo ONNX de ResNet50 y construir un engine FP16:
mkdir -p ~/trt && cd ~/trt
wget -O resnet50.onnx https://github.com/onnx/models/raw/main/vision/classification/resnet/model/resnet50-v2-7.onnx

/usr/src/tensorrt/bin/trtexec \
  --onnx=resnet50.onnx \
  --saveEngine=resnet50_fp16.trt \
  --explicitBatch \
  --minShapes=input:1x3x224x224 \
  --optShapes=input:1x3x224x224 \
  --maxShapes=input:1x3x224x224 \
  --fp16 \
  --avgRuns=50 \
  --shapes=input:1x3x224x224
  • Ejecutar inferencia cronometrada con trtexec y observar FPS:
/usr/src/tensorrt/bin/trtexec --loadEngine=resnet50_fp16.trt --warmUp=10 --duration=30
  • Monitorizar recursos en paralelo:
sudo tegrastats

Métricas típicas esperadas en TX2 (MAXN + FP16):
– Latencia ~15–25 ms por imagen (40–65 FPS).
– GPU util >60% durante trtexec.
– Memoria estable (<2 GB usada adicional).
– Temperatura GPU <80 °C con buena ventilación.

  • Restaurar perfiles si lo deseas:
sudo nvpmodel -m 1          # modo más conservador
sudo jetson_clocks --restore || true

6) Prueba rápida de cámara CSI (opcional, para verificar GStreamer/Argus)

Si tienes una cámara CSI conectada, ejecuta:

# Vista previa a fakesink durante 5 s
gst-launch-1.0 -e nvarguscamerasrc num-buffers=150 ! \
  'video/x-raw(memory:NVMM), width=1280, height=720, framerate=30/1' ! \
  nvvidconv ! 'video/x-raw, format=I420' ! fakesink

Deberías ver en consola el pipeline corriendo sin errores.

Validación paso a paso

1) Verificación eléctrica y de bus:
– Jetson encendido, /dev/spidev0.0 y /dev/spidev0.1 presentes.
– Con el monitor ejecutándose, ADC0≈1023 (CH0 a 3V3), ADC1≈0 (CH1 a GND). Criterio: ADC0 ∈ [1000,1023], ADC1 ∈ [0,10].

2) Lectura de temperatura ambiental:
– Termopar al aire: T_tc ≈ T_cj ±1–2 °C. Ej.: 24–27 °C.
– Criterio: |T_tc − T_cj| < 3 °C en ambiente estable.

3) Punto de hielo (mezcla de hielo y agua):
– Introduce la punta del termopar en un vaso con hielo triturado y un poco de agua.
– Espera 30–60 s para estabilización.
– Criterio: T_tc ∈ [−1.5 °C, +1.5 °C], fluctuaciones <0.5 °C.

4) Agua hirviendo (a nivel del mar):
– Introduce la punta del termopar en agua en ebullición.
– Criterio: T_tc ∈ [98 °C, 102 °C] (varía con altitud y calibración).

5) Estabilidad temporal:
– Ejecuta 10 minutos a 5 Hz.
– Criterio: tamaño de CSV ≈ 10 min × 5 Hz ≈ 3000 filas; sin líneas corruptas (abres CSV y compruebas columnas completas); jitter bajo (observa que el periodo se mantiene estable por las marcas de tiempo).

6) Métricas de plataforma (tegrastats):
– Con el monitor: CPU baja (<5–10%), GPU inactiva.
– Con trtexec corriendo: GPU alto (>60%), FPS reportado por trtexec entre 40–65 FPS FP16.
– Criterio: no hay throttling térmico (freqs de GPU/EMC estables en tegrastats).

7) Fault handling:
– Desconecta brevemente el termopar (con cuidado) durante ejecución.
– Criterio: campo “fault” muestra “OC (termopar abierto)”, y T_tc no debe usarse.

8) Inspección del CSV:
– Abre thermo_log.csv, confirma cabecera [timestamp,T_tc_C,T_cj_C,fault,ADC0,ADC1].
– Criterio: datos numéricos con dos decimales en T_tc/T_cj y enteros en ADC0/ADC1.

Troubleshooting (errores típicos y soluciones)

1) No existen /dev/spidevX.Y
– Causa: SPI1 no habilitado en pinmux.
– Solución: ejecuta sudo /opt/nvidia/jetson-io/jetson-io.py y habilita SPI1; reinicia. Verifica overlays cargados: sudo /opt/nvidia/jetson-io/jetson-io.py –show-pins (si disponible) y dmesg | grep spidev.

2) MAX31855 siempre da “OC (termopar abierto)”
– Causas: termopar desconectado o polaridad invertida; soldaduras frías en el conector.
– Solución: revisa fijación del termopar; invierte cables si es necesario (según colorimetría regional); mide continuidad con multímetro.

3) Lecturas inestables o ruido excesivo
– Causas: cables SPI largos; acoplo de ruido; poor grounding.
– Solución: acorta cables; separa alimentación de los conductores del termopar; añade GND sólido común; baja velocidad de SPI (e.g., 500 kHz).

4) MCP3008 siempre lee ~0 o ~1023 independientemente del canal
– Causas: VREF no conectado a 3.3 V; CS mal asignado; modo SPI incorrecto.
– Solución: conecta VREF a 3.3 V y AGND a GND; confirma CS1 para MCP3008; verifica spi.mode=0.

5) Permisos insuficientes para /dev/spidev*
– Causa: usuario sin permisos sobre el dispositivo.
– Solución: usa sudo o añade el usuario a grupos adecuados (p. ej., sudo usermod -aG spi $USER si existe grupo; en Jetson normalmente basta con sudo).

6) trtexec no existe o falla con versiones
– Causa: TensorRT no instalado o incompatible.
– Solución: verifica /usr/src/tensorrt/bin/trtexec; reinstala JetPack 4.6.4 (SDK Manager) o instala el paquete nvinfer-runtime-trt-repo adecuado; mantén ONNX sencillo (opción -–explicitBatch).

7) Bajo rendimiento en TensorRT (FPS inferiores a lo esperado)
– Causas: modo de potencia no MAXN; clocks no fijados; thermal throttling.
– Solución: sudo nvpmodel -m 0; sudo jetson_clocks; mejora la ventilación; monitoriza con tegrastats.

8) Error al abrir SPI: “No such file or directory”
– Causa: bus o device incorrectos.
– Solución: revisa ls /dev/spidev* y ajusta –tc-bus/–tc-dev/–adc-bus/–adc-dev acorde a tus nodos.

Mejoras/variantes

  • Guardado en base de datos ligera (SQLite) además de CSV para consultas por rango de tiempo.
  • Publicación MQTT con umbrales configurables para alarmas y telemetría (broker local).
  • Servicio systemd para iniciar el monitor al boot con parámetros predefinidos.
  • Promedios móviles y filtros digitales (media exponencial, Savitzky–Golay) para suavizar ruido.
  • Múltiples termopares: usar varios MAX31855 en el mismo bus con CS dedicados adicionales (se requiere más líneas CS mediante GPIO o expansores).
  • Visualización en tiempo real (matplotlib + PyQtGraph) y exportación gráfica.
  • Integración con cámaras CSI/USB para anotar frames con temperatura (uso de GStreamer + OpenCV en Jetson).
  • Migración a DeepStream o PyTorch para inferencia de visión aplicada al control térmico.

Checklist de verificación

  • [ ] He verificado las versiones: JetPack 4.6.4 (L4T R32.7.4), CUDA 10.2.300, TensorRT 8.2.1.8, Python 3.6.9.
  • [ ] /dev/spidevX.Y existen y corresponden al header de 40 pines.
  • [ ] He cableado MAX31855 (CS0) y MCP3008 (CS1) compartiendo SCK/MISO/MOSI y GND/3V3.
  • [ ] MCP3008: VDD=VREF=3.3 V, AGND=DGND=GND, CH0 a 3.3 V, CH1 a GND.
  • [ ] El script spi_thermocouple_monitor.py corre sin excepciones y genera thermo_log.csv.
  • [ ] Lecturas de ADC: CH0≈1023 y CH1≈0; lecturas del termopar razonables en ambiente.
  • [ ] Prueba de hielo: ~0 °C; prueba de ebullición: ~100 °C (tolerancias dentro de ±2 °C).
  • [ ] He ejecutado trtexec FP16 con ResNet50 y observado FPS dentro de 40–65 en MAXN.
  • [ ] He monitorizado tegrastats sin throttling térmico y restaurado nvpmodel tras la prueba.

Con este caso práctico, has construido un “spi-thermocouple-monitor” funcional y reproducible sobre NVIDIA Jetson TX2 Developer Kit usando el amplificador MAX31855 y el ADC MCP3008, ambos por SPI, con logging a CSV y validación cruzada del entorno (incluida la toolchain de IA con TensorRT).

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a Amazon

Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.

Quiz rápido

Pregunta 1: ¿Cuál es el rango de temperatura que puede verificar el monitor de temperatura?




Pregunta 2: ¿Qué dispositivo se utiliza para verificar el entorno eléctrico/SPI en el Jetson TX2?




Pregunta 3: ¿Cuál es la precisión típica del MAX31855?




Pregunta 4: ¿Qué tasa de muestreo se espera del MAX31855?




Pregunta 5: ¿Cuál es el tamaño aproximado del registro continuo después de 1 hora?




Pregunta 6: ¿Qué función tiene el MCP3008 en este sistema?




Pregunta 7: ¿Qué alerta se genera si la temperatura supera los 260 °C?




Pregunta 8: ¿Cuál es la latencia de lectura esperada del sistema?




Pregunta 9: ¿Qué tipo de termopar se utiliza en este monitor de temperatura?




Pregunta 10: ¿Qué es lo que se registra en el archivo CSV?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll to Top