Skip to content

10. Input devices

GROUP ASSIGNMENT

Assignment: Adding a sensor to my ESP32 microcontroller. I would like to add a pressure matrix sensor.

Initial Trial

I created a 3 x 3 matrix with 9 sensor reading points. I tested it on paper with velostat and copper tape. To test this out, I used an Arduino Uno.

Velostat

A pressure-sensitive conductive material often used in creating flexible sensors. It is typically a black, flexible, and thin sheet that can change its electrical resistance when pressure or force is applied to it.

  • Material Composition: Velostat is made from a polymer that is impregnated with carbon black. This composition allows it to be both flexible and conductive.

  • Conductive Properties: The material exhibits piezoresistive properties, meaning its electrical resistance decreases when pressure is applied. This makes it useful for creating pressure sensors and switches.

  • How It Works: When Velostat is placed between two conductive layers (such as aluminum foil or conductive fabric), applying pressure to the layers compresses the Velostat and changes its resistance. This change can be measured using a microcontroller or an analog-to-digital converter.

In this trial, we are using an analog-to-digital converter.

Velostat Matrix

A Velostat matrix consists of an array of conductive rows and columns with Velostat material placed at their intersections. When pressure is applied at any intersection, the resistance of the Velostat at that point changes, allowing the system to detect the specific location and magnitude of the pressure.

  • Conductive Layers: 3 rows (horizontally) and 3 columns (vertically)

  • Velostat Points: small pieces of velostat material placed at each intersection

  • Connections: the ends of the rows and columns are connected to the Arduino Uno

Matrix

Code

#define numRows 3
#define numCols 3
#define sensorPoints numRows* numCols

int rows[] = { A0, A1, A2 };
int cols[] = { 8, 9, 10 };
int incomingValues[sensorPoints] = {};  // this is the array of all the 9 sensors

void setup() {
  for (int i = 0; i < numRows; i++) { pinMode(rows[i], INPUT); }   // so that it can be an input but increasing up to the number of rows that we have in the array
  for (int i = 0; i < numCols; i++) { pinMode(cols[i], OUTPUT); }  // so that it can be an input but increasing up to the number of columns that we have in the array
  Serial.begin(9600);
}

void loop() {
  for (int colCount = 0; colCount < numCols; colCount++) {
    digitalWrite(cols[colCount], HIGH);
    for (int rowCount = 0; rowCount < numRows; rowCount++) {
      incomingValues[colCount * numRows + rowCount] = analogRead(rows[rowCount]);  // it does this function first three times before closing and going to the one outside of it
    }
    digitalWrite(cols[colCount], LOW);  // its reading the one row three times then it turns it off and jumps to the next row
  }
  for (int i = 0; i < sensorPoints; i++) {
    Serial.print(incomingValues[i]);
    if (i < sensorPoints - 1)
      Serial.print("\t");
  }
  Serial.println();
  delay(100);
}

In this code, there are 3 rows and 3 columns which creates an array of 9 points (sensors). In the setup, the rows are being acknowledged as the inputs and the columns as the outputs. In the loop, each column is activated, set at HIGH then goes through each row. It then reads the analog values from the current row sensor, stores it and moves to the next one. Once all the rows have been read, it moves to the next column and repeats the same thing. After all the columns have been scanned, it displays all the values stored.

Array Explanation

Java Code for Processing

Serial myPort; // The serial port
int rows = 3;
int cols = 3;
int maxNumberOfSensors = rows*cols;
float[] sensorValue = new float[maxNumberOfSensors]; // global variable for storing mapped sensor values
float[] previousValue = new float[maxNumberOfSensors]; // array of previous values
int rectSize = 0;
int rectY;
void setup () {
  size(600, 600); // set up the window to whatever size you want
  rectSize = width/rows;

  println(Serial.list()); // List all the available serial ports
  String portName = Serial.list()[2]; // set the number of your serial port!
  myPort = new Serial(this, portName, 9600);
  myPort.clear();
  myPort.bufferUntil('\n'); // don’t generate a serialEvent() until you get a newline (\n) byte
  background(255); // set inital background
  smooth(); // turn on antialiasing
  rectMode(CORNER);
}

void draw () {
  for (int i = 0; i < maxNumberOfSensors; i++) {
    fill(sensorValue[i]);
    rect(rectSize * (i%rows), rectY, rectSize, rectSize); //top left
    if ((i+1) % rows == 0) rectY += rectSize;
  }
  rectY=0;
}

void serialEvent(Serial myPort) {
  String inString = myPort.readStringUntil('\n'); // get the ASCII string
  println("test");
  if (inString != null) { // if it’s not empty
    inString = trim(inString); // trim off any whitespace
    int incomingValues[] = int(split(inString, "\t")); // convert to an array of ints

    if (incomingValues.length <= maxNumberOfSensors && incomingValues.length > 0) {
      for (int i = 0; i < incomingValues.length; i++) {
        println("Raw sensor value: " + incomingValues[i]);
        sensorValue[i] = map(incomingValues[i], -50, 1000, 0, 255);
        println("Mapped sensor value: " + sensorValue[i]);
      }
    }
  }
}

This code in processing sets up a display window then creates the 3 x 3 by dividing the window into the rectangles. It then sets the background color to white. In the draw function, it sets the fill color of the rectangles based on the mapped sensor values.

When you are working in Processing, make sure that the Serial Monitor on Arduino IDE is closed before playing on Processing. Also, make sure to check which port/com you are using and change the value in the code as necessary.

ESP32-S3 Pressure Sensor Matrix

Using the ESP32 Microcontroller previously made, I created another 3 x 3 matrix of copper tape and velostat and tested it.

The rows are the analog pins (ADC1 on the ESP32 pinouts) that are connected to the pins and through a resistor to the GND of the board. The columns are the digital pins that connect directly to the pins of the esp.

Matrix to ESP

Code

The code includes some debugging to see if they are connecting and being read or not. The output will print the row and column indices along with the corresponding analog values and then after that will print the sensor values.

#define numRows 3
#define numCols 3
#define sensorPoints numRows * numCols

int rows[] = { 4, 5, 6 };  // Analog input pins (ADC1 channels)
int cols[] = { 35, 36, 37 };  // Digital output pins (GPIO pins)
int incomingValues[sensorPoints] = {};  // Array to store sensor values

void setup() {
  Serial.begin(9600);  // Initialize serial communication
  while (!Serial) {}   // Wait for the Serial Monitor to open
  delay(1000);         // Delay for stability

  for (int i = 0; i < numRows; i++) {
    pinMode(rows[i], INPUT);  // Set row pins as analog inputs
  }
  for (int i = 0; i < numCols; i++) {
    pinMode(cols[i], OUTPUT);  // Set column pins as digital outputs
  }
}

void loop() {
  // Read analog values from rows
  for (int colCount = 0; colCount < numCols; colCount++) {
    digitalWrite(cols[colCount], HIGH);  // Activate the current column
    for (int rowCount = 0; rowCount < numRows; rowCount++) {
      incomingValues[colCount * numRows + rowCount] = analogRead(rows[rowCount]);  // Read analog value from the row
      // Debugging output
      Serial.print("Analog value at (");
      Serial.print(rowCount);
      Serial.print(", ");
      Serial.print(colCount);
      Serial.print("): ");
      Serial.println(incomingValues[colCount * numRows + rowCount]);
    }
    digitalWrite(cols[colCount], LOW);  // Deactivate the current column
  }

  // Print sensor values
  Serial.println("Sensor values:");
  for (int i = 0; i < sensorPoints; i++) {
    Serial.print(incomingValues[i]);
    if (i < sensorPoints - 1)
      Serial.print("\t");
  }
  Serial.println();  // New line after all values are printed
  delay(100);        // Short delay before next loop iteration
}

Working Video

Showing the values fluctuate depending on the pressure of the matrix. Having the code show the values for each sensor allows to understand the ranges for each.

Now that the system works, I created the board to then use for the final project.

Component Quantity
10kOhm Resistor 6
Male Connectors 15