Tag: interaction

Sending motion data to the Blynk app (part 2 of the Blynk tutorial)

In the first blog post we explained the basics of controlling the body interaction 2 (BI2) vibrator development board using the concept of  (virtual) pins. This time we want to send data from the BI2 board to the Blynk app. The BI2 has the MPU-9250 9DoF (9 Degrees of Freedom) IMU (Inertial Measurement Unit) sensor on board. This sensor is a combination of an accelerometer, gyroscope and magnetometer. Especially the accelerometer is important for motion detection. This could be used for controlling the vibrator as show with the body interaction 1 (BI1).

For measuring the motion data we use the asukiaa library. Please search and install the library in the Arduino library manager.

In the program code the library must be included and a MPU9250 sensor object must be defined. Finally we need several variables of the type float.

#include <MPU9250_asukiaaa.h>
MPU9250 mySensor;
float aX, aY, aZ, mDirection, pitch, roll, yaw;

In the setup part of the program we need to tell the MPU9250 how it is connected to the ESP8266 microcontroller. [The MPU9250 IMU is connected by the I2C bus to the ESP8266 microcontroller: the sda pin of the IMU is connected to pin 4, the scl pin to pin 5. The connection between MPU9250 and ESP8266 is managed with the standard Wire library.]

For using the accelerometer and magnetometer we have to initialize the sensor with a begiAccel() call to the IMU library.

Wire.begin(4, 5); //sda, scl
mySensor.setWire(&Wire);
mySensor.beginAccel();
mySensor.beginMag();

We have to tell the program how often data is sent to the app. Therefore we need an important concept in microcontroller programming:

Timer

With the help of the timer we can tell the microcontroller to do a given tasks again and again e.g. after 1000 microsecond. You cannot use the delay function to pass time as this would interrupt the important call to the Blynk.run(); function which is located in the loop part of the program.

First we have to define an object of type Timer.

BlynkTimer timer;

In the setup part we have to say how often what the timer has to do. in this example the timer will call the function myTimerEvent every 1000 microsecond.

timer.setInterval(1000L, myTimerEvent);

In the loop part of the program we have to call the timer to keep things going:

timer.run(); // Initiates BlynkTimer

Now we need the function myTimerEvent what has to be done every 1000 seconds.

void myTimerEvent()
{
  // here add was has to be done
}

First we have to update the sensors (accelUpdate, magUpdate). Then we read out the acceleration data in the X, Y and direction. You can already use this data but they are hard to catch. Therefore we can calculate the pitch, roll and yaw. These are angles from -180° to +180°. The calculation is complicated and I don’t understand it. But with the given formulas you get a very rough approximation which makes the data quite accessible.

void myTimerEvent() {
  mySensor.accelUpdate();
  aX = mySensor.accelX();
  aY = mySensor.accelY();
  aZ = mySensor.accelZ();

  // calculate pitch, roll, yaw (raw approximation)
  float pitch = 180 * atan (aX/sqrt(aY*aY + aZ*aZ))/M_PI;
  float roll = 180 * atan (aY/sqrt(aX*aX + aZ*aZ))/M_PI;
  float yaw = 180 * atan (aZ/sqrt(aX*aX + aZ*aZ))/M_PI;

  // read gyroscope update
  mySensor.magUpdate();
  mDirection = mySensor.magHorizDirection();
}

Finally we send the data back to the Blynk app. Now we use the virtual pins. For the variables pitch we  use virtual pin 2 (V2), for roll V3, for yaw V4 and for mDirection V5. We have to add the following line to the myTimerEvent function.

void myTimerEvent() {
  // send data to app via virtual ports, e.g. virtual pin V2 is set to pitch
  Blynk.virtualWrite(V2, pitch);
  Blynk.virtualWrite(V3, roll);
  Blynk.virtualWrite(V4, yaw);
  Blynk.virtualWrite(V5, mDirection);
}

Now the data are continously sent to the Blynk app. To visualize the data we add the widget SuperChart.

For each variable we have to define the input (virtual) pin. For pitch we use the virtual pin V2. In addition we define the color and style of the graph and more.

 

Finally the super graph shows us the date from the accelerometer which are updated every second.

First part of the tutorial (setup Arduino, setup Blynk, LED and motor control) is here

Here is the complete code:

 

/*************************************************************
bodyinteraction.org
sample program for reading MPU data, setting LED color and motor speed
*/
#define BLYNK_PRINT Serial
// include this library in the Arduino library manager
#include "FastLED.h"

// How many leds in your strip?
#define NUM_LEDS 1
// LED data pin is connected to pin?
#define DATA_PIN 14

// Define the array of leds
CRGB leds[NUM_LEDS];
int wave;

// include this library in the Arduino library manager
#include <MPU9250_asukiaaa.h>
MPU9250 mySensor;
float aX, aY, aZ, mDirection, pitch, roll, yaw;

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "Your Auth Token XXXXXXXXXX";

// Your WiFi credentials.
char ssid[] = "YOUR SSID   XXXXXXXXXXXXXX";
char pass[] = "YOUR Password XXXXXXXXXXXX";
BlynkTimer timer;

void myTimerEvent()
{
  // read acceleration data
  mySensor.accelUpdate();
  aX = mySensor.accelX();
  aY = mySensor.accelY();
  aZ = mySensor.accelZ();
  // read gyroscope update
  mySensor.magUpdate();
  mDirection = mySensor.magHorizDirection();
  // calculate pitch, roll, yaw (raw approximation)
  float pitch = 180 * atan (aX/sqrt(aY*aY + aZ*aZ))/M_PI;
  float roll = 180 * atan (aY/sqrt(aX*aX + aZ*aZ))/M_PI;
  float yaw = 180 * atan (aZ/sqrt(aX*aX + aZ*aZ))/M_PI;
  // send data to app via virtual ports, e.g. virtual pin V2 is set to pitch
  Blynk.virtualWrite(V2, pitch);
  Blynk.virtualWrite(V3, roll);
  Blynk.virtualWrite(V4, yaw);
  Blynk.virtualWrite(V5, mDirection);
}

BLYNK_WRITE(V0) // set RGB color values which are transmitted from the app as V0 (virtual pin 0)
{ 
  int i = param[0].asInt();
  int j = param[1].asInt();
  int k = param[2].asInt();
  leds[0].setRGB(j,i,k);
  FastLED.show();
}

void setup()
{
  Serial.begin(115200);
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);

  Wire.begin(4, 5); //sda, scl
  mySensor.setWire(&Wire);
  mySensor.beginAccel();
  mySensor.beginMag();

  Blynk.begin(auth, ssid, pass);
  timer.setInterval(1000L, myTimerEvent);
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

 

Please feel free to comment or write to jacardano@gmail.com

Internet of (sex) things – part 4: Building a sex toy dashboard with Node-RED

In the fourth part of the tutorial we explain the development of a dashboard for our sex toy.

The series has 4 parts:

part 1: Exploring the internet of (sex) things

part 2: MQTT messages

part 3: Node-RED

part 4: Building a sex toy dashboard with Node-RED

The dashboard is used to visualize certain data eg. the speed of the vibration motor and the movements of the vibrator. In addition it can have some control elements eg. for changing the vibration pattern.

ui-all

The window above is called a tab. You can have multiple tabs. The Motor, Data, Status and Controls – windows are called groups. The Controls – group has buttons to set the motor mode. In addition there is a slider which will set the motor to a constant speed. And there is an on/off button for the LED.

You have to install the Node-RED dashboard. Therefore you need at least version 0.14 of Node-RED. At the time this text was written the standard Node-RED installation is version 0.13 which is not sufficient for the dashboard.

Therefore check your Node-RED version. If it is equal or better than 0.14, skip this step:

  • Download & unzip the latest version from github (eg. https://github.com/node-red/node-red/releases/tag/0.15.2).
  • Now change to newly created directory eg “node-red-0.15.2”
  • On Windows: Start a command shell in adminstration mode
  • Execute “npm install” to install Node-RED.

If your Node-RED version is 0.14 or better install the dashboard:

Some  remarks:

Let’s start and have a look at the new Node-RED interface: On the left side you will find the dashboard or user interface nodes. And on the right side there is new dashboard – tab. It contains all dashboard nodes which are used in the flow ordered hierarchical.

node-red-ui

But where is the dashboard? Just open your browser and go to one of the URLs:

http://localhost:1880/ui/#/0 or
http://127.0.0.1:1880/ui/#/0

How can I get all the flows? You can download all flows here: bi-ui-node-red. Unzip the file and you will get a text file. Open the text file in an editor. Select the text and copy it to the clipboard.

Now we will explain two flows in detail.

Now go the Node-RED window, open the menu (it is on the left top side), select Import -> Clipboard.import1

A new window will open where you can insert the text (CTRL+V). Then press the Import-button.

import2

nodemcu prototype breadboardThe Arduino sketch was updated for the dashboard. Please download the Arduino sketch from here: iost-part4-v12. Unzip the file. Compile and upload to your hardware (see part 1 of the tutorial).

 

In the first flow we will receive some vibration motor sex toy data which are sent by the MQTT protocol. We will display the data using a gauge and a graph element.

Let’ start with the MQTT input node. There is nothing new. Just connect to the MQTT server and subscribe the topic “BIoutTopic2” – which the sex toy uses to send out data.mqtt-in

Now add the function node “JSON” which will parse the incoming message and places the result in “payload”.

But we want to know the motor speed only. Therefore we need a function node which passes the vibration motor speed as payload and deletes all other data. Please use the following JavaScript code:

get-motor-speed-function-node

To display the speed we need to more nodes. The gauge node gauge-node displays the actual speed. Connect the gauge node with the function node. You can add the range – the minimum and maximum value (0 and 1023).motor-gauge

 

Now add a chart node chart-nodeand connect it with the function node, too.

 

Next we want the chart node and the gauge node to be together as shown in the next image.

motor

We have to make a group and put both nodes into the group. Have a look on the dashboard at the right side. Make a new group and move the gauge and chart node below the group called “Motor”.

dashboard-top

slider-nodeNow we explain the second flow. It is used to send commands to the sex toy. We will use a slider to control the speed. But there is one problem: the slider should display the actual speed of the vibration motor. Therefore we manipulate the slider. To display the actual motor speed we have to move the slider appropriate to the actual speed. The slider will be part of the control group:

controls

Now get the slider node and edit the node as follows:

slider-motor-speed

Then connect the node with the “get motor speed” function which was introduced in the first flow.

construct-json-motor-speed-function-nodeFinally comes the trick part. Get a new function node and connect it with the slider. This node will construct the JSON message which will be sent to the sex toy using MQTT. The JavaScript code of the function node is as follows:

function-node-for-constructing-json-speed-command

msg.payload={messageType:"execute", actuator:"motor1",
             actuatorMode:"constant", actuatorValue:msg.payload}
msg.topic = "BIinTopic";
return msg;

Now connect the function node with a new MQTT output node. Leave the topic empty as it will be passed from the input nodes:

mqtt-out-message-to-bi

Using Node-RED with the Node-RED dashboard we are able to make a user interface for our sex toy(s). We could easily display the motion of the sex toy as well as the vibration motor speed. You could argue that we had a (very simple) user interface already in part 1 of the tutorial, without having to use MQTT, Node-RED and the Node-RED dashboard. That’s true. But imagine you have several sex toys and want to control them. You could easily add a tab in Node-RED for each sex toy. Or you could build more sophisticated flows incorporating several sex toy. Why not interconnecting the vibrating necklace with a penis ring and one of the plugs or dildos?

There are a lot of flows and nodes already available at http://flows.nodered.org/. (Of course not in the sex toy domain)

Why not play music for a given sex toy vibrator mode? Or control the sex toy using another IOT device…

How a program for the body interaction 1 works

The P5_fin script (program) is the basic Arduino script which demonstrates all functions available:

  • The speed of the vibration motor is controlled by movements.
  • Movement data are sent to other body interaction boards.
  • Vibration strength is adjusted when near by body interaction boards have different speed

BI1 interaction pattern

How it works:

The P5_fin script reads data from the accelerometer. Depending of the measured motion the vibration motor is speed up or slowed down. (Slow motion = reduce vibration motor speed, fast motion = speed up).

When the measured motion changes the motion data are sent out and can be received by other BI1. At the same time this script listen to other body interaction boards which send their motion data to all listening nodes.

CodebenderWithBI script and parametersWhen the measured motion of other body interaction board are different from the motion measured by this script, the vibration motor is adjusted (speed up or slowed down). So two or more body interaction boards can influence each other and synchronize after some time. The documented script is available in codebender. In this how-to the uploading of the script is explained.

 

%d bloggers like this: