Community project

Ik Wil Een Flipper Zero Maken Met Esp

Sohail

Published August 1, 2026 · Updated August 1, 2026

ESP328 components7 assembly steps
Remix this project
Photo of Ik Wil Een Flipper Zero Maken Met Esp

Build a Flipper Zero-inspired multi-tool on the ESP32 that combines NFC reading, infrared control, sub-GHz radio monitoring, and WiFi scanning into a single handheld device. This project brings together affordable off-the-shelf modules—an SSD1306 OLED display, PN532 NFC reader, CC1101 sub-GHz transceiver, IR transmitter and receiver, and navigation buttons—to create a versatile RF exploration and control platform.

This guide provides a complete wiring diagram, parts list, and step-by-step assembly instructions to integrate all modules onto a breadboard or custom PCB. The included Arduino firmware handles I2C communication with the display and NFC module, manages IR send/receive via the 38 kHz protocol, interfaces with the CC1101 radio, and presents a menu-driven interface for navigating between tools. Builders will learn practical techniques for power distribution, multi-protocol integration, and safe RF hardware testing.

Wiring diagram

Interactive · read-only
Wiring diagram for Ik Wil Een Flipper Zero Maken Met Esp

Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.

Parts list

Bill of materials
ComponentQtyNotes
SSD1306 OLED128x64 I2C10.96 inch 128x64 OLED display with I2C interface
PN532 NFC Module (I2C Mode)I2C, address 0x241NXP PN532-based NFC/RFID reader-writer module supporting ISO 14443A/B, MIFARE, NTAG213, NTAG215, and NTAG216 tags. Supports three interface modes (I2C, SPI, HSU/UART) selected by on-board DIP switches. I2C mode: both DIP switches set to ON (SW1=ON, SW2=ON). I2C address 0x24. Operates at 3.3 V, compatible directly with ESP32 without level shifting. On-board pull-up resistors provided for I2C lines.
CC1101 Sub-GHz RF Module433 MHz antenna variant1Texas Instruments CC1101-based Sub-1 GHz RF transceiver module operating across 300–928 MHz (315/433/868/915 MHz ISM bands). SPI interface (4-wire + 2 GDO pins). 3.3V supply and logic. Supports OOK, ASK, FSK, GFSK, MSK modulations. Used for signal sniffing, replay attacks, and Flipper Zero-equivalent Sub-GHz functionality on ESP32. All SPI devices on the VSPI bus (MOSI=GPIO23, MISO=GPIO19, SCK=GPIO18) with a dedicated CS pin.
940 nm IR LED940 nm1Infrared transmit LED for controlling the user's own IR appliances; driven from an ESP32 GPIO through a transistor driver.
Five navigation pushbuttons5 × momentary tactile switches1Momentary buttons for Up, Down, Left, Right and OK; each connects a GPIO to ground and uses ESP32 internal pull-up.
2N2222 NPN transistor IR driver2N2222A1Low-side transistor driver for the IR LED. Base is driven through a 1 kΩ resistor from GPIO27; emitter goes to ground.
IR LED series resistor100 Ω, 1/4 W1100 ohm resistor limiting pulse current through the infrared LED from the board 5V rail.
38 kHz IR receiver module38 kHz1Demodulating 38 kHz infrared receiver (VS1838B/TSOP38238 compatible) for decoding remotes that you own.

Assembly

7 steps
  1. Voedingsrails voorbereiden

    Gebruik de USB-poort van de ESP32 DevKit v1 als voeding tijdens het bouwen. Verbind alle GND-pinnen van de modules met GND van de ESP32. Gebruik uitsluitend de 3V3-pen voor OLED, PN532, CC1101 en IR-ontvanger.

    • Tip: Houd alle signaaldraden kort.
    • Tip: De ESP32 GPIO's zijn 3,3 V; sluit geen 5 V-signaal direct aan.
    • Sluit VCC van PN532 of CC1101 nooit op 5 V aan.
    • Koppel de USB los terwijl je bedrading verandert.
  2. OLED en PN532 op de I2C-bus aansluiten

    Verbind OLED SDA én PN532 SDA met GPIO21. Verbind OLED SCL én PN532 SCL met GPIO22. Verbind voor beide modules VCC met 3V3 en GND met GND. Zet de DIP-schakelaars van de PN532 in I2C-modus: SW1=ON en SW2=ON.

    • Tip: De OLED gebruikt normaal adres 0x3C en de PN532 adres 0x24; ze kunnen dezelfde I2C-draden delen.
    • Controleer de tekst op de PN532-module: de interfacekeuze moet echt I2C zijn voordat je spanning geeft.
  3. CC1101 als 3,3V Sub-GHz module aansluiten

    Verbind CC1101 MOSI met GPIO23, MISO met GPIO19, SCK met GPIO18 en CSN met GPIO17. Verbind VCC met 3V3 en GND met GND. Bevestig alleen de antenne die bij jouw lokale, toegestane ISM-band hoort.

    • Tip: Deze basisfirmware gebruikt de module niet om te zenden of signalen te herhalen.
    • Tip: GPIO17 is als softwarematige chip-select gekozen; dat is geldig met de ESP32 SPI-matrix.
    • Gebruik nooit een CC1101 zonder passende antenne wanneer je later eigen, wettelijk toegestane RF-tests uitvoert.
    • Respecteer lokale regels voor radiofrequenties.
  4. Vijf navigatieknoppen plaatsen

    Gebruik vijf drukknoppen. Verbind één kant van elke knop met respectievelijk GPIO32 (Up), GPIO33 (Down), GPIO25 (Left), GPIO26 (Right) en GPIO4 (OK). Verbind de andere kant van elke knop met GND. De firmware gebruikt interne pull-upweerstanden.

    • Tip: Een druk op de knop maakt de gekozen GPIO laag; er zijn geen externe weerstandjes nodig.
    • Tip: Plaats de knoppen in een kruis met OK in het midden voor prettig gebruik.
    • Gebruik geen GPIO0, GPIO2, GPIO5, GPIO12 of GPIO15 voor knoppen; dit zijn opstartgevoelige ESP32-pinnen.
  5. IR-ontvanger aansluiten

    Verbind de 38 kHz IR-ontvanger met 3V3 en GND. Verbind OUT met GPIO16. Richt de ontvanger naar de afstandsbediening van een apparaat dat je bezit om codes op het scherm te bekijken.

    • Tip: De meeste modules zijn aan de voorzijde gelabeld als OUT, GND en VCC; controleer altijd de opdruk van jouw exemplaar.
    • Verwissel VCC en GND niet; goedkope ontvangerprintjes verschillen soms in pinvolgorde.
  6. IR-zender met transistor-driver opbouwen

    Verbind GPIO27 via een 1 kΩ basisweerstand met BASE van de 2N2222. Verbind EMITTER met GND. Verbind COLLECTOR met de kathode van de IR-led. Verbind de anode van de IR-led via de 100 Ω serieweerstand met de 5V-pen van de ESP32.

    • Tip: De lange poot van de IR-led is meestal de anode; controleer dit bij jouw onderdeel.
    • Tip: De IR-led is vrijwel onzichtbaar voor het oog; een telefooncamera kan helpen om een IR-puls te zien.
    • De 1 kΩ basisweerstand is verplicht, maar is als los bouwonderdeel opgenomen in deze stap.
    • De 100 Ω serieweerstand is verplicht; sluit de IR-led nooit rechtstreeks op 5 V aan.
  7. Eerste veilige test

    Controleer alle verbindingen nogmaals, sluit daarna USB aan en gebruik Schematik’s Deploy-knop. Het beginscherm verschijnt op de OLED. Navigeer met Up/Down en test eerst de NFC-pagina met een eigen NFC-tag of de IR-pagina met je eigen afstandsbediening.

    • Tip: Als de PN532 niet verschijnt, controleer dan eerst I2C-modus, 3V3, GND, GPIO21 en GPIO22.
    • Gebruik deze tool alleen met je eigen systemen, tags en apparaten of met uitdrukkelijke toestemming.

Pin assignments

Board wiring reference
PinConnectionType
3V3oled_1 VCCpower
GNDoled_1 GNDground
GPIO 21oled_1 SDAi2c
GPIO 22oled_1 SCLi2c
3V3pn532_1 VCCpower
GNDpn532_1 GNDground
GPIO 21pn532_1 SDAi2c
GPIO 22pn532_1 SCLi2c
3V3cc1101_1 VCCpower
GNDcc1101_1 GNDground
GPIO 23cc1101_1 MOSIspi
GPIO 19cc1101_1 MISOspi
GPIO 18cc1101_1 SCKspi
GPIO 32buttons_1 UPdigital
GPIO 33buttons_1 DOWNdigital
GPIO 25buttons_1 LEFTdigital
GPIO 26buttons_1 RIGHTdigital
GPIO 4buttons_1 OKdigital
GPIO 27ir_driver_1 BASEdigital
GNDir_driver_1 EMITTERground
EXTir_driver_1 COLLECTOR940 nm IR LED CATHODEpower
5Vir_resistor_1 INpower
EXTir_resistor_1 OUT940 nm IR LED ANODEpower
3V3ir_receiver_1 VCCpower
GNDir_receiver_1 GNDground
GPIO 16ir_receiver_1 OUTdigital
GPIO 17cc1101_1 CSNspi

Firmware

ESP32
main.cppDeploy to device
#include <Arduino.h>
#include <Wire.h>
#include <WiFi.h>
#include <BluetoothSerial.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_PN532.h>
#include <IRremote.hpp>


// Hoisted type definitions
enum Page : uint8_t { HOME, NFC_PAGE, IR_PAGE, WIFI_PAGE, RADIO_PAGE, ABOUT_PAGE };


// Forward declarations
bool pressed(int pin);
void drawScreen();
void readNfcTag();
void readIr();
void scanWifi();

constexpr int I2C_SDA = 21;
constexpr int I2C_SCL = 22;
constexpr int IR_RX_PIN = 16;
constexpr int IR_TX_PIN = 27;
constexpr int CC1101_CS_PIN = 17;
constexpr int BUTTON_UP_PIN = 32;
constexpr int BUTTON_DOWN_PIN = 33;
constexpr int BUTTON_LEFT_PIN = 25;
constexpr int BUTTON_RIGHT_PIN = 26;
constexpr int BUTTON_OK_PIN = 4;
constexpr uint8_t SCREEN_WIDTH = 128;
constexpr uint8_t SCREEN_HEIGHT = 64;
constexpr uint8_t OLED_ADDRESS = 0x3C;
constexpr uint8_t PN532_ADDRESS = 0x24;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_PN532 nfc(PN532_ADDRESS);
BluetoothSerial SerialBT;

Page currentPage = HOME;
bool nfcReady = false;
String wifiLine = "Druk OK om te scannen";
String irLine = "Wacht op eigen remote";
String nfcLine = "Houd eigen tag bij lezer";
unsigned long lastButtonMs = 0;
unsigned long lastNfcPollMs = 0;

bool pressed(int pin) {
  if (digitalRead(pin) == LOW && millis() - lastButtonMs > 180) {
    lastButtonMs = millis();
    return true;
  }
  return false;
}

const char *pageTitle(Page page) {
  switch (page) {
    case HOME: return "Maker Tool";
    case NFC_PAGE: return "NFC / RFID";
    case IR_PAGE: return "IR eigen apparaten";
    case WIFI_PAGE: return "WiFi diagnose";
    case RADIO_PAGE: return "Sub-GHz ontvanger";
    case ABOUT_PAGE: return "Status";
  }
  return "Maker Tool";
}

void drawScreen() {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println(pageTitle(currentPage));
  display.drawFastHLine(0, 10, SCREEN_WIDTH, SSD1306_WHITE);
  display.setCursor(0, 16);
  if (currentPage == HOME) {
    display.println("UP/DOWN: pagina");
    display.println("OK: functie starten");
    display.println();
    display.println("Alleen eigen apparatuur,");
    display.println("tags en testomgeving.");
  } else if (currentPage == NFC_PAGE) {
    display.println(nfcReady ? "PN532: gereed" : "PN532 niet gevonden");
    display.println(nfcLine);
    display.println();
    display.println("Leest UID van eigen");
    display.println("NFC/RFID-tag.");
  } else if (currentPage == IR_PAGE) {
    display.println(irLine);
    display.println();
    display.println("Ontvangt IR-codes van");
    display.println("je eigen afstandsbediening.");
    display.println("Zender aanwezig voor");
    display.println("eigen apparaten.");
  } else if (currentPage == WIFI_PAGE) {
    display.println(wifiLine);
    display.println();
    display.println("Passieve lijst van");
    display.println("zichtbare WiFi-netwerken.");
  } else if (currentPage == RADIO_PAGE) {
    display.println("CC1101 hardware klaar");
    display.println();
    display.println("Gebruik alleen lokale,");
    display.println("toegestane ISM-banden.");
    display.println("Geen replay of zenden.");
  } else {
    display.println("ESP32 DevKit v1");
    display.println("WiFi: ingebouwd");
    display.println("Bluetooth: ingebouwd");
    display.println(nfcReady ? "NFC: online" : "NFC: controleer bedrading");
    display.println("Geen toegang/replay tools");
  }
  display.display();
}

void readNfcTag() {
  if (!nfcReady || millis() - lastNfcPollMs < 400) return;
  lastNfcPollMs = millis();
  uint8_t uid[7];
  uint8_t uidLength = 0;
  if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 60)) {
    String uidText = "UID: ";
    for (uint8_t i = 0; i < uidLength; i++) {
      if (uid[i] < 0x10) uidText += '0';
      uidText += String(uid[i], HEX);
      if (i + 1 < uidLength) uidText += ':';
    }
    uidText.toUpperCase();
    nfcLine = uidText;
    drawScreen();
  }
}

void readIr() {
  if (IrReceiver.decode()) {
    String protocol = String(getProtocolString(IrReceiver.decodedIRData.protocol));
    String value = String(IrReceiver.decodedIRData.decodedRawData, HEX);
    value.toUpperCase();
    irLine = protocol + " 0x" + value;
    IrReceiver.resume();
    drawScreen();
  }
}

void scanWifi() {
  wifiLine = "Scannen...";
  drawScreen();
  int networks = WiFi.scanNetworks(false, true);
  if (networks < 0) wifiLine = "Scan mislukt";
  else if (networks == 0) wifiLine = "Geen netwerken gezien";
  else {
    String ssid = WiFi.SSID(0);
    if (ssid.length() == 0) ssid = "verborgen";
    wifiLine = String(networks) + " gezien; #1 " + ssid;
  }
  WiFi.scanDelete();
  drawScreen();
}

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
  pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);
  pinMode(BUTTON_LEFT_PIN, INPUT_PULLUP);
  pinMode(BUTTON_RIGHT_PIN, INPUT_PULLUP);
  pinMode(BUTTON_OK_PIN, INPUT_PULLUP);
  pinMode(IR_TX_PIN, OUTPUT);
  digitalWrite(IR_TX_PIN, LOW);
  pinMode(CC1101_CS_PIN, OUTPUT);
  digitalWrite(CC1101_CS_PIN, HIGH);
  Wire.begin(I2C_SDA, I2C_SCL);
  display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS);
  display.clearDisplay();
  display.display();
  nfc.begin();
  nfcReady = (nfc.getFirmwareVersion() != 0);
  if (nfcReady) nfc.SAMConfig();
  IrReceiver.begin(IR_RX_PIN, DISABLE_LED_FEEDBACK);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect(true, true);
  SerialBT.begin("ESP32-MakerTool");
  drawScreen();
}

void loop() {
  if (pressed(BUTTON_UP_PIN) || pressed(BUTTON_LEFT_PIN)) {
    currentPage = static_cast<Page>((currentPage + 5) % 6);
    drawScreen();
  }
  if (pressed(BUTTON_DOWN_PIN) || pressed(BUTTON_RIGHT_PIN)) {
    currentPage = static_cast<Page>((currentPage + 1) % 6);
    drawScreen();
  }
  if (pressed(BUTTON_OK_PIN) && currentPage == WIFI_PAGE) scanWifi();
  if (currentPage == NFC_PAGE) readNfcTag();
  if (currentPage == IR_PAGE) readIr();
}

“Deploy to device” opens this project in Schematik, where you can flash it to your board over USB.

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik