Pages: 1 [2] 3 4   Go Down
Author Topic: Neuling hat ne Frage Projekt Leuchtturm-Karte  (Read 5018 times)
0 Members and 2 Guests are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es funktioniert smiley-lol smiley-lol smiley-lol

Du bist ein Held

Danke
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 175
Posts: 3291
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es funktioniert smiley-lol smiley-lol smiley-lol

Du bist ein Held

Danke

Bitte, gern geschehen!
In lichten Momenten schreibe ich sowas hin und es funktioniert praktisch auf Anhieb.

Zwei kleine Code-Korrekturen habe ich aber trotzdem noch:

Das  "Serial.begin(9600);" ist natürlich überflüssig in einem Programm, das nichts über Serial ausgibt.
Schadet aber auch nicht weiter.

Gewichtiger ist die leicht falsche Abbruchbedingung, es muss in dieser Zeile ">=" statt "=" heißen,
korrekt wäre:
while (onoffCount>0 && inCycleTime-Turmdata[3+Turmdata[2]-onoffCount]>=0)

Dann wird das Timing auch nicht " ca. +/- zwei Millisekunden " sondern "besser als  +/- eine Millisekunde" eingehalten.
Das habe ich gerade mal mit ein paar Timing-Tests festgestellt.

Wenn ich mich nicht verrechnet habe, dauert es 51660 Sekunden, bis sich ein identischer Blinkzyklus wiederholt, man kann also kaum zweimal pro Tag absolut identische Blinkfolgen beobachten.

Der Quellcode ist so gestaltet, dass sich mehr blinkende Türme in einer größeren Karte leicht auch nachträglich einbauen lassen. Und die "Drehzahl" der loop()-Funktion liegt momentan mit 6 Türmen bei weit über 2000 pro Sekunde, so daß jeder Turmstatus in jeder Millisekunde mehr als zweimal aktualisiert wird, da sind also noch Reserven vorhanden.

Viel Spaß beim Basteln Deiner blinkenden Landkarte!
Logged

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3501
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Eine andere Variante wäre z.B. so:

Code:
//
//  www.blinkenlight.net
//
//  Copyright 2013 Udo Klein
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program. If not, see http://www.gnu.org/licenses/

#include <MsTimer2.h>

const uint8_t pins = 6;

template <uint8_t led, uint16_t d1, uint16_t d2, uint16_t d3, uint16_t d4,
                       uint16_t d5, uint16_t d6, uint16_t d7, uint16_t d8>
void light_my_fire() {  
    static uint16_t phase = 0;
    
    phase = phase < d1+d2+d3+d4+d5+d6+d7+d8-1? phase+1: 0;

    digitalWrite(led, phase < d1                  ? HIGH:
                      phase < d1+d2               ? LOW:
                      phase < d1+d2+d3            ? HIGH:
                      phase < d1+d2+d3+d4         ? LOW:
                      phase < d1+d2+d3+d4+d5      ? HIGH:
                      phase < d1+d2+d3+d4+d5+d6   ? LOW:
                      phase < d1+d2+d3+d4+d5+d6+d7? HIGH:
                                                    LOW);                                                  
}

void blink() {
    light_my_fire<0,  200, 2800,  200, 2800,  200, 5800,    0,    0>();
    light_my_fire<1, 3000, 3000, 3000, 3000,    0, 8500,    0,    0>();
    light_my_fire<2,  700, 2300,  700, 2300,  700, 2300,  700, 5300>();
    light_my_fire<3, 6000, 6000,    0,    0,    0,    0,    0,    0>();
    light_my_fire<4, 6000, 3000,    0,    0,    0,    0,    0,    0>();
    light_my_fire<5, 6000, 1000,    0,    0,    0,    0,    0,    0>();


}

void setup() {
    for (uint8_t pin=0; pin<pins; ++pin) {
        pinMode(pin, OUTPUT);
    }

    MsTimer2::set(1, blink);
    MsTimer2::start();
}

void loop() {}

Und wenn gewünscht ist, daß die Leuchtfeuer nicht 100% gleich in der Phase laufen, dann einfach bei der letzten Pause immer 1ms draufhauen. Also so:

Code:
//
//  www.blinkenlight.net
//
//  Copyright 2013 Udo Klein
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program. If not, see http://www.gnu.org/licenses/

#include <MsTimer2.h>

const uint8_t pins = 6;

template <uint8_t led, uint16_t d1, uint16_t d2, uint16_t d3, uint16_t d4,
                       uint16_t d5, uint16_t d6, uint16_t d7, uint16_t d8>
void light_my_fire() {  
    static uint16_t phase = 0;
    
    phase = phase < d1+d2+d3+d4+d5+d6+d7+d8-1? phase+1: 0;

    digitalWrite(led, phase < d1                  ? HIGH:
                      phase < d1+d2               ? LOW:
                      phase < d1+d2+d3            ? HIGH:
                      phase < d1+d2+d3+d4         ? LOW:
                      phase < d1+d2+d3+d4+d5      ? HIGH:
                      phase < d1+d2+d3+d4+d5+d6   ? LOW:
                      phase < d1+d2+d3+d4+d5+d6+d7? HIGH:
                                                    LOW);                                                  
}

void blink() {
    light_my_fire<0,  200, 2800,  200, 2800,  200, 5801,    0,    0>();
    light_my_fire<1, 3000, 3000, 3000, 3000,    0, 8501,    0,    0>();
    light_my_fire<2,  700, 2300,  700, 2300,  700, 2300,  700, 5301>();
    light_my_fire<3, 6000, 6001,    0,    0,    0,    0,    0,    0>();
    light_my_fire<4, 6000, 3001,    0,    0,    0,    0,    0,    0>();
    light_my_fire<5, 6000, 1001,    0,    0,    0,    0,    0,    0>();


}

void setup() {
    for (uint8_t pin=0; pin<pins; ++pin) {
        pinMode(pin, OUTPUT);
    }

    MsTimer2::set(1, blink);
    MsTimer2::start();
}

void loop() {}
Logged

Check out my experiments http://blog.blinkenlight.net

Germany S-H
Offline Offline
Faraday Member
**
Karma: 175
Posts: 3291
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eine andere Variante wäre z.B. so:

Das habe ich mir gedacht, dass Dein Programm ganz anders wird als meins.
Und vom Mikrosekunden-Timing her noch viel akkurater als meins, das die Timings nur mit millis() macht.

Sehr schöner Programm-Sketch!
Logged

Germany
Online Online
Edison Member
*
Karma: 48
Posts: 2347
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sehr schöner Programm-Sketch!
Dem möchte ich nur bedingt zustimmen, ich denke nämlich, dass das so manchen Anfänger überfordern wird. Auf jeden Fall ist er sehr effektiv programmiert und aus meiner Sicht eine sehr gute Leistung. smiley
Logged

Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3501
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So wie ich das sehe ist Meins nicht genauer als Deins. Das Hauptproblem ist wie immer die Genauigkeit des Hardware Taktes. Das Einzige wo Deine Lösung ein bischen daneben haut ist alle 50 Tage beim millis overflow. Ansonsten sehe ich nicht wieso Deine Lösung weniger genau sein sollte. Wieso denkst Du, daß Deine Lösung nicht so genau ist?

Anmerkung: durch das Pollen von "millis" fängst Du Dir zwar Phasenjitter ein, aber den hat meine Lösung auch. Wenn ich den nicht haben wollte müsste ich Timer 0 stoppen. Aber genauer wird es dadurch auch nicht. Nur der Jitter nimmt dann ab.

Hauptunterschied ist der deutlich geringere Speicherverbrauch und die geringere Prozessorlast bei meiner Lösung. Und loop() bleibt frei smiley-wink Aber am Ende zählt immer nur ob die Anforderungen erfüllt sind und da ist Deine Lösung gleich gut. Und sie war schneller verfügbar.


Knobelfrage: warum funktioniert mein Programm überhaupt?

D.h. wo hält es eigentlich den Phasenzustand der Leuchttürme? Betonung auf "mehr als ein Turm" smiley-wink
Logged

Check out my experiments http://blog.blinkenlight.net

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3501
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@sth77: wieso überfordert das Anfänger? Copy + Paste kann jeder smiley-wink Die Lösung von Jurs ist auch nicht leichter zu verstehen wenn man nicht programmieren kann.
Logged

Check out my experiments http://blog.blinkenlight.net

Germany S-H
Offline Offline
Faraday Member
**
Karma: 175
Posts: 3291
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dem möchte ich nur bedingt zustimmen, ich denke nämlich, dass das so manchen Anfänger überfordern wird.

Ja, von meinem Programm-Sketch werden Anfänger auf Anhieb vermutlich mehr Codeteile verstehen als von Udos Code.

Aber andererseits ist Copy-and-Paste bei einem fertigen Programm so oder so nicht allzu schwierig.

Das mit den "Templates" gehört beispielsweise so überhaupt nicht zu meinen Programmiertechniken und selbst ich mußte eben erstmal googeln, was Templates bei C++-Code überhaupt sind und was die machen. Also bei Udos Code mußte ich auch erstmal Tante Google bemühen, um den Code überhaupt zu verstehen, was der macht.

Interrupts und Nicht-Standard-Libraries sind auch nicht das allererste Thema für Anfänger, aber wenigstens damit habe ich schon was gemacht und die MsTimer-Library auch schon mal früher gesehen als ich mir Udos DCF-Empfangsfilter angesehen habe.
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 175
Posts: 3291
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das Einzige wo Deine Lösung ein bischen daneben haut ist alle 50 Tage beim millis overflow.

Ja, wobei man das 50-Tage-Problem mit einer Subtraktions-Arithmetik statt Modulo-Arithmetik und einigen Zusatzvariablen auch in meinem Programm beseitigen könnte und das Programm damit wohl auch noch schneller machen könnte.

Ansonsten sehe ich nicht wieso Deine Lösung weniger genau sein sollte. Wieso denkst Du, daß Deine Lösung nicht so genau ist? Anmerkung: durch das Pollen von "millis" fängst Du Dir zwar Phasenjitter ein, aber den hat meine Lösung auch. Wenn ich den nicht haben wollte müsste ich Timer 0 stoppen. Aber genauer wird es dadurch auch nicht. Nur der Jitter nimmt dann ab.

Ich habe zum Testen mal eine Interrupt-0 Behandlungsroutine für Pin-2 eingeklinkt, in der die High- und Low-Pegel vom micros()-Timing her genau ausgemessen und in der Loop per Serial ausgegeben werden. Bei meinem Programm jittert es, und bei den Timings mit Deinem Programm-Sketch sind keine Differenzen zum Soll-Timing feststellbar.

Quote
Hauptunterschied ist der deutlich geringere Speicherverbrauch und die geringere Prozessorlast bei meiner Lösung. Und loop() bleibt frei smiley-wink

Prozessorlast und freie loop() OK, da gebe ich Dir Recht.

Aber lasse bei meinem Programm mal die nicht benötigte Initialisierung mit "Serial.begin(9600)" im Programm-Sketch weg! Also die kompilierte Programmdatei von meinem Programm ist dann DEUTLICH kleiner als die von Deinem. Mit auskommentierter Serial-Initialisierung hat mein Programm unter Arduino 1.0.1 nur eine angezeigte Binäre Sketchgröße von 1254 Bytes.

Quote
Knobelfrage: warum funktioniert mein Programm überhaupt?

D.h. wo hält es eigentlich den Phasenzustand der Leuchttürme? Betonung auf "mehr als ein Turm" smiley-wink

Der Phasenzustand der Leuchttürme wird doch in Deinem wie auch in meinem Sketch nur im LED-Pin gespeichert und vor dem Setzen des Pins jedesmal zur Laufzeit neu ermittelt: In meinem Sketch in den Zeilen unmittelbar vor dem Setzen des Zustands mit digitalWrite, und bei Deinem Sketch direkt im digitalWrite-Funktionsaufruf per Verzweigungslogik.

@twoll065: Die MsTimer2-Library mußt Du vor dem Kompilieren schon noch herunterladen und im Libraries-Verzeichnis installieren, Udo verwendet nämlich nicht nur erweiterte Programmiertechniken, sondern auch eine externe Nicht-Standard Library in seinem Sketch.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Habe ich gemacht

ausgegeben wird:

avrdude: stk500_getsync(): not in sync: resp=0xf0


Was heißt das?
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 175
Posts: 3291
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ausgegeben wird:

avrdude: stk500_getsync(): not in sync: resp=0xf0

Was heißt das?

Manchmal verhaspeln sich Compiler und Uploader, einfach nochmal probieren!
Funktioniert's auch nach mehrmaligen Versuchen nicht?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alles neu gestartet aber geht nicht
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 175
Posts: 3291
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alles neu gestartet aber geht nicht

Merkwürdig.
Nimm in Udos Sketch mal andere Pins für die LEDs als die Hardware-Serial RX/TX Pins an 0 und 1!

Vielleicht ist Udos Programm ja so schnell, dass es schon Ausgaben an 0 und 1 macht, während der Upload noch gar nicht abgeschlossen ist.

Vorschlag: Nimm die Pins 2 bis 7 als LED-Pins statt 0 bis 5!

Statt:
Code:
light_my_fire<0,  200, 2800,  200, 2800,  200, 5800,    0,    0>();
 light_my_fire<1, 3000, 3000, 3000, 3000,    0, 8500,    0,    0>();
Setze
Code:
light_my_fire<6,  200, 2800,  200, 2800,  200, 5800,    0,    0>();
 light_my_fire<7, 3000, 3000, 3000, 3000,    0, 8500,    0,    0>();

Und statt:
Code:
for (uint8_t pin=0; pin<pins; ++pin) {
        pinMode(pin, OUTPUT);
    }
Setze:
Code:
for (uint8_t pin=2; pin<pins+2; ++pin) {
        pinMode(pin, OUTPUT);
    }
Logged

Offline Offline
Full Member
***
Karma: 5
Posts: 193
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hast du den korrekten Com-Port und das richtige Board ausgwählt, bzw.
überhaupt einen Arduino angeschloßen?

Addi
Logged

  / \    _|  _| o
 /--\ (_| (_| |

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hab ich gemacht, umgesteckt auf 2-7, Code geändert, 2-5 leuchten normal und 6+7 glimmen nur im Takt.
Logged

Pages: 1 [2] 3 4   Go Up
Jump to: