Einfache Schaltung, Coding Hilfe

Hallo liebe Arduino Freunde,

ich bin leider nicht sehr versiert im Umgang mit Boards wie dem Arduino aber habe aktuell ein Projekt, dass ich kurzfristig realisieren muss.

Folgende Ausgangssituation:

Ich habe einen Dehnungsmessreifen (mit 2 Kontakten), welcher dazu verwendet werden soll eine aufgebrachte Kraft zu erfassen. Hierbei gilt, dass sich der Widerstandswert des DMS verringert wenn die aufgebrachte Kraft ansteigt.

Nun soll der Arduino dazu verwendet werden eine grüne LED zum leuchten zu bringen, wenn eine bestimmte Kraft (bzw. ein bestimmter Widerstandswert des DMS) erreicht wird. Wenn die aufgebrachte Kraft größer oder kleiner ist, soll eine rote LED leuchten.

Hierzu habe ich mir folgende Schaltung überlegt:

DMS und ein fester Widerstand in Reihe an den Arduino angeschlossen. Die Spannung zwischen den beiden Widerständen wird abgegriffen und auf einen analogen Eingang gelegt.

Nach meinem Verständnis kann ich nun die sich ergebende Spannung erfassen (0-5V --> 0-1023).

Der Code den ich mir grob übelegt habe würde mithilfe einer if, else if, else Abfrage zwei digitale Ausgänge ansteuern und entsprechend der Aufgabenstellung eine rote bzw. eine grüne LED zum leuchten bringen.

Ich würde mich freuen wenn mich jemand mit etwas Erfahrung sagen könnte, ob das so funktionieren kann oder ob ich schon im Ansatz daneben liege.

Vielen Dank schonmal.

Falls irgendwas unklar ist kann ich auch noch die Schaltung oder so nachreichen.

MfG
ArduD2

Der Dehmungsmesstreifen verhält sich nicht wie ein Potentiometer, welches dir eine Spannung zwischen 0 und 5V liefert beim drehen. Die Widerstandsänderung eines DMS ist sehr gering. Die dazu korrospondierenden Spannungsänderungen liegen im Millivoltbereich - in der selben Größenordnung, wie die Auflösung des AD-Wandlers im letzten Bit!
Für sowas gibt es darauf spezialisierte ICs, die garnicht teuer sind.
Googele mal nach HX711. Den gibt es für etwas mehr als einen Euro auf einer briefmarkengroßen Platine.

Danke für die schnelle Antwort, werde mal noch etwas recherchieren.

Bei dem Sensor handelt es sich übrigens um einen FSR400 von Intelink Elektronics.

Das scheint für deine Bedürfnisse zu gehen:

Wenn der Vorwiderstand in der gleichen Größenordung wie der FSR bei deiner zu messenden Last ist, ist die Auflösung am größten ( also z.B. 10k bei ca. 200g )
FSR.png
Statt des opamp im Bild kannst du gleich einen Arduino-Analogpin nehmen.

Das mit den 2 if und 2 else ist schon richtig

void loop ()  {
  int wert = analogRead(A0);
  if (wert > MAX) rot();
  else if (wert < MIN) rot();
  else gruen();
}
void rot() {
  digitalWrite(REDPIN, HIGH);
  digitalWrite(GREENPIN, LOW);
}

Danke auch dir.

Auf das Bild war ich auch gerade im Datenblatt gestoßen.

Verstehe ich es richtig, dass ich also meine ursprünglich erdachte Schaltung verwenden kann?

Der Aufbau wie in deinem Bild, nur ohne OP, entspräche ja der oben von mir beschriebenen Idee.

Da ich wie gesagt neu bin auf dem Arduino....wieso kann ich auf den OP verzichten?

Der OP entkoppelt den Kraftsensor vom digitalen Eingang und paßt den Innenwiderstand an. Dies weil zum messen der Spannung der ADC einen kleinen Kondensator lädt und der Ladestrom bei zu hohen Widerständen im Spannungteiler (Sensor) nicht genügend groß ist damit der Konsensator in der vorgegebenen Zeit auf die volle Spannung auflädt. wenn Du keine schnellen Messungen brauchst kannst Du einen 0,1µF Kondensator zwischen analogen Eingang und masse schalten. Bei schnellen Lastwechseln bruchst Du den OP.
Grüße Uwe

Danke Uwe.
Was meinst du mit schnell? Denn “schnell” ist ja bei Embedded Anwendungen immer Definitionssache :wink:
Sekunden können da ja schon oft Ewigkeiten sein.

Es geht quasi darum über eine entsprechene Mechanik mit dem Finger eine Kraft auf eine Feder auszuüben um festzustellen, ob diese die “richtigen” Eigenschaften hat. Die Federkraft soll also nicht zu hoch und auch nicht zu niedrig sein.

Wenn jemand noch Lust und Zeit hat sich meinen Code durchzulesen und ihn zu zerreißen :wink: oder mir zu bestätigen, dass des so evtl. funzt…ich wäre demjenigen sehr verbunden. Letzteres wäre mir natürlich lieber.

Danke nochmal an Michael_x

int SensorPIN   = A0; //Definition des analogen Eingangs
int GREENPIN    = 12; //Definition des digitalen Ausgangs fuer die gruene LED
int REDPIN      = 13; //Definition des digitalen Ausgangs fuer die rote LED

    
int wert  = 0;  //Variablendeklaration fuer das Sensorsignal

int MAX         = 500;  //Definition des maximalen Spannungswertes
int MIN         = 300;  //Definition des minimalen Spannungswertes


void setup() {
  

  pinMode(GREENPIN, OUTPUT);  
  pinMode(REDPIN,   OUTPUT);  

}

void loop ()  {
  int wert = analogRead(A0);
  if (wert > MAX) rot();
  else if (wert < MIN) rot();
  else gruen();
}
void rot() {
  digitalWrite(REDPIN, HIGH);
  digitalWrite(GREENPIN, LOW);
}

void gruen() {
  digitalWrite(GREENPIN, HIGH);
  digitalWrite(REDPIN, LOW);
}

Du brauchst es nicht "schnell", wenn deine einzige Anwendung entweder eine rote oder grüne LED ist.
Wenn du Schingungen durch eine unterschiedliche resultierende Mischfarbe messen wolltest, wäre das etwas anderes :wink:

Der von Uwe vorgeschlagene Kondensator, aus dem sich beim Messen der ADC versorgt, schadet natürlich nicht.

Die globale Variable  int wert;  wird übrigens nicht verwendet und ist auch nicht erforderlich.
Sonst habe selbst ich nichts an deinem Sketch zu meckern.
Nachtrag: Doch, wenn du [b]const byte [/b] GREENPIN=12; schreibst (usw), wird dein Sketch ein bisschen kleiner.

Hallo michael_x, aus welchem Grund sollte der sketch kleiner werden. Hab ich nicht verstanden.
Habs probiert mit der IDE 1.6.7 und hat jedes mal die gleiche Größe

Dann hat der Optimizer seinen Job gut gemacht.
Das muss ihm nicht immer so gut gelingen.
Besser ist es, ihn zu seinem Glück zu zwingen, bzw. eine offensichtliche Chance zu geben.

Für einen Uno übersetzt:

int pin=13;
// const byte pin = 13;

void setup() {
  Serial.begin(9600);
  pinMode (pin, OUTPUT);
}

void loop() {
  digitalWrite(pin, ! digitalRead(pin));
}

const:
Der Sketch verwendet 2.170 Bytes ...
Globale Variablen verwenden 182 Bytes

int:
Der Sketch verwendet 2.178 Bytes
Globale Variablen verwenden 184 Bytes

"Aus welchem Grund?": const kann eben besser optimiert werden. Und die zwei Byte im RAM für int pin;   sind wirklich überflüssig.

Jau, danke nochmal an alle.

Es funktioniert (ohne OP und ohne Kondensator) :smiley:

Mal sehen ob ich noch dazu komme den Code zu optimieren.

Besten Gruß
ArduD2

Hallo michael_x
ich noch mal

Der Sketch verwendet 1.750 Bytes (5%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes.
Globale Variablen verwenden 182 Bytes (8%) des dynamischen Speichers, 1.866 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes.

das sagt die IDE 1.6.7 mit Arduino Uno egal ob ich " int pin=13;"oder " const byte pin = 13;" schreibe

Weiss nicht mit welchen sketch du testest.
Beim Sketch von ArduD2 - 2016-12-05, 19:59:54
ergibt sich für mich mit IDE 1.6.7 für Uno
entweder

int:
Der Sketch verwendet 1.022 Bytes (3%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes.
Globale Variablen verwenden 19 Bytes (0%) des dynamischen Speichers

oder

const:
Der Sketch verwendet 984 Bytes (3%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes.
Globale Variablen verwenden 11 Bytes (0%) des dynamischen Speichers

mit

const int SensorPIN   = A0; //Definition des analogen Eingangs
const int GREENPIN    = 12; //Definition des digitalen Ausgangs fuer die gruene LED
const int REDPIN      = 13; //Definition des digitalen Ausgangs fuer die rote LED
  
const int MAX         = 500;  //Definition des maximalen Spannungswertes
const int MIN         = 300;  //Definition des minimalen Spannungswertes

Interessanterweise spart das nur 8 Byte, obwohl 5 int-Variable wegfallen.SensorPinwurde auch so schon wegoptimiert, weil gar nicht verwendet.

Hatte den aus #10 verwendet.

mit dem sketch

int SensorPIN   = A0; //Definition des analogen Eingangs
int GREENPIN    = 12; //Definition des digitalen Ausgangs fuer die gruene LED
int REDPIN      = 13; //Definition des digitalen Ausgangs fuer die rote LED

   
int wert  = 0;  //Variablendeklaration fuer das Sensorsignal

int MAX         = 500;  //Definition des maximalen Spannungswertes
int MIN         = 300;  //Definition des minimalen Spannungswertes


void setup() {
 

  pinMode(GREENPIN, OUTPUT); 
  pinMode(REDPIN,   OUTPUT); 

}

void loop ()  {
  int wert = analogRead(A0);
  if (wert > MAX) rot();
  else if (wert < MIN) rot();
  else gruen();
}
void rot() {
  digitalWrite(REDPIN, HIGH);
  digitalWrite(GREENPIN, LOW);
}

void gruen() {
  digitalWrite(GREENPIN, HIGH);
  digitalWrite(REDPIN, LOW);
}

Der Sketch verwendet 834 Bytes (2%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes.
Globale Variablen verwenden 9 Bytes (0%) des dynamischen Speichers, 2.039 Bytes für lokale Variablen verbleiben. Das Maximum sind 2.048 Bytes.

so sieht das bei mir aus ob “int” oder “const int”
was ist bei mir anders als bei dir?

Blöde Frage zwischendurch. Ist die Größe eventuell abhängig vom Betriebssystem?
Ich nutze WIN10

Ist die Größe eventuell abhängig vom Betriebssystem?

Nöö...
Eher von der Toolchain, und ihren Einstellungen/Parametern.

Das wird jetzt interessant:
Bei mir werden diese Compiler-Optionen verwendet:

C:\Program Files (x86)\Arduino\1.6.7\arduino-builder -dump-prefs -logger=machine -hardware "C:\Program Files (x86)\Arduino\1.6.7\hardware" -hardware "C:\Users\michael_x\AppData\Local\Arduino15\packages" -hardware "C:\Users\michael_x\Documents\Arduino\hardware" -tools "C:\Program Files (x86)\Arduino\1.6.7\tools-builder" -tools "C:\Program Files (x86)\Arduino\1.6.7\hardware\tools\avr" -tools "C:\Users\michael_x\AppData\Local\Arduino15\packages" -built-in-libraries "C:\Program Files (x86)\Arduino\1.6.7\libraries" -libraries "C:\Users\michael_x\Documents\Arduino\libraries" -fqbn=arduino:avr:uno -ide-version=10607 -build-path "C:\Users\michael_x\AppData\Local\Temp\build7d8d693931ba46af4173879cfabfa4a5.tmp" -warnings=all -prefs=build.warn_data_percentage=75 -verbose "C:\Users\michael_x\Documents\Arduino\sketch_dec06a\sketch_dec06a.ino"
C:\Program Files (x86)\Arduino\1.6.7\arduino-builder -compile -logger=machine -hardware "C:\Program Files (x86)\Arduino\1.6.7\hardware" -hardware "C:\Users\michael_x\AppData\Local\Arduino15\packages" -hardware "C:\Users\michael_x\Documents\Arduino\hardware" -tools "C:\Program Files (x86)\Arduino\1.6.7\tools-builder" -tools "C:\Program Files (x86)\Arduino\1.6.7\hardware\tools\avr" -tools "C:\Users\michael_x\AppData\Local\Arduino15\packages" -built-in-libraries "C:\Program Files (x86)\Arduino\1.6.7\libraries" -libraries "C:\Users\michael_x\Documents\Arduino\libraries" -fqbn=arduino:avr:uno -ide-version=10607 -build-path "C:\Users\michael_x\AppData\Local\Temp\build7d8d693931ba46af4173879cfabfa4a5.tmp" -warnings=all -prefs=build.warn_data_percentage=75 -verbose "C:\Users\michael_x\Documents\Arduino\sketch_dec06a\sketch_dec06a.ino"
"C:\Program Files (x86)\Arduino\1.6.7\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Program Files (x86)\Arduino\1.6.7\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\1.6.7\hardware\arduino\avr\variants\standard" "C:\Users\michael_x\AppData\Local\Temp\build7d8d693931ba46af4173879cfabfa4a5.tmp\sketch\sketch_dec06a.ino.cpp" -o "nul"
...

Muss irgendwas in diesen Compiler-Optionen sein, was bei dir besser ist !
-c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -w -x c++ -E -CC -mmcu=atmega328p

Hallo Leute,

ich hätte noch mal eine grundsätzliche Frage...

Ich betreibe den Arduino Nano über vier 1.5 V Batterien (also mit 6V) über den VIN port.
Kann ich den Arduino Nano mit angeschlossenen Batterien gleichzeitig über USB an den PC anschließen um mir über die serielle Schnittstelle die Messwerte anzeigen zu lassen, oder zerschieße ich dann das Gerät?