Go Down

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

ma1kels

Jetzt mal doof gefragt, wo liegt der Unterschied zu dem gezeigten hier in dem Video: https://www.youtube.com/watch?v=xvmgzwjKnN4? Da funktioniert es doch auch nach dem Schema?!

ma1kels

Na ja, das ist noch der Code vom letzten Mal.

Mit dem du 1 von den 6 Spalten messen kannst,  (wenn du sie entsprechend anschliesst)

Aber sonst immer noch in Ordnung, schätze ich mal...
Der serielle Monitor hat mir jetzt mal bei starker Belastung der entsprechenden Reihe/Spalte Werte von bis zu 900 ausgegeben. Über Dreisatz kann ich mir nun also meinen Spannungswert errechnen oder? (5V = 1023 und xV = 900). Wie komme ich jetzt aber auf den Widerstandswert? Also R = U/I, doch was ist mein I? Und besteht die möglich dann anschließend noch einen Druckwert zu ermitteln?

michael_x

Über den Spannungsteiler

 U1 / (U1+ U2) = R1 / ( R1 + R2)

(U1 + U2) sind deine 5V

R2 ist dein Spannungsteiler-Widerstand


Aber brauchst du den Widerstand überhaupt ?
Und wie kriegt man bei solch einer Matte aus dem gemessenen Widerstand den Druck?

Einfacher dürfte es sein, zu gegebenen Gewichten die sich ergebenden Roh-Messwerte zu notieren.
Und auf einigermaßen lineare Verhältnisse hoffen.
Oder das Haupt-Augenmerk auf imposante gaphische Darstellung legen ;)


Nach dem verlinkten Video sieht das Ganze ja einfach und problemlos aus, Viel Erfolg ! 


ma1kels

Nach dem verlinkten Video sieht das Ganze ja einfach und problemlos aus, Viel Erfolg ! 

Ich habe es auch bereits mit dem dort verwendeten code versucht umzusetzen. Habe diesen natürlich auf eine 12x6 Matrix angepasst, sowohl im Arduino als auch im Processing. Ändere ich die beiden Sketche nicht, also starte ich es mit 15x15, dann läuft alles bis auf die Darstellung im Processing, die zeigt mir natürlich 225 Kästchen an. Aber sobald ich alle Befehle auf 12x6 anpasse und wieder auf den Arduino spiele, dann zeigt mir die Darstellung zwar 72 Kästchen an, aber es tut sich nicht wirklich was. Woran könnte es liegen?

michael_x

#34
Jul 12, 2018, 02:34 pm Last Edit: Jul 12, 2018, 02:45 pm by michael_x
Woran könnte es liegen?

An deiner Anpassung ;)

"Sowohl im Arduino als auch im Processing"

ma1kels

Woran könnte es liegen?

An deiner Anpassung ;)

"Sowohl im Arduino als auch im Processing"
Vielleicht kann ja mal einer noch darüber gucken?
Hier der Processing Code:
Code: [Select]


import processing.serial.*;
import processing.opengl.*;


int bgcolor;                 // Background color
int fgcolor;                 // Fill color
Serial myPort;                       // The serial port
int[] serialInArray = new int[72];    // Where we'll put what we receive
int[] pastInArray = new int [72];
float[][] colorTarget   = new float[3][255];
float[][] currentColor   = new float[3][255];
PVector[][] vertices = new PVector[6][12];
float[] verticesTZ = new float[12];
float w = 18;
float ease = 0.75;

int serialCount = 0;                 // A count of how many bytes we receive
int xpos, ypos;                  // Starting position
boolean firstContact = false;        // Whether we've heard from the microcontroller
int tiempoant;
int render=0;
int dif=0;

void setup() {
  size(960, 600, OPENGL);  // Stage size
  noStroke();      // No border on the next thing draw
 
 
  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
 
  myPort = new Serial(this, Serial.list()[1], 115200);
 
  for (int j = 0; j < 12; j++) {
        for (int i = 0; i < 6; i++) {
            vertices[i][j] = new PVector( i*w, j*w, 0);
        }
    }
   
 
}

void draw() {

  if (render==1) {
   
    translate(width/4, 100);
    rotateX(0.5);
    //rotateX(PI/10);
    background(0);
    for (int j=0; j<11; j++) {
      beginShape(QUAD_STRIP);
      for (int i=0; i<6; i++) {
          stroke(255);
     
          fill(serialInArray[j*6+i], 0, 0);
          float x = i*width/12;
          float y = j*height/6;
          verticesTZ[i] = serialInArray[j*6+i];
         
          vertices[i][j].z += (verticesTZ[i]-vertices[i][j].z)*ease;
          vertex( vertices[i][j].x, vertices[i][j].y, vertices[i][j].z);
          vertex( vertices[i][j+1].x, vertices[i][j+1].y, vertices[i][j+1].z);
        }
         endShape(CLOSE);
        //        println();
      }
      render=0;
  }
}

void serialEvent(Serial myPort) {
  // read a byte from the serial port:
  int inByte = myPort.read();
  // if this is the first byte received, and it's an A,
  // clear the serial buffer and note that you've
  // h
  //  ad first contact from the microcontroller.
  // Otherwise, add the incoming byte to the array:
  if (firstContact == false) {
    if (inByte == 'A') {
      myPort.clear();          // clear the serial port buffer
      firstContact = true;     // you've had first contact from the microcontroller
      myPort.write('A');       // ask for more
    }
  } else {
    // Add the latest byte from the serial port to array:

      serialInArray[serialCount] = inByte;

    serialCount++;

    // If we have 3 bytes:
    if (serialCount > 71 ) {
      println(millis()-tiempoant);
      tiempoant = millis();
     
      render = 1;
   
      // Send a capital A to request new sensor readings:
      myPort.write('A');
      // Reset serialCount:
      serialCount = 0;
    }
  }
}


Und hier das Arduino Pendant:
Code: [Select]


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

//Mux control pins for Output signal (OUT_pin) default for arduino mini pro
const byte w0 = 9;
const byte w1 = 8;
const byte w2 = 7;
const byte w3 = 6;

//Mux in "SIG" pin default for arduino mini pro
const byte SIG_pin = 0;

//Mux out "SIG" pin default for arduino mini pro
const byte OUT_pin = 5;

//Row and Column pins default for arduino mini pro
const byte STATUS_pin = 3;
const byte COL_pin = 2;

const boolean muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };


//incoming serial byte
int inByte = 0;

int valor = 0;               //variable for sending bytes to processing
int calibra[12][6];         //Calibration array for the min values of each od the 72 sensors.
int minsensor=254;          //Variable for staring the min array
int multiplier = 254;
int pastmatrix[12][6];

void setup(){
   
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
 
  pinMode(w0, OUTPUT);
  pinMode(w1, OUTPUT);
  pinMode(w2, OUTPUT);
  pinMode(w3, OUTPUT);
 
  pinMode(OUT_pin, OUTPUT);
 
  pinMode(STATUS_pin, OUTPUT);
  pinMode(COL_pin, OUTPUT);

 
  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
 
  digitalWrite(w0, LOW);
  digitalWrite(w1, LOW);
  digitalWrite(w2, LOW);
  digitalWrite(w3, LOW);
 
  digitalWrite(OUT_pin, HIGH);
  digitalWrite(STATUS_pin, HIGH);
  digitalWrite(COL_pin, HIGH);
 
 
 
  Serial.begin(115200);
 
  Serial.println("\n\Calibrating...\n");
 
  // Full of 0's of initial matrix
  for(byte j = 0; j < 12; j ++){
    writeMux(j);
    for(byte i = 0; i < 6; i ++)
      calibra[j][i] = 0;
  }
 
  // Calibration
  for(byte k = 0; k < 50; k++){ 
    for(byte j = 0; j < 12; j ++){
      writeMux(j);
      for(byte i = 0; i < 6; i ++)
        calibra[j][i] = calibra[j][i] + readMux(i);
    }
  }
 
  //Print averages
  for(byte j = 0; j < 12; j ++){
    writeMux(j);
    for(byte i = 0; i < 6; i ++){
      calibra[j][i] = calibra[j][i]/50;
      if(calibra[j][i] < minsensor)
        minsensor = calibra[j][i];
      Serial.print(calibra[j][i]);
      Serial.print("\t");
    }
  Serial.println();
  }
 
  Serial.println();
  Serial.print("Minimum Value: ");
  Serial.println(minsensor);
  Serial.println();
 
  establishContact();
 
  digitalWrite(COL_pin, LOW);
}


void loop(){
  //Loop through and read all 16 values
  //Reports back Value at channel 6 is: 346
  if (Serial.available() > 0){
    inByte = Serial.read();
   
    if(inByte == 'A'){
   
      for(int j = 12; j >= 0; j--){
        writeMux(j);
       
        for(int i = 0; i < 7; i++){
           
          valor = readMux(i);
         
          //Saturation sensors
          int limsup = 450;
          if(valor > limsup)
            valor = limsup;
           
          if(valor < calibra[j][i])
            valor = calibra[j][i]; 
         
          valor = map(valor,minsensor, limsup,1,254);
         
          if(valor < 150)
            valor = 0;
          if(valor > 254)
            valor = 254;
         
          Serial.write(valor);
          digitalWrite(COL_pin,!digitalRead(COL_pin));
        }
      }
    }
       
  }
}


int readMux(byte channel){
  byte controlPin[] = {s0, s1, s2, s3};

  //loop through the 4 sig
  for(int i = 0; i < 4; i ++){
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }

  //read the value at the SIG pin
  int val = analogRead(SIG_pin);

  //return the value
  return val;
}

void writeMux(byte channel){
  byte controlPin[] = {w0, w1, w2, w3};

  //loop through the 4 sig
  for(byte i = 0; i < 4; i ++){
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A');   // send a capital A
    delay(300);
  }
}


Im Anhang ist ein Foto der Darstellung die ich von Processing bekomme. Nur dass das Ganze sich ständig bewegt.

DrDiettrich

Mir kommen die Konstruktoren mit "new int[]..." verdächtig vor. Falls hier die Arrays zur Laufzeit erzeugt werden, kann das zu Problemen mit dem dynamischen Speicher führen.

michael_x

@DrDiettrich:  Die Überschriften "Arduino Code" / "Processing Code" sind vertauscht.

import processing.serial.*; ist natürlich Java.

DrDiettrich

Ah ja, ich habe mich schon über setup() und loop() im Processing Code gewundert ;-)

ma1kels

@DrDiettrich:  Die Überschriften "Arduino Code" / "Processing Code" sind vertauscht.

import processing.serial.*; ist natürlich Java.
Stimmt, auch eben erst gemerkt. Sorry dafür :)

ma1kels

Kann mir nochmal jemand sagen wie ich den Widerstand für den Spannungsteiler wähle? Wenn ich mein Multimeter anschließe zeigt mir dieses einen sich dauernd abnehmenden Wert beginnend bei 50kOhm bis ca 20kOhm... beim Aufbringen von Druck ändert sich dieser auf etwa 2 - 1,5kOhm.

DrDiettrich

Vielleicht kriecht das Material beim Auflegen der Meßspitzen. Der Meßwiderstand sollte etwa in der Mitte des Widerstandsbereichs liegen, wobei die Obergrenze schon durch die normale Belastung (Körpergewicht) begrenzt ist.

SpaghettiCode

Hi,

die Messung des Widerstandes ist am genauesten, wenn Du oben wie unten den gleichen Spannungswert hast (rawADC 1024 / 2), zu den Rändern hin wird der Wert immer ungenauer. Die Messfehlerkurve ergibt eine Badewanne zwischen den Werten 0 bis 1023, in der Mitte flach (genau) und knapp vor dem Rand jeweils steil ansteigend. Da Du Werte zwischen 1,5k und ca. 20k nennst, würde ich ca. 5,4k Ohm nehmen, dann hast Du in Richtung 1,5k Faktor 3,6x wie auch in Richtung 20k, liegst also in der Mitte Deiner genannten Daten.

Gruß André

Go Up