Wiznet makers

Benjamin

Published June 17, 2026 ©

121 UCC

11 WCC

10 VAR

0 Contests

0 Followers

2 Following

Original Link

AR22 LCU: W5500 Ethernet TCP Dose Logging on a Dual-Range STM32F446 Radiation Detector

AR22 LCU v1.1 is a dual-range gamma radiation detector on STM32F446 that streams real-time dose-rate JSON over a W5500 Ethernet TCP server on port 15022.

COMPONENTS Hardware components

WIZnet - W5500

x 1

SPI1 @12.5 MHz, CS=PA4, RST=PC4. Static IP 192.168.1.22:15022. TCP server for dose-rate JSON streaming. ETH_LOG_ENABLE=1 in main.c.


PROJECT DESCRIPTION

📌 Overview

The AR22 LCU (Local Control Unit) v1.1 is a dual-range gamma radiation detector built on an STM32F446VET6 MCU. It counts pulses from two Geiger-Mueller tubes, applies an adaptive exponential moving average filter, displays the live dose rate on a 256x64 SSD1322 OLED, and triggers a buzzer alarm when a configurable threshold is exceeded. Version 1.1 adds one more output channel: a W5500 Ethernet TCP server on port 15022 that streams the live dose rate as a JSON line to any connected client - telnet 192.168.1.22 15022 and you get {"val":1.23,"unit":"uSv/h"} every two seconds.

The measurement range spans 0.1 µSv/h to 100 mSv/h across two hardware ranges (LOW: µSv/h scale, HIGH: up to 150+ mSv/h). Range switching is automatic with hysteresis. Calibration constants and alarm thresholds are stored in an I2C EEPROM.

AR22 LCU radiation detector with W5500 Ethernet TCP streaming AR22 LCU: dual-range gamma detector streaming dose-rate JSON over W5500 Ethernet. Generated technical illustration.

System Configuration

The AR22 LCU uses an STM32F446VET6 running at 100 MHz from an 8 MHz HSE crystal with the FPU enabled. Two Geiger-Mueller tubes provide the dual-range input:

  • Low-dose tube (LND7128-class): pulses counted on TIM1 external trigger (PE7). Conversion factor ~0.601 CPM/(µSv/h), with dead-time correction applied.
  • High-dose tube (LND71631-class): pulses counted on TIM8 external trigger (PA0). Conversion factor ~48 CPM/(µSv/h).

TIM4 provides a 1 ms timebase interrupt that accumulates counts and fires the 1-second EMA update. An SSD1322 OLED (256x64, 4 bpp grayscale) on SPI4+DMA shows the current reading. A 24C01 I2C EEPROM (128 bytes) holds the alarm threshold and the two conversion factors persistently. Four EXTI buttons (PE9-PE12) handle alarm set, digit shift, and value up/down. A TIM5 PWM channel drives the buzzer at ~3.7 kHz.

The W5500 sits on SPI1 (12.5 MHz: APB2 100 MHz / prescaler 8) with CS on PA4 and RST on PC4. It is isolated from the base firmware behind a single compile-time macro: #define ETH_LOG_ENABLE 1. Setting it to 0 removes every Ethernet call from the build with no other changes needed.

System Architecture & Data Flow

The measurement chain runs independently of the Ethernet path, which makes the networking addition non-intrusive:

AR22 LCU system architecture block diagram System architecture: GM pulses enter the STM32F446 hardware timers; the EMA filter, OLED, and W5500 TCP path all read the same dose variable. Generated technical diagram.

Every second, the 1 ms TIM4 ISR snapshots and resets both hardware counters. process_dose_ema() computes the adaptive EMA: when the new count diverges sharply from the running average, the smoothing factor alpha increases for a fast response; when the reading is stable, alpha drops to suppress noise. The result is stored in gmDoseLow or gmDoseHigh (µSv/h). process_range_check() then decides whether to stay on LOW or switch to HIGH (threshold 1000 µSv/h, ±200 hysteresis).

Every 0.2 seconds the OLED is refreshed. Every 2 seconds net_app_send_dose() reads the current range's dose variable and calls send() on the open TCP socket. If no client is connected, the call returns immediately.

Adaptive EMA Filter

The dual-range EMA is the core signal-processing step. For each range, process_dose_ema() computes:

  • An instantaneous count rate
  • A divergence metric between the new count and the current average
  • A dynamic alpha that rises when divergence is high (fast alarm response) and falls during steady-state (noise floor suppression)
  • A dose rate in µSv/h via the conversion factor (plus dead-time correction for the low-dose tube: n_corrected = n / (1 - n*tau))

The low-dose range shows 0.05 µSv/h as a floor when the count falls below the noise threshold. If the reading stays below 0.05 for 300 consecutive seconds, the firmware triggers a NO COUNT FAIL display.

⚙️ Role of the W5500

The W5500 is the only network interface on the board. It connects directly to a standard Ethernet switch or PC NIC and handles all TCP/IP framing in silicon, which means the STM32F446 application code never deals with IP checksums, TCP state machines, or retransmit timers - the chip handles all of that internally through its hardware TOE.

W5500 TCP server state machine and JSON streaming path W5500 TCP server: net_app_poll() drives the socket state machine; net_app_send_dose() calls send() with a JSON line every 2 s. Generated technical diagram.

The integration in MyLib/W5500/ is self-contained:

  • w5500_port_ar22.c implements the hardware abstraction layer (CS/RST GPIO, HAL_SPI_TransmitReceive/Transmit/Receive wrappers).
  • w5500_eth.c handles chip reset, VERSIONR verification, and MAC/IP/subnet/gateway register writes.
  • net_app.c owns the single TCP socket (socket 0, port 15022) using the WIZnet ioLibrary socket API directly.

The TCP server state machine in net_app_poll() follows the canonical ioLibrary pattern:

case SOCK_CLOSED:  socket(NET_SOCK, Sn_MR_TCP, NET_PORT, 0); break;
case SOCK_INIT:    listen(NET_SOCK);                           break;
case SOCK_ESTABLISHED: /* drain RX buffer, send JSON via send() */ break;
case SOCK_CLOSE_WAIT:  disconnect(NET_SOCK);                   break;

When a client connects, every 2-second call to net_app_send_dose(dose_uSv) formats a JSON line and calls send(). The unit auto-switches from uSv/h to mSv/h at 100 µSv/h to match the OLED display range. The W5500 MAC uses WIZnet's registered OUI: 00:08:DC:22:00:01.

The design is chip-agnostic from the application's point of view: net_app.c calls only standard ioLibrary socket functions, so porting to a W6100 or W5100S requires only a port-layer swap.

Where It Fits - Value and Limits

The AR22 LCU is a practical example of adding always-on Ethernet monitoring to safety-critical embedded hardware without disturbing validated firmware. Radiation detectors in labs, storage rooms, or industrial areas can now pipe live dose readings into a Python script, MQTT bridge, or data logger over plain TCP - no polling agent, no custom driver, just telnet or socket.recv().

Limits to be aware of: the Ethernet port is a single static IP with no DHCP, no TLS, and no authentication. Anyone on the same LAN segment who connects to port 15022 receives the data stream. There is no firmware support for simultaneous connections from multiple clients (socket 0 is the only one used). The repo contains firmware only - no schematic or PCB files are publicly available.

Related WIZnet Maker Projects

A Low-Cost IoT Gamma-Ray Spectrometer with the Easy-F407V-ETH (W5500) Board (Grade A) uses a scintillation detector and the STM32F407 ADC+DMA to capture gamma pulse heights, then streams a full energy spectrum (hundreds of data points per frame) over W5500 to a PC - answering "what kind of gamma source?" rather than "how much total exposure?". Both projects pair an STM32 with W5500 for radiation data over Ethernet, but the sensor types and data formats are opposite: a scintillation crystal resolves photon energy; a GM tube counts pulses and converts to dose rate. That spectrometer starts from a board with W5500 already soldered on; AR22 LCU shows how to graft W5500 onto an existing instrument without changing the measurement chain. The two projects together cover both ends of the Ethernet-plus-radiation design space - full hardware co-design vs. firmware-only upgrade.

Scintillation Monitor with Ethernet Interface (Maniak003/ScintMonitor) (Grade B) is an STM32 design with a window comparator and an Ethernet port, plus KiCad and FreeCAD hardware files in the repository. It confirms the Ethernet-for-radiation-monitoring pattern, but leaves signal processing and firmware architecture largely as an exercise. The contrast with AR22 LCU is instructive: ScintMonitor provides the hardware geometry (PCB, enclosure CAD), while AR22 LCU provides the firmware depth - adaptive dual-range EMA, calibration storage in EEPROM, alarm with ACK hysteresis, and the ETH_LOG_ENABLE compile-time switch that lets you add or remove Ethernet from a production binary without touching the core detection code. Together they sketch what a complete open-source radiation monitor with Ethernet would look like.

