ESP8266 Mobile Rick Roll Captive Portal

A fun project to Rick Roll friends or strangers wirelessly.

Similar projects worth following
The purpose of this project was to help me get familiar with programming for the ESP8266 and have a bit of fun.

* User connects to the device broadcasting an SSID of "FREE Highspeed WiFi" (this is configurable of course)
* The captive portal helper on their phone/table/computer kicks in and presents them with a page showing "Terms of Service" and a button labeled "I Accept"
* When they click the button a full screen animated GIF of Rick Astley dancing appears and an audio clip of "Never Gonna Give You Up" starts playing on loop along with a message in the bottom right letting them know they got Rick Rolled (Incase they don't understand what's going on)

On bootup, the buzzer plays a little bit of "Never Gonna Give You Up". To access the console, connect to the ESP8266 Access Point and browse to "" (default user/pass is admin/password). From here you can monitor all connections and see when someone gets Rick Roll'd by the device. The console also allows you to enter commands to get more info about the status of the device, change the SSID, get the Rick Roll count, beep the buzzer and lots more.

The "debug" setting is on by default and shows you all DNS and HTTP requests made to the device. It's kind of cool to see all the sites that the apps on your phone are trying to access. Check out the screenshots of the console for a glimpse of what it looks like. Some apps are very noisy. You can toggle the "debug" off to not see that stuff.

  • 1 × WeMos D1 Mini (ESP8266 ESP-12F)
  • 1 × Piezo Buzzer
  • 1 × USB Battery Pack
  • 1 × Micro-USB Cable

  • IP Intialization & SSID Change

    jaime03/28/2017 at 22:43 0 comments

    • Fixed issue when initializing and setting up the IP Address
    • Fixed issue changing SSID from the console
      - It would change it in the configuration and save it but it would not make it active
    • Updated some deprecated calls with the JSON object

  • Autoscan fixed

    jaime01/24/2017 at 07:56 0 comments

    • Fixed autoscan function. It wasn’t actually changing to least used channel.
    • Enhanced autoscan function. It now does multiple scans (3) to detect more access points before determining least used channel.
    • Added callback to display wifi events connects/disconnects.
    • Stubbed up functions to disconnectStationByIP and disconnectStationByMAC for future use.

  • Over engineered for your enjoyment!

    jaime08/25/2016 at 02:33 4 comments

    Ok... I just merged the Enhanced Console branch to master. The console still needs some work but I wanted to get all of these new features out. Here is a list of what is in this update.

    • Added EEPROM saving of settings and RR count
    • Added a "reset" command to the console to reset the EEPROM
    • Modified "count" command to accept an argument to manually set the count
    • Added "silent" command to toggle the buzzer audio on or off
    • Added "eeprom" command to show the contents of the EEPROM
    • Added 'version' variable to use to determine when to upgrade EEPROM values
    • Change to build flags to fix "invalid cast from type 'IPAddress' to type 'u8_t* {aka unsigned char*}'" error.
    • FIX: Rick Rolling a device that doesn't return a "User-Agent" header was causing a crash.
    • Implemented Basic Authentication for /console & /console.htm
      (Default user/pass is admin/password)
    • Implemented Progress bar in console on OTA Update
    • Added ability to override IP based on domain during DNS Query
    • Modified getDomainNameWithoutWwwPrefix to get with or without WWW prefix
    • Added onOverride callback to DNS Server
    • Implemented Password on OTA Update (Same password as console)
    • Now scans available networks to determine least used channel and uses that channel for AP Mode (accounts for overlapping side channels)
    • Added ability to show/set the Rick Roll message from the console
    • Optimized the console command logic
    • Added "user", "pass" and "save" commands to console
    • Tweaked Captive Portal Page a bit
    • Fixed a warning in the DNSServer.h file
    • Tweaked redirect code to fix Captive Portal helper popup on some Android devices
    • Added SVG version of main image on Captive Portal Page
    • Fixed "beep rr" command
    • Added "beepc n" command where 'n' is ms (more of a chirp than a beep)
    • Added extra_script ""
    • Moved DNSServer to lib folder and formatted with astyle
    • Added "chan" command to show/set WiFi channel manually (0 = Auto Select)
    • Added "int" command to show/set Automatic WiFi Scan to adjust channel
      When set the system will do a WiFi scan at the set interval and change the WiFi channel to what ever it determines will have the least interference
    • More tweaks to console. Separated files and added new setting fields.
    • When building the SPIFFS build it clones the 'www' to 'data' and gzips the appropriate files automatically to save space
    • Modified "" to add a file to the "data" folder explaining where to modify files instead
    • Changed "flash_speed" formatting when sending settings
    • More tweaks to the console
    • Added "info" page and set it to load when someone clicks on the RR Message
    • Automatically installs dependencies now
    • User can now click on Rick Roll message to get more info about what "Rick Rolling" actually is
    • Added "scan" command to console to display WiFi networks in area

  • "Enhanced Console" Branch

    jaime08/17/2016 at 16:38 0 comments

    I've been working on enhancing the console. It's not complete yet but it is shaping up. When it is done it will work better with iOS and Windows Mobile devices.

  • Crash Fixed and Automatic Install of Dependencies

    jaime08/17/2016 at 16:36 0 comments

    I discovered that some devices don't return a "User-Agent" header and that was causing the mobile-rr to crash. This has been corrected.

    Dependencies are automatically installed now thanks to the changes to "platformio.ini" by ivankravets.

  • *RESOLVED* Compile Error: invalid cast from type 'IPAddress' to type 'u8_t* {aka unsigned char*}'

    jaime08/10/2016 at 17:19 0 comments

    Source code has been updated. The last update to PlatformIO is causing a compile error. Changing the build_flags in "platformio.ini" corrects/works around the issue.

    build_flags = -ULWIP_OPEN_SRC -Wl,-Tesp8266.flash.4m.ld

  • More tweaks to the EEPROM and a few new console commands

    jaime07/31/2016 at 06:18 0 comments

    • Added more settings to the EEPROM functions
    • Modified "count" command to accept an argument to manually set the count
    • Added "silent" command to toggle the buzzer audio on or off
    • Added "restore" command to reinitialize the EEPROM
    • Added "eeprom" command to show the contents of the EEPROM
    • Added 'version' variable to use to determine when to upgrade EEPROM values

  • Settings saved to EEPROM

    jaime07/29/2016 at 23:06 0 comments

    I added functions to save some settings to EEPROM. (SSID, username, password, rrcount) They are reloaded on bootup. The username/password will be used in the future to secure the console and OTA update feature.

    The RR count is saved so can see session and total RR count in the console with the "count" command.

View all 8 project logs

  • 1
    Step 1


    Connect the '+' lead of the piezo to GPIO 4 (D2 on WeMos D1 Mini) and '-' lead to Ground. I chose GPIO 4 because I installed the long leads with the headers on the WeMos D1 Mini. The spacing from ground was perfect to just plug the buzzer in direct between G & D2.

  • 2
    Step 2

    Build Firmware

    I use PlatformIO to build this.

    • Install PlatformIO and let it update itself on first startup
    • Once updated and restarted, clone the "mobile-rr" project to a folder and open the project in PlatformIO
    • Next build the firmware by clicking the checkmark icon on the toolbar

  • 3
    Step 3

    Upload Firmware and SPIFFS data

    After your firmware build is successful you can upload it by clicking the arrow under the checkmark in the PlatformIO toolbar.

    You can add/edit the files in the "www" folder to your liking. (Files in the "www" folder will be cloned and gzipped to the "data" folder when building.) Then follow the instructions below to build and upload the SPIFFS file system image to your ESP8266.

    Note: Anytime you make changes to the firmware or the data you can rebuild and upload either without the need to install the other again. They reside in different areas of the flash memory.

    To save more space you can gzip the HTML, Javascript and CSS files in the data directory. Just make sure they have a .gz extension and they will be served up properly.

View all 3 instructions

Enjoy this project?



Gregory Benson wrote 05/30/2023 at 06:32 point

Hello! Giving this a try and it gave an error trying to build. The error seems to have pointed me to where it says "to Json" and "from Json" here: .pio/libdeps/d1_mini_pro/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp and pointed to advice would be really helpful! Thank you!

  Are you sure? yes | no

staceywhitmore wrote 04/17/2022 at 07:39 point

This doesn't explain the purpose of the Piezo Buzzer and why it's connected to one of the GPIO pins of the esp8266. Is it supposed to make a buzz noise whenever somebody pings it and attempts to connect?

  Are you sure? yes | no

jed wrote 04/16/2019 at 21:13 point

Just saw this and this is one time where LOL is exactly my reaction. "10 out of 10" as my granddaughter would say.

To respond to JustBeing - Do you want to know when you've hooked another fish?

  Are you sure? yes | no

justbeingkelton349 wrote 06/25/2018 at 05:17 point

do you need the busser?

  Are you sure? yes | no

TheWild Webster wrote 09/19/2017 at 02:33 point

Do you get a pop-up on android with your /generate_204  handler? I can't seem to get any of my server projects to redirect to the landing page I want or even pop up anything more than a message saying the connection is limited.

  Are you sure? yes | no

jaime wrote 11/20/2017 at 19:21 point

On some android devices it pops up like it is suppose to but on others I just get the notification that you're talking about.  I have not figured out what is required to make it pop up on every system. 

My Galaxy S5 only shows the notification when I connect to my ESP8266 but when I go to a restaurant that has free wifi their captive portal triggers the popup.  I have not been able to determine what is triggering it so I could implement it in this project.

Any help is greatly appreciated in figuring this issue out.  I have it posted in the github issues for feedback from others. 

  Are you sure? yes | no

Peter Berson wrote 07/30/2017 at 11:55 point has anyone been successful getting this to work on OS X mac sierra? I used mac ports to install scons and I am having trouble getting the script to see the Library. Is this essential to get this working? Is there another way to upload the files into the board? Any help would be greatly appreciated.

Thank you

  Are you sure? yes | no

jaime wrote 07/31/2017 at 08:16 point

Platform IO executes that before building the SPIFFS image.  It's not meant to be run directly.  It does some processing of the files in the "www" folder to save flash memory space and transfer the files faster when someone connects to the access point.

  Are you sure? yes | no

Peter Berson wrote 07/31/2017 at 17:20 point

Jamie, when I run via OS X terminal it complains about Scons.Script not found. It gives me an error on this line "from SCons.Script import DefaultEnvironment" I do not believe it will work from Platform IO but I will check out your updated version and see.

  Are you sure? yes | no

Peter Berson wrote 08/01/2017 at 02:33 point

Nevermind, after I used your latest file everything worked fine. Need to tweak the platformio.ini as I am using "ADAFRUIT FEATHER HUZZAH WITH ESP8266 WIFI" board I also lowered the baud rate to 115200. Great project.

  Are you sure? yes | no

jaime wrote 11/20/2017 at 19:22 point

Oh good.  Glad you were able to get it going.  :)

  Are you sure? yes | no

blinkingthing wrote 04/29/2017 at 17:02 point

I'm having trouble compiling this with platformIO. I've never used platformIO or Atom but I followed the discussion here and change the build flags in platormio.ini to "build_flags = -ULWIP_OPEN_SRC -Wl,-Tesp8266.flash.4m.ld". I still get the same error as I do before editing the build flags. Am I missing something obvious outside of saving platformio.ini after editing the build flags?

Error log: 

[04/29/17 10:01:12] Processing d1_mini (build_flags: -ULWIP_OPEN_SRC -Wl,-Tesp8266.flash.4m.ld; lib_deps: ArduinoJson, ESPAsyncTCP, ESPAsyncWebServer; board_f_cpu: 160000000
L; platform: espressif8266; upload_speed: 921600; board: d1_mini; framework: arduino; extra_script:; custom_option: "gz|css|js")
Detected non-PlatformIO `custom_option` option in `[env:]` section
Verbose mode can be enabled via `-v, --verbose` option
Converting mobile-rr.ino
Collected 27 compatible libraries
Looking for dependencies...
Library Dependency Graph
|-- v5.9.0
|-- v1.0.1
|   |-- v1.0
|   |-- v1.0.1
|   |   |-- v1.0
|   |-- v1.0
|   |-- v1.0
|   |-- v5.9.0
|   |-- v1.0
|   |-- v1.0
|-- v1.0
|-- v1.0
|-- v1.0
|   |-- v1.0
|   |--
|   |   |-- v1.0
|-- v1.0
|-- v1.0
Compiling .pioenvs\d1_mini\src\mobile-rr.ino.o
Archiving .pioenvs\d1_mini\lib\libESP8266WiFi.a
Compiling .pioenvs\d1_mini\lib\ESPAsyncTCP_ID305\ESPAsyncTCPbuffer.o
Compiling .pioenvs\d1_mini\lib\ESPAsyncTCP_ID305\SyncClient.o
Compiling .pioenvs\d1_mini\lib\ESPAsyncTCP_ID305\tcp_axtls.o
Compiling .pioenvs\d1_mini\lib\Hash\Hash.o
Compiling .pioenvs\d1_mini\lib\Hash\sha1\sha1.o
Compiling .pioenvs\d1_mini\lib\ESPAsyncWebServer_ID306\AsyncEventSource.o
Compiling .pioenvs\d1_mini\lib\ESPAsyncWebServer_ID306\AsyncWebSocket.o

In file included from C:\Users\where\.platformio\packages\framework-arduinoespressif8266\tools\sdk\include/user_interface.h:13:0,
from C:/Users/where/Documents/Projects/mobile-rr-master/src/mobile-rr.ino:49:
C:/Users/where/Documents/Projects/mobile-rr-master/src/mobile-rr.ino: In function 'void wifi_handle_event_cb(System_Event_t*)':
C:\Users\where\.platformio\packages\framework-arduinoespressif8266\tools\sdk\include/ip_addr.h:56:39: error: invalid operands of types 'ip_addr*' and 'int' to binary 'operat
#define IP2STR(addr) (uint8_t)(addr & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 24) & 0xFF)
C:/Users/where/Documents/Projects/mobile-rr-master/src/mobile-rr.ino:1072:22: note: in expansion of macro 'IP2STR'
IP2STR ( &evt->event_info.got_ip.ip ),
C:\Users\where\.platformio\packages\framework-arduinoespressif8266\tools\sdk\include/ip_addr.h:56:65: error: invalid operands of types 'ip_addr*' and 'int' to binary 'operat
#define IP2STR(addr) (uint8_t)(addr & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 24) & 0xFF)
C:/Users/where/Documents/Projects/mobile-rr-master/src/mobile-rr.ino:1072:22: note: in expansion of macro 'IP2STR'
IP2STR ( &evt->event_info.got_ip.ip ),
C:\Users\where\.platformio\packages\framework-arduinoespressif8266\tools\sdk\include/ip_addr.h:56:96: error: invalid operands of types 'ip_addr*' and 'int' to binary 'operat

It continues.....

  Are you sure? yes | no

jaime wrote 05/16/2017 at 01:25 point

I modified the code and removed the need for that build flag in the latest code.  Have you made sure that platformio is totally up to date as well as the platformio libraries?

Open a terminal window in PlatformIO (icon on sidebar) and use the following two commands.

pio update

pio lib update

  Are you sure? yes | no

Guus van Marle wrote 03/24/2017 at 15:31 point

can I change the code so it will automaticly rick roll you when you connect so you don't have to press "I Accept"?

  Are you sure? yes | no

jaime wrote 03/28/2017 at 22:45 point

You need some kind of interaction from the user on a mobile device to make an MP3 play.  The "I Accept" button is that interaction.  If you just want the animated GIF then you can edit the html to do that.

  Are you sure? yes | no

Guus van Marle wrote 03/22/2017 at 20:28 point

Can I upload it with the arduino IDE? and when i try do do it whit platformio I don't get the side bar whit the check mark.

  Are you sure? yes | no

jaime wrote 03/22/2017 at 21:33 point

It is possible but these instructions do not apply to Arduino IDE.

Part of the reason for this project was to learn to use PlatformIO.

  Are you sure? yes | no

Guus van Marle wrote 03/23/2017 at 06:00 point

Never mind i got it working with the arduino IDE. Thank you very very much for making this.

  Are you sure? yes | no

justbeingkelton349 wrote 06/25/2018 at 05:38 point

hey i cant figure out how to do it can you please tell me 

  Are you sure? yes | no

Dennis wrote 03/09/2017 at 13:48 point

Another issue that I experience is that I can change the ssid via the console (and it is retained), however, the actual ssid that is broadcasted is still the original ssid... 

My board is an AI-Thinker ESP8266MOD as D1 mini.

  Are you sure? yes | no

jaime wrote 03/21/2017 at 23:41 point

Sorry so slow to reply.  I've posted a modification to fix that.
I changed the way it used to work and meant to finish fixing it after I corrected the problem with changing channels automatically.

  Are you sure? yes | no

Dennis wrote 03/08/2017 at 15:52 point

I have an issue with the ip address that the ESP8266 hands out. It will assign the ip address range and not the that is mentioned in the description.

Edit 9-3-2017: I've changed all references to and that works now.

  Are you sure? yes | no

jaime wrote 03/21/2017 at 23:41 point

Not sure why that was an issue for you but glad you got it working.  :)

  Are you sure? yes | no

jaime wrote 03/28/2017 at 22:46 point

Found the issue and it seems to be fixed now.  Thanks for letting me know about the issue.

  Are you sure? yes | no

hypersonic5000 wrote 01/07/2017 at 02:53 point

Hey, I got this to work but I keep getting errors on my browser (Chrome in case that matters) the error is "ERR_TOO_MANY_REDIRECTS". I have cleared all my cookies but that doesn't fix it so I was wondering if there are any fixes in the code of the device? thanks.

  Are you sure? yes | no

sp33dsk8 wrote 01/10/2017 at 00:37 point

Which phone is that on?

  Are you sure? yes | no

sp33dsk8 wrote 01/10/2017 at 00:55 point

I get the feeling you're dealing with Apple problems

  Are you sure? yes | no

jaime wrote 01/16/2017 at 21:05 point

Can you access the console?  Did you upload the SPIFFS image?

  Are you sure? yes | no

hypersonic5000 wrote 01/16/2017 at 21:33 point

