- SF800 Solar Speicher Tutorial         
Ergebnis 1 bis 10 von 25

Thema: YACCBOA - YetAnotherCameraControlerBasedOnArduino

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.04.2010
    Ort
    Im Städtedreieck Köln-Bonn-Aachen
    Alter
    37
    Beiträge
    106
    Das Arduino Pro Mini hat den ATmega328 als µC verbaut. Dieser hat 3 Timerbausteine (2x 8Bit und 1x 16Bit).
    Ich würde es damit versuchen.

    Entweder du liest das/die Register TCNTx per Hand aus, oder du stellst einen Timer so ein, dass er alle 1ms einen Überlauf hat und einen Interrupt auslöst.

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    40
    Beiträge
    557
    Ich bin mir nicht sicher wo das Problem liegt. Ich habe heute Vormittag den Durchlauf der Funktion mal per
    Code:
    micros_durchlauf_start = micros();
    .....
    jede menge Code
    .....
    micros_durchlauf = micros() - micros_durchlauf_start;
    Serial.println(micros_durchlauf);
    gemessen. Dabei werden mir pro Durchlauf 20-28 Microsekunden ausgegeben. Was mich aber stutzig macht ist ein Wert nach ca. 100 Durchläufen aus der Reihe schlägt und mit rund -15500µs angegeben wird. Es ist bei jeden Aufruf der Funktion nur ein einzelner Wert nach ca 100 Durchläufen.


    Ich bin mir nicht sicher, ob ein Timer-Interrupt mein Problem lösen wird. Die Funktion scheint ja (meistens) schnell genug zu sein, um sogar mehrmals pro Millisekunde auf ein evtl. auszuführendes Event zu überprüfen. Die ISR müsste ja ähnlich aussehen wie meine bisher verwendete (nachfolgende) Funktion.
    Code:
    void ausloesen(void)
    {
      int millis_start = millis();
      int millis_aktuell = millis();
      int status_ventil_open[3] = {0,0,0};
      int status_ventil_closed[3] = {0,0,0};
      int status_blitz = 0;
      int status_sva = 0;
      int status_trigger = 0;
      int timer_blitz = 500;
      int kamera_delay = 82;
      int micros_durchlauf = 0;
      int micros_durchlauf_start = 0;
      
    
    
      
      lcd.clear();
      lcd.home();
      lcd.print(valve_delay[1]);
      sva();
      
      
      while(tmp == 0)
      {
        millis_aktuell = millis() - millis_start;
        micros_durchlauf_start = micros();
        
         
    //    lcd.setCursor(0,2);
    //    lcd.print(millis_aktuell);
        
        // Ventile öffnen
        for(int i = 0; i<valve_amount;i++)
        {    
          if((millis_aktuell > valve_delay[i]) && (status_ventil_open[i] == 0) && (valve_active[i] == 1))
          {
            digitalWrite(+i,HIGH);
            status_ventil_open[i] = 1;
          }
        }
        
        // Ventile schließen
        for(int i=0;i<valve_amount;i++)
        {
          if((millis_aktuell > (valve_delay[i]+valve_size[i])) && status_ventil_closed[i] == 0)
          {
            digitalWrite(+i,LOW);
            status_ventil_closed[i] = 1;
          }
        }
        
        // Kamera auslösen
        if((millis_aktuell > (timer_blitz - kamera_delay) && (status_trigger == 0)))
        {
          digitalWrite(13,HIGH);
          status_trigger = 1;
        }
        
        // Blitze auslösen
        if((millis_aktuell > timer_blitz) && (status_blitz == 0))
        {
          trigger_blitze();
          status_blitz = 1;
        }
        
        micros_durchlauf = micros() - micros_durchlauf_start;
        Serial.println(micros_durchlauf);
        if(millis_aktuell > 2000)
        {
          tmp=1;
          digitalWrite(13,LOW);
          display_setup_valve_delay();
        }
      }
    }
    Alles ist möglich. Unmögliches dauert nur etwas länger!

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.04.2010
    Ort
    Im Städtedreieck Köln-Bonn-Aachen
    Alter
    37
    Beiträge
    106
    Okay... ich habe min. 10 mal die Antwort hier verworfen.

    Was mich stört, ist das eine menge Lib. aufgerufen werden, die für mich scheinbar der Plattform Arduino als Entwicklungsumgebung abhängig sind.
    Korregiere mich, wenn das nicht stimmt.

    Ich würde immer noch einfach den 16Bit Timer im Hintergrund mitlaufen lassen und ihn als Zeitgeber nehmen.
    Aber ich weiß jetzt nicht, ob Arduino einen so tief in die Hardware des µC rein läst. Sprich ob du einfach das CS11-Bit im TCCR1B Register auf High setzten kannst und das TCNT1 Register einfach auslesen kann, ohne eine aufwendige Funktion zu benutzen.

    Sprich so:
    Code:
    unsigned int auslesen;
    TCCR1B|=(1<<CS11);
    auslesen=TCNT1;
    Die Anweisungen dauern jeweils meine ich max. 4 Takte.

    Daher meine Grundlegende Frage: Kannst du direkt, ohne irgendwelche Funktionen, auf die Register zugreifen?

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    Hallo,

    schickes Gerät, gefällt mir sehr gut. Wollte auf deine PM antworten, aber dein Postfach ist voll.

    @Jimmybot Beim Arduino läuft bereits der Timer im Hintergrund im Interrupt als Zeitgeber. Da würde ich nicht dran herum schrauben.

    Das Problem liegt vermutlich eher an den Variablen Typen. Millis() und micros() geben 'unsigned long' zurück, du verwendest 'int' (das sind beim Arduino 16Bit Werte). Das kann zu Überläufen und ungeahnten Problemen führen.

    Bei meinen Tests habe ich nur schnöde delay() Aufrufe verwendet, will aber auch später millis() verwenden. Brauche ich aber erst wenn ich mehrere Ventile verwende.
    Kann meinen Code aber gerne hier posten, falls gewünscht.

    LG Peter

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.04.2010
    Ort
    Im Städtedreieck Köln-Bonn-Aachen
    Alter
    37
    Beiträge
    106
    Zitat Zitat von m.a.r.v.i.n Beitrag anzeigen

    @Jimmybot Beim Arduino läuft bereits der Timer im Hintergrund im Interrupt als Zeitgeber. Da würde ich nicht dran herum schrauben.
    Wieder was dazu gelernt. Danke für den Hinweis.

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    40
    Beiträge
    557
    Danke für die Antwort. Timer sind, wie schon erwähnt, durch die Arduino IDE zum Teil belegt. Gibt Wege diese freizulegen und zu nutzen. Aber da bin ich noch nicht fit genug für.

    Der Hinweis mit den Datentypen ist berechtigt. Hab ich ganz vergessen. Werde ich mir morgen mal Gedanken drüber machen.

    PS: Postfach ist wieder frei
    Alles ist möglich. Unmögliches dauert nur etwas länger!

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    40
    Beiträge
    557
    Zwei Fehler die zu seltsamen Verhalten führten. Zuerst habe ich in der for-Schleife für das Öffnen der Ventile durch ständiges Testen und Ändern nur noch Schwachsinn stehen gehabt. Etwas Schlaf und ein frisches Auge haben dies behoben. Dazu habe ich jetzt die Variablen für millis() als unsigned long initialisiert. Ich hab den Überlauf etwas unterschätzt. Hatte nur im Kopf, dass millis(); nach 49 Tagen überläuft. Ich hab dabei aber ignoriert, dass meine Variablen als Integer schon schneller überlaufen.

    Jetzt machen die Ventile was sie sollen. Nur die Wassertropfen muss ich noch bändigen.

    Als nächstes steht etwas Optimierung auf dem Plan. Der Code ist kaum kommentiert, ein paar Funktionen lassen sich vereinfachen oder auslagern um sie an mehreren Stelen zu nutzen. Zur Zeit sind 18.740 Bytes (von einem Maximum von 30.720 Bytes) in Gebrauch. Und ein paar Funktionen sollen noch implementiert werden
    Geändert von Arkon (09.01.2014 um 06:30 Uhr)
    Alles ist möglich. Unmögliches dauert nur etwas länger!

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test