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.
Pin Mapping Table
| Nano Every Pin | Module | Function | Wire Color Std |
|---|---|---|---|
| 5V | MAX31855 / OLED / SSR+ | VCC / VIN | Red |
| GND | All Modules | Common Ground | Black |
| D11 (COPI) | MAX31855 (SDO) | SPI Data Out | Blue |
| D12 (CIPO) | MAX31855 (SDI) | SPI Data In | Purple |
| D13 (SCK) | MAX31855 (SCK) | SPI Clock | Orange |
| D10 | MAX31855 (CS) | Chip Select (Active LOW) | Yellow |
| A4 (SDA) | OLED (SDA) | I2C Data | Green |
| A5 (SCL) | OLED (SCL) | I2C Clock | White |
| D3 | SSR-25DA (+) | Time-Proportioned PWM Out | Brown |
Wiring Execution Steps
- 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.
- 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.
- 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).
- 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
- 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.