I figured out how to make it work. I had to change some settings and re upload the SPIFFS image. (BTW sp33dsk8 I don't and never will use apple)

  Are you sure? yes | no

sp33dsk8 wrote 12/19/2016 at 05:19 point

Using 3.5V on the 5V input I was drawing an average of 84mA for anyone who's curious.

  Are you sure? yes | no

sp33dsk8 wrote 12/18/2016 at 23:09 point

For whatever reason the auto sign-in system browser just loops the song over and over even when I close the page and turn the screen off on android.

  Are you sure? yes | no

jaime wrote 12/28/2016 at 19:50 point

Oh wow... hehe.  That's even better! :D

For some reason my Samsung Galaxy S5 phone doesn't automatically popup the browser when connecting to it.  Glad that it works for you though.  What phone and Android OS version are you running?  

  Are you sure? yes | no

sp33dsk8 wrote 12/18/2016 at 22:38 point

So much respect for you! This had to of taken at least 20 straight hacking hours to build.  It all looks so professional.  Can we set it up to become dns of open wifi networks?  :D  I'll have these scattered across the town.... 

  Are you sure? yes | no

jaime wrote 12/28/2016 at 19:50 point

Thanks...  it was fun putting this together.  Still tweaking some things out here and there.

  Are you sure? yes | no

bill wrote 12/05/2016 at 05:07 point

Hi guys,

I was able to compile and upload.   I am able to connect to the that AP name, but when I open a web browser shouldn't it have the free wifi screen displayed ?  using android...

  Are you sure? yes | no

sp33dsk8 wrote 12/18/2016 at 22:39 point

Read through the tutorial on this page one more time you missed a step ;) specifically the second half of step 3. Good luck :D

  Are you sure? yes | no

dwight2020 wrote 11/14/2016 at 17:11 point

Is there a way to make it activate on https:// requests?  Also when my ipad connects to it I have to then go into safari and search an http:// address for it to work.  Shouldn't it just activate right when I connect to the AP?  Great project though :)

  Are you sure? yes | no

jaime wrote 11/21/2016 at 18:57 point

Yes... when you connect it should launch an Internet Connection Helper type view.  I'm not sure why that isn't happening with the latest changes I've made.  I will see if I can figure out what is going on.

  Are you sure? yes | no

jaime wrote 12/28/2016 at 19:47 point

Pull the latest from github and rebuild your SPIFFS image and upload it.  I've disabled the "embed_media" function for now.  It seems that IOS/OSX captive portal helpers don't popup automatically with the media embedded into the HTML.

  Are you sure? yes | no

ClockLoop wrote 10/29/2016 at 19:57 point

Something went wrong with the latest build using PlatformIO

BUT you can get it going with ArduinoIDE:  Check it --->

  Are you sure? yes | no

jaime wrote 11/02/2016 at 22:07 point

I just updated PlatformIO and everything compiled and uploaded just fine.

  Are you sure? yes | no

JomarX wrote 10/21/2016 at 11:10 point

Cant seem to make a proper build, too many dependcies missing?

Converting mobile-rr.ino
Collected 24 compatible libraries
Looking for dependencies...
Library Dependency Graph
|--  v1.0
|--  v1.0
|   |--  v1.0
|   |-- 
|   |   |--  v1.0
|--  v1.0
|--  v1.0
|--  v1.0
|   |--  v1.0
|   |--  v1.0
Compiling .pioenvs\d1_mini\src\mobile-rr.ino.o
Compiling .pioenvs\d1_mini\FrameworkArduino\core_esp8266_wiring.o
Compiling .pioenvs\d1_mini\FrameworkArduino\core_esp8266_wiring_analog.o
Compiling .pioenvs\d1_mini\FrameworkArduino\core_esp8266_wiring_digital.o
D:/ESP8266/code/RickRollESP1/src/mobile-rr.ino:67:25: fatal error: ArduinoJson.h: No such file or directory
// Forward declaration of methods                                                          *
compilation terminated.
*** [.pioenvs\d1_mini\src\mobile-rr.ino.o] Error 1
 [ERROR] Took 8.62 seconds

  Are you sure? yes | no

jaime wrote 11/07/2016 at 21:31 point

It seems the automatic dependancy discovery stuff doesn't work so good for some.  The platformio.ini has been updated to help.

  Are you sure? yes | no

Chris wrote 10/02/2016 at 18:17 point

Hi,  I am using an ESP-01, and accordingly changed by platformio env and board to esp01, and changed PIEZO_PIN to 2 in the program itself (I have not yet attached a piezo).  Both the regular and slimmed-down SPIFF upload fine, but the access point never appears after reboot  (I have tried several permutations of GPIO 0 and 2 being high and low).  I must be missing something obvious, but does anyone know what it is?


  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates