Go Down

Topic: Resistives Sensorarray für eine Schuhsohle (Velostat) (Read 4079 times) previous topic - next topic

ma1kels

Hi! Das hier ist mein erstes Arduino-Projekt, welches ich für die Uni benötige.
Ich habe eine Schuhsohle gebastelt mit je 6 Spalten und 12 Zeilen an Kupferbahnen (Bild ist angehängt). Dazwischen liegt eine Velostat-Schicht. Teste ich das Ganze vorab mit dem Multimeter scheint es auch ganz gut zu funktionieren. So für die Auswertung habe ich mir zwei 16-Channel-Analog Multiplexer von SparkFun besorgt und programmieren möchte ich es mit einem Arduino Pro Mini.

Meine Frage jetzt, weiß jemand wie ich die Kreuzungen der Kupferbahnen, also die einzelnen Sensorelemente, über den seriellen Monitor auslesen kann? (Widerstand? Spannung? Druck?)
Evtl. wäre auch ein Sketch für Arduino und Processing zur visualisierten Darstellung wo auf der Sohle und wie stark der Druck aufgebracht wird, hilfreich.

Ich bedanke mich schon herzlichst im Voraus bei euch allen!!


michael_x

Und die 6*12 = 72 Widerstand-Werte zu erfassen ist kein Problem?
Toll. (Zeig mal ;) )


Wie schnell soll das Ganze sein?
Die Auflösung ist vermutlich nicht so hoch. Ein Byte/Wert reicht sicher; wenn das Ergebnis nur als verschiedene Farben dargestellt wird, evtl. sogar nur Werte '0' ...'9'

DrDiettrich

Die Widerstände hängen über die Velostat-Schicht zusammen, nehme ich an. Oder gehört zu jeder Kreuzung ein isolierter Velostat-Punkt?

Ein Arduino kann nur Spannungen messen, es muß also über einen Multiplexer eine Spannung an eine Sensor-Zeile gelegt werden, mit dem anderen Multiplexer wird die Spalte ausgewählt, und mit einem Analog-Eingang und einem Ableit-Widerstand nach Gnd verbunden werden (Spannungsteiler). Mit 6 Analog-Eingängen kann man den zweiten Mux auch sparen, nur geht dann kein I2C mehr (benutzt A5/A6).

michael_x

Quote from: ma1kels
zwei 16-Channel-Analog Multiplexer von SparkFun
Wenn es die hier sind oder etwas ähnliches, reicht eigentlich einer, der mit 4 Adress-Bits einen von 12 (16) Kanälen lesen kann. 6 Ausgangspins für die Spalten, bleibt Rx / Tx frei für den "SerialMonitor" bzw. das PC - Anzeige/Auswerteprogramm.

Quote
Teste ich das Ganze vorab mit dem Multimeter scheint es auch ganz gut zu funktionieren.
Ich nehme mal an, du nimmst einen Widerstandsmessbereich und misst zwischen einer Spalte und eine Zeile? Wenn du dann den Kreuzungspunkt belastest, ändert sich der Messwert ?

Mit dem Arduino kannst du nur Spannungen messen. Brauchst also einen zusätzlichen konstanten Widerstand, der mit deinem Messwiderstand einen Spannungsteiler bildet.
Code: [Select]

Spalten  1 ... 6 

Zeilen  A0 ... A11 

            |
            |
   S0 ---- MUX  --- SIG --+-- R ---- GND
   S1 ----                |
   S2 ----                +--------- A0
   S3 ----

 Eine der Spalten 1..6 HIGH und die 4 Adress-Bits S0 .. S3 per Arduino OUTPUT einstellen, und an A0 kann der entsprechende Messwert gelesen werden.

Die Auflösung ist am besten, wenn der Widerstand R eine ähnliche Größenordnung hat wie der Widerstand zwischen Zeile und Spalte.

Erstmal je Adresse die 6 Spalten lesen und nacheinander in einer Zeile die Werte auf Serial ausgeben.
Dann das gleiche für die nächste Adresse in der nächsten Zeile.

Zum Spass kannst du den Messwert vor der Ausgabe durch 100 teilen und bekommst so nur einstellige Zahlen, die sich so von selbst in einer Matrix abbilden, die deiner Schuhsohle entspricht. ( Sowas meinte ich mit geringer Auflösung)

ma1kels

okay, den ersten Teil verstehe ich. Aber mit dem "code" verstehe ich nicht ganz was du mir sagen willst?!

Und ab hier..

Quote
Die Auflösung ist am besten, wenn der Widerstand R eine ähnliche Größenordnung hat wie der Widerstand zwischen Zeile und Spalte.

Erstmal je Adresse die 6 Spalten lesen und nacheinander in einer Zeile die Werte auf Serial ausgeben.
Dann das gleiche für die nächste Adresse in der nächsten Zeile.

Zum Spass kannst du den Messwert vor der Ausgabe durch 100 teilen und bekommst so nur einstellige Zahlen, die sich so von selbst in einer Matrix abbilden, die deiner Schuhsohle entspricht. ( Sowas meinte ich mit geringer Auflösung)
.. hört es bei mir ganz auf  :( Also ich verstehe es was du meinst, aber ich hab keine Ahnung wie man das im Arduino Sketch umsetzt.

Hier ist mal der Steckbrett-Aufbau (Auf dem Bild wird ein Array von 15x15 verwendet, bei mir bleibt es 6x12): https://cdn.instructables.com/FDC/6B90/IB3HOF9S/FDC6B90IB3HOF9S.LARGE.jpg und im Anhang ist ein Bild des Sohlen-Aufbaus zu sehen.

Auf jeden Fall vielen Dank für die bereits geleistete Hilfe.

gregorss

.. hört es bei mir ganz auf  :( Also ich verstehe es was du meinst, aber ich hab keine Ahnung wie man das im Arduino Sketch umsetzt.
Michael spricht vom Messen (Spannungen mit dem Multimeter). Da musst Du im Sketch überhaupt nichts tun.

Gruß

Gregor
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

LD-

Bei dir ändert sich der Widerstand der Schicht zwischen den Kontakten. Du misst quasi immer den Widerstand zwischen den beiden Bahnen eines Kreuzungspunktes deiner Sohle. Mit dem Multimeter gar kein Problem, dummerweise kann ein MCU keinen Widerstand direkt messen. Allerdings können sie meist recht gut Spannung messen. Also wandelst du den Widerstandswert in eine Spannung um mittels eines Spannungsteilers. Ein solcher besteht in der Regel aus 2 Widerständen in Reihe, wobei die Spannung in der Mitte der beiden Widerstände gemessen wird. Du hast bis jetzt nur einen Widerstand (genauer 72x einen Einzelwiderstand, welcher seinen Wert ändert). Um einen Spannungsteiler daraus zu machen brauchst du einen festen Referenzwiderstand. Dieser sollte ungefähr in der Größenordnung liegen, in der sich auch der Widerstandswert deiner Schickt befindet. Ansonsten geht die Änderung durch das Draufdrücken auf die Schicht komplett unter.

Wenn es jetzt ans Programmieren geht einfach über den Mux einen der Kreuzungspunkte wählen und über "analogRead(Pin)" den Spannungswert auslesen. Anschließend kannst du diesen in den eigentlichen Wiederstandwert oder auch in einen Druck umrechnen.

Um zu schauen ob es geht einfach alle 72 Werte als lange Zeile oder in einer Art kleinen Tabelle ausgeben (Im Setup: Serial.begin(), im Loop: Serial.println("text")). Sieht nicht hübsch aus, aber du solltest sehen, dass sich die Werte ändern. Später kann man das ganze dann als Pixel darstellen.

ma1kels

Quote
Bei dir ändert sich der Widerstand der Schicht zwischen den Kontakten. Du misst quasi immer den Widerstand zwischen den beiden Bahnen eines Kreuzungspunktes deiner Sohle. Mit dem Multimeter gar kein Problem, dummerweise kann ein MCU keinen Widerstand direkt messen. Allerdings können sie meist recht gut Spannung messen. Also wandelst du den Widerstandswert in eine Spannung um mittels eines Spannungsteilers. Ein solcher besteht in der Regel aus 2 Widerständen in Reihe, wobei die Spannung in der Mitte der beiden Widerstände gemessen wird. Du hast bis jetzt nur einen Widerstand (genauer 72x einen Einzelwiderstand, welcher seinen Wert ändert). Um einen Spannungsteiler daraus zu machen brauchst du einen festen Referenzwiderstand. Dieser sollte ungefähr in der Größenordnung liegen, in der sich auch der Widerstandswert deiner Schickt befindet. Ansonsten geht die Änderung durch das Draufdrücken auf die Schicht komplett unter.
Das heißt also ich messe nochmal den Widerstand zwischen den beiden Bahnen eines Kreuzungspunktes und wähle dann einen Referenzwiderstand der dieser Größenordnung entspricht, richtig?! Wie verschalte ich diesen dann auf dem Steckbrett? An den VCC-Pin des Arduino? Sorry für die banalen Fragen, aber für mich ist es nicht ganz so simpel  :smiley-confuse:

 
Quote
Wenn es jetzt ans Programmieren geht einfach über den Mux einen der Kreuzungspunkte wählen und über "analogRead(Pin)" den Spannungswert auslesen
Ich schließe quasi meine Sohle jetzt an die beiden Mux an und über "analogRead(Pin)" wähle ich die entsprechenden Kanäle dann?

michael_x

#8
Jul 09, 2018, 12:11 pm Last Edit: Jul 09, 2018, 02:42 pm by michael_x Reason: Ergänzung
Sorry für die Verwirrung. "Code"-Formatierung habe ich nur verwendet, damit die Ascii-Grafik besser rüber kommt.
GND und A0 sind Arduino Pins
S0 ... S3 sind Multiplexer Pins die vom Arduino angesteuert werden
A0 ... A11 sind die Multiplexer Eingänge
SIG der Multiplexer Ausgang
R der Spannungsteiler-Widerstand

--- + |  sollen Verbindungen darstellen und das Ganze einen Schaltplan, keinen Code.



Quote
Ich schließe quasi meine Sohle jetzt an die beiden Mux an und über "analogRead(Pin)" wähle ich die entsprechenden Kanäle dann?
Wenn du unbedingt zwei Mux verwenden willst, adressierst du über einen eine Spalte und über den anderen eine Zeile. und nutzt aus, dass die Mux bidirektional arbeiten. Der eine SIG bekommt 5V und schaltet diese auf 1 von 6 (16) Ausgängen, der andere SIG hat liefert dann die Spannung hinter dem Messwiderstand.

Um den Analogwert zu lesen brauchst du nur einen einzigen Analog-Eingang und einen Spannungsteiler-Widerstand.

ma1kels

Eine der Spalten 1..6 HIGH und die 4 Adress-Bits S0 .. S3 per Arduino OUTPUT einstellen, und an A0 kann der entsprechende Messwert gelesen werden.


Erstmal je Adresse die 6 Spalten lesen und nacheinander in einer Zeile die Werte auf Serial ausgeben.
Dann das gleiche für die nächste Adresse in der nächsten Zeile.

Wenn es jetzt ans Programmieren geht einfach über den Mux einen der Kreuzungspunkte wählen und über "analogRead(Pin)" den Spannungswert auslesen. Anschließend kannst du diesen in den eigentlichen Wiederstandwert oder auch in einen Druck umrechnen.

Um zu schauen ob es geht einfach alle 72 Werte als lange Zeile oder in einer Art kleinen Tabelle ausgeben (Im Setup: Serial.begin(), im Loop: Serial.println("text")). Sieht nicht hübsch aus, aber du solltest sehen, dass sich die Werte ändern. Später kann man das ganze dann als Pixel darstellen.
So ich habe jetzt mal die hier erwähnten Hinweise versucht als code darzustellen ... Kann jemand mal darüber gucken und mir feedback geben ob es den so gemeint ist?

Code: [Select]

//Mux control pins for output signal (OUT_pin) default for arduino mini pro
const byte s0 = 13;
const byte s1 = 12;
const byte s2 = 11;
const byte s3 = 10;

int columnPin = 9;

int analogPin = A0;

int val = 0;

void setup() {
 
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);

  digitalWrite(columnPin, HIGH);

  Serial.begin(9600);

  
}

void loop() {
  val = analogRead(analogPin);
  Serial.println(val);

}

michael_x

Das ist doch schonmal ein Anfang ;)

Ich sehe jetzt nicht genau, wofür
   int columnPin = 9;
gut ist.

Willst du 1 oder 2 Multiplexer verwenden?
( Im Augenblick verwendest du noch gar keinen, bzw. liest permanent von Kanal 0 )

Erstmal mit nur einem MUX und ohne dynamische Spalten-Anwahl:
Musst du nacheinander die Kanäle 0 .. 11  des MUX adressieren.

z.B. so oder ähnlich:

Code: [Select]
...
byte kanal = 0; // Wertebereich 0 .. 11
void loop () {
  setzeMUXAdresse(kanal, s0, s1, s2, s3) ;
  int val =  analogRead(analogPin);
  Serial.print ("Kanal "); Serial print(kanal);
  Serial.print(" : "); Serial.println(val);
  delay(100); // zum Test verlangsamen
  kanal++;
  if (kanal > 11) kanal = 0;
}

void setzeMUXAdresse(byte kanal, const byte S0, const byte S1, const byte S2, const byte S3) {
  digitalWrite(S0, bitRead(kanal, 0);
  digitalWrite(S1, bitRead(kanal, 1);
  digitalWrite(S2, bitRead(kanal, 2);
  digitalWrite(S3, bitRead(kanal, 3);
}
Mit den vielen Parametern kannst du die Funktion setzeMUXAdresse mehrfach (für zwei MUX) verwenden.

ma1kels





Quote
Willst du 1 oder 2 Multiplexer verwenden?
( Im Augenblick verwendest du noch gar keinen, bzw. liest permanent von Kanal 0 )
Na wenn es mit 1 Multiplexer auch geht, dann erstmal einen ;)

Quote
Erstmal mit nur einem MUX und ohne dynamische Spalten-Anwahl:
Musst du nacheinander die Kanäle 0 .. 11  des MUX adressieren.

z.B. so oder ähnlich:

Okay, ich hab den sketch jetzt mal angepasst und deinen part noch eingebunden. Der serielle Monitor gibt mir jetzt Kanal 0: 0 - Kanal 11:0 aus. (Habe die Schaltung noch nicht umgebaut und den Spannungsteiler noch nicht drin.) Wenn das dann richtig aufgebaut ist sollte mir hier die Spannung angezeigt werden, richtig? Also ich drücke quasi auf meiner Sohle auf einen Kreuzungspunkt von Spalte und Reihe und je nachdem welche Reihe (Kanal 0-11) nun belastet wird, so zeigt mir der serielle Monitor den entsprechenden Wert?

Wo schließe ich den aber jetzt mein Kabel mit den 6 Pins an? Also die 12 Pins kommen ja an den Multiplexer an Ch 0-11, soweit ist es mir klar.

Danke!  

Hier mein aktueller code:


Code: [Select]

//Mux control pins for output signal (OUT_pin) default for arduino mini pro
const byte s0 = 13;
const byte s1 = 12;
const byte s2 = 11;
const byte s3 = 10;

int analogPin = A0;

int val = 0;

byte kanal = 0; // Wertebereich 0 .. 11

void setup() {
 
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);


  Serial.begin(9600);
 
}

void loop() {
  setzeMUXAdresse(kanal, s0, s1, s2, s3) ;
  int val =  analogRead(analogPin);
  Serial.print("Kanal"); Serial.print(kanal);
  Serial.print(" : "); Serial.println(val);
  delay(500);
  kanal++;
  if (kanal > 11) kanal = 0;
}

void setzeMUXAdresse(byte kanal, const byte S0, const byte S1, const byte S2, const byte S3) {
  digitalWrite(S0, bitRead(kanal, 0));
  digitalWrite(S1, bitRead(kanal, 1));
  digitalWrite(S2, bitRead(kanal, 2));
  digitalWrite(S3, bitRead(kanal, 3));
}

michael_x

Ich würde langsam vorgehen, und mich erstmal über 12 lebende Messwerte freuen, bevor ich auch noch die 6 Spalten schalte.

Dazu brauchst du nur die interessierende Spalte mit 5V zu verbinden und den Widerstand zwischen GND und den Analog-Eingang = MUX - Ausgang. Fertig ist der Spannungsteiler.


Statt 5V kannst du natürlich auch einen von 6 weiteren Ausgängen verwenden, die du an die Spalten anschliesst und so das Spalten-Multiplexen direkt machst.

ma1kels

Ich würde langsam vorgehen, und mich erstmal über 12 lebende Messwerte freuen, bevor ich auch noch die 6 Spalten schalte.
Na ich kriege aber doch keinen Messwert wenn ich nur die 12 Reihen schalte, weil dieser entsteht doch durch den Kontakt von "Spalte - Velostat - Reihe" ?! Oder verstehe ich dich jetzt falsch?


Quote
Statt 5V kannst du natürlich auch einen von 6 weiteren Ausgängen verwenden, die du an die Spalten anschliesst und so das Spalten-Multiplexen direkt machst.
Von welchen Ausgängen ist die Rede? Mit 5V direkt verbinden wird nicht gehen da ich die Spalten und Reihen ja über Flachbandkabel mit 6-poligen und 12-poligen Steckverbinder kontaktiert habe.

michael_x

#14
Jul 11, 2018, 02:18 am Last Edit: Jul 11, 2018, 02:19 am by michael_x Reason: mit Bild
Mir ist ein Problem aufgefallen:
Wenn alle Kreuzungspunkte mit der Velostat-Widerstandsmatte untereinander verbunden sind, bräuchte man noch zusätzlich in jedem Kreuzungspunkt eine Diode, um das Ganze frei von Rückwirkungen zu halten, oder ?

Aber das müsste auch schon bei deiner direkten Widerstandmessung zwischen einem Spalten- und einem Reihendraht der Fall sein, auch wenn die gerade nicht aktiven Reihen und Spalten nicht auf LOW, sondern offen sind.

Oder habe ich da einen Denkfehler ?

Go Up