Interrupt-Driven W5500 UDP Server on STM32F4 with FreeRTOS and ioLibrary (Grade A) is a reference implementation of the ioLibrary socket API on STM32F407 with FreeRTOS, using UDP and a hardware receive interrupt. net_app.c in AR22 LCU uses the same socket() / listen() / send() / getSn_SR() call sequence - readers of that post will recognize the state machine immediately. Three concrete differences distinguish AR22 LCU from that reference: (1) TCP instead of UDP - a connected TCP session means the client's recv() returns an error the instant the detector goes offline, whereas UDP silently drops packets; (2) no RTOS - the main loop polling model keeps the 1 ms TIM4 count-capture ISR free of task-scheduling jitter, which matters for accurate GM pulse accounting; (3) production context - AR22 LCU is a working instrument, not a tutorial; the Ethernet layer was added after the detection firmware was already validated, which is why the ETH_LOG_ENABLE toggle exists.

❓ FAQ

Q. Does the dose-rate streaming require any special client software? No. Any program that opens a TCP connection to 192.168.1.22:15022 receives newline-delimited JSON. telnet 192.168.1.22 15022, Python socket.recv(), or netcat all work without modification.

Q. What happens to the detector if Ethernet is disconnected? Nothing. The detection, OLED display, and alarm functions run entirely in the STM32F446 main loop regardless of the W5500 link state. net_app_poll() and net_app_send_dose() are no-ops when s_ready is false or the socket is not in ESTABLISHED state.

Q. Can the W5500 feature be disabled at compile time? Yes. Setting #define ETH_LOG_ENABLE 0 in main.c excludes every Ethernet include and function call from the build. The binary reverts to the validated base firmware with no linker changes.

Q. What is the Ethernet configuration? Static IP only: 192.168.1.22, subnet 255.255.255.0, gateway 192.168.1.1. The MAC address uses WIZnet's registered OUI: 00:08:DC:22:00:01. DHCP is not implemented.

Q. How often is dose data sent over TCP? Once every two seconds, matching the main loop's net_app_send_dose() call cadence. The unit auto-selects uSv/h below 100 µSv/h and mSv/h at or above that threshold, consistent with the OLED display range.


한국어 (Korean)

📌 개요

AR22 LCU(Local Control Unit) v1.1은 STM32F446VET6 MCU 기반의 이중 레인지 감마선 방사선 검출기입니다. 2개의 가이거-뮬러 관에서 펄스를 계수하고, 적응형 지수이동평균 필터로 선량률을 산출한 뒤, SSD1322 OLED에 표시하고, 설정된 임계값 초과 시 부저 경보를 울립니다. v1.1에서는 출력 채널이 하나 더 추가됩니다. W5500 이더넷 TCP 서버(포트 15022)가 2초마다 현재 선량률을 JSON으로 전송합니다. telnet 192.168.1.22 15022로 접속하면 {"val":1.23,"unit":"uSv/h"} 형태의 응답을 받습니다.

측정 범위는 0.1 µSv/h에서 100 mSv/h까지이며, 두 레인지(LOW: µSv/h 스케일, HIGH: 150+ mSv/h까지)를 자동으로 전환합니다. 교정 계수와 알람 임계값은 I2C EEPROM에 영구 저장됩니다.

AR22 LCU 방사선 검출기 W5500 이더넷 TCP 스트리밍 AR22 LCU: W5500 이더넷으로 선량률 JSON을 실시간 전송하는 이중 레인지 감마선 검출기. 생성 일러스트.

시스템 구성

STM32F446VET6(@100 MHz, HSE 8 MHz, FPU 활성화)에 두 개의 가이거-뮬러 관을 연결합니다.

  • 저선량 관 (LND7128급): TIM1 외부 트리거(PE7)로 펄스 계수. 변환계수 약 0.601 CPM/(µSv/h), 데드타임 보정 적용.
  • 고선량 관 (LND71631급): TIM8 외부 트리거(PA0)로 펄스 계수. 변환계수 약 48 CPM/(µSv/h).

TIM4 1ms 인터럽트가 카운터를 누적하고 1초마다 EMA를 업데이트합니다. SSD1322 OLED(SPI4+DMA)에 현재 선량이 표시되고, 24C01 I2C EEPROM(128바이트)에 알람 임계값과 변환계수가 저장됩니다. 버튼 4개(PE9-PE12)로 알람 설정, 자리 이동, 값 조작이 가능합니다.

