Here’s how to make your own telepresence hug toy. Each circuit connects to the Arduino IoT Cloud and translates your hug into a soothing vibration on the other toy. Xyla Foxlin originally developed this project as a crowdfunded product, and we collaborated to bring this DIY version to life.

#define SECRET_SSID "your wifi network name"
#define SECRET_OPTIONAL_PASS "password"
#define SECRET_DEVICE_KEY "device key"

// Code generated by Arduino IoT Cloud, DO NOT EDIT.

#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>

const char DEVICE_LOGIN_NAME[]  = "device login name";

const char SSID[]               = SECRET_SSID;    // Network SSID (name)
const char PASS[]               = SECRET_OPTIONAL_PASS;    // Network password (use for WPA, or use as key for WEP)
const char DEVICE_KEY[]  = SECRET_DEVICE_KEY;    // Secret device password

void onHugChange();

bool hug;

void initProperties(){

  ArduinoCloud.setBoardId(DEVICE_LOGIN_NAME);
  ArduinoCloud.setSecretDeviceKey(DEVICE_KEY);
  ArduinoCloud.addProperty(hug, READWRITE, ON_CHANGE, onHugChange);

}

WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
/*
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/9d1757b4-9143-4d8a-9719-987c5ca56e58

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  bool hug;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

//#include "thingProperties.h"

#include <Wire.h>
#include "Adafruit_MPRLS.h"

// You dont *need* a reset and EOC pin for most uses, so we set to -1 and don't connect
#define RESET_PIN  -1  // set to any GPIO pin # to hard-reset on begin()
#define EOC_PIN    -1  // set to any GPIO pin to read end-of-conversion by pin
Adafruit_MPRLS mpr = Adafruit_MPRLS(RESET_PIN, EOC_PIN);

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  pinMode(12, OUTPUT);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
  */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  
  Serial.println("MPRLS Simple Test");
  if (! mpr.begin()) {
    Serial.println("Failed to communicate with MPRLS sensor, check wiring?");
    while (1) {
      delay(10);
    }
  }
  Serial.println("Found MPRLS sensor");
}

void loop() {
  ArduinoCloud.update();
  
  float pressure_hPa = mpr.readPressure();
  Serial.print("Pressure (hPa): "); Serial.println(pressure_hPa);
  Serial.print("Pressure (PSI): "); Serial.println(pressure_hPa / 68.947572932);
    if (pressure_hPa > 1100){
    hug=true;
    Serial.println("Hug = true");
     Serial.println("buzz buzz loop");
   digitalWrite(12, HIGH);
   delay(1000);
   digitalWrite(12, LOW);
  }else{
    hug=false;
    Serial.println("Hug = false");
  }
  delay(1000);


}




/*
  Since Hug is READ_WRITE variable, onHugChange() is
  executed every time a new value is received from IoT Cloud.
*/
void onHugChange()  {
  if(hug==true){
   Serial.println("buzz buzz onHugChange");
   digitalWrite(12, HIGH);
   delay(1000);
   digitalWrite(12, LOW);
  }
  
}