Arduino Forum

International => Deutsch => Topic started by: makertom on Aug 26, 2015, 03:22 pm

Title: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 26, 2015, 03:22 pm
Ich messe mit einem Arduino Uno die Aufladespannung eines Kondensators. Wenn die Spannung von 0,01V überschritten ist, soll der Arduino mit der millis() Funkton anfangen zu zählen. Wenn dann 3,16V erreicht ist soll die Zeit die der Kondensator brauchte um bis 3,16V zu laden in Millisekunden auf einem Display angezeigt werden.

Könnt ihr mir helfen wie ich die Zeit ausmessen kann?
Ich bin für jede Hilfe dankbar.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: Serenifly on Aug 26, 2015, 03:32 pm
Hast du vor das mit dem ADC zu messen? Das wird etwas kritisch bei 10mV mit 4,88mV Auflösung. Ein Komparator wäre da genauer. Den kann man an einem normalen digitalen Eingang abfragen, oder auch per Interrupt.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 26, 2015, 03:45 pm
@ Serenifly
Danke für deine Antwort.
ich denke der ADC sollte zum Messen ausreichen.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: michael_x on Aug 26, 2015, 03:57 pm
Quote
ich denke der ADC sollte zum Messen ausreichen.
Wenn ganze millis, ca. +-5mV als Auflösung und Vcc als Vref für nom. 5V  reichen, dann ja.

analogRead(), millis() und eine passende LCD library für dein Display, fertig.
Das Problem wird eher sein, wann und wie eine neue Messung gestartet wird...
 
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: DrDiettrich on Aug 26, 2015, 10:48 pm
Warum nicht einfach den Code für einen kapazitiven Sensor nehmen, und digital abfragen? Da kann man zwar die Schaltschwelle nicht einstellen, aber 3,16V erscheinen mir ja auch ziemlich willkürlich.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 27, 2015, 09:51 am
Mein größtes Problem ist gerade, dass der Timer zwar bei 0,1V anfängt zu zählen; dann bei 3,16V aber weiterläuft und nicht anhält um mir den Wert anzuzeigen. Ich möchte sehen wie lange der Kondensator braucht bis 3,16V zu laden.

Danke für eure Hilfe.

@DrDiettrich
3,16V ist 1 Tau des Kondensators wenn man ihn mit 5V auflädt.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: ardubu on Aug 27, 2015, 09:57 am
wie sieht dein Sketch aus?
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 27, 2015, 10:04 am
Hier ist der Code. Sorry ich bin noch Anfänger.

/*
Pinbelegung:
Arduino 1 auf 14 Display
       3 auf 13
       4 auf 12
       5 auf 11
       11 auf 6
       12 auf 4
       */
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);

int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 100000.0; // Wiederstand R1 (100K)
float R2 = 10000.0; // Wiederstand R2 (10K)     
int value = 0;
void setup()
         {
  pinMode(analogInput, INPUT);
  lcd.begin(16, 4);
 }
void loop()
         {
         
delay(100); //Hier wird die 2,5 sek. lange pause gemacht.
         
         
       

  // read the value at analog input

          value = analogRead(4);
  vout = (value * 5.0) / 1024.0 + 0.00; // see text
  vin = vout ;//((R1+R2)/R2)*8.75/8.54;
  //if (vin<0.09) {vin=0.0;} //statement to quash undesired reading !

          lcd.setCursor(0,1);
          if (vin>3.16) {lcd.print("1 Tau");}
          if (vin<3.16) {lcd.write(25);}
          if (vin<3.16) {lcd.write(25);}
          if (vin<3.16) {lcd.write(25);}
          if (vin<3.16) {lcd.write(25);}
          if (vin<3.16) {lcd.write(25);}
          if (vin<3.16) {lcd.write(25);}
          if (vin<3.16) {lcd.write(25);}
         
          lcd.setCursor(9,1);
          if (vin>4.965) {lcd.print("5 Tau");}
          if (vin<4.965) {lcd.write(25);}
          if (vin<4.965) {lcd.write(25);}
          if (vin<4.965) {lcd.write(25);}
          if (vin<4.965) {lcd.write(25);}
          if (vin<4.965) {lcd.write(25);}
          if (vin<4.965) {lcd.write(25);}
          if (vin<4.965) {lcd.write(25);}
         
          lcd.setCursor(0,2);
          if (vin>0.1) {lcd.print(millis());}
          if (vin>3.16) {} // an dieser stelle komme ich nicht weiter. ich weis nicht wie ich den Zähler anhalten soll und die Zeit, die der Kondensator brauchte um bis hier zu laden anzuzeigen.
         
             
          lcd.setCursor(0,0);
  lcd.print("Kondensatorkurve");

  lcd.setCursor(0, 3);
  lcd.print("C1"); 
          if (vin>0.5) {lcd.write(255);} //Hier wird der Abstand der Balken eingestellt.
          if (vin<0.5) {lcd.write(25);}
          if (vin>1.0) {lcd.write(255);}
          if (vin<1.0) {lcd.write(25);}
          if (vin>1.5) {lcd.write(255);}
          if (vin<1.5) {lcd.write(25);}
          if (vin>2.0) {lcd.write(255);}
          if (vin<2.0) {lcd.write(25);}
          if (vin>2.5) {lcd.write(255);}
          if (vin<2.5) {lcd.write(25);}
          if (vin>3.0) {lcd.write(255);}
          if (vin<3.0) {lcd.write(25);}
          if (vin>3.5) {lcd.write(255);}
          if (vin<3.5) {lcd.write(25);}
          if (vin>4.0) {lcd.write(255);}
          if (vin<4.0) {lcd.write(25);}
          if (vin>4.5) {lcd.write(255);}
          if (vin<4.5) {lcd.write(25);}
          if (vin>5.0) {lcd.write(255);}
          if (vin<5.0) {lcd.write(25);}


          lcd.setCursor(11, 3);
          lcd.print(vin); lcd.print("V");
         

       
 }
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: combie on Aug 27, 2015, 10:52 am
Dieses könnte dir als Ansatz dienen, eine brauchbare Kondensatormessung aufzubauen:
https://www.mikrocontroller.net/articles/AVR_Transistortester (https://www.mikrocontroller.net/articles/AVR_Transistortester)
Denn dieser Ansatz funktioniert sehr gut.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 27, 2015, 11:19 am
Was ich vorhabe ist eigendlich das :
1. Startzeit merken
2. Kondensator aufladen und ständig analog read machen.
3. Wenn ich 3,16V erreicht habe dann möchte ich die Endzeit - Startzeit rechnen.

Könntet ihr mir sagen wie ich das im Code machen sollte?
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: combie on Aug 27, 2015, 12:27 pm
Quote
Was ich vorhabe ist eigendlich das :
Du beschreibst einen Weg, nicht das Ziel. Oder?

Möchtest du die Kapazität ermitteln?
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 27, 2015, 01:34 pm
Ich möchte die Spannung messen die der Kondensator gerade hat.

Wenn 3,16V erreicht sind will ich einfach den Zähler (millis) stoppen. Ich weis aber nicht wie ich das anstellen soll. Ich müsste einfach nur den Zähler pausieren.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: michael_x on Aug 27, 2015, 01:41 pm
Quote
Möchtest du die Kapazität ermitteln?
Eher die Zeitkonstante eines RC-Glieds bestimmen ...

Nehmen wir mal an, die schwierigen Aufgaben hättest du geschafft: Den Kondensator entladen und einen Start-Trigger erkannt und du weisst wie du was auf das Display ausgibst...
Code: [Select]

#define MINIMUM 3  // StartKriterum > 0.002*Vcc (ca. 0.01V )
#define MAXIMUM 614 // Ende bei >  0.6*Vcc         ( ca. 3.00V )


void setup() { Serial.begin(9600); } // statt LCD-Anzeige
void loop() {
  static bool running;
  static unsigned long startzeit;  
  static bool starttrigger = true; // mit Reset geht's los, danach ist unklar

  int wert = analogRead(A0);

  if (running == false && wert == 0  && starttrigger) {
    running = true;
    starttrigger = false;
  }
  
  if (running && startzeit == 0 && wert >= MINIMUM)  
       startzeit = millis();

  if (running && wert >= MAXIMUM) {
     running = false;
     unsigned long dauer = millis() - startzeit;
     Serial.print(dauer); Serial.println (" msec");
     Serial.println("Entladen und Reset fuer neue Messung");
  }

}
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 27, 2015, 01:59 pm
Danke für die Antwort.

Als ich Teile des Programms in meinen Code implementiert habe kommen allerdins diese Fehlermeldungen:

sketch_aug26a.ino: In function 'void loop()':
sketch_aug26a:68: error: 'running' was not declared in this scope
sketch_aug26a:68: error: 'wert' was not declared in this scope
sketch_aug26a:68: error: 'starttrigger' was not declared in this scope
sketch_aug26a:73: error: 'running' was not declared in this scope
sketch_aug26a:73: error: 'startzeit' was not declared in this scope
sketch_aug26a:73: error: 'wert' was not declared in this scope
sketch_aug26a:76: error: 'running' was not declared in this scope
sketch_aug26a:76: error: 'wert' was not declared in this scope
sketch_aug26a:78: error: 'startzeit' was not declared in this scope
'running' was not declared in this scope

Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 27, 2015, 02:00 pm
Der Code sieht jetzt so aus:



/*
Pinbelegung:
Arduino 1 auf 14 Display
        3 auf 13
        4 auf 12
        5 auf 11
        11 auf 6
        12 auf 4
        */

#include <LiquidCrystal.h>

   LiquidCrystal lcd(12,11,5,4,3,2);

   int analogInput = 0;
   float vout = 0.0;
   float vin = 0.0;
   float R1 = 100000.0; // Wiederstand R1 (100K)
   float R2 = 10000.0; // Wiederstand R2 (10K)     
   int value = 0;
        #define MINIMUM 3  // StartKriterum > 0.002*Vcc (ca. 0.01V )
        #define MAXIMUM 614 // Ende bei >  0.6*Vcc         ( ca. 3.00V )
   void setup()
          {
      pinMode(analogInput, INPUT);
      lcd.begin(16, 4);
     }
   void loop()
          {
           
delay(100); //Hier wird die 2,5 sek. lange pause gemacht.
           
           
         

      // read the value at analog input

           value = analogRead(4);
      vout = (value * 5.0) / 1024.0 + 0.00; // see text
      vin = vout ;//((R1+R2)/R2)*8.75/8.54;
      //if (vin<0.09) {vin=0.0;} //statement to quash undesired reading !

           lcd.setCursor(0,1);
           if (vin>3.16) {lcd.print("1 Tau");}
           if (vin<3.16) {lcd.write(25);}
           if (vin<3.16) {lcd.write(25);}
           if (vin<3.16) {lcd.write(25);}
           if (vin<3.16) {lcd.write(25);}
           if (vin<3.16) {lcd.write(25);}
           if (vin<3.16) {lcd.write(25);}
           if (vin<3.16) {lcd.write(25);}
           
           lcd.setCursor(9,1);
           if (vin>4.965) {lcd.print("5 Tau");}
           if (vin<4.965) {lcd.write(25);}
           if (vin<4.965) {lcd.write(25);}
           if (vin<4.965) {lcd.write(25);}
           if (vin<4.965) {lcd.write(25);}
           if (vin<4.965) {lcd.write(25);}
           if (vin<4.965) {lcd.write(25);}
           if (vin<4.965) {lcd.write(25);}
           
         /*  lcd.setCursor(0,2);
           if (vin>0.1) {lcd.print(millis());}
           if (vin>3.16) {} */ // an dieser stelle komme ich nicht weiter. ich weis nicht wie ich den Zähler anhalten soll und die Zeit, die der Kondensator brauchte um bis hier zu laden anzuzeigen.
             
if (running == false && wert == 0  && starttrigger) {
    running = true;
    starttrigger = false;
  }
 
  if (running && startzeit == 0 && wert >= MINIMUM)   
       startzeit = millis();

  if (running && wert >= MAXIMUM) {
     running = false;
     unsigned long dauer = millis() - startzeit;
     Serial.print(dauer); Serial.println (" msec");
     Serial.println("Entladen und Reset fuer neue Messung");
  }
             
             
           lcd.setCursor(0,0);
      lcd.print("Kondensatorkurve");
   
      lcd.setCursor(0, 3);
      lcd.print("C1"); 
           if (vin>0.5) {lcd.write(255);} //Hier wird der Abstand der Balken eingestellt.
           if (vin<0.5) {lcd.write(25);}
           if (vin>1.0) {lcd.write(255);}
           if (vin<1.0) {lcd.write(25);}
           if (vin>1.5) {lcd.write(255);}
           if (vin<1.5) {lcd.write(25);}
           if (vin>2.0) {lcd.write(255);}
           if (vin<2.0) {lcd.write(25);}
           if (vin>2.5) {lcd.write(255);}
           if (vin<2.5) {lcd.write(25);}
           if (vin>3.0) {lcd.write(255);}
           if (vin<3.0) {lcd.write(25);}
           if (vin>3.5) {lcd.write(255);}
           if (vin<3.5) {lcd.write(25);}
           if (vin>4.0) {lcd.write(255);}
           if (vin<4.0) {lcd.write(25);}
           if (vin>4.5) {lcd.write(255);}
           if (vin<4.5) {lcd.write(25);}
           if (vin>5.0) {lcd.write(255);}
           if (vin<5.0) {lcd.write(25);}


           lcd.setCursor(11, 3);
           lcd.print(vin); lcd.print("V");
           

       
     }
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: michael_x on Aug 27, 2015, 02:22 pm
Dann schau mal das Beispiel allein an, und erkenne dass millis() nie angehalten wird,
Die Differenz millis() - startzeit kann natürlich, wenn die Zeit es erlaubt, auch während der Messung ermittelt und angezeigt werden.

Und wenn du unbedingt willst, kannst du loop() auch nur alle 100 ms laufen lassen (Schade, aber ist ja dein sketch) Lieber würde ich noch einen zweiten Zeitmerker nehmen, der dir mit der gleichen Methode
if (millis() - letzteAnzeige > 100)  { ... } sagt, wann das Display wieder aktualisiert werden soll.


Nachtrag: Glaub nicht, dass nur weil du mit float rechnest, 3.16 auch 3.16V wären. Krieg lieber raus, welcher Wert (0 .. 1023) deiner 4.965 entspricht.

Um einen LCD Balken zu zeichnen, braucht man keine float-Berechnung.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 27, 2015, 03:29 pm
Vielen Dank für deine Mühe. Morgen will ich mich etwas mit deinen Tipps auseinandersetzen.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: ardubu on Aug 27, 2015, 05:36 pm
du hast Teile von dem Sketch von michael_x übernommen, aber die Variablendeklaration vergessen.
Ändere in deinem Sketch wert in value und setze am Anfang von loop
Code: [Select]
static bool running;
            static unsigned long startzeit; 
            static bool starttrigger = true; // mit Reset geht's los, danach ist unklar
ein, dann müsste es fehlerfrei kompelieren.

Wenn du einen Sketch ins Forum kopieren willst, benutze bitte </> oben links über den Smilies.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: ardubu on Aug 27, 2015, 11:34 pm
beim betrachten deines Sketches sind mir noch ein paar Dinge aufgefallen:
Quote
int analogInput = 0;
pinMode(analogInput, INPUT);
value = analogRead(4);
Du defenierst analogInput als A0, liest dann aber A4 ein.
Quote
vout = (value * 5.0) / 1024.0 + 0.00; // see text
      vin = vout ;//((R1+R2)/R2)*8.75/8.54;
Bei einem 10Bit ADC gehen die Werte von 0 bis 1023, also müsstest du durch 1023 teilen.
Wofür steht das + 0.00?
Du setzt vin=Vout ohne Bedingung, also könntest du gleich vin = (value * 5.0) / 1023.0; nehmen
Quote
float R1 = 100000.0; // Wiederstand R1 (100K)
   float R2 = 10000.0; // Wiederstand R2 (10K)   
Du definierst R1 + R2, benutzt sie aber in deinem Sketch nicht.
Quote
lcd.begin(16, 4);
Du initialisierst dein Display mit 16 Zeichen und 4 Zeilen, rufst aber 20 x lcd.write auf.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: makertom on Aug 28, 2015, 10:06 am
@ ardubu; michael_x

Vielen dank für eure Hilfe. Jetzt funktioniert das Programm endlich! :D

Danke auch an alle anderen die geholfen haben.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: michael_x on Aug 28, 2015, 01:39 pm
Quote
also müsstest du durch 1023 teilen
falsch.

Du hast in 10 Bit 1024 mögliche Werte ( 0 .. 1023 ).

Ein einfach verständliches Beispiel ohne Rundungsfehler:
Wenn du das in nur 16 Ergebnisse umrechnen willst, multiplizierst du es mit 16  und teilst durch 1024, erhältst den richtigen Wert im Bereich 0 .. 15.

Klar, in float wirst du ohne Aufrunden nie den Wert 5.0000 erhalten, wenn du mit 5.00 / 1024  multiplizierst, und das wollen die meisten bei "Vollausschlag" sehen.
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: ardubu on Aug 28, 2015, 04:23 pm
Quote
falsch.
ich glaube da irrst du. Es sind zwar 1024 Werte, aber der erste Wert ist 0 und damit bleiben von o bis zum Ende nur 1023 Werte über. Versuche einmal 3V mit 2 Bit darzustellen, dann hat jede Sufe 1V.

 



 
   3V        --   4. Wert
               |
   2V      --     3. Wert
             |
   1V    --       2. Wert
           |
   0V  --         1. Wert
Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: michael_x on Aug 28, 2015, 05:04 pm
Quote
Versuche einmal 3V mit 2 Bit darzustellen, dann hat jede Sufe 1V.
Eben. (Sind übrigens eher 4V, wenn du 2 bit hast und jede Stufe 1V entsprechen soll)

bei einem 10 Bit ADC (0 - 1023) ist die Richtige Umrechnung wert >> 8  ( oder * 4 / 1024 )  macht daraus 2 Bit mit den möglichen Werten 0 1 2 3. Jeder Bereich ist dann gleich groß.

Title: Re: Arduino Zeit zwischen Aufgaben messen
Post by: DrDiettrich on Aug 28, 2015, 11:04 pm
Aus dem ATmega Datenblatt:
Quote
The ADC converts an analog input voltage to a 10-bit digital value through successive approximation.
The minimum value represents GND and the maximum value represents the voltage on the AREF pin minus 1 LSB.
Das entspricht dem üblichen ADC Design, ist definitiv nicht Arduino spezifisch. Eine Eingangsspannung von exakt AREF würde 1024 entsprechen, doch dieser Wert liegt außerhalb des 10 Bit Bereichs (0-1023).

Genau das selbe Verhalten findet man beim DAC, und ein solcher ist ja Teil des ADC. Ein DAC Ausgang kann nie seine AREF erreichen, seine maximale Ausgangsspannung bleibt immer eine Stufe (LSB) drunter.