W5500은 SPI1(12.5 MHz)에 연결되며, CS=PA4, RST=PC4입니다. #define ETH_LOG_ENABLE 1로 활성화하고, 0으로 변경하면 이더넷 관련 코드가 빌드에서 완전히 제외됩니다.

시스템 아키텍처 및 데이터 흐름

측정 경로와 이더넷 경로는 독립적으로 동작합니다.

AR22 LCU 시스템 아키텍처 블록 다이어그램 시스템 아키텍처: GM 펄스 -> STM32F446 하드웨어 타이머 -> EMA 필터 -> OLED/알람/W5500 TCP 스트리밍. 생성 기술 다이어그램.

TIM4 ISR이 1초마다 카운터를 읽어 process_dose_ema()를 호출합니다. EMA는 변화가 크면 알파를 높여 빠르게 반응하고, 안정 시에는 낮춰 노이즈를 억제합니다. process_range_check()가 1000 µSv/h 임계값(±200 히스테리시스)으로 레인지를 자동 전환합니다.

0.2초마다 OLED가 갱신되고, 2초마다 net_app_send_dose()가 현재 선량을 TCP 소켓으로 전송합니다. 클라이언트가 연결되지 않으면 즉시 반환됩니다.

적응형 EMA 필터

process_dose_ema()는 각 레인지에서 순시 카운트율, 현재 평균과의 발산도, 동적 알파를 계산합니다. 저선량 레인지는 데드타임 보정(n_corrected = n / (1 - n*tau))도 적용됩니다. 선량이 0.05 µSv/h 아래로 300초 유지되면 NO COUNT FAIL이 표시됩니다.

⚙️ W5500의 역할

W5500은 보드의 유일한 네트워크 인터페이스입니다. 표준 이더넷 스위치 또는 PC NIC에 직접 연결되며, TCP/IP 처리(체크섬, TCP 상태 머신, 재전송 타이머)를 칩 내부에서 모두 수행합니다. STM32F446 애플리케이션 코드는 ioLibrary 소켓 API만 호출하면 됩니다.

W5500 TCP 서버 상태 머신 및 JSON 스트리밍 경로 W5500 TCP 서버: net_app_poll()이 소켓 상태 머신을 구동하고, net_app_send_dose()가 2초마다 JSON 라인을 전송합니다. 생성 기술 다이어그램.

MyLib/W5500/은 자기완결적 구조입니다: - w5500_port_ar22.c: CS/RST GPIO 및 HAL SPI 래퍼 - w5500_eth.c: 칩 리셋, VERSIONR 검증, MAC/IP 레지스터 설정 - net_app.c: ioLibrary 소켓 API 기반 TCP 서버 구현

MAC 주소는 WIZnet 공인 OUI를 사용합니다: 00:08:DC:22:00:01.

적용 범위와 한계

AR22 LCU는 검증된 방사선 검출 펌웨어에 상시 이더넷 모니터링을 비침습적으로 추가하는 좋은 예시입니다. 실험실, 보관실, 산업 현장의 검출기가 표준 TCP로 선량 데이터를 Python 스크립트, MQTT 브리지, 데이터 로거에 전송할 수 있습니다.

주의사항: 고정 IP만 지원하며(DHCP 없음), TLS나 인증이 없습니다. 동일 LAN의 누구나 포트 15022에 접속하면 데이터를 수신할 수 있습니다. 동시 다중 클라이언트 연결은 지원하지 않으며, 회로도나 PCB 파일은 공개되어 있지 않습니다.

관련 WIZnet 메이커 프로젝트

W5500을 활용한 저비용 IoT 감마선 분광기 (Grade A): STM32F407의 ADC+DMA로 신틸레이션 펄스 높이를 측정하고, 에너지 스펙트럼(수백 포인트짜리 분포)을 W5500으로 PC에 스트리밍합니다. "어떤 감마선원인가"를 판별하는 분광기입니다. 공통점은 STM32+W5500+이더넷+방사선이지만, 목적이 다릅니다. 선량률(dose rate)이 아니라 에너지 분해능(energy resolution)이 목표이고, 데이터도 단순 float 하나가 아니라 스펙트럼 배열 전체입니다. 그 프로젝트는 W5500이 이미 내장된 보드에서 출발하고, AR22 LCU는 검증된 기존 펌웨어에 W5500을 나중에 추가한 구조입니다. 두 프로젝트를 함께 보면 이더넷+방사선 설계의 두 극단을 볼 수 있습니다. 하드웨어 공동 설계(처음부터 W5500 포함) vs. 펌웨어만 업그레이드(기존 회로 유지).

유선 이더넷 인터페이스 신틸레이션 모니터 (Grade B): STM32 기반 신틸레이션 검출기에 윈도우 비교기와 이더넷을 붙인 설계로, KiCad 회로도와 FreeCAD 인클로저 파일까지 포함합니다. 이더넷-방사선 조합 자체를 확인해주는 프로젝트이지만, 신호 처리와 펌웨어 아키텍처는 미완성에 가깝습니다. AR22 LCU와의 대비가 명확합니다. 이 프로젝트는 하드웨어 형상(PCB, 케이스)을 제공하고, AR22 LCU는 펌웨어 깊이를 제공합니다. 이중 레인지 적응형 EMA, EEPROM 교정 저장, ACK 히스테리시스 알람, 그리고 핵심 검출 코드를 건드리지 않고 이더넷을 on/off하는 ETH_LOG_ENABLE 패턴. 두 프로젝트를 합치면 오픈소스 이더넷 방사선 모니터의 완성 구조가 보입니다.

STM32F4 + FreeRTOS + ioLibrary W5500 UDP 서버 (Grade A): STM32F407+FreeRTOS 환경에서 인터럽트 방식의 UDP 수신과 ioLibrary 소켓 API를 레퍼런스 코드로 정리한 프로젝트입니다. net_app.csocket() / listen() / send() / getSn_SR() 호출 순서가 이 프로젝트의 패턴과 거의 동일합니다. 세 가지 차이점이 AR22 LCU만의 특징을 드러냅니다. (1) TCP vs UDP: TCP 세션을 유지하면 검출기가 오프라인이 되는 순간 클라이언트의 recv()가 즉시 오류를 반환합니다. UDP는 패킷이 사라져도 클라이언트가 알 수 없습니다. (2) RTOS 없음: 메인 루프 폴링 방식이 1ms TIM4 인터럽트(GM 펄스 누적)에 태스크 스케줄링 지터를 일으키지 않습니다. 방사선 계수 정확도에 직접 영향을 미치는 부분입니다. (3) 실 장비 펌웨어: AR22 LCU는 이미 검증된 계측기 펌웨어에 이더넷을 나중에 추가한 결과물입니다. ETH_LOG_ENABLE 토글은 그 흔적이고, 이것이 레퍼런스 코드와 가장 큰 맥락 차이입니다.

❓ FAQ

클라이언트 소프트웨어가 필요한가요? 아닙니다. 192.168.1.22:15022로 TCP 연결을 열 수 있는 어떤 프로그램이든 사용할 수 있습니다. telnet, Python socket, netcat 모두 별도 설정 없이 동작합니다.

이더넷이 끊기면 검출기 동작에 영향이 있나요? 없습니다. 검출, OLED 표시, 알람 기능은 W5500 링크 상태와 무관하게 동작합니다. net_app_poll()net_app_send_dose()는 소켓이 ESTABLISHED 상태가 아닐 때 즉시 반환됩니다.

컴파일 타임에 이더넷 기능을 끌 수 있나요? 네. main.c에서 #define ETH_LOG_ENABLE 0으로 변경하면 모든 이더넷 관련 코드가 빌드에서 제외됩니다. 링커 설정 변경 없이 베이스 펌웨어로 즉시 복원됩니다.

이더넷 설정은 어떻게 되나요? 고정 IP 전용입니다: IP 192.168.1.22, 서브넷 255.255.255.0, 게이트웨이 192.168.1.1. MAC은 WIZnet 공인 OUI 00:08:DC:22:00:01을 사용합니다. DHCP는 지원하지 않습니다.

데이터는 얼마나 자주 전송되나요? 2초마다 한 번 전송됩니다. 100 µSv/h 미만이면 uSv/h, 이상이면 mSv/h 단위로 자동 전환되며, OLED 표시와 동일한 기준이 적용됩니다.

Documents
  • Source Code (GitHub)

    Full AR22 LCU v1.1 firmware: STM32F446VE, dual-range GM detector, W5500 TCP server, SSD1322 OLED

  • WIZnet W5500 Product Page

    W5500 datasheet and product overview

  • WIZnet ioLibrary Driver (GitHub)

    The ioLibrary TCP/IP socket API used directly in MyLib/W5500/ioLibrary/

  • AR22 LCU System Overview (docs/OVERVIEW.md)

    Full system overview: measurement chain, peripherals, display, alarm, Ethernet

Comments Write