If you are looking to design a robust circuit diagram with Arduino for high-temperature closed-loop control, the standard Arduino Uno falls short on processing overhead and timer precision. The benchmark setup for 2026 is the Arduino Nano Every (ATmega4809) paired with a MAX31855 thermocouple amplifier and a Solid State Relay (SSR). This combination provides the RAM headroom for PID math, native 5V logic for industrial modules, and the I/O speed required for zero-cross AC switching.

This guide walks through drafting the schematic, mapping the SPI and I2C buses, and writing time-proportioned PID control code that prevents the rapid chatter that destroys mechanical relays.

System Architecture and Power Budget

Before routing a single jumper wire, you must verify the 5V rail budget. The Nano Every's onboard regulator can source roughly 500mA, but USB power limits often cap out around 500mA total. Here is the exact power draw for our component list.

Bill of Materials & Power Spec Sheet

Component (Exact Variant) Nominal Voltage Current Draw Interface / Notes
Arduino Nano Every (ATmega4809) 5V (USB) ~25 mA Microcontroller Base
Adafruit MAX31855 Breakout 5V (Regulated to 3.3V) 4 mA SPI, Type-K Thermocouple
128x64 SSD1306 OLED (0x3C) 5V 20 mA (peak) I2C Display
Fotek SSR-25DA (Zero-Cross) 3-32V DC (Input) 15 mA (Input LED) Drives 120/240V AC Load

Total 5V rail draw: ~64 mA. This leaves over 400 mA of headroom, ensuring the Nano Every's voltage regulator will not thermally throttle during continuous operation.

The Core Circuit Diagram with Arduino Nano Every

Drafting a reliable circuit diagram with Arduino requires strict separation of low-voltage logic (SPI/I2C) and high-current switching paths. The MAX31855 uses SPI, which on the Nano Every maps to specific digital pins, not just the ICSP header.

Callout Tip: The Nano Every uses the ATmega4809 chip. Unlike the classic Nano (ATmega328P), its SPI pins are strictly D11 (COPI/MOSI), D12 (CIPO/MISO), and D13 (SCK). Do not attempt to bit-bang SPI on arbitrary pins for the MAX31855; hardware SPI is required to meet the sensor's timing constraints.

Pin Mapping Table

Nano Every Pin Module Function Wire Color Std
5VMAX31855 / OLED / SSR+VCC / VINRed
GNDAll ModulesCommon GroundBlack
D11 (COPI)MAX31855 (SDO)SPI Data OutBlue
D12 (CIPO)MAX31855 (SDI)SPI Data InPurple
D13 (SCK)MAX31855 (SCK)SPI ClockOrange
D10MAX31855 (CS)Chip Select (Active LOW)Yellow
A4 (SDA)OLED (SDA)I2C DataGreen
A5 (SCL)OLED (SCL)I2C ClockWhite
D3SSR-25DA (+)Time-Proportioned PWM OutBrown

Wiring Execution Steps

  1. Establish the Power Bus: Run 5V and GND from the Nano Every to your breadboard power rails. Use 22 AWG solid copper wire for the rails to prevent voltage sag when the OLED screen updates.
  2. Route SPI Lines: Connect D11, D12, D13, and D10 to the MAX31855. Keep these wires under 15 cm (6 inches) long. SPI is highly susceptible to capacitive coupling; long jumper wires will cause bit-shift errors in the thermocouple readings.
  3. Connect I2C Display: Wire A4 and A5 to the OLED. Ensure the OLED has 4.7kΩ pull-up resistors on the SDA and SCL lines (most Adafruit and generic SSD1306 modules include these onboard).
  4. Wire the SSR Control: Connect D3 to the positive input of the Fotek SSR-25DA. Connect the negative input to GND. Do not connect the AC load side yet.

Complete Compilable PID Control Code

The most common mistake in Arduino heater builds is using analogWrite() to drive a zero-cross AC Solid State Relay. A standard SSR-25DA expects a steady DC voltage (3-32V) to latch the internal triac until the AC waveform crosses zero. Feeding it a 490Hz PWM signal from analogWrite() will cause the SSR to chatter, overheat, and fail catastrophically.

The correct method is time-proportioning. We define a time window (e.g., 2000ms) and use the PID output to determine what percentage of that window the SSR stays ON. The code below targets the Arduino Nano Every and implements this safely.

#include <SPI.h>
#include <Adafruit_MAX31855.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <PID_v1.h>

// --- PIN DEFINITIONS ---
#define MAXCS   10
#define SSR_PIN 3

// --- DISPLAY DEFINITIONS ---
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// --- SENSOR INITIALIZATION ---
Adafruit_MAX31855 thermocouple(MAXCS);

// --- PID VARIABLES ---
double Setpoint, Input, Output;
// Aggressive tuning parameters for a fast-heating low-mass element
// Adjust Kp, Ki, Kd based on your specific thermal mass
double Kp = 400, Ki = 5, Kd = 100;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

// --- TIME PROPORTIONING VARIABLES ---
int WindowSize = 2000; // 2 second window for AC zero-cross SSR
unsigned long windowStartTime;

void setup() {
  Serial.begin(115200);
  
  // Initialize OLED
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Halt on display failure
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);

  // Initialize MAX31855
  delay(500); // Wait for MAX31855 to stabilize
  
  // Initialize PID
  Setpoint = 200.0; // Target 200°C
  myPID.SetOutputLimits(0, WindowSize);
  myPID.SetMode(AUTOMATIC);
  
  windowStartTime = millis();
  
  // Set SSR pin as digital output, NOT PWM
  pinMode(SSR_PIN, OUTPUT);
  digitalWrite(SSR_PIN, LOW);
}

void loop() {
  // 1. Read Temperature with Error Handling
  double temp = thermocouple.readCelsius();
  
  // Check for MAX31855 specific fault codes
  uint8_t error = thermocouple.readError();
  if (isnan(temp) || error != 0) {
    handleSensorError(error);
    digitalWrite(SSR_PIN, LOW); // Fail-safe: kill heat on sensor error
    return;
  }
  
  Input = temp;
  myPID.Compute();

  // 2. Time-Proportioning Output for SSR
  unsigned long now = millis();
  if (now - windowStartTime > WindowSize) {
    windowStartTime += WindowSize;
  }
  
  if (Output > (now - windowStartTime)) {
    digitalWrite(SSR_PIN, HIGH);
  } else {
    digitalWrite(SSR_PIN, LOW);
  }

  // 3. Update Display and Serial (Throttled to 4Hz)
  static unsigned long lastDisplay = 0;
  if (millis() - lastDisplay > 250) {
    lastDisplay = millis();
    updateDisplay(temp, Output);
  }
}

void handleSensorError(uint8_t error) {
  Serial.print("MAX31855 Error: ");
  if (error & 0x01) Serial.print("OC ");  // Open Circuit
  if (error & 0x02) Serial.print("SCG "); // Short to GND
  if (error & 0x04) Serial.print("SCV "); // Short to VCC
  Serial.println();
  
  display.clearDisplay();
  display.setCursor(0,0);
  display.println("SENSOR FAULT!");
  display.println("HEATER DISABLED");
  display.display();
}

void updateDisplay(double temp, double out) {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print("Temp: "); display.print(temp, 1); display.println(" C");
  display.print("Targ: "); display.print(Setpoint, 1); display.println(" C");
  display.print("PID Out: "); display.print((out/WindowSize)*100, 0); display.println(" %");
  display.display();
}

Debugging: First Three Things to Check When It Fails

When a closed-loop thermal system misbehaves, the issue is rarely the math; it is almost always the physical interface. If your system fails to heat or throws faults, check these three items in order.

1. The Exact Error String: "MAX31855 Error: OC"

If the Serial Monitor outputs MAX31855 Error: OC (Open Circuit), the amplifier cannot detect the thermocouple junction. The Fix: Check the polarity of the Type-K thermocouple. The red wire is negative (alumel), and the yellow wire is positive (chromel). The Adafruit MAX31855 breakout silkscreen marks the positive terminal. Reversing these will cause erratic negative readings or an OC fault. Also, verify that the thermocouple plug is fully seated; a loose ceramic bead will break the microvolt signal path.

2. SSR Chatter or Failure to Trigger

If the red LED on the Fotek SSR-25DA flickers rapidly but the AC load never powers on, you are likely feeding it a high-frequency PWM signal from a misguided analogWrite() implementation, or the Nano Every's 5V output is sagging below the SSR's 3V minimum trigger threshold under load. The Fix: Measure the DC voltage across the SSR input terminals with a multimeter while the system calls for heat. It must read a steady ~4.8V to 5.0V. If it reads lower, check your breadboard power rails for high resistance. Ensure the code uses the time-proportioning digitalWrite() logic provided above.

3. I2C Display Hanging the Loop

If the system heats correctly but the OLED freezes, or the Nano Every reboots randomly, the I2C bus is likely experiencing noise-induced lockups. The high dV/dt switching of the SSR can inject noise into the 5V rail. The Fix: Add a 100µF electrolytic capacitor and a 0.1µF ceramic capacitor in parallel across the 5V and GND rails directly adjacent to the OLED module. This local decoupling absorbs the high-frequency switching noise before it corrupts the I2C SDA/SCL lines.

Extending or Simplifying the Build

Depending on your bench requirements, you may need to scale this circuit diagram with Arduino up or down.

Simplify: Drop the I2C OLED

If you are building a permanent enclosure where the display isn't needed, remove the SSD1306. Instead, format the serial output for the Arduino IDE Serial Plotter. Change the serial print to output comma-separated values: Serial.print(Input); Serial.print(","); Serial.println(Setpoint);. This gives you real-time PID tuning visualization without the I2C overhead or wiring complexity.

Extend: Add MQTT Telemetry

To log thermal profiles over WiFi, swap the Nano Every for an ESP32-WROOM-32. The SPI and I2C pin mappings will change (ESP32 default SPI is D19/D23/D18/D5), but the time-proportioning logic remains identical. Use the PubSubClient library to publish the Input and Output variables to an MQTT broker like Mosquitto every 5 seconds for long-term thermal profiling.

Mains Safety and Wiring Caveats

CRITICAL SAFETY WARNING: The output side of the SSR-25DA switches lethal mains voltage (120V/240V AC).
  • Never wire or troubleshoot the AC load side while the system is energized. De-energize the breaker and verify dead with a tested CAT III multimeter.
  • The SSR-25DA is a zero-cross relay. It does NOT provide galvanic isolation from the mains if the internal triac fails shorted. Always install a mechanical toggle switch or a rated circuit breaker in series with the AC hot line to physically disconnect the heating element.
  • Mount the SSR to a proper aluminum heatsink with thermal paste. Even at 10A, the internal voltage drop (~1.6V) generates 16W of heat, which will destroy a plastic-mounted SSR in minutes without active dissipation.

NEC-style guidance: Ensure all mains wiring uses appropriate gauge wire (e.g., 14 AWG for 15A circuits) and is housed in a grounded, fire-retardant enclosure. Your local AHJ has final authority on permanent installations.

By respecting the separation of logic and power, utilizing hardware SPI, and implementing software time-proportioning, this circuit diagram with Arduino Nano Every provides a foundation for laboratory-grade thermal control that will outlast mechanical relay setups by orders of magnitude.