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?



Martijn wrote 08/28/2016 at 08:45 point

for some reason I cant login to the console no mather what password I set

did change it to cant touch this  ;)

  Are you sure? yes | no

jaime wrote 08/28/2016 at 12:23 point

Comment out these two lines to disable the authentication.  Then you can change it and then re-enable those lines.

if ( !request->authenticate ( username, password ) )
    return request->requestAuthentication();

  Are you sure? yes | no

dejan wrote 08/20/2016 at 14:26 point

Now that it works, I was thinking maybe put some Mc Hammers on it, couse you know you cant touch this, right :D

  Are you sure? yes | no

jaime wrote 08/21/2016 at 02:17 point

lol... nice.

  Are you sure? yes | no

733 wrote 08/27/2016 at 13:30 point

A delayed stop button...  That follows with "stop...  Hammer time....."  :-). 

  Are you sure? yes | no

john wrote 08/20/2016 at 05:45 point

Thanks  for this Jaime; Saw it, loved it, had to build it, actually had the RA CD back when I was young.  Introduced my kids to it. Few hiccups with the Wemos D1 and USB drivers but solved with using a decent USB cable and google for the right win 7 x64 drivers.  Great little project.  Ive got limited understanding how it works, but am good at following instructions.  There is a bit of screwiness in reconnecting my android phone again and sometimes it doesnt load, but the idevices the rest of the family had got directed to the splash screen fine automatically.  Im thinking its getting a harry potter refresh and off to school with my daughter ;)

Im struggling with replacing the <audio tag a <video tag in index.html and adding an m.mp4 short mpeg 4 clip to data.  (Also struggling to paste into this window the code?)

After accept nothing happens.  Chrome on android phone. Should this work?

<video width="320" height="240" preload="auto" autoplay>

<source="m.mp4" type="video/mp4">


  Are you sure? yes | no

jaime wrote 08/21/2016 at 02:16 point

Oh awesome!  Yes... there is an issue with getting the captive portal helper to automatically popup on Android.  I'm working on fixing that so it works the same as it does on iOS devices. 

You'll have to modify the javascript used to start the audio and change it to start the video.  On a mobile device, you need a user interaction to play media.  That user interaction in this case is when the user clicks the "I Accept" button.

Actually, if you just use the same ID as the previous audio tag that should do the trick.

<video id="a" width="320" height="240" preload="auto">
<source="m.mp4" type="video/mp4">

That may work.

  Are you sure? yes | no

dejan wrote 08/19/2016 at 13:31 point


I am trying to build this project, but I have a bit of a pain compiling the code.

It gives me these errors :

text in red color:     /mobile-rr-master/src/mobile-rr.ino:443:13: error: 'rrsession' was not declared in this scope
text in yellow color : rrtotal++;
text in red color:     /mobile-rr-master/src/mobile-rr.ino:444:13: error: 'rrtotal' was not declared in this scope
text in yellow color : IPAddress remoteIP = request->client()->remoteIP();
text in red color:     scons: *** [.pioenvs\d1_mini\src\tmp_ino_to.o]  Error 1

Could someone please help me fix this

I am new to programming, and have never programmed anything except some PIC micros.

System is win7 and I already added pio lib install 306 and pio lib install 64

Thank you.

  Are you sure? yes | no

jaime wrote 08/19/2016 at 18:14 point

Oops... sorry about that.  I accidentally mixed some code from the Enhanced Console branch where I changed the names of those variables.  I updated the code.  If you pull it now it should compile properly.

  Are you sure? yes | no

dejan wrote 08/19/2016 at 20:46 point

Well I actually managed to fix the problem, it works now. It is a great project. Actually the first I tried to replicate here on :D thanx to danrochman on github I added two lines of code and everything is working now. WIll be fun watching people on the beach trying to connect : D Thank you so mutch for this ;)

  Are you sure? yes | no

nam.ereh.won wrote 08/02/2016 at 23:25 point

I'm trying to build it in PlatformIO and it's failing with the following error:
p_addr.h:223:43: error: invalid cast from type 'IPAddress' to type 'u8_t* {aka unsigned char*}'
Any ideas?

  Are you sure? yes | no

Yahmez wrote 08/04/2016 at 23:54 point

same issue here.

  Are you sure? yes | no


[this comment has been deleted]

nam.ereh.won wrote 08/05/2016 at 18:33 point

I'm on Win 7x64. Tried it on three different machines. One with a fresh OS install.

  Are you sure? yes | no

Yahmez wrote 08/05/2016 at 22:34 point

Im on Windows 7 32bit...

  Are you sure? yes | no

Jason wrote 08/05/2016 at 19:22 point

I'm getting the same error. I've tried fresh installs of PlatformIO on OSX and Win7.

  Are you sure? yes | no

Jason wrote 08/06/2016 at 14:08 point

I posted the error over at and user valeros was quick to find the solution.

Basically, you replace the line:

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


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

in your platformio.ini file. This file is located in the folder you download from github (mobile-rr) and is in the root. Once I made this change, the project compiled without errors and I was able to then upload the SPIFFS image. I immediately connected to the resulting hotspot and was rickrolled right away. :)

I hope this helps. The topic over at is here:



  Are you sure? yes | no

nam.ereh.won wrote 08/06/2016 at 15:25 point

Ah that did it. Also had to gzip the text-based files to get the SPIFFS upload to work. Time to head to some parks and broadcast some Free PokeMon Go Wifi.

  Are you sure? yes | no

Yahmez wrote 08/07/2016 at 17:11 point

Thanks for this, it works now! Oh, this is going to be fun!

  Are you sure? yes | no

jaime wrote 08/10/2016 at 17:23 point

Nice!  I posted a message there too and they referred me to your post with the solution.  :D  Thanks.  I've updated the source on github.

  Are you sure? yes | no

jaime wrote 08/11/2016 at 17:48 point

Change the build_flags to this  (remove the comma) to build a 4MB SPIFFS file system.

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

  Are you sure? yes | no

oliverditlevsen wrote 07/31/2016 at 12:32 point

Oh yesss, dis gon b gud.

  Are you sure? yes | no

James wrote 07/26/2016 at 11:52 point

Hi Jamie

I've taken the advice on GZipping the appropriate files within the Data folder. I'm getting a 100% flash on both steps, but i'm not seeing any open access point.

I do however notice in your screen shots there are more files then whats contained withing the project provided. most notably the Clang file.

I have downloaded and installed Clang according to the directions given in the Atom IDE, but i'm not getting the same results.

Anything obvious i might have missed? I've never used Atom before, i'm much more familiar with the Arduino IDE.

My module does work i might add, I've re-flashed it with one of my own creations and it works right off the bat.

  Are you sure? yes | no

jaime wrote 07/31/2016 at 04:22 point

Some of those files that are shown in the screenshots were created by PlatformIO when initializing the project.  Try this.  Create a new project in PlatformIO and copy in the "src" and "data" folders from this project.  Then compare your platformio.ini to the one in this project and copy in the missing lines.  That should get you up and going.  If not, contact me via private message and we can chat on skype and I can help you get it going.

  Are you sure? yes | no

Stan wrote 07/26/2016 at 02:54 point

Great job - have got it working on a NodeMCU.

More importantly, the code is a great reference for a whole heap of things - such as spiffs which I have never used in the past.

  Are you sure? yes | no

jaime wrote 08/10/2016 at 17:26 point

It was a learning project for me.  I hope that it helps others out as well.  I'm still adding to it.

  Are you sure? yes | no

unigamer wrote 07/22/2016 at 19:53 point

I bought a WeMos D1 Mini specifically for this project and I am happy to say it all worked! I love the idea and feel it could be combined in some way with my annoying machine ( Perhaps a step too far?!

Edit: I also want to mention the loading of the gif and MP3 was instant and as soon as I clicked "Accept" I was roll'd, just in case anyone still has doubts.

  Are you sure? yes | no

jaime wrote 07/22/2016 at 20:49 point

Great... glad you got it going.  :)

  Are you sure? yes | no

Simeon G wrote 07/21/2016 at 00:12 point

Looks fun. So far i have found all my 8266 have 512kb boo. Found some 2MB chips and tryed to replace but cant get it to work, cant get the baud to set to read the error. From what i can tell if u can set the spiffs to 1.5 itd be enough but need to make a custom ld file as only the curent ones only do 1mb / 1mb. trying to make it work off an sd card but running into SD.h not liking FS.h and ESPAsyncWebServer.h uses FS.h

  Are you sure? yes | no

jaime wrote 07/21/2016 at 07:47 point

Check the replies below. Excluding a few files will get it working without the console.

Although if you just gzip the HTML, Javascript and CSS files in the data folder it should fit in a 1MB SPIFFS image.

  Are you sure? yes | no

Simeon G wrote 07/23/2016 at 00:43 point

So got the salvaged 2MB 25x16avsig to work, came off old motherboard. Had to erase it, used esptool, also had to set flash mode to dout . esp11 lacks pins so used gpio1 (pin 2 in ide) for the piezo. Still trying to get it to work constantly likes to half load things and not always redirect. Will have to try upgrading a esp12. 

edited platformio.ini and changed

build_flags = -Wl,-Tesp8266.flash.2m.ld


board_flash_mode = dout

Compressing worked well. 

getFreeHeap:        40488 B
getSketchSize:      309.91 KB
getFreeSketchSpace: 712.00 KB
getFlashChipSize:   2.00 MB
getFlashChipSpeed:  80 MHz
Name                           -      Size
/m.mp3.gz                      - 147.87 KB
/terminal.js.gz                -  22.85 KB
/l.png                         -   8.88 KB
/jquery-1.12.3.js.gz           -  31.93 KB
/a.gif.gz                      - 493.91 KB
/index.htm.gz                  -   2.06 KB
/favicon.ico.gz                -     524 B
/console.htm.gz                -   1.01 KB
/terminal.css.gz               -   1.09 KB
/a.mp3.gz                      -   2.56 KB
10 Files, 722.12 KB of 934.88 KB Used
212.76 KB Free

  Are you sure? yes | no

jaromir.sukuba wrote 07/20/2016 at 07:20 point


I built this project and flashed into nodemcu board. It runs, creates wifi hotspot, I can see it lives in debug outputs via serial terminal, though every website is redirected to and browser isn't able to connect, complaining about bad redirection. No Rick Eastley :-(

It behaves the same on two different devices, each with different OS and browser.

Any idea what is wrong here? Am I redirect-rolled?

  Are you sure? yes | no

jaime wrote 07/20/2016 at 17:48 point

The SPIFFS file system has not been uploaded to the ESP.  The page can't be found in the file system so it is redirecting (to the same page).

  Are you sure? yes | no

jaromir.sukuba wrote 07/21/2016 at 07:17 point

Oh, thanks - I really missed the upload SPIFFS image to nodeMCU board step.
By the way, at first I loaded image for Wemos D1 into nodeMCU and it didn't work. Recompiling image for NodeMCU failed with full filesystem error (smaller FLASH in the module?), so I had to remove the terminal stuff. So now I have the basic functionality (rickrolling), though no terminal - I can live with that. 

Hope this will be useful for somebody running into the same problems.

By the way - this is my first encounter with platformio (Atom) IDE. It was really painful.

  Are you sure? yes | no

jaime wrote 07/21/2016 at 07:39 point

Great... glad you got it working.

I have only used PlatformIO with my WeMos D1 mini.  I wasn't aware of any issues building for other configurations.  It would probably be best to include some more configurations in the "platformio.ini".  Then people could just uncomment the one that is for their board.

To get the Rick Roll count you could add another route similar to the "trigger" but it wouldn't increment the count.  That way you could hit the URL to figure out how many RRs you've doled out.  :)

Something like this added to the setupHTTPServer function should do the trick.

Then you'd just hit to check the RR count.


httpd.on ( "/count", HTTP_GET, [] ( AsyncWebServerRequest * request )
request->send ( 200, "text/html", String ( rrcount ) ) ;
} );


I updated the source on github with this addition.

  Are you sure? yes | no

James wrote 07/20/2016 at 05:08 point

Will this sketch fit onto an ESP with 1MB Flash, or will I have to go shopping for an ESP-12F?

  Are you sure? yes | no

jaime wrote 07/20/2016 at 17:47 point

You need the space to fit all of the data files.

  Are you sure? yes | no

jaime wrote 07/21/2016 at 07:45 point

jaromir.sukuba suggested leaving out the console.  That would do the trick.

Just delete the following files from the data folder.


If you gzip the HTML, Javascript and CSS files it should fit in 1MB though.

  Are you sure? yes | no

Ted Mieske wrote 07/19/2016 at 16:29 point

Where's the firmware for this project?

  Are you sure? yes | no

jaime wrote 07/19/2016 at 19:13 point

There is a github link above.  "mobile-rr" :)

  Are you sure? yes | no

Sly wrote 07/19/2016 at 15:51 point

It works, great (fun) !

  Are you sure? yes | no

jareklupinski wrote 07/19/2016 at 13:03 point

love it :D

  Are you sure? yes | no

@richms wrote 07/16/2016 at 02:13 point

Ahaha, Might have to dust off one of the idle ESPs and give this a go and power it on at the mall where people are always trying to mooch off the shops free wifi.

  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