hardware building
Arduino ESP32 touchcode + serial data send
#include <Arduino.h>
#include <touchy.h>
aTouch t1(12); // initalize pin13 as touch pin
aTouch t2(14); // initalize pin13 as touch pin
float hor = 0.;
float vert = 0.;
void sendDATA(){
Serial.print(hor);
Serial.print(";");
Serial.print(vert);
Serial.println();
delay(10);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
t1.readAndProcessInput();
t2.readAndProcessInput();
if( t1.is_triggered ){
hor +=.03;
// Serial.println("Touch1 pressed");
}
if( t2.is_triggered ){
hor -=.03;
//Serial.println("Touch2 pressed");
}
hor *=.98;
hor = constrain(hor, -1., 1.);
Serial.println(hor);
sendDATA();
delay(10);
// put your main code here, to run repeatedly:
}
// ----------------------------------
// ------- TRXYS TOUCH HELPERS ------
// ----------------------------------
// ( put this code PRIOR to your mainloop code or you will get nice errors :) )
// simple lerp helper function
float return_lerp(float _s, int _target,int _time){
_s = _s + (( float(_target) - _s)/float(_time));
return _s;
}
class aTouch {
private:
bool prev_touch_state = false;
byte pin;
int smooth_time = 3;
int trigger_threshold = 15;
long ts = 0;
public:
int current_val = 0;
int smoothed_val = 0;
int diff_val = 0;
bool is_triggered = false;
bool on_pressed = false;
bool on_released = false;
bool is_holded = false;
aTouch(byte pin) {
this->pin = pin;
}
void readAndProcessInput() {
// reset interaction states
on_pressed = false;
on_released = false;
// directly read out values TWICE = BUGFIX for debouncing
current_val = touchRead(pin);
delayMicroseconds(10);
current_val = touchRead(pin);
//calculate smoothed input values
smoothed_val = return_lerp(smoothed_val,current_val,smooth_time);
// calc current differential sum of button
diff_val = smoothed_val - current_val;
// check if there is a noticable difference input values
if( diff_val > trigger_threshold){
if(prev_touch_state == false){
is_triggered = true;
prev_touch_state = is_triggered;
on_pressed = true;
ts = millis(); // set timestamp for hold routine
}
}else if( diff_val < trigger_threshold*-.4){
if(prev_touch_state == true){
is_triggered = false;
prev_touch_state = is_triggered;
on_released = true;
}
}
// calculate timed holding function
if( ts + 2500 < millis() && is_triggered){
is_holded = true;
}else{
is_holded = false;
}
delayMicroseconds(2);
}
};
basic unity data read and gameobject rotation
using System.Collections;
using System;
using System.IO.Ports;
using UnityEngine;
public class balance_controller : MonoBehaviour
{
public float hor = 0f;
public float vert = 0f;
float shor = 0f;
SerialPort stream;
// SELECT YOUR COM PORT AND BAUDRATE
public string port = "COM37";
int baudrate = 9600;
int readTimeout = 25;
public GameObject cam;
void Start()
{
// open port. Be shure in unity edit > project settings > player is NET2.0 and not NET2.0Subset
stream = new SerialPort("\\\\.\\" + port, baudrate);
try
{
stream.ReadTimeout = readTimeout;
}
catch (System.IO.IOException ioe)
{
Debug.Log("IOException: " + ioe.Message);
}
stream.Open();
}
// Update is called once per frame
void Update()
{
string dataString = "null received";
if (stream.IsOpen)
{
try
{
dataString = stream.ReadLine();
// Debug.Log("RCV_ : " + dataString);
}
catch (System.IO.IOException ioe)
{
Debug.Log("IOException: " + ioe.Message);
}
}
else
dataString = "NOT OPEN";
// Debug.Log("RCV_ : " + dataString);
if (!dataString.Equals("NOT OPEN"))
{
// recived string is like "accx;accy;accz;gyrox;gyroy;gyroz"
char splitChar = ';';
string[] dataRaw = dataString.Split(splitChar);
// normalized accelerometer values
hor = float.Parse(dataRaw[0]) ;
// vert = float.Parse(dataRaw[1]) ;
}
shor = Mathf.Lerp(shor,hor,.3f);
cam.transform.rotation = Quaternion.Euler(new Vector3(0,180f+shor*-.5f,0));
}
}