Arduino Launch emulator (ESP32)

I bought a ESP32 microcontroller dev board. This microcontroller has BLE built in and gave me an idea. Why not make it show up as a launch so buttplugio can talk to it. This way i can use buttplugio with all non bluetooth toys!

This is just a proof of concept but it seems to be working perfectly already.

//code

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

#define SERVICE_UUID          "88f80580-0000-01e6-aace-0002a5d5c51b" //launch service
#define CHARACTERISTIC_UUID_1 "88f80581-0000-01e6-aace-0002a5d5c51b" //launch characteristic
#define CHARACTERISTIC_UUID_2 "88f80582-0000-01e6-aace-0002a5d5c51b" //we need this to fool buttplugio to think its talking to a real launch
#define CHARACTERISTIC_UUID_3 "88f80583-0000-01e6-aace-0002a5d5c51b" //we need this to fool buttplugio to think its talking to a real launch

#define PIN_STEP 25
#define PIN_DIR 26

#define STROKE_LENGTH 16 //stroke length

int motor_pos = 0;    //Current position of the stepper motor 0-100
int motor_target = 0; //Value that has been send by ButtplugIO 0-100
int motor_speed = 0;  //speed between 0-100

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();

      if (value.length() == 2) {

        motor_target = (int)value[0];
        motor_speed = 200000/max((int)value[1],1);

      }else{
        Serial.println("ERROR1");
      }
    }
};

void setup() {
  pinMode(PIN_DIR, OUTPUT);
  pinMode(PIN_STEP, OUTPUT);
  
  Serial.begin(115200);

  Serial.println("Starting");

  BLEDevice::init("Launch");// Name of the device
  BLEServer *pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID_1,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pService->createCharacteristic(
                           CHARACTERISTIC_UUID_2,
                           BLECharacteristic::PROPERTY_READ |
                           BLECharacteristic::PROPERTY_WRITE
                         );                                     
  pService->createCharacteristic(
                           CHARACTERISTIC_UUID_3,
                           BLECharacteristic::PROPERTY_READ |
                           BLECharacteristic::PROPERTY_WRITE
                         ); 

                         
  pCharacteristic->setCallbacks(new MyCallbacks());

  pCharacteristic->setValue("00");//random test value
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();
}


void loop() {
    //check if we need to make a step up or down
    if(motor_pos < motor_target*STROKE_LENGTH){
      motor_pos++;
      digitalWrite(PIN_DIR, LOW);
      digitalWrite(PIN_STEP, HIGH);
    }else if(motor_pos > motor_target*STROKE_LENGTH){
      motor_pos--;
      digitalWrite(PIN_DIR, HIGH);
      digitalWrite(PIN_STEP, HIGH);
    }
    
    delayMicroseconds (max(motor_speed/STROKE_LENGTH/2, 10));
    digitalWrite(PIN_STEP, LOW);
    delayMicroseconds (max(motor_speed/STROKE_LENGTH/2, 10));
    
    Serial.println(motor_pos);
}
3 Likes

Awesome work! We’ve played around with using peripheral BLE before to do emulation (you can do this on desktop/mobile APIs too), but haven’t really released much yet. Cool to see that you got it working for Launch stuff. :smiley:

1 Like

Can I ask what ESP32 your using?

Guessing some thing like:
ESP32 2.4GHz Dual-Mode WiFi + Bluetooth Dual Cores
MakerFocus ESP32 Development Board WiFi Bluetooth
MINI D1 ESP32 ESP-32S WIFI + Bluetooth Module
?

Yes. They are all using the same chip with buildin bluetooth LE. So any of them will work.

I am not shure if this fits here, but create an Emulation with the ESP32 is something I tried out a lot but didnt get any results, probably because of my missing Knowledge :smiley:
My interests are more like emulate a vibrating buttplug and create something like an universal remote. You can connect this to all of your toys with an external vibrating remote to control the toys over the internet.
So you see it may be not really buttplug.io related, because it would be enough for me to use the official app like lovense, but wont say no if buttplug.io have a similar app to let your Partner control your vibrations, but i didnt found something similar like this instead of here.
Do you have any kind of tutorial on how to emulate something so the app or program thinks your ESP32 ist an actual device?

Yeah we’re hoping to get an online service going with Buttplug/Intiface at some point. I just have to stop rewriting the core library over and over first.

Couldn’t they use https://metafetish-white-label-teledildonics-server.glitch.me/ ?

Hi.
How much coding would it be to use a servo or two instead of a stepper?
Like hooking the ESP32 to a OSR2?


//tt

I’m thinking about building something like this, because I’ve gotten frustrated with some of the limits of existing devices, and believe I have some idea what parts would work.

Except… what’s the typical current draw of a vibrator anyway? Providing suitable voltage for something that originally ran on 2 AA batteries is no problem, but the amperage I’m not certain about.

I have printed off the Machine in the link. But I do find it is quite a bit noisy.

I used the the following parts

ESP32 devkit
nema 17 stepper
a4988 stepper driver
and a 12vdc wall power supply

With the example code i can get the toy functioning.

I feel like the toy needs a bit if a redesign

i would make the piston ride 8mm bar with liner bearings. move the mount for the motor and separate components to their own compartment.

Somewhat related to this, our Vibhub project uses an ESP32. If you’re looking for a devboard with a two dual channel motor controllers, it could be a starting point for for testing.