Project tutorial
Bling Bra: Wearable, Sexy and Connected IoT Bra

Bling Bra: Wearable, Sexy and Connected IoT Bra © GPL3+

Sexy bra using Arduino MKR1000, Neopixels, and controlled from your smartphone.

  • 1 comment
  • 14 respects

Components and supplies

Necessary tools and machines

sewing needle

Apps and online services

Mobile web browser

About this project


Many makers sacrifice their social life to play with devices and spend many hours and days making fun things. However, the non-maker do not understand that a robot is something beautiful even if there is a breadboard, components and noise in this tinny thing.

Wearable devices are an opportunity towards the reconciliation between the makers and the rest of the population. By building sexy wearable things, people can understand that things that we build are not some useless toys for big boys :D

The idea

Some lingerie companies are investigating approaches to incorporate IoT technology in their products. However, the majority of those efforts try to find useful application that change the life of the consumer. This link describe some of those efforts.

The Idea behind this project is to have fun IoT Bra to play with. Like chewing gum, just for fun !. You can use the connected Bra because you want to share a funny moment with your boy/girl friend. Dancers may also use it to give wireless interaction capability to their public. 

Video 1 (oops! MKR1000 is 3v not 5v as i say in the video)

Oops! MKR1000 is 3v (not 5v as i say in the video)

How it works

Before giving technical details let's look at the interaction model. Figure 1 illustrates in interaction between the Bra and the mobile device.

You can use your mobile device as an access point. Once the access point started, turn on the MKR1000 by connecting the battery. The MKR1000 will get connected to your mobile device. You can then request the control web page from you mobile device (or computer if connected to the same access point) using the IP of the MKR1000.

You can use the serial monitor to get the IP address of the MKR1000. One other way to do that is to use the HotSpotManager App to get the IP of the connected devices to your access point.

Using the IP of the MKR1000, you can request the control web app (ex.  ). The Figure 2 illustrates how the web application looks like. the color picker is used to choose the RGB value that will be sent to the Bra and displayed using the neopixels.

 Sew on the components and the Bra

You need to sew on the components to the Bra. The schematics illustrates the links between the components. Figure 3 illustrates how to put all that in the Bra.

The IC Socket is very useful to sew on the Level-Shifter (3V to 5V) as it allows you to sew on without damaging this useful component.

This component is needed to connect the 5v neopixels to the 3v MKR1000.

I suggest that doing the stitching on the outside or covering the thread on the inside to protect it from shorts from the skin.  (Thanks Leslie Birch for the feedback)

The access point credentials

You have to put your access point credentials on the sketch before uploading it to the board. As illustrated bellow. You need to put your SSID and PASS on the .ino file.

char ssid[] = "yourMobileDeviceAP_SSID";      //  your network SSID (name)  
char pass[] = "yourMobileDeviceAP_password";   // your network password

The embedded web app

The Bra are controlled a web app that use mobile jquerry. It use also a jscolor as web color picker.

The web app have two behaviors according to the request. If you ask for the root file (ex. ), the web app will send the HTML/Javascript that is used for the control. If you ask for the path /neo/R/G/B where R, G, and B are values between 0 and 255 (ex.  ), the web app will update the color on the NeoPixels and send a status as response. The code bellow illustrates this behaviors.

void loop() {    WiFiClient client = server.available();   // listen for incoming clients
    if (client) {                             // if you get a client,
        digitalWrite(ledpin, HIGH);
        Serial.println("new client");           // print a message out the serial port
        String currentLine = "";                // make a String to hold incoming data from the client
        while (client.connected()) {            // loop while the client's connected
            if (client.available()) {             // if there's bytes to read from the client,
                char c =;             // read a byte, then
                Serial.write(c);                    // print it out the serial monitor
                if (c == '\n') {                    // if the byte is a newline character
                    // if the current line is blank, you got two newline characters in a row.
                    // that's the end of the client HTTP request, so send a response:
                    if (currentLine.length() != 0) {
                        if(currentLine.indexOf("GET") != -1){
                          if (currentLine.indexOf("/neo") != -1) {
                          }else {
                    else {      // if you got a newline, then clear currentLine:
                        currentLine = "";
                else if (c != '\r') {    // if you got anything else but a carriage return character,
                    currentLine += c;      // add it to the end of the currentLine
        // close the connection:
        Serial.println("client disonnected");
        digitalWrite(ledpin, LOW);
void sendStatus(String currentLine, WiFiClient client){
  Serial.println("processing the url params from :");
  int r = currentLine.indexOf("/");
      r = currentLine.indexOf("/", r + 1);
  int g = currentLine.indexOf("/", r + 1);
  int b = currentLine.indexOf("/", g + 1);
  int e = currentLine.indexOf(" ", b + 1);
  r = currentLine.substring(r + 1, g).toInt();
  g = currentLine.substring(g + 1, b).toInt();
  b = currentLine.substring(b + 1, e).toInt();
  Serial.println("r=" + String(r) + ", g=" + String(g) + ", b=" + String(b)); 
  for(int i=0;i<NUMPIXELS;i++){
      // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
      pixels.setPixelColor(i, pixels.Color(r,g,b));; // This sends the updated pixel color to the hardware.
    // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
  // and a content-type so the client knows what's coming, then a blank line:
  client.println("HTTP/1.1 201 OK");
  client.println("Connection: close");
    // the content of the HTTP response follows the header:
void sendPage(WiFiClient client){
  Serial.println("Sending Main Page");
  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
  // and a content-type so the client knows what's coming, then a blank line:
  client.println("HTTP/1.1 200 OK");
  client.println("Connection: close");
  // the content of the HTTP response follows the header:
client.print("<!DOCTYPE html>\n");
client.print("  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n");
client.print("  <link href=\"\" rel=\"stylesheet\" type=\"text/css\" />\n");
client.print("  <script src=\"\"></script>\n");
client.print("  <script src=\"\"></script>\n");
client.print("  <script src=\"\"></script>\n");
client.print("  <meta charset=utf-8 />\n");
client.print("  <title>Neo Bling Bra</title>\n");
client.print("  <script>\n");
client.print("    $(document).bind('pageinit', function() {\n");
client.print("      $(\"#neocolor\").on(\"change\", function() {\n");
client.print("        var hex = $.trim($(\"#neocolor\").val());\n");
client.print("        var rgburl = \"neo/\"+parseInt(hex.substring(0, 2), 16)+\"/\"+parseInt(hex.substring(2, 4), 16)+\"/\"+parseInt(hex.substring(4, 6), 16);\n");
client.print("        $.get(rgburl, function(data, status){\n");
client.print("          alert(\"Data: \" + data + \"Status: \" + status);\n");
client.print("        });\n");
client.print("        $(\"#footerH3 span\").text( rgburl );\n");
client.print("      });\n");
client.print("    });\n");
client.print("  </script>\n");
client.print("<div data-role=\"page\">\n");
client.print("  <div data-role=\"header\"><h1>Neo Bling Bra</h1></div>\n");
client.print("  <div data-role=\"content\">\n");
client.print("    <input class=\"jscolor\" id=\"neocolor\" value=\"99CC00\" />\n");
client.print("  </div>\n");
client.print("  <div data-role=\"footer\">\n");
client.print("    <h3 id=\"footerH3\" >Push color <span></span> to the Bra</h3>\n");
client.print("  </div>\n");
  // The HTTP response ends with another blank line:
  // break out of the while loop:

Replicate and have fun !!

You are ready now to replicate the project. Enjoy and feel free to ask me for more details.


BlingBra code
Repository on GitHub


Picture of the configuration
NeoPixels and 74AHCT125 (Quad Level-Shifter) are not available on Fritzing, i used other components for the illustration and added a note (ex. push button to represent neopixels)
Connections bb
Picture of the configuration
NeoPixels and 74AHCT125 (Quad Level-Shifter) are not available on Fritzing, i used other components for the illustration and added a note. (ex. the push button represents the neopixels)
Connections bb


Similar projects you might like

Stylish IoT Neck Warmer Controlled from Mobile Browser

Project tutorial by Dr. Charif Mahmoudi

  • 32 respects

IoT PCR: Low Cost DNA Replication Connected to the Internet.

Project showcase by kemfic

  • 1 comment
  • 43 respects

Gesture-Controlled Robot

Project tutorial by Youssef El-Gendy and Romina Abachi

  • 15 respects

GPS Datalogger, Spatial Analysis, and Azure IoT Hub.

Project tutorial by Shawn Cruise

  • 98 respects

Arduino 101 - Intel Curie Pattern Matching Dress

Project tutorial by Kitty Yeung

  • 66 respects

IoT for Coins

Project tutorial by Erik Moran

  • 52 respects
Add projectSign up / Login