There were two tensile testing machines, which were outdated in terms of data-logging. So to say they "logged" their data, by drawing with a pencil on a moving paper.
But these drawings on those papers were not very useful. So we needed a method to measure that data digitally to compute graphs out of it.
The machines had in common, that there were moving counter-weights. These counter-weight moved a slider, on which the pencil would be mounted on. When applying force to the testing parts, these slider would move: So at this spot, we could measure the applied force!

The tensile testing machine.

The moving part: slider.

The first idea:
Attaching a acceleration sensor on the moving slider. So to integrate the acceleration of a specific axis twice, to get the moved distance. The distance could be converted by a function to the applied force.
A prototype turned out to be not effective, due to too much noise in the measurements, when the slider is moving too slow. So, this method was discarded.

The second idea: Measuring the distance between a fixed starting point and the slider. The outcome of this measurement would be dependent on the resolution of the sensor. A VL6180X sensor was selected by it's specifications of measurable distance (15mm to 120mm) which was perfect in our case. Also it had a pretty decent resolution of 1mm.

The prototype was later cased. Additionally parts were added.

Circuit example of the prototype.

The prototype was mounted:

And a test was made:
Click here to go to the video.

The outputed graph turned out to be in good quality:

Later the finished product was assembled and cased nicely:

The following code was used to output the measured data to asd-card:
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include "Adafruit_VL6180X.h"
const float feed = 2.95; // Vorschub in mm/s
const int timestep = 5; // Timestep in unit * s
const float unit = pow(10, -3);
int loopcount = 0;
Adafruit_VL6180X vl = Adafruit_VL6180X();
File myFile;
void setup() {
  while (!Serial) {
  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  Serial.println("initialization done.");
  // Open the file and start data-logging
  myFile ="data.txt", FILE_WRITE);
  if (myFile) {
  } else {}
void loop() {
  // Reading distance sendor
  uint8_t distance = vl.readRange();
  uint8_t status = vl.readRangeStatus();
  if (status == VL6180X_ERROR_NONE) {
    Serial.println(" ");
    // Log distance on SD Card
    myFile ="data.txt", FILE_WRITE);
    if (myFile) {
      myFile.println("x.append(" + String(loopcount*timestep*feed*unit) + ")");
      myFile.println("y.append(" + String(distance) + ")");
    } else {}

Where the following code was used to get a graph from the SD-Card data:
import matplotlib.pyplot as plt
x = []
y = []

f = lambda x: -172.738+9.5728*x-0.129813*x**2+0.000927464*x**3+9.97949441548167*10**(-7)*x**4-3.642889412070504*10**(-8)*x**5+1.0685472812988267*10**(-10)*x**6

y_dN = [f(el) for el in y]

fig = plt.figure()
ax1 = fig.add_axes((0.1, 0.2, 0.8, 0.7))

ax1.set_title('Zugversuch 29.03.2020 \n *** GmbH & Co KG')
ax1.set_xlabel('Elongation in mm seit Messbeginn')
ax1.set_ylabel('Zuglast in daN')

ax1.scatter(x, y_dN, s=2)

# center text
fig.text(0.5, 0.04, 'Band, Kennblatt 3103 \n max. Zugkraft (abgelesen): 3880N, max. Elongation: 84mm', ha='center', bbox=dict(facecolor='white', alpha=0.5))
#fig.text(0.5, 0.5, '*** GmbH & Co KG', fontsize=20, ha='center', alpha=0.5, bbox=dict(facecolor='black', alpha=0.125))

#fig.set_size_inches(7, 5, forward=True)

Or as a part of my project "mercurial" the following piece of javascript could be used to transfer the data directly in the browser:
async function loadFileAsText() {
  var fileToLoad = document.getElementById("f_i").files[0];
  var o = Array();

  var fileReader = new FileReader();
  let promise = new Promise((resolve, reject) => {
    fileReader.onload = function(fileLoadedEvent){
      var textFromFileLoaded =;
      var lines = textFromFileLoaded.split('\n');
      for (var i = 0; i < lines.length; i++) {
  fileReader.readAsText(fileToLoad, "UTF-8");

  await promise;

  return o;

function convert(x) {
  return -172.738+9.5728*x-0.129813*x**2+0.000927464*x**3+9.97949441548167*10**(-7)*x**4-3.642889412070504*10**(-8)*x**5+1.0685472812988267*10**(-10)*x**6

async function drawData() {                
  o = await loadFileAsText();

  var feed = parseFloat(document.getElementById('feed').value);
  var title = document.getElementById('title').value;
  var subtitle = document.getElementById('subtitle').value;
  var xaxis = document.getElementById('x-axis').value;
  var yaxis = document.getElementById('y-axis').value;

  var o_x = Array();
  o[0].forEach(element => {
    o_x.push(element * feed);
  var o_y = Array();
  o[1].forEach(element => {
  o[0].forEach(element => {

  var trace = {
    x: o_x,
    y: o_y,
    type: 'scatter',
    mode: 'markers'
  var data = [trace];
  var layout = {
    title: title + '
' + subtitle + '', xaxis: { rangemode: 'tozero', showgrid: false, title: { text: xaxis, font: { family: 'Courier New, monospace', size: 18, color: '#7f7f7f' } }, }, yaxis: { rangemode: 'tozero', showgrid: false, title: { text: yaxis, font: { family: 'Courier New, monospace', size: 18, color: '#7f7f7f' } } }, //autosize: false, showlegend: false, grid: { columns: 2 } }; Plotly.newPlot('plot', data, layout); }