Category: Arduino

New vibrator design “fusion”


fusion-quer-look-throughbodyinteraction designed a lot of vibrating toys, some are usable as massage devices, some are explicit sex toys (vibrator ring, balls), some are experimental (collar). Everyone is motion controlled. If you have more than one they will influence each other remotely, eg. a vibrator and a vibrator ring.


But a device like a classic big vibrator is still missing. So we designed the “fusion” which is approx 19cm long and up to 4+cm in diameter. It is called fusion as the case is made of silicone and 3d printed material (ABS).


We have put the body interaction vibrator development board, motor and battery in a silicone form. There is an on/off switch – so when you travel the vibrator doesn’t wake up when it is moved. And you can charge the battery with a USB micro connector. There is a spacious inlay for the electronics, so it will be easy to get it done.


  • easy to charge the battery via USB
  • on/off switch
  • hard handle
  • flexible upper part
  • large (if you like this)
  • ISP interface (“hacker port”) accessible


  • only the silicone part of the form can be put under water for cleaning

What do you need?

  • 200 ml silicone with high shore A rate, eg. shore A 45 from
  • optional: special colour for silicone molding
  • 3d print of the molding form, inlay and closure
  • tinker wire
  • body interaction vibrator development board with LiPo and motor (or similar Arduino boards)
  • bin for preparing the silicone, something to stir the silicone

How much is it?

  • Board, battery, motor: 30$ (buy at Tindie)
  • Silicone: 10$
  • 3d Prints: less than 5$

Step by step instructions

Step 1: Print out the inlay, the form and the enclosure


Download as zip-file: Fusion

Download at Thingiverse:

Step 2: Prepare the inlay: Insert the body interaction board and the LiPo battery

The body interaction vibrator development board is inserted into the provided rails. It it doesn’t fit in use a file to remove printing artefacts. Use some glue to fix the board. Then insert the battery and fix it.

Important: The Micro USB connector must be above the upper part of the inlay.

inlay with description

Step 3: fix the wires of the vibration motor

The vibration motor will hang down from the inlay as the inlay will be put in the form upside down. You can influence the position of the motor by shortening the wire or fixing the wire to e.g. to the battery. In this case the wire of the motor was threaded between battery and board. Therefore the  motor will be in the middle of the vibrator.

inlay-inner-partfusion-looking-through-2in the center there is the overmolded vibration motor

Step 5: Prepare the form

Use some tinker wire to “press” both parts of the form tight together.molding-form-emptyUse some wax to fix little holes in the form where the printer failed. (These are the white spots)


Step 6: Insert inlay into the form

There must be some space between inlay and form for the silicone.

Remark: The two wedge like forms at both sides of the inlay help to hold the inlay. The wedge can be removed after molding.inlay-in-molding-form

Step 7: Cast the silicone

Prepare the silicone as the producer recommends. It takes some time to pour the large amount of silicone into the narrow form. The silicone we use must be used within 10 minutes. So start at once after preparing the silicone.

Important: The USB micro connector, the switch and the ISP connector shouldn’t be dashed with silicone. If this happens remove the silicone. Maybe some silicone will remain behind. This can be removed later when the silicone is solid.molded

The battery is covered with silicone, the USB connecor and switch are not.drying-seen-from-top

Step 8: Remove the form

Remove the tinker wire. Remove overhanging part of the silicone. Carefully tear both parts of the form away. You can use a knife, but be careful not to “hurt” the vibrator. Remove overhanging silicone at the vibrator. Also remove the two wedge like forms at both sides of the inlay.

unboxing-fusionfusion looking through complete

Step 9: Install the closure

Now you can put the closure on the inlay. Fix the closure with glue. (Be careful! The USB connector is not very strong.) closed-inlayround_something_055_final_cap_onlyfusion-closure

Tinker, share and download from Tinkercad:

form and inlay:


Download as zip-file: Fusion

Download at Thingiverse:


USB powered charging station for the silicone molded vibrator

charging-station-in-action-with-body-interaction-vibrator-so-much-balls-smallWe made a DIY silicone molded vibrator (see here, here and here) using the Arduino compatible body interaction vibrator development board and a wireless charging module. Now we need a charging station where you can put your vibrator for battery charging.

We need a simple box for the wireless charging sender (transmitter) module and the coil. In addition we need a USB cable which we will cut though and connect to the charging module.

It is important to keep the distance between sender and receiver coil as small as possible. The larger the distance is the less power will be transmitted. Therefore the plate where you put the vibrator must be very thin. There are different modules available.


What do you need?

  • A USB cable
  • Wireless charging sender (transmitter) eg. from Seeed Studio, 5V input. The sender (transmitter) will be placed in the charging station. The receiver module will be part of the vibrator. There are different modules available. Look for a 5V input module.seeedwirelesscharging


A. Print out part A and B. Download STL files (zip file)



B. Cut a USB cable. Plug the cable through the hole of form B.

C. Now connect the USB wires with the sender module. Solder the red wire to the (+) pad on the wireless charging sender. Solder the black wire to the (-) pad.


D. Glue the sender board on the bottom of the red form. Put some glue on the cable to fix it. We used hot glue.


E. Now glue the black form and the sender coil together. We used simple “UHU”-like glue. If the distance between coil and form is too large the charging could be rather slow. So don’t use too much glue.


F. Now put together both parts. Again we used a simple glue.


G. Insert the USB connector to your PC or any other source. Now the vibrator should be charged which is indicated by an orange LED.

charging-station-in-action-with-body-interaction-vibrator-so-much-ballsReady! Have fun with your collection of wireless DIY Arduino-compatible vibrators.


Download STL files (zip file)

All files at Thingiverse:

Tinker and share with Tinkercad:

Part A

Part B

New fusion 3d printed and silicone molded vibrator

fusion tinkercadThis is the initial design. The round curved form will be in silicone with vibration motor within (vibration motor not shown on sketch). The red part is 3d printed. It is the enclosure for the body interaction vibrator development board and LiPo battery. You can plug-in the Micro USB connector for battery charging. In addition there is an on/off switch e.g. for travelling.

Connecting a servo motor – move your vibrator

The body interaction vibrator development board can be connected with additional sensors and actuators. In this post we show how to connect a servo motor. A servo motor can adjust its shaft to be positioned in varies angles. We use a inexpensive SG92R servo which can be positioned in any position between 0° and 180°.

servo-birdNow we can build eg. a linear actuator which could be useful for sex toys. If you have a 3d printer you can build your linear actuator and fix the servo motor. You can download the design here.


Connecting servo motor and body interaction vibrator development board

The servo motor has 3 wires: ground (-) (black or brown wire), power (+) (red wire) and control (yellow or orange).

servo connection 2pcb-bottomConnect the (+) wire to the body interaction board. You can use the pad on the bottom side as shown on the image.

servo pcb layoutservo-pcb-from-topThen turn the board around to the top side. Now you can solder the black wire to the “GND” (ground) pad. Then solder the orange or yellow control wire to the leftmost pad “PA1”.

Programming the servo motor

The standard Arduino servo library will not work on the body interaction board. But you can use the TinyServo library. Download the library as *.zip file  here or here and read the forum post.

Go into the Arduino library manager and include the ZIP file. Please restart Arduino.

The following script attaches the servo motor and shows how to control it.

// servo control with the body interaction development board using the TinyServo library
// -- adaption of the demo script by
//'s ATTiny Hardware Timer Assisted Servo Library v1.0 20-Nov-13

#include <TinyServo.h>
const byte SERVOS = 1; // number of servos is 1
const byte servoPin[SERVOS] = { 7 }; // servo is connected to PA1 which is pin 7
#define SERVO 0 // our servo is given the name "SERVO"

void setup() {

void loop() {
  moveServo(SERVO, 180); // move servo to 180°
  moveServo(SERVO, 0); // move servo to 0
  for (int i = 0; i <= 180; i++) {
    moveServo(SERVO, i); // move servo from 0° to 180° in 1° steps
  moveServo(SERVO, 0); // move servo to 0°



Programming Tutorial part 4: Sinus

Nervous Optic by Ben Felten, CC BY-ND 2.0

Nervous Optic by Ben Felten, CC BY-ND 2.0

In tutorial 3 – “ramps” we learned how to repeat instructions again and again using the for statement. In this tutorial we need the for loop again, bur instead of changing the motor speed by a constant value we want a more dynamic behavior. Therefore we use the sinus function – a classical pattern used for controlling vibrators.

Here is a straight forward approach:

for (float i = 0; i < 20000; i = i + 0.05) {
  analogWrite(motor, (sin(i)); //motor speed set to sin(i) 

We are changing the variable i in small steps of 0.05. So the variable i will become 0, 0.05, 0.1, 0.15, 0,2 … and so on.

But this doesn’t work. Let’s have a look at the sinus function. Just use the google search and type in “sin(x)”. You will see  the following curve:

sin(x) in google

There are two problems:

  • There are values below 0 (on the vertical or y-axis). If the value is 0 or below 0 the motor is off.
  • The maximal value is 1. But  we need values between the minimal motor speed (around 40) and the maximal speed (always 255).

You can try to adjust the function and visualize it with google search. Maybe you will discover an interesting variant of the sinus curve.

We use the following function:

(sin(x)+1) 0.5 * (maximal motor speed – minimal motor speed)) + minimal motor speed

  • Sin(x)+1: add 1 to get positive values only between 0 and 2 instead of -1 and 1.
  • Multiply by 0.5: get values between 0 an 1 instead 0 and 2
  • Multiply with maximal motor speed  (255) – minimal motor speed (40): values are now between 0 and 215
  • Add minimal speed: values are between 40 and 255. So the motor will always be on.



This is the script. Please have a look at tutorial 2 if you don’t know how to upload the script.

 // tutorial sinus 
int motor = 3; 
int minimal_motorspeed = 50; 

void setup() { 
  pinMode(motor, OUTPUT); 
void loop() { 
  for (float i = 0; i < 20000; i = i + 0.05) { 
    analogWrite(motor, ((sin(i) + 1) * 0.5 * 215) + 40); 

If you want to slow down the changes in the motor speed change delay(5) and take larger values.

Go back to tutorial 3: ramps

Programming the body interaction 1 (BI) part 2

Reading the accelerometer data

The BI has built in the accelerometer Bosch BMA020. The BMA020 is a 3-axis accelerometer and reads acceleration data in X, Y and Z direction. The accelerometer is used to control the operation of the BI. It captures changes in movement eg. slowing, speed up, change of direction. Steady movement can not be captured. Nevertheless it is possible to calculate the orientation of the BI eg. upright or downright.

To read out the data we use the JeeLib – a great library we will use to control other devices and read out sensors (read here how to install). The library must be included, add:

#include <JeeLib.h>

In JeeLib the accelerometer is called GravityPlug. It is not connected to a pin directly (as the vibration motor). Instead it is connected to the I2C bus, but at this point ignore the details. Just add:

PortI2C myBus (1);
GravityPlug sensor (myBus);

Now we can read out the accelerometer using the name “sensor”.

Now we want to read out the sensor. This is done by adding “.getAxes()” to “sensor”. But before we declare a new variable called p, where we the acceleration in X-, Y- and Z-axis is stored:

const int* p = sensor.getAxes();

The acceleration in x-direction is stored in p[0], y-direction in p[1] and z-direction in p[2].

p[0], p[1] and p[2] are integers. When there is no acceleration (eg. the BI is not moved) the value would be approx 0. If you move it horizontally to the right it will return positive values. If you move it horizontal to the left it will return negative values. (Could be vice versa, it depends on the orientation of the accelerometer).

We introduce 3 new variables x, y and z for storing the values:

int x,y,z;

As we are not interested in the direction of the acceleration we convert negative values to positives. This is known as the absolute value and is computed with the function abs(), see:

x = abs(p[0]); 
y = abs(p[1]); 
z = abs(p[2]);

We also introduce a further variable called “threshold”. Only values above a given threshold will change the behaviour of the vibration motor. This is useful to ignore the gravity which influences at least of the axises.

int threshold = 250;

Now we put everything together. The script should start the vibration motor if there is acceleration either in x, y or z direction above a threshold. Otherwise the motor is off.

#include JeeLib.h;
PortI2C myBus (1);
GravityPlug sensor (myBus);

int motor = 3;
int threshold = 100;
int x, y, z;

void setup() {
 pinMode(motor, OUTPUT);

void loop() {
  const int* p = sensor.getAxes();
  x = abs(p[0]);
  y = abs(p[1]);
  z = abs(p[2]);
  analogWrite(motor, 0); //motor off
  if (x &amp;gt; threshold || y &amp;gt; threshold || z &amp;gt; threshold) {
    analogWrite(motor, 255); //motor on
 delay(2000);  // wait for 2 second

Let’s take a further look at the loop. Every time when the instruction in the loop are executed, the sensor will be read out. The absolute values are stored in x, y and z by using the abs() function. Then the motor is set off.

The following statement

analogWrite(motor, 255);

will turn the motor on if the following condition is true:

(x > threshold || y > threshold || z > threshold)

The condition is true when either x > threshold or y > threshold or z > threshold. You can read “||” as logical or. Read more about the if function and boolean operators (or, and, not).

Finally a delay functions stops further processing for 2 seconds. Then the loop will be executed again, starting to read out the accelerometer values.

In depth example of reading the BMA020:

Jeelib GravityPlug  – how to read out the BMA020 with the JeeLib library.

More about Acceleration and Gyros and how to calculate the orientation:


Copy the source code (script) into an Arduino window. Then click compile . If everything is ok you get the message done compiling. sucessful compiling

Then upload the code to the body interaction 1. If everything is ok you get the message done uploading. You can ignore the warnings. done uploadingBut if you don’t get the done uploading message something went wrong. in this case read the following post:

Go to the next tutorial (part 3): ramps

%d bloggers like this: