Project tutorial
Ever Blooming Mechanical Tulip

Ever Blooming Mechanical Tulip © CC BY-NC-SA

Mechanical tulip sculpture that blooms with just gentle touch and can shine into any color of a rainbow.

  • 6,470 views
  • 26 comments
  • 143 respects

Components and supplies

Ard nano
Arduino Nano R3
×1
Sg90 servo motor 180 degrees sg90 micro
SG90 Micro-servo motor
×1
TTP223 touch sensor
×1
1mm brass wire
×1
2mm brass tubing
×1
0.3mm insulated copper wire
×1
WS2812 5050 NeoPixel LED
×7
White SMD 1206 LED
×30

About this project

Everlasting flower for your everlasting love. A perfect not-only Valentine's day gift to your loved one. This mechanical tulip will bloom into any color possible with just gentle touch of your hand. Its six petals will slowly open and light up. When petals are closed they create incredible ambient light with leaf patterns.

Video that touched 1.8 million of hearts

How does it work?

But before I will tell you how to create this beauty, let's talk briefly about how it works. Tulip consists of 6 petals each with 5 SMD white LEDs. Each petal is connected with one of the Arduino output pins. Blossom hides 7 NeoPixel RGB LEDs. From an electrical point of view, the whole flower is ground and veins in petals are a positive voltage. Petals are opened by a pushrod which is going all the way down the stem to the base. The pushrod is controlled by a movement of a small hobby servo. Small leaf on the side of the stem is connected to TTP223 touch sensor inside the base and creates a capacitive touchpad. The wooden base contains a servo motor, touch IC and Arduino Nano. Let's build one yourself!

What are you gonna need?

  • 1mm brass rod
  • 2mm brass tubing with 1, 2mm hole
  • 0.3mm copper wire with insulation
  • Some wood for pedestal
  • Arduino Nano
  • TTP223 touch sensor
  • Small servo

What you need to know before you start

  • How to solder brass (great article)
  • How to build with Arduino
  • How to use servos
  • How to use LEDs and NeoPixels

I am not telling you any dimensions of the components and exact shape of the blossom. I think every flower should be a unique one.

The petals (4h)

Let's start with the most satisfying part first - petals of the blossom. Note that number in the brackets is a time required to do the step.

The first thing you need is a template for the blossom. I created mine from plaster poured into tube mold. When it dried I shaped it into a tulip blossom. You can 3D print it as well but I don't have a 3D printer. The plaster is great because it is easy to machine and a pencil can draw on it. Single petal is 1/4 of the surface of the template so at the end when there are gonna be 6 of them, they will slightly overlap each other creating exact look of a tulip blossom. I draw the petal shape on the surface of the plaster with a pencil. When I was satisfied with the petal shape I carved it into the plaster with a knife to help me hold rods in place while soldering.

Petal consists of 1mm brass rod going all the way around the shape. Inside the petal are 5 SMD 1206 white LEDs and a "vein" structure from the very same wire. First, create the circumferential wire, take your time bending it. Cut a small piece of tubing and pass it on the bottom flat part of the wire - this will be the hinge petal will move around. Solder ends of the wire together, make sure you don't fill the tubing with solder. It needs to move freely. Finish the petal with LEDs and venous structure. Watch me making a single petal. Shame on me, this is the only footage I have from making the flower.

Making 1 of 6 petals

Now make 5 more of these. All petals need to be exactly the same. It's really crucial. Otherwise, they would not resemble a nice even tulip shape at the end when closed and may even get stuck.

Blossom (1h)

So far so good? It's time to solder all the petals together. The base of the blossom is hexagonal - 6 petals. Petals are fixed to the hexagon via hinges. The hexagon, however, is slightly irregular. I failed with a regular one. Petals need to overlap each other and if the hexagon is regular they are not allowed to. Three petals are closer to the center (inner petals) and other 3 in slight offset (outer petals). For that, I created a template and printed it on a paper. The red shape is the final irregular hexagon made out of two nested regular hexagons. Solder all the hinges (tubings) to the hexagon. Rays coming out of the center of the template will help you to solder the petals in a correct position. The center of the petal needs to follow the ray line coming out of the center of the hexagon. At the end when you close the petals you will have the final shape of the blossom. Nice isn't it?

Creating the stem and pushrod (1h)

This is not how I proceed in my making of the flower. I first finished the mechanism inside the blossom and then added a stem and pushrod to it. It added a lot of misery into the making. Once I almost wanted to trash it and never look back. Next time I will first start with the stem. So you should as well.

Movement of the petals is created by a 1mm brass pushrod freely moving inside a brass tubing. Petals are connected to the pushrod through a really tiny hexagon with small 2mm long hinges on each side - pushrod head. Hexagon is sitting perpendicularly on the pushrod with a help of small bar running through the center of the hexagon. This is watchmaker's job.

To create the pushrod head I created the second template. First, bend the wire to form the tiny hexagon. Then cut small 2mm long tubings and pass them on the wire. Solder the wire to finish the hexagonal shape. Again make sure you do not solder the tubing to the wire. Continue by soldering wire into the center of the hexagon. And finish the rod by soldering a 1mm wire perpendicular to the center of the pushrod head. Hurray! You have your pushrod.

Build the stem. Cut brass tubing to the desired length. And now the second crucial part. The stem needs to be perfectly perpendicular to the hexagonal base of blossom, needs to be in the exact center of it and there needs to be enough room for the pushrod head to move down to close the petals. First, I soldered two wires to one end of the stem to create a V-shaped expansion. These will be the 2 out of 6 wires connecting stem to the vertices of hexagonal base.

So flip the blossom upside down and solder the V-shaped expansion to the 2 opposite vertices of the hexagonal base. Check the shape. If you put a rod inside the stem it needs to come out in the center of the blossom. Take your time here making it perfect. It's really a crucial part. When you are fine with it, solder 4 more wires between the rest of the hexagon's vertices and the top of the stem. Make sure not to solder the hole inside the tubing!

Petals mechanism (6h)

This is the part you gonna regret you ever started making the flower in the first place. I almost throw it into the trash once. But hey, I am not the most patient guy ever. You are gonna nail it! For this part, I've got inspired by steam engines and their rods, pistons, and flywheels.

Make yourself a test stand. Fix the flower with the stem in an upward position. Put the pushrod through the stem with its head upward. Solder short tubing perpendicular to the bottom end of the pushrod and create yourself a small connecting rod out of 1mm brass wire to connect servo and the pushrod (see the picture above). You should be able to move with pushrod up and down using a servo. Try it by hooking up your Arduino. Before you can start soldering the connecting rods between petals and pushrod head you need to tune up the servo movement with Arduino. Write your code to move pushrod up and down in a way when in the topmost position the pushrod head end is flush with blossom hexagonal base. And in the lowest position, it sits on the bottom of the blossom V-shaped base.

Tip: Use Adafruit_TiCoServo library to control the servo. It will allow you later to control NeoPixels at the same time as the servo.

Tip: To make your pushrod movement is as soft as possible, use the hole closest to the center of the servo arm. The servo will need to spin longer but with shorter steps.

As the pushrod moves up it pushes the connecting rod and petals down. As it moves down it drags connecting rods and petals are being closed.

Petals are currently missing one crucial part - petal pin. This hinge makes the petals move. The hinge sits on a bar (see image below) which is soldered to each petal parallel to its base. Petal pin needs to be above the surface of the petal in order to allow it to fully open as you can see on the animation. Make yourself one such bar with a hinge from tubing and solder it to the first petal. This will need a lot of experimenting with the size of the bar and its distance from the petal base to allow the pushrod to fully open and close the petal. Use trial and error method. Solder the bar to a suitable position and add connecting rod between the pushrod pin and the petal pin. If you have your pushrod in the upper position and your petal in a fully opened position, space between pushrod pin and petal pin is the length of the connecting rod.

Now try to move with pushrod up and down to see what is happening. If it works fine without any rubbing and petal can be closed and opened you are done (with the first petal)! If not, try a different length of connecting rod or different position of the bar. In order to finish the blossom, duplicate the same bar and connecting rod on each of the 5 remaining petals. The 3 outer petals need to be a little lower when the blossom is opened to allow them to properly overlap the inner petals while closing. In the end, you should be able to close and open the blossom. Don't panic if you failed to do the perfect shape for the first try. It only means all the petals are not perfectly the same. It will probably take a lot of fine-tuning to create a perfect shape - slightly different lengths of connecting rods and positions of bars. Take your time here! A reward is near.

Detailed view of the mechanism.

Rainbow pistil (1h)

If you made it to this step you are a king and the hardest parts are behind you. Inside the blossom, I put 7 NeoPixels LEDs to shine from inside. These LEDs need only one DATA wire to be controlled and can be daisy chained. I soldered 6 of these between two small hexagons (another template of course). Lower hexagon is a ground wire and the upper one is a positive voltage. Solder appropriate leads of NeoPixels to these hexagon rings. These LEDs are placed under the 45-degree angle to shine into sides. To make it even better place the seventh LED into the center of the upper hexagon. Last but not least connect DATA IN and OUT leads to create a daisy chain.

This structure will need two wires going down to the pedestal - VCC and DATA. The ground is taken from the flower frame. Solder one thin 0.3 insulated copper wire to the upper ring for VCC and the second one to the first LED in the daisy-chain for DATA. These wires will at the end go down to the pedestal. Make them at least 3 times the length of the stem. Ends of these wires need to be released from their transparent insulation prior to soldering. Heat won't destroy it. Use a knife to strip off the insulation. You can test the LEDs now to make sure they work. Be gentle with these copper wires. If you accidentally strip the insulation anywhere else than ends, you might get a short circuit!

Last brass soldering work is now going to happen! Place the pistil structure to the center of the blossom. Slightly offset it from the blossom hexagonal base to leave enough room for petals connecting rods. For me, it was 1cm above the blossom hexagon. Connect all the vertices with brass rods to make a solid structure. The flower is done! Test it now to see if petals can still move freely.

Making roots (2h)

Both petals and NeoPixel LEDs need power wires to shine. The whole flower sculpture will be a ground but there are 6 petals and 2 wires for NeoPixels that need to be connected to Arduino in the pedestal. For that, thin 0.3mm copper wires with transparent insulations will be wrapped around the stem tubing. Two wires for Neopixels are already done. Solder another 6 to the loose vein wire on each petal near the hinge and pass the wire through the blossom structure down the stem. Make sure you don't bend these wires in sharp angles, it would break soon.

Now gather all the wires near the upper end of the stem tubing and secure them using strapping tape. Don't tighten it too much yet, allow wires to be pulled through it. Now nicely organize all the wires inside the blossom. Make sure petals are free to move and the pushrod is not colliding with the wires as well. Done? Now tighten the strapping tape.

Wires are now flying around the stem uncontrollably. You need to patiently and slowly wrap them down the stem. Tightly and evenly. It took me at least an hour to finish this step. When you are at the end of the stem, place another strapping tape to secure the wires there and use clear superglue to fix them in the place. Make sure not to seal the tubing with the pushrod!

Last wire missing is a ground. Solder another copper wire to the bottom end of the stem. You should end up with 9 wires coming out of the flower. It'd wise now to connect all the wires to Arduino and test whether there is no short circuit and all the LEDs light up.

The flowerpot (2h)

I wanted the flower to grow out of the artificial flowerpot which would also hide all the electronics. I've used a piece of wood and processed it into a cylinder 4cm high and 9cm in diameter. I don't have a lathe, so I used a circular saw to cut raw shape and then a press drill to act as an improvised lathe. Then I carved an opening 2.5cm deep and 7cm in diameter using hand milling cutter to fit servo, Arduino Nano and the touch sensor IC. On the bottom side of the cylinder, there is also a small opening to precisely fit Arduino Nano USB port to be able to connect the USB cable from the side.

If you have your flowerpot, drill a hole in diameter of your flower stem with wires in a place where the flower will grow - probably in the center. Try to fit your flower. Be careful with the wires. If you bend them under a sharp angle, they will break. In the end, I've also added a large hole from the inside of the pedestal to make more room for servo's arm and connecting rod.

You can do whatever shape of flowerpot you like, just keep in mind you need to fit all the electronics inside.

Touch leaf-pad (1h)

Mechanical tulip needs some kind of interactive element that would allow the person to make it bloom. I've chosen TTP223 touch sensor IC from my Arduinoflake project. But where to put a touchpad? I've decided to add a little leaf on the side of the stem that would both make the flower more natural and also will act as a capacitive touchpad. When touched it would trigger the TTP223 sensor and tell Arduino to open the blossom. This will be piece of cake for you now when you have finished such a complicated sculpture. Use the same technique as for the petals just omit the LEDs. I've also created a template for myself. Drill another small hole into the pedestal next to the stem hole to hold the leaf in the place.

If you don't want or can't use a capacitive touch sensor you can add a normal push button to the pedestal. It will do the same job.

Putting it together (2h)

This is the final step of the assembly! Are you nervous? Insert your flower stem into its hole in the pedestal again. Now, this is an important step. Measure twice before you cut! Open the blossom into its full opening. And cut the end of the pushrod coming out of the stem flush with the stem. Now when you close the blossom again, pushrod should draw out of the stem. Solder a short tubing perpendicularly to the pushrod. This will be a hinge for the connecting rod with the servo arm. When you let go the blossom and the rod, it should stop full open because the tubing will act as a stop as well.

You can now glue the stem into the pedestal. Make sure stem tubing end is flush with the inside of the pedestal to leave as much space for servo arm as possible. I've used superglue again. Make sure you don't glue the pushrod with the stem tubing. It would ruin your work!

Next, glue in the leaf-pad. Before you do solder a copper wire to it to be able to connect the leaf-pad to TTP223 touch sensor.

Put flower upside down. Be careful around the sculpture, do not break it right now! It would be so much waste! First, put the servo into final position. Its arm should be already prepared from the test stand. Just find the sweet spot where servo arm would move freely inside the pedestal and connect connecting rod to the pushrod. To secure the servo in place I used a piece of sheet metal and two screws. I wanted to be flexible here in case of servo breakdown or a wrong placement. But if you are confident you can glue it in.

If you have TTP223 module, solder the wire to leaf-pad on the original TTP223 module's touchpad (opposite side where the components are). You will need to scratch down the protective silk mask to expose the copper layer. Glue the touch module in.

Petal leafs wires (there are 6 of them) has to be connected to Arduino via current limiting resistors. Petals are basically LEDs. I've used six 200ohm resistors soldered on a tiny piece of perf board. Glue it in.

And the last component into the pedestal is Arduino Nano itself as a brain of the mechanical tulip. Place it into the opening in pedestal so it can be connected to your computer and wire it with all other components:

  • servo data wire ⭢ D9 (required for Adafruit_TiCoServo library)
  • TTP223 touch sensor data ⭢ D2 (to make use of interrupt)
  • Neopixel data ⭢ A0 (any output pin will do)
  • Petals ⭢ D3, D4, D5, D6, D10, D11 (any output pins will do)
  • Flower ground wire ⭢ GND
  • Neopixel VCC wire ⭢ 5V
  • TTP223 touch sensor GND ⭢ GND
  • TTP223 touch sensor VCC ⭢ 5V
  • Servo GND ⭢ GND
  • Servo VCC ⭢ 5V

Coding (1h)

Programming is the easiest part of all. You already have your code for the servo. Now you only need to be able to control NeoPixels, LEDs on petals and the touch sensor. Take a look into my code attached. It will give you everything you need to make your flower work. If you used my wiring scheme, you can use it right away. But don't forget to change the servo OPEN and CLOSED values. They will be definitely different.

It's done!

Don't forget to share your creation! Like this article. Also consider supporting me by buying some of my products on my Tindie store.

You can find me and my latest projects on my Twitter account.

Code

flower.inoArduino
Tulip source code
#include <Adafruit_NeoPixel.h>
#include <Adafruit_TiCoServo.h>
#include "SoftPWM.h"

#define NEOPIXEL_PIN A0
#define TOUCH_SENSOR_PIN 2

#define SERVO_PIN 9
//#define SERVO_OPEN 1750
#define SERVO_OPEN 1650
#define SERVO_SAFE_MIDDLE 1000
#define SERVO_CLOSED 775

#define RED 0
#define GREEN 1
#define BLUE 2

float currentRGB[] = {0, 0, 0};
float changeRGB[] = {0, 0, 0};
byte newRGB[] = {0, 0, 0};

#define MODE_SLEEPING 0
#define MODE_BLOOM 3
#define MODE_BLOOMING 4
#define MODE_BLOOMED 5
#define MODE_FADE 6
#define MODE_FADING 7
#define MODE_FADED 8
#define MODE_FALLINGASLEEP 9

#define MODE_RAINBOW 90

byte mode = MODE_FADED;

byte petalPins[] = {3, 4, 5, 6, 10, 11};

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(7, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ400);
Adafruit_TiCoServo servo;

int servoChange = 1; // open
int servoPosition = SERVO_SAFE_MIDDLE;

void setup() {
  Serial.begin(115200);
  pixels.begin();
  servo.attach(SERVO_PIN, SERVO_CLOSED, SERVO_OPEN);

  pinMode(TOUCH_SENSOR_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(TOUCH_SENSOR_PIN), _touchISR, RISING);

  randomSeed(analogRead(A7));
  SoftPWMBegin();

  pixelsUnifiedColor(pixels.Color(0, 0, 0));
  //pixelsUnifiedColor(pixels.Color(255, 70, 0));

  prepareCrossFade(140, 70, 0, 140);
  servo.write(servoPosition);
}

int counter = 0;
byte speed = 15;

void loop() {
  boolean done = true;
  switch (mode) {
    case MODE_BLOOM:
      prepareCrossFadeBloom(500);
      changeMode(MODE_BLOOMING);
      break;

    case MODE_BLOOMING:
      done = crossFade() && done;
      done = openPetals() && done;
      done = petalsBloom(counter) && done;
      if (done) {
        changeMode(MODE_BLOOMED);
      }
      break;

    case MODE_FADE:
      //prepareCrossFade(0, 0, 0, 800);
      changeMode(MODE_FADING);
      break;

    case MODE_FADING:
      done = crossFade() && done;
      done = closePetals() && done;
      done = petalsFade(counter) && done;
      if (done) {
        changeMode(MODE_FADED);
      }
      break;

    case MODE_FADED:
      //prepareCrossFade(140, 70, 0, 140);
      changeMode(MODE_FALLINGASLEEP);
      break;

    case MODE_FALLINGASLEEP:
      done = crossFade() && done;
      done = closePetals() && done;
      if (done) {
        changeMode(MODE_SLEEPING);
      }
      break;

    case MODE_RAINBOW:
      rainbow(counter);
      break;
  }

  counter++;
  delay(speed);
}

void changeMode(byte newMode) {
  if (mode != newMode) {
    mode = newMode;
    counter = 0;
  }
}

void _touchISR() {
  if (mode == MODE_SLEEPING) {
    changeMode(MODE_BLOOM);
  }
  else if (mode == MODE_BLOOMED) {
    changeMode(MODE_FADE);
  }
}

// petals animations

boolean petalsBloom(int j) {
  if (j < 250) {
    return false; // delay
  }
  if (j > 750) {
    return true;
  }
  int val = (j - 250) / 2;
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(petalPins[i], val);
  }
  return false;
}

boolean petalsFade(int j) {
  if (j > 510) {
    return true;
  }
  for (int i = 0; i < 6; i++) {
    SoftPWMSet(petalPins[i], (510 - j) / 2);
  }
  return false;
}

// animations

void prepareCrossFadeBloom(unsigned int duration) {
  byte color = random(0, 5);
  switch (color) {
    case 0: // white
      prepareCrossFade(140, 140, 140, duration);
      break;
    case 1: // red
      prepareCrossFade(140, 5, 0, duration);
      break;
    case 2: // blue
      prepareCrossFade(30, 70, 170, duration);
      break;
    case 3: // pink
      prepareCrossFade(140, 0, 70, duration);
      break;
    case 4: // orange
      prepareCrossFade(255, 70, 0, duration);
      break;
  }
}

void rainbow(int j) {
  uint16_t i;
  byte num = pixels.numPixels() - 1;
  pixels.setPixelColor(pixels.numPixels() - 1, 100, 100, 100);

  for (i = 0; i < num; i++) {
    pixels.setPixelColor(i, colorWheel(((i * 256 / num) + j) & 255));
  }
  pixels.show();
}

// servo function

boolean openPetals() {
  if (servoPosition >= SERVO_OPEN) {
    return true;
  }
  servoPosition ++;
  servo.write(servoPosition);
  return false;
}

boolean closePetals() {
  if (servoPosition <= SERVO_CLOSED) {
    return true;
  }
  servoPosition --;
  servo.write(servoPosition);
  return false;
}

// utility function

void pixelsUnifiedColor(uint32_t color) {
  for (unsigned int i = 0; i < pixels.numPixels(); i++) {
    pixels.setPixelColor(i, color);
  }
  pixels.show();
}

void prepareCrossFade(byte red, byte green, byte blue, unsigned int duration) {
  float rchange = red - currentRGB[RED];
  float gchange = green - currentRGB[GREEN];
  float bchange = blue - currentRGB[BLUE];

  changeRGB[RED] = rchange / (float) duration;
  changeRGB[GREEN] = gchange / (float) duration;
  changeRGB[BLUE] = bchange / (float) duration;

  newRGB[RED] = red;
  newRGB[GREEN] = green;
  newRGB[BLUE] = blue;

  Serial.print(newRGB[RED]);
  Serial.print(" ");
  Serial.print(newRGB[GREEN]);
  Serial.print(" ");
  Serial.print(newRGB[BLUE]);
  Serial.print(" (");
  Serial.print(changeRGB[RED]);
  Serial.print(" ");
  Serial.print(changeRGB[GREEN]);
  Serial.print(" ");
  Serial.print(changeRGB[BLUE]);
  Serial.println(")");
}

boolean crossFade() {
  if (currentRGB[RED] == newRGB[RED] && currentRGB[GREEN] == newRGB[GREEN] && currentRGB[BLUE] == newRGB[BLUE]) {
    return true;
  }
  for (byte i = 0; i < 3; i++) {
    if (changeRGB[i] > 0 && currentRGB[i] < newRGB[i]) {
      currentRGB[i] = currentRGB[i] + changeRGB[i];
    }
    else if (changeRGB[i] < 0 && currentRGB[i] > newRGB[i]) {
      currentRGB[i] = currentRGB[i] + changeRGB[i];
    }
    else {
      currentRGB[i] = newRGB[i];
    }
  }
  pixelsUnifiedColor(pixels.Color(currentRGB[RED], currentRGB[GREEN], currentRGB[BLUE]));
  /*
    Serial.print(currentRGB[RED]);
    Serial.print(" ");
    Serial.print(currentRGB[GREEN]);
    Serial.print(" ");
    Serial.print(currentRGB[BLUE]);
    Serial.println();
  */
  return false;
}

uint32_t colorWheel(byte wheelPos) {
  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  wheelPos = 255 - wheelPos;
  if (wheelPos < 85) {
    return pixels.Color(255 - wheelPos * 3, 0, wheelPos * 3);
  }
  if (wheelPos < 170) {
    wheelPos -= 85;
    return pixels.Color(0, wheelPos * 3, 255 - wheelPos * 3);
  }
  wheelPos -= 170;
  return pixels.Color(wheelPos * 3, 255 - wheelPos * 3, 0);
}

Comments

Similar projects you might like

Freeformable Circuit | Real Freeform Circuit!

Project tutorial by Devanagaraj

  • 1,606 views
  • 0 comments
  • 3 respects

"Living Art" Arduino-Controlled Desk Lamp

Project tutorial by Modustrial Maker

  • 8,947 views
  • 2 comments
  • 25 respects

RCar | Robots for All!

Project tutorial by Luís Rita

  • 5,831 views
  • 1 comment
  • 40 respects

How to Configure NeoPixels Using Vixen Lights and Arduino

Project tutorial by Victor Aguilar

  • 18,257 views
  • 32 comments
  • 38 respects

Arduino Compatible Nano NeoPixel Controller

Project tutorial by Team Whimsy Makerspace

  • 15,035 views
  • 1 comment
  • 19 respects

DMX RGB LED Outdoor

Project tutorial by Sebastian Wiessner

  • 10,225 views
  • 6 comments
  • 15 respects
Add projectSign up / Login