
// DIY sensor touchpad
// Markus Opitz 2026
// instructables.com


#include <Arduino.h>

// measure ***********************
const int ADC_PIN = A0;
const float VCC = 3.3;
const float R_REF = 1000000.0;   // 1 MOhm reference resistor
const int N_SAMPLES = 64;

//coordinates **************
float resMin = 2.0;
float resMax = 6.0;
float resLine;
float resValue;
int x, y;
float resX;

// OLED ******************
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_ADDR 0x3D   // I2C-address (mostly 0x3C)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);


float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {  //for using float values in a map funktion
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}


void setup() {
  Serial.begin(115200);
  delay(500);

  resLine = (resMax-resMin)/7;    // 7 lines  --> a 9 lines on OLED display
  Serial.println(resLine, 3); delay(2000);


  pinMode(ADC_PIN, INPUT);
  analogReadResolution(12);
  analogSetPinAttenuation(ADC_PIN, ADC_11db); // großer Messbereich bis nahe 3.3 V

  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
    Serial.println(F("SSD1306 not found"));
    for (;;);
  }
  display.clearDisplay();
  display.setTextSize(2); 
  display.setTextColor(WHITE);
  display.setCursor(30, 25);
  display.println(F("ready"));
  display.display();
  delay(1000);
}

void loop() {
  uint32_t sum = 0;

  for (int i = 0; i < N_SAMPLES; i++) {
    sum += analogReadMilliVolts(ADC_PIN);
    delayMicroseconds(200);
  }

  float vOut = (sum / (float)N_SAMPLES) / 1000.0;

  float rX;
  if (vOut <= 0.001) {
    rX = 0.0;
  } else if (vOut >= VCC - 0.001) {
    rX = INFINITY;
  } else {
    rX = R_REF * vOut / (VCC - vOut);
  }

  Serial.print("Vout = ");
  Serial.print(vOut, 3);
  Serial.print(" V, Rx = ");
  resValue = rX / 1000000.0;

  if (isinf(rX)) {
    Serial.println("> Messbereich / sehr hochohmig");
  } 
  else if (resValue > 75) Serial.println(" - ");
  else {
    Serial.print(resValue, 3);
    Serial.print(" MOhm     ");
    checkXY();
    Serial.print(x); Serial.print("  "); Serial.println(y);
    displayDot();
  }

  delay(500);
}

void checkXY() {
    if ((resValue > resMin) && (resValue < (resMin + resLine))) {
    y=5;
    //resX = resValue;
    //x = mapFloat(resX, resMin,(resMin+ resLine) , 1, 128);
    x = (int)mapFloat(resValue, resMin, (resMin+ resLine), 1, 126);
    //Serial.println("line 1");
    }
  if ((resValue > resMin + resLine) && (resValue < (resMin + 2 * resLine))) {
    y=14;
    resX = resValue;
    //x = mapFloat(resX, (resMin + 1*resLine),(resMin+ 2*resLine) , 128, 1);
    x = (int)mapFloat(resValue, (resMin + 1*resLine), (resMin+ 2*resLine), 126, 1);
    //Serial.println("line 2");
    }
  if ((resValue > resMin + 2 * resLine) && (resValue < (resMin + 3 * resLine))) {
    y=23;
    resX = resValue;
    //x = mapFloat(resX, (resMin + 2*resLine),(resMin+ 3*resLine) , 1, 128);
    x = (int)mapFloat(resValue, (resMin + 2*resLine), (resMin+ 3*resLine), 1, 126);
    //Serial.println("line 3");
    }
  if ((resValue > resMin + 3 * resLine) && (resValue < (resMin + 4 * resLine))) {
    y=32;
    resX = resValue;
    //x = mapFloat(resX, (resMin + 3*resLine),(resMin+ 4*resLine) , 128, 1);
    x = (int)mapFloat(resValue, (resMin + 3*resLine), (resMin+ 4*resLine), 126, 1);
    //Serial.println("line 4");
    }
  if ((resValue > resMin + 4 * resLine) && (resValue < (resMin + 5 * resLine))) {
    y=41;
    resX = resValue;
    //x = mapFloat(resX, (resMin + 4*resLine),(resMin+ 5*resLine) , 1, 128);
    x = (int)mapFloat(resValue, (resMin + 4*resLine), (resMin+ 5*resLine), 1, 126);
    //Serial.println("line 5");
   }
  if ((resValue > resMin + 5 * resLine) && (resValue < (resMin + 6 * resLine))) {
    y=50;
    resX = resValue;
    //x = mapFloat(resX, (resMin + 5*resLine),(resMin+ 6*resLine) , 128, 1);
    x = (int)mapFloat(resValue, (resMin + 5*resLine), (resMin+ 6*resLine), 126, 1);
    //Serial.println("line 6");
   }
  if ((resValue > resMin + 6 * resLine) && (resValue < (resMax))) {
    y=59;
    resX = resValue;
    //x = mapFloat(resX, (resMin+6*resLine),(resMax) , 1, 128);
    x = (int)mapFloat(resValue, (resMin + 6*resLine), resMax, 1, 126);
    //Serial.println("line 7");
    }
}

void displayDot() {
  display.clearDisplay();
  display.fillCircle(x, y, 2, SSD1306_WHITE);
  display.display();
  delay(10);
}