|

Arduino AI-Powered Mystery Lock (Arduino Nano ESP32 + OpenAI + Arduino IoT Cloud)

Overview

AI and Arduino are combined to create a quiz-to-unlock smart lock. OpenAI generates a short question and validates the reply; the Arduino Nano ESP32 controls a 12 V solenoid via MOSFET/relay and updates an Arduino IoT Cloud dashboard. Correct answer → brief unlock. Wrong answer → buzzer pattern and reset. Hardware remains minimal; intelligence is provided by the AI layer.

Components needed

  • Arduino Nano ESP32
  • 12 V solenoid door lock + 9–12 V DC supply
  • N-MOSFET (logic-level) or relay module + flyback diode (e.g., 1N4007)
  • Buzzer (active or transistor-driven)
  • Common GND between 12 V rail and Nano ESP32

Circuit

The hardware stays simple so we can focus on the AI control layer. A 12 V solenoid lock is driven via MOSFET or relay with a flyback diode across the coil. The Arduino Nano ESP32 handles Wi-Fi and secure HTTPS calls to the OpenAI API. We keep a common ground between the 12 V supply and the microcontroller. Pin mapping is identical to my earlier project: D5 → Lock, D6 → Buzzer. If your relay board is active-LOW, invert the logic in code. Add a hidden manual override if you like. The point is: hardware stays familiar; the intelligence comes from AI.

  • Solenoid → MOSFET drain (or relay NO), source → GND, diode across solenoid (cathode to +12 V).
  • Use a separate 12 V supply for the lock; share ground with the Nano ESP32.
  • Some relay boards are active-LOW; invert logic in firmware if required.
  • Optional manual override switch recommended.

You can either connect the lock to the MOSFET or the Relay which can be turned on and off programmatically. I decide to connect the Lock to the MOSFET so that I can connect some other device like a bulb or something to the relay. You can use the other switch to connect any additional devices like a lamp or a motor to open the door.

This is just my design, Like I said earlier, I will provide the schematics in the description so that you can redesign the entire thing, customize it and then make your own version of it. Or you can make my version as such. Whatever you do, first thing is to try it out on a breadboard. Once you are getting the output, then you can use it as such or make your PCB.

Arduino IoT Cloud Setup

  1. Thing variables
    • initiate (bool, Read/Write) – triggers question generation
    • question (String, Read-only) – displays the prompt
    • answer (String, Read/Write) – user reply
    • sendAnswer (bool, Read/Write) – submits reply
    • lockStatus (bool, Read-only) – true while unlocked pulse is active
  2. Secrets
    • OPENAI_API_KEY, Wi-Fi credentials (store in Secrets; avoid hard-coding).
  3. Associated Device
    • Select Arduino Nano ESP32 and confirm a COM port (esptool uploads).

Dashboard (Widgets & Layout)

  • Button (momentary)initiate (label: Initiate)
  • Value/Label (large)question (label: Question)
  • Text Inputanswer (placeholder: Type answer…)
  • Button (momentary)sendAnswer (label: Send Answer)
  • Status/LED (read-only)lockStatus (True = UNLOCKED, False = LOCKED)

Recommended order: Initiate → Question → Answer → Send Answer → Lock Status. Mobile control available via Arduino IoT Remote.

Firmware Flow (AI-first)

  1. Generate: pressing initiate calls OpenAI to return {question, answer}. The canonical answer is cached in firmware (not editable from UI).
  2. Validate: pressing sendAnswer calls OpenAI with {question, answer_canonical, user_answer}; model returns {is_correct}.
  3. Actuate:
    • Correct → show welcome message, set lockStatus = true, drive D5 HIGH for UNLOCK_MS, then LOW, set lockStatus = false, reset UI.
    • Wrong → buzzer triple-beep pattern on D6, brief notice, reset UI.
  4. UI sync: ArduinoCloud.update() is called right after status/message changes so the dashboard mirrors hardware state.

Function Summary

The sketch pulls Arduino IoT Cloud variables from thingProperties.h, includes Wi-Fi/HTTPS and ArduinoJson, defines BUZZ, LOCK_PIN, and UNLOCK_MS, then declares a global canonicalAnswer plus two helpers: resetUI() (sets the dashboard back to “Press Initiate…”, clears answer/canonicalAnswer, and pushes an ArduinoCloud.update()), and buzzErrorPattern() (triple-beep pattern on the buzzer).

It sets OpenAI endpoint/key, forward-declares OpenAI functions, and in setup() opens Serial, configures the lock/buzzer pins, starts Arduino Cloud, and initializes the UI (lockStatus=false, prompt text). The loop() just calls ArduinoCloud.update(). When initiate flips, onInitiateChange() auto-resets the button, forces the lock LOW (locked), clears UI state, calls openaiGenerateQuestion() to fetch {question, answer}, shows the question, and caches the canonical answer. onSendAnswerChange() auto-resets its button, sanity-checks that a question/answer exist, calls openaiValidateAnswer(), and on success displays a welcome message, sets lockStatus=true, pushes an update, energizes the strike (digitalWrite(LOCK_PIN, HIGH) for UNLOCK_MS), relocks, sets lockStatus=false, updates again, and resetUI(); on failure it plays the buzzer pattern, shows a brief “Wrong answer” message, updates, delays, then resetUI().

The OpenAI helpers build strict JSON chat payloads (buildGeneratePayload() returns {question,answer}; buildValidatePayload() asks for {is_correct}) using model gpt-4o-mini with response_format: json_object; openaiGenerateQuestion()/openaiValidateAnswer() POST via httpPostJson(), parse the outer Chat Completions response (choices[0].message.content) as JSON, and extract fields; httpPostJson() uses WiFiClientSecure (insecure for quick start), adds Authorization: Bearer <SECRET_OPENAI_API_KEY>, handles HTTP errors, and returns the response body.

  • onInitiateChange(): keeps lock closed, clears UI, requests a new AI question, displays it.
  • onSendAnswerChange(): validates the reply with AI; on success unlocks briefly, on failure plays buzzer and resets.
  • resetUI(): restores default prompt and clears fields.
  • buzzErrorPattern(): two groups of quick triple-beeps (active buzzer) or tone sequence (passive).
  • OpenAI helpers: one builds/POSTs the generate payload and parses {question, answer}; the other builds/POSTs the validate payload and parses {is_correct}.
  • httpPostJson(): HTTPS POST with bearer key using WiFiClientSecure and HTTPClient.

Testing Procedure

  1. Power the 12 V rail; confirm common ground with Nano ESP32.
  2. Open dashboard; press Initiate; verify a question appears.
  3. Enter a wrong reply; confirm buzzer pattern and UI reset.
  4. Enter the correct reply; confirm lock click (D5 HIGH), lockStatus = true during pulse, then reset.

Customization

  • Question theme: math, general knowledge, or franchise topics.
  • Difficulty/category: add dashboard dropdown and include in prompts.
  • Cooldowns/limits: lock out after repeated failures.
  • Attempt log: append short history to a String variable.
  • Security hardening: optional backend to issue HMAC-signed unlock tokens to the device.

Troubleshooting

  • Buzzer works, lock silent → verify D5 = Lock, 12 V supply present, diode orientation, common GND, relay active-LOW behavior.
  • Dashboard stuck → ensure ArduinoCloud.update() after status/text changes.
  • Upload issues on Windows → confirm Nano ESP32 appears as COM port (esptool), not Arduino DFU.

Notes

This build demonstrates AI + Arduino integration: OpenAI handles reasoning and validation, while the Nano ESP32 provides deterministic, reliable control of real-world hardware via the Arduino IoT Cloud dashboard.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *