Show Posts
Pages: 1 ... 84 85 [86] 87 88 ... 203
1276  International / Deutsch / Re: Alps EC11 Problem mit Drehrichtung on: November 20, 2013, 01:27:54 pm
Scheint gut zu funktionieren, noch keine wirklichen Springer.

Falls es mit längeren LCD-Textausgaben beim gleichzeitigen Drehen springen sollte, kannst Du ggf. eine Spezial-LCD-Ausgabefunktion machen, die zeichenweise auf LCD ausgibt und nach jedem einzelnen Zeichen einmal den Drehgeber abfragt.

Mein Code ist jedenfalls der einzige mir bekannte Code für Drehgeber, bei dem über "impulseError" mitgezählt wird, ob und ggf. wie oft die Eingabe springt, also nicht ausgewertet werden kann, weil die Phasenänderung weder einer Rechts- noch einer Linksdrehung entspricht. So kannst Du testen, bis zu welcher Drehgeschwindigkeit noch keine Fehler auftreten.

P.S.: Falls du nicht überall sowas bei deinen Sketchen besetzt (// sollte nie vorkommen), habe ich den Sketch vermutlich schonmal bei durchfliegen hier in den Foren von dir gelesen smiley-wink

Ja, gut aufgepaßt: Den Code habe ich heute zum zweiten mal ins Forum gepostet.  smiley-mr-green
1277  International / Deutsch / Re: Alps EC11 Problem mit Drehrichtung on: November 20, 2013, 12:23:17 pm
Ich habe noch ein paar Probleme mit der Genauigkeit meines Alps EC11 Encoders. Der Encoder hat PinA und PinB sowie einen geminesamen Kontakt. Des weiteren einen 2 poligen Taster. Den Taster kann ich mit einem 0,1µ und externen PullDown erfolgreich entprellen. Habe es bei den Encodereingängen auch soweit versucht, ebenfalls mit 10k PullDown. Leider verhält sich der Encoder identisch, als wenn er ohne die Schaltung betrieben wird.

Habe derzeit erst einen kleinen Testcode soweit zusammengestellt. Interrupt wollte ich nicht zwingend nutzen.

Ich habe hier mal einen Testcode für Drehgeber geschrieben, der ohne Interrupts arbeitet und die Eingänge in der loop abfragt.

Schaltung: Keine äußere Beschaltung notwendig, im Sketch werden die internen PullUps für die A- und B- Eingänge aktiviert.

Programmlogik: Während der Drehgeber dreht, wird in der Auswertung nur zusammengezählt, was an Rechts- und Linksimpulsen auftritt, und sobald eine Pause von mindestens TIMEOUT Millisekunden auftritt (Default=20ms) wird eine Auswertung der Drehgeberimpulse auf Serial ausgegeben.

Das Prellen, wenn es auftritt, wird softwaretechnisch dadurch herausgerechnet, dass am Ende immer die Differenz der gezählten Rechts- und Linksimpulse gebildet wird. Falls also beim Rechtsdrehen tatsächlich (wegen Prellens) gezählt werden sollte RRRRLRRRR wird bei der Ausgabe der Differenz automatisch die richtige Schritteanzahl ausgegeben.

Außerdem habe ich auch mal eine Erkennung für "zu schneller Überdrehen" eingebaut, d.h. falls einzelne Impulse beim Abfragen verpasst werden, werden Fehler in der Variablen "impulseError" mitgezählt.

Durch diese Programmlogik, dass beim schnellen Drehen nur schnell gezählt aber überhaupt nichts ausgegeben wird, während nur in Drehpausen eine Ausgabe auf Serial erfolgt, kann der Serial-Sendepuffer in meinem Test-Sketch nicht überlaufen.

Ich weiß nicht, ob das bei Deinem Sketch das Problem ist, aber wenn Dir beim Pollen der Eingänge nämlich der serielle Ausgangspuffer überläuft, werden die Eingänge nur noch sehr langsam und unregelmäßig abgefragt, und es gehen dann in jedem Fall Drehimpulse verloren. Falls Dir der serielle Sendepuffer überlaufen kann, wärst Du mit einer Auswertung in einer ausreichend oft laufenden Timer-Interruptroutine wahrscheinlich besser bedient.

Schaue es Dir mal an, ob Dein Drehgeber damit genauer arbeitet:
Code:
#define ENCODER_A 2
#define ENCODER_B 3

#define ERRORCODE 9999
#define TIMEOUT 20

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(ENCODER_A, INPUT_PULLUP);
  pinMode(ENCODER_B, INPUT_PULLUP);
  encoderImpuls(); // Initialisiert den Anfangszustand des Drehgebers
}

int encoderImpuls()
{
  static byte state=0;
  state= state<<2;
  if (digitalRead(ENCODER_A)) bitSet(state,1);
  if (digitalRead(ENCODER_B)) bitSet(state,0);
  state= state & 0xF;
  switch(state)
  {
    case 0b0000:
    case 0b0101:
    case 0b1010:
    case 0b1111: return 0; // keine Änderung an den Eingängen
    case 0b0001:
    case 0b0111:
    case 0b1110:
    case 0b1000: return -1; // links Impuls an den Eingängen
    case 0b0010:
    case 0b1011:
    case 0b1101:
    case 0b0100: return 1; // rechts Impuls an den Eingängen
    default: return ERRORCODE;  // Error (z.B. wegen verpaßter Impulse)
  }  
}


int impulseRechts=0, impulseLinks=0, impulseError=0;

boolean impulsAuswertung()
{
  static unsigned long letzterImpuls;
  switch (encoderImpuls())
  {
    case 0: if (millis()-letzterImpuls>TIMEOUT) return true;
            return false;  
    case ERRORCODE:
            impulseError++;
            break;  
    case 1: impulseRechts++;
            break;  
    case -1:impulseLinks++;
            break;  
    default: Serial.println("Internal Error in impulsAuswertung"); // sollte nie vorkommen
  }  
  letzterImpuls=millis();
  return false;
}


void loop() {
  if (!impulsAuswertung()) return;
  if (impulseRechts>impulseLinks)
  {
     Serial.print("R: ");Serial.println(impulseRechts-impulseLinks);
  }
  else if (impulseLinks>impulseRechts)
  {
     Serial.print("L: ");Serial.println(impulseLinks-impulseRechts);
  }
  if (impulseError>0)
  {
     Serial.print("E: ");Serial.println(impulseError);
  }
  impulseRechts=0;
  impulseLinks=0;
  impulseError=0;
}

P.S.: Und wenn mein Sketch beim Testen Werte für "impulseError" anzeigt, dann hängt das natürlich auch mit Deinem LCD und den LCD-Ausgaben aus dem PROGMEM-Flashspeicher zusammen: Textkonstanten aus dem PROGMEM zu ziehen kostet Zeit, und ein LCD-Display ist beim Schreiben auch immer für Verzögerungen von einigen Millisekunden gut. Wenn während einer Ausgabe auf LCD zwei Drehgeber-Impulse auftreten, geht einer davon verloren. Im Zweifelsfall: Langsam genug drehen.
1278  International / Deutsch / Re: Zeit zwischen 2 Aktionen messen on: November 20, 2013, 07:28:05 am
und bei der nächsten Erkennung von Punkt (a) durch Sensor 1 in form eines Delays ( dann 2,5 sek.) in Verbindung mit dem Klick

Aha, allmählich wird es klarer:

Du möchtest also doch keine Hellseher-Apparatur, sondern eine Apparatur die zwei Dinge machen kann:
1,) Zeit zwischen zwei Ereignissen messen und diese Zeit (bzw. die Hälfte davon) merken
2.) Erst NACH einem weiteren ersten Ereignis die Hälfte der unter 1. gemessenen Zeit warten und eine Aktion auslösen

Kommen die Ereignisse denn schnell und automatisch nacheinander, so wie etwa fallende Tropfen aus einem Wasserhahn?

So dass Du immer vier Ereignisse wie folgt abarbeiten kannst:
a) warte bis beide Sensoren über 18 als Anzeigewert haben
b) warte darauf, dass der 1. Sensor unter 18 fällt, starte die Zeitmessung
c) warte darauf, dass der 2. Sensor unter 18 fällt, stoppe die Zeitmessung, teile die gmessene Zeit durch 2
d) warte bis beide Sensoren über 18 als Anzeigewert haben
e) warte darauf, dass der 1. Sensor wieder unter 18 fällt, starte die Zeitmessung
f) warte die halbe gemessene Zeit und löse die Aktion aus

Und das dann endlos hintereinander weg, so ungefähr?
1279  International / Deutsch / Re: SD-Karte: Dateinamen als String öffnen on: November 20, 2013, 04:10:34 am
Ja, klingt prima. Leider waren meine ersten Timer-Tests ernüchternd. Die Libs beißen sich irgendwie mit meinen anderen Bibliotheken, ich muss da morgen noch einmal testen.

Ähem, wenn ich mal drüber nachdenke, kann das mit dem überlappenden Abspielen per Timer-Interrupts auch gar nicht funktionieren: Der Atmega hat ja nur eine Hardware-SPI-Schnittstelle. Und diese kann immer nur NACHEINANDER von verschiedenen Geräten verwendet werden.

Du steuerst ja auch Deine LEDs per SPI an:
- SPI steuert die LEDs
- SPI liest die Daten von SD-Karte
Beides kann sich nicht überlappen, sondern erst muß der SPI-Bus wieder frei sein, dann kann er von einem anderen SPI-Gerät benutzt werden. Also kannst Du insbesondere nicht während eine 6ms laufende Dateilesefunktion läuft zwischendurch per Timer die LEDs über SPI setzen.

Die gleichzeitige und überlappende Verwendung von SPI ist nur mit zwei SPI-Schnittstellen möglich. Also zum Beispiel mit zwei Arduino-Boards, die untereinander Daten austauschen. Bei einem Board ist die SPI-Schnittstelle mit der SD-Karte verbunden und beim anderen Board ist die SPI-Schnittstelle mit den LEDs verbunden. Und zwischen beiden Boards muss eine schnelle Datenverbindung realisiert werden, die NICHT auf SPI basiert, und mit der das eine Board (was die LEDs abspielt) bei Bedarf innerhalb eines Timer-Interrupts jeweils 180 Bytes Daten vom anderen Board blitzschnell abholen kannn (innerhalb eines Hardware-Interrupts).

Oder mache ich jetzt einen Denkfehler und Deine LEDs nutzen gar nicht Hardware-SPI trotz der Bezeichnung "SPI" in Deinem Library-Namen? Irgendwie konnte ich bei solchen LED-Streifen wie Du sie vermutlich verwendest, gar keine richtige SPI-Schnittstelle entdecken, insbesondere keine Clock-Leitung und keinen Chipselect-Anschluss, wie es für SPI-Geräte typisch ist.

Ich glaube, ich muss mir selbst mal ein paar solcher RGB-LEDs als Experimentiermaterial holen.
1280  International / Deutsch / Re: RTC Abfrage in Variable speichern und weiter verwenden on: November 19, 2013, 07:20:13 am
Und wenn man es einfach so macht (z.B. in der main-loop oder in einer 1sec-Task in der main-loop)?

Und was machst Du dann, wenn das Gerät an einem Tag zwischen 0 Uhr und vor 7 Uhr eingeschaltet wird?
1281  International / Deutsch / Re: Interrupt Routine hängt sich auf! on: November 19, 2013, 04:46:50 am
momentan ist es so das er mir auch 0.00 ausgibt, wenn ich das Triggersignal abmache. Da er in der loop ja permanent Serial.println(Energiewert) ausgibt.
Wie schaffe ich ne vernünftige Alternative, das er in der loop immer nur den Energiewert ausgibt wenn ich mein Signal auch anliegen habe.

Kann Dein Energiewert auch negativ werden oder sind die Werte immer 0 oder größer Null?

In dem Fall brauchst Du nach dem Auslesen den Wert nur auf einen negativen Wert setzen und gibst ihn nur dann aus, wenn er größer oder gleich null ist. Den Wert kann er dann nur von der ISR erhalten haben:

Code:
  noInterrupts(); // ist das hier an der richtigen Stelle?
  if (Energiewert>=0) Serial.println(Energiewert);
  Energiewert=-1;
  interrupts();

Falls Energiewert auch negative gültige Werte annehmen kann, benötigst Du eine boolean-Hilfsvariable, dann setzt Du z.B. in der ISR den Wert auf gültig:
EnergiewertValid=true;
und beim Auslesen:
Code:
  noInterrupts(); // ist das hier an der richtigen Stelle?
  if (EnergiewertValid) Serial.println(Energiewert);
  EnergiewertValid=false;
  interrupts();

Die Anzahl der "Zeichen pro Sekunde", die Du über die serielle Schnittstelle maximal ausgeben kannst, ist immer Baudrate geteilt durch 10. D.h. bei 115200 Baud kannst Du maximal 11520 Zeichen pro Sekunde ausgeben.

Beim Ausgeben von "Zeilen" daran denken, dass auch die Steuerzeichen am Zeilenende mitzählen, das sind üblicherweise immer zwei Steuerzeichen für CR (Carriage Return) und LF (Linefeed). D.h. wenn Du Zahlen mit einer Länge von 10 ausgibst und am Ende einen Zeilenvorschub mit 2 Zeichen, dann sind das 12 Zeichen pro Zeile, dann schaffst Du bei 115200 Baud maximal:
11520/12 = 960 Zeilen pro Sekunde
1282  International / Deutsch / Re: Library einbinden und integer umwandeln on: November 19, 2013, 04:31:49 am
ich glaube, du verstehst mich falsch.
...
Nun gibt es das netino projekt (Net-io programmieren über arduino ide)

Ja, das glaube ich auch, dass ich es nicht vestanden habe.
Aber jetzt scheint es etwas klarer zu werden:

- Du hast einen Arduino mit Ethernet-Shield
- Du hast keine/kaum Ahnung von Arduino-Programmierung
- Du hast ein AVR Net-IO
- Du hast keine Ahnung von AVR Net-IO Programmierung
- Du hast Dateien von einem "netino projekt", mit dem man Net-IO über die Arduino-IDE programmieren kannst
- Und dieses "netino projekt" bekommst Du nicht zum Laufen

Ich weiß nicht, ob ich's jetzt verstanden habe, aber helfen kann ich Dir dabei nicht, soweit es nicht Arduino-Boards, -Shields oder -Software betrifft. Von AVR Net-IO habe ich keine Ahnung. Und in den gruseligen ENC28j60 Netzwerkchip möchte ich mich gar nicht einarbeiten, wo doch der W5100 des Ethernet-Shields viel komfortabler umd speichersparender zu programmieren ist.

außerdem benötige ich allgemein hilfe wie ich den analogwert mit den 0 vorweg hinbekomme

Ganzzahlen mit führenden Nullen formatierst Du am komfortabelsten mit "sprintf" bzw. mit der gegen Pufferüberläufe sicheren Funktion "snprintf": Beispielcode:
Code:
void setup() { 
  Serial.begin(9600);     
  int a0,a1,a2,a3,a4,a5; // integer-Variablen
  char line[41]; // String für 40 Zeichen plus Nullzeichen am Ende
  a0=analogRead(A0);
  a1=analogRead(A1);
  a2=analogRead(A2);
  a3=analogRead(A3);
  a4=analogRead(A4);
  a5=analogRead(A5);
  snprintf(line,sizeof(line),"%06d:%04d:%03d blabla %05d?%04d!%04d",a0,a1,a2,a3,a4,a5);
  Serial.println(line);
}

Die Funktionen sprintf bzw. snprintf arbeiten mit einem "Formatierungs-String", in dem Du festlegst, was für Variablen wie formatiert werden sollen. "%0" steht dabei für "formatiere mit führenden Nullen", die nächste(n) Ziffer(n) stehen für die zu formatierende Mindestbreite und das "d" in "%06d" steht für "Dezimalzahl".

Hinweis: Die Standard-Library bei der Arduino-Programmierung ist die "AVR libc", Dokumentation hier:
http://www.nongnu.org/avr-libc/user-manual/modules.html

Wenn Du nähere Erläuterungen zu den einzelnen Funktionen benötigst, kannst Du den Funktionsnamen leicht googeln und Dir die Verwendung in C- bzw. C++ Tutorials irgendwo im Internet ansehen, da fast alle Funktionen der AVR libc auch in anderen C-Standardlibraries enthalten sind.


1283  International / Deutsch / Re: RTC Abfrage in Variable speichern und weiter verwenden on: November 19, 2013, 04:06:53 am
Eine Frage habe ich noch ob es möglich wäre das so um zustellen das nicht um ca 0 Uhr ein neues Log erstellt wird sondern zm um ca 7 Uhr? Also wenn das nicht zu aufwendig wäre sonst reicht das so auch

Verwendest Du eine Time-Library, die Unix-Zeitstempel (Sekunden seit 01.01.1970) unterstützt?

In dem Fall wäre es einfach, Du würdest einfach vor 7 Uhr (hour<7) einen Sonderfall behandeln:
- Datum und Zeit in einen Unix-Timestamp umwandeln
- davon 86400 Sekunden abziehen (= 1 Tag)
- den verminderten Unix-Timestamp wieder in Zeit und Datum zurückwandeln
- und dann diese Datumsangaben zur Bildung des Dateinamens "vor einem Tag" verwenden

Leider läßt sich der vorangegangene Tag erst ab dem 2. eines Monats leicht errechnen, man zieht einfach 1 vom aktuellen Tag ab. Aber am ersten eines Monats klappt es so nicht: Der vorangegangene Monat kann 28,29,30 oder 31 Tage gehabt haben, und außer einem Monatswechsel kann auch ein Jahreswechsel stattgefunden haben. Das mit dem Unix-Timestamp, von dem 86400 Sekunden abgezogen und der dann zurückgewandelt wird, klappt aber an jedem Tag jeden Jahres.

Falls Du keine Time-Library verwenden möchtest, könnte man sich aber auch was anderes überlegen. Gerade am letzten Wochenende hatte jemand danach gefragt, wie man aus Zeit und Datum den Unix-Zeitstempel errechnen kann und ich hatte ihm dafür eine genialistischen Dreizeiler-Funktion gemacht. Da müßte ich nochmal googeln und ggf. etwas programmieren, ob das rückwärts genau so einfach funktioniert.

Wie gesagt: Standardmäßig über den Unix-Zeitstempel den Vortag berechnen wie oben beschrieben, das ist mit der "Time" Library möglich.
1284  International / Deutsch / Re: SD-Karte: Dateinamen als String öffnen on: November 19, 2013, 03:37:56 am
haben dazu geführt, dass ich jetzt schon bei ca 2 ms pro Spalte angekommen bin. Das ist fantastisch!!

Leider kommst Du nur "im Schnitt" auf unter 2ms. Das Einlesen einer Bildzeile dauert zwischen 0,12 und 5,9 ms. Die zum Einlesen von 180 Bytes benötigte Zeit ist stark schwankend.

D.h. wenn Du das Einlesen der RGB-Bits und das Setzen der LEDs beides in der loop machst, und die Anzeigedauer ist weniger als 6ms, dann bekommst Du nur schwankende Anzeigedauern realisiert. Z.B. bei einer Soll-Anzeigedauer von 2ms werden zwar viele Bildzeilen 2ms lang dargestellt (ein notwendiges delay kann man über delayMicroseconds() steuern), aber wenn das Nachladen von SD mal wieder 6 ms dauert, werden unvermeidbar einzelne Bildzeilen auch 6 ms lang angezeigt.

Eine gleichmäßige Anzeigedauer kannst Du nur mit Timer-Interrupts erreichen
- in der loop werden mehrere Zeilenpuffer vollgeladen (mit schwankender Lesegeschwindigkeit)
- ein Timer-Interrupt alls 2 ms stellt die LED-Zustände dar (mit gleichbleibender Abspielgeschwindigkeit)

Ja, ich hab's jetzt so gelöst: Im Bildheader steht in Byte 18/19 die Bildbreite und in Byte 22/23 die Höhe drin. Ich nehme einfach die Breite * 3 und fange mit 'ner While-Schleife an hochzuzählen. Irgendwann ist das Ergebnis durch 4 teilbar (Modulo) und DAS  speichere ich ab als Variable dats_bytes_pro_zeile. Funktioniert hervorragend. Bei 59 * 3 = 177 ist dann eben das erste durch 4 teilbare Ergebnis 180.

Ich habe einfach Konstanten definiert, die der Präprozessor ausrechnet:
#define NUMLEDS 59
#define LEDBUF_SIZE NUMLEDS*3  // 177 Bytes RGB
#define BMPBUF_SIZE (LEDBUF_SIZE+3)/4*4  // 180 Bytes per line in image file

Diese definierten Konstanten rechnet der Präprozessor aus, der Compiler verwendet dann direkt 59, 177 und 180 als Konstanten.

Also: Ich widerrufe öffentlich: SD IST NICHT LANGSAM!!! SD ist schnell, wenn man weiß wie man zugreifen muss. smiley

Ja, man hat zwar nicht so viel Datendurchsatz wie bei RAM-Speicher, aber bis über 200 kByte/s sind auch mit SD-Speicher als Leserate möglich.
1285  International / Deutsch / Re: Library einbinden und integer umwandeln on: November 19, 2013, 02:59:27 am

Mit einem AVR Net-io scheinst Du für mich komplett im falschen Forum zu sein. 
Hier geht es um Arduino-Hardware, Arduino-Software und Arduino-kompatibles Zubehör zu vorstehendem.
Ein Board mit Atmega32 ist kein Arduino und ein AVR Net-IO Board ist auch kein Arduino.

Wenn Du das (und noch mehr), was Du mit dem AVR Net-io machen kannst, mit einem Arduino machen wolltest, dann würdest Du als Hardware benötigen:
- ein Arduino-kompatibles Board (z.B. UNO oder MEGA)
- ein Ethernet-Shield mit W5100
1286  International / Deutsch / Re: Zeit zwischen 2 Aktionen messen on: November 19, 2013, 02:44:13 am
ich habe wie ihr sehen könnt 2 Sensorwerte die wiederum Fotowiderstände sind an einer ...ich nenne es mal.... "Apparatur" angebracht

OK, dann nenne ich es auch mal "Apparatur".

Wenn man sich also Sensorwert 1 und 2 als punkte auf einer Strecke vorstellen möchte, möchte ich nicht das Der Klick an den jeweiligen punkten sondern genau in der Mitte davon zuschlägt.

Aha, eine Hellseher-Apparatur:
Deine Apparatur soll also "nach der Hälfte der Zeit" irgendeine Aktion auslösen, wobei die Gesamtzeit noch gar nicht gemessen wurde.
1287  International / Deutsch / Re: RTC Abfrage in Variable speichern und weiter verwenden on: November 18, 2013, 03:07:12 pm
Zur Verständnis noch mal, bin noch nicht so lang am Programmiern.

Die gepostete Funktion irgendwo "zwischen zwei anderen Funktionen" (z.B. zwischen setup und loop) ins Programm einfügen und dort, wo die Datei geöffnet werden soll, dann:
Code:
 logfile = SD.open(formatFilename(day,month,year,"CSV"), FILE_WRITE);

Also anstelle des Dateinamens einfach die Funktion aufrufen, die den Dateinamen bildet. und an SD.open übergeben.

Natürlich müßtest Du day, month, year (oder vergleichbare Variablen) vorher aus Deiner RTC ausgelesen haben, damit Du sie dann in den Funktionsaufruf einsetzen kannst.
1288  International / Deutsch / Re: RTC Abfrage in Variable speichern und weiter verwenden on: November 18, 2013, 01:54:31 pm
Nur will ich jetz eine Funktion mit einbauen die mir jeden Tag der übersichtshalber ein neues Logfile erstellt.

Am einfachsten öffnest Du als Namen der Logdatei einen Dateinamen, den Du aus Jahr, Monat und Tag immer dann bildest, wenn die Logdatei geöffnet werden soll. Zum Beispiel mit dieser Funktion:

Code:
char* formatFilename(int day, int month, int year, char* ext)
{
  static char filename[13];
  snprintf(filename,sizeof(filename),"%04d%02d%02d.%s",year,month,day,ext);
  return filename;
}

Diese Funktion würde beim Aufruf (mit entsprechenden aktuellen Parametern):
Code:
char* filename=formatFilename(day,month,year,"CSV");
oder
char* filename=formatFilename(day,month,year,"TXT");
heute den Dateinamen 20131118.CSV bzw 20131118.TXT bilden.
Und wenn Du dieselbe Funktion morgen aufrufst 20131119.CSV oder 20131119.TXT.

Diese Art Dateinamen hat auch den Vorteil: Ohne dass im FAT-Dateisystem Zeitstempel für die Logdatei gesetzt sein müssen, kannst Du eine Liste dieser Dateien auf jedem Betriebssystem trotzdem chronologisch sortieren: Alphabetische und chronologische Sortierung sind beim Sortieren solcher Dateinamen nämlich identisch.
1289  International / Deutsch / Re: Interrupt Routine hängt sich auf! on: November 18, 2013, 02:32:15 am
@jurs: habe das neu hinzugefügte in der loop markiert, meinst du es so?
Energiewert ist ja als volatile deklariert am Anfang des Programms.

Ja, serielle Ausgaben von der loop aus aufrufen, nicht in der Interrupt-Routine, genau das meinte ich.
Nein, in Codeabschnitten kannst Du nichts "markieren", außer mit Kommentaren.

Problematisch ist auch das meine loop() nicht hinterherkommt was die Abarbeitung der FunktionSerielle_Eingabe_string() betrifft, dieich nach deinem Ansatz auf gebaut habe.

Einleseroutinen mit "delay(100)" oder ähnliches sind nur für Programme sinnvoll, die als Mindestanforderung haben, dass sie "interaktiv auf Eingaben reagieren" sollen. Für Programme, mit erhöhten Anforderungen an schnelle Signalverarbeitung ist JEDES delay() im Programm unbedingt zu vermeiden. In Programmen mit schneller Signalverarbeitung brauchst Du statt so einer Anfänger-Einleseroutine eine anders aufgebaute, delayfreie Routine zum Einlesen von der seriellen Schnittstelle.

Und wie schon von Serenifly mit ähnlicher Aussage geschrieben, sind Deine EEPROM-Schreibaktionen im Sketch irgendwie sinnfrei.

EEPROM-Speicher ist nur begrenzt oft beschreibbar, Atmega garantiert nur für 10000 mal. D.h. EEPROM-Speicher sollte nur für die seltene Speicherung von längerfristig gültigen Daten verwendet werden, sagen wir mal Einstell- und Konfigurationswerte. Beim ständigen Beschreiben immer derselben Speicherstellen hast Du EEPROM-Speicher in kürzester Zeit kaputtgeschrieben und der Speicher ist defekt. Lediglich das Auslesen von EEPROM-Speicher ist unbegrenzt oft möglich.

Nur RAM-Speicher, also normale Variablen im RAM, darfst Du beliebig oft ändern, ohne dass es dabei zu Abnutzungserscheinungen kommt, aber für EEPROM-Speicherstellen gilt das nicht.
1290  International / Deutsch / Re: Wasserdichtes Arduino Uno Gehäuse gesucht on: November 17, 2013, 06:11:20 am
Es müsste auf dem Balkon Regen trotzen.

Sind diese runden Kabelschächte aus Silikon und man muss ein Loch rein machen?
http://www.ebay.de/itm/neu-2-LEGRAND-Abzweigdosen-IP55-Plexo-ROT-80x80x45-92015-/301017118783

Für einen Wetterschutz im Außenbereich brauchst Du kein "wasserdichtes Gehäuse", sondern ein "regengeschütztes Gehäuse".

Wasserdichtheit ist eher schädlich, da bei einer Dichtheit des Gehäuses im Außenbereich ein anderes Problem zuschlägt als der Regen: Kondenswasser! D.h. durch eindringende Luft und durch Temperaturschwankungen bildet sich im Gehäuse Kondenswasser, und wenn das Kondenswasser nicht wegtrocknen kann, hast Du Deine Schaltung wochen- oder monatelan in einer nassen Tropfsteinhöhle untergebracht und die Schaltung ist spätestens nach einigen Monaten korrodiert und wird ausfallen.

Um an einer Schaltung im Außenbereich ohne teure und aufwändige Maßnahmen lange freude zu haben, muß die Schaltung in einem luftigen, aber regengeschützten Gehäuse untergebracht sein. 

Die von Dir gezeigte "Feuchtraumdose" (die normale graue Baumarkt-Ausführung tut es auch) beispielsweise regengeschützt unter einem Dachüberstand im Freien regengeschützt montiert. Oder mit einer "Regenschutzhaube" drüber.

Die Luft darf gerne reinkommen: Damit eventuell sich bei ungünstigen Wetterlagen bildendes Kondenswasser innerhalb kürzester Zeit wegtrocknen kann. 

Allerdings darf auch der Insektenschutz bei den Lüftungsöffnungen nicht vernachlässigt werden, sonste können Dir Marienkäfer die Platine zukacken oder kleine Spinnen im Gehäuse brüten. Im Zweifelsfall so eine Feuchtraum-Verteilerdose
- regengeschützt anbringen (z.B. unter einem Dachüberstand, oder unter einer nach unten offnen Haube)
- auch gegen direkte Sonneneinstrahlung geschützt anbringen (um Überhitzung zu vermeiden)
- von unten ins Gehäuse lieber ein "Lüftungsloch" zusätzlich reinbohren, zwecks Verdunstung von Kondenswasser
- und Lüftungslöcher gegen das Eindringen von Insekten sichern, z.B. mit einen davorgeklebten Stück Fliegengitter.

Es ist nicht gut, im Außenbereich untergebrachte Platinen in zu dicht schließenden Gehäusen unterzubringen, da richtet das Kondenswasser, das bei Temperaturunterschieden im Gehäuse entsteht, in wenigen Monaten sehr große Schäden an.

Gut Regengeschützte, aber auch gut durchlüftete Gehäuse sind besser als extrem wasserdicht schließende Gehäuse.

Und am besten für einen langjährigen Betrieb im Freien sind mit Elektronik-Vergußmasse vergossene Schaltungen. Aber das ist relativ aufwändig und gute Elektronik-Vergußmassen gehen auch kräftig ins Geld.


Pages: 1 ... 84 85 [86] 87 88 ... 203