Hallo Da der 2560 voll zulange brauch um meine Sensoren aus zu lesen und aus zuwerten so wie auf Displays anzuzeigen, und das an das Ethernet schilt weiter zugeben. habe ich versucht es mit einen Interrupt pin der mit dem int pin vom enc28j60 zu verbinden. die Erkennung wenn ein client sich verbinden zuwollen scheint auch zu laufen leider bricht der 2560 noch vor der ersten Daten Übertragung zum Browser einfach ab. und macht bei der letzten Aufgabe vor dem unterbrechen weiter ODER bleibt in der int schleife hängen. Wie habt ihr das gelöst ? Vielen dank
DAVID -. schrieb: > Wie habt ihr das gelöst ? Wir haben unsere Probleme klar und ausführlich dargestellt und einen sauberen Schreibstil gewählt, inklusive einigermassen korrekter Grammatik und Gross/Kleinschreibung.
> Wie habt ihr das gelöst ?
Mit anderer Hardware und vermutlich auch anderer Software.
DANKE für die Hilfe :- ) Ich habe schon extra auf Rechtschreibung gedachtet na gut groß und klein Schreibung ist untergegangen aber egal. Ich habe mal den code für Ethernet angefügt dieser ist noch nicht fertig.
DAVID -. schrieb: > Ich habe schon extra auf Rechtschreibung gedachtet na gut groß und klein > Schreibung ist untergegangen aber egal. Worauf Du bei all diesem Achten aber nicht geachtet hast, ist eine verständliche Darstellung Deines Problems. Ganz sicher ist Dein µC nicht zu langsam, das wird Dein Programm sein.
Hmm ich habe 2 Code teile die einzeln stabil und fehlerfrei laufen. Code eins ist zum auslesen von Temperatur Sensoren und Magnet Schaltern und anzeigen der werte auf Displays. Code teil 2 ist der LAN teil wo die Sensoren Daten auf eine Ethernet karte gesendet werden sollen. wie sagt beides einzeln geht. Versuche ich jetzt nur EIN der 12 DS18B20 auszulesen und übergebe nur ein Sensor wert der Ethernet karte geht das auch GRADE noch so mit ein paar sec Ladezeit der Seite. Übergebe ich jetzt aber alle 12 temp werte und lasse diese auch noch auf ein Display zusätzlich ausgeben bekomme ich Natürlich keine Verbindung mehr. Da kam mir die Idee mit dem Interrupt pins. Der enc28j60 gibt bei Verbindungsaufbau aufbau ja 3,8 Volt welche sich für für die Erkennung eignen. Ich habe also ein void bereich für lan gemacht der nur gestartet wird wenn der int pin vom enc28j60 auf LOW geht. Soweit geht das auch er 2560 erkennt den LOW Pegel springt zu dem void lan bereich und bricht dann irgendwo ab.(kann ich nicht nachvollziehen) Der enc28j60 sendet aber weiterhin ein LOW Signal da dieser ja auf seine Daten wartet und keine bekommt. Ich hoffe das ist verständlicher.
Vergiss mal die Interrupt Leitung, die brauchst du nicht. Der Ethernet
Controller puffert die Kommunikation und wenn der Puffer nicht
ausreicht, werden die Pakete durch das TCP Protokoll automatisch
wiederholt.
Zwischen Ethernet Controller und Mikrocontroller ist das Timing völlig
entspannt.
In deinem Programmteil mit der Displayausgabe hast du möglicherweise
lange Warteschleifen, die dazu führen, dass der andere programmteil für
die LAN Kommunikation gar nicht mehr ausgeführt wird. Falls das der Fall
ist, musst Du Dir überlegen, wie du dein Programm Multi-Taksing fähig
machst (Suchwort: Zustandautomat oder Endlicher Automat).
Es könnte auch sein, dass du einen Watchdog verwendest, der durch die
Zeitaufwändige Kommunikation mit dem Display nicht mehr schnell genug
bedient wird. Dann musst du das Zeitintervall des Watchdogs entsprechend
erhöhen.
Mehr kann man nur sagen, wenn du das komplette Projekt inclusive
Schaltplan veröffentlichst.
> kann ich nicht nachvollziehen
Dafür gibt es ICE Debugger, oder Log-Meldungen die du auf eine serielle
Konsole ausgibst.
eins vor weg: Ich bin noch nicht sehr weit mit Programmierer Fähigkeiten dies bitte ich zu berücksichtigen. Ich habe dein post aufmerksam gelesen und und bin für deine Anmerkungen sehr dankbar. Ich selber habe aber kein Watchdog verwendet. Und eine wartezeit gibt es nur bei den Temperatur fühlern von 550 ms das ist der Kompromiss zwischen fehlerhafter Übertragung und Geschwindigkeit Die bepinung wäre wie folgt: die 3 Displays vom typ LCD2004 Display sind mit 11, 10 ,(9 bis 6), 5, 4 verbunden. Lan am 2560: 53 SS) /51 MOSI /50 MISO /52 SCK Lan karte 10 SS /11 MOSI /12 MISO /13 SCK Inter. 0 = Digitaler Pin 2 Temperatur Sensoren hängen am pin 22 0-15A Spannungsmessung (Füllzustände)
DAVID -. schrieb: > Ich habe mal den code für Ethernet angefügt dieser ist noch nicht > fertig. Dann kann es auch nicht gehen!
SEHR gute Hilfe ! meinst du will ich die lokale IP geXXX habe ? Danke fürs nicht lesen mit nicht fertig meinte ich damals das noch nicht alles eingebaut ist was ich mir vorstelle und die botton noch nicht an der richtigen stelle sind.
DAVID -. schrieb: > und die botton noch nicht an > der richtigen stelle sind. Dann kann es nicht gehen!
Ich habe übrigens ein paar Fehler im Code gefunden. Die sehen alle in etwa so aus:
1 | float spannung8 = sensorValue8 * (4.9 / 1023.0); |
Heute hatte ich das schon mal geschrieben, aber man kann es nicht oft genug wiederholen: 1023 ist genauso falsch wie 2047 und 4095. Dort muss immer eine Zweierpotenz stehen. Lies mal den Beitrag "1023 oder 1024" Und dann nimm weiterhin die 1023, weil die dir besser gefällt. Aber falsch ist sie trotzdem. Und im Datenblatt des ADC steht sicher auch was Anderes. Und zudem MUSS der kleine AVR zu langsam sein, wenn du ihn als 8-Bitter so unnötig mit 32-Bit-Fließkommaoperationen zutextest.
Die loop() Funktion enthält eine Menge Displayausgaben. Ich sehe aber nicht, wo die LAN() Funktion aufgerufen wird. Anscheinen gar nicht. Du hast geschrieben, dass dein Programm ausfällt, wenn du beides kombinierst. Aber ich kann nicht sehen, wie du die beiden Programmteile kombiniert hast. Die LAN() Funktion enthält eine while() Schleife, die wiederholt wird, solange der Client verbunden ist. Aber innerhalb der Schleife wird die Verbindung getrennt (was auch so sein soll). Die Schleife wird also immer genau ein mal durchlaufen, daher kannst du sie weglassen. Der generierte HTML Text ist voller Fehler. Du solltest das mal mit deinem Web-Browser in eine Datei abspeichern und durch ein Kontroll-Programm laufen lassen, dass alle Fehler meldet (https://validator.w3.org/#validate_by_upload).
> float temp1 = (12,34); Was ist das eigentlich für eine komische Syntax? Das kenne ich so nicht. Fließkommazahlen schreibt man so: > float temp1 = 12.34; Siehe http://en.cppreference.com/w/cpp/language/floating_literal Und https://www.arduino.cc/en/reference/float
Danke Lothar Miller du hast vollkommen recht an das habe ich gar nicht mehr gedacht. ich werde es auf HIGH und LOW Erkennung (digitalRead) umbauen was ohnehin besser zu mein vorgaben passt. Und danke auch dir Stefan die LAN Funktion wird durch den Interrupt Pin 0 vom Ethernet Schild gestartet. Ich habe auch dein Radschlag berücksichtigt und verzichte auf den interrupt. Zum Testen habe ich mal alles einzeln zusammen gebaut bis es nicht mehr lief und über geblieben ist das auslesen der 18b20 nehme ich das raus und ändere sonst nix läuft es super. Displays zeigen nur test an Spannung werden noch unverändert gemessen Und LAN läuft auch super. Wäre meine Schlussfolgerung ich muss erreichen das ich anstellen bei jeden Durchgang die Sensoren auszulesen immer nur ein wert hochzählen lasse und nach sagen wir 100 Durchläufe eine abfrage mache. Eine Messung pro Minute reicht mehr wie aus. Noch eine Überlegung zusätzlich wenn ich anstelle float einfach int nehme weil ich auf die Kommastelle der Temperaturen verzichten kann würde es reichen alle float werte der Berechnung auf int zu ändern ? PS Stimmt Stefan das ist ein Tippfehler von mir wird geändert.
:
Bearbeitet durch User
> Und danke auch dir Stefan die LAN Funktion wird durch den > Interrupt Pin 0 vom Ethernet Schild gestartet. Diese Arduino Library baut auf uIP auf, damit kenne ich mich gut aus. uIP erfordert, dass eine Reihe von Funktionen des Treiber immer wieder aufgerufen werden. In der Ardunio Library ist der entsprechende Code in UIPEthernetClass::tick(); Diese Methode wird wiederum von zahlreichen anderen Methoden der Library aufgerufen. Die Ethernet Schnittstelle wird nur funktionieren, wenn du wuasi ununterbrochen immer wieder Funktionen der Ethernet Library aufrufst. In deinem Fall wird die Ethernet Library nach der Initialisierung zunächst gar nicht mehr aufgerufen. Deswegen hat dein Server (der Arduino) keine Verbindungen angenommen. Du hast einen Interrupt benutzt, um die LAN Funktion zu starten. Dein Problem ist, dass du nach dem Erzeugen der Webseite noch viele male UIPEthernetClass::tick() aufrufen musst, bis die Ethernet Kommunikation vollständig abgeschlossen ist. Aber das wäre ein unsauberer Ansatz. uIP ist nicht dafür ausgelegt, nur ab und zu bei Bedarf ausgeführt zu werden - schon gar nicht in einer Interruptroutine. Sondern du sollst es ständig ausführen. Das Hauptprogramm (loop) soll immer wieder bei jedem Schleifendurchlauf eine Funktion der Ethernet library aufrufen, welche UIPEthernetClass::tick() enthält. Zum Beispiel UIPServer::available(). Auf https://www.arduino.cc/en/Reference/ServerAvailable findest du ein korrektes Minimalbeispiel:
1 | void loop() |
2 | {
|
3 | EthernetClient client = server.available(); |
4 | if (client) { |
5 | server.write(client.read()); |
6 | }
|
7 | }
|
Hier wird praktisch immer wieder server.available() aufgerufen, auch wenn gar keine Verbindung besteht. Diese Funktion beinhaltet wiederum einen Aufruf der tick() Funktion, welche der Kern des Netzwerktreiber ist. Außerdem: AVR Mikrocontroller können Interruptroutinen nicht durch weitere Interrupts unterbrechen. Da du sehr viel Code in der LAN-Interruptroutine untergebracht hast, werden alle anderen Interrupts entsprechend lamge stehen bleiben - zum Beispiel der Systemtimer. Das ist auch Käse. Schreibe dein Hauptprogramm (loop) als Zustandsautomat um, so dass es deine beiden Programmteile quasi parallel ausführt. Und vergiss die Interrupt-Leitung, die schafft nur weitere noch komplexere Seiteneffekte die du nicht haben willst. By the way: Die Dokumentation der Library ist schrecklich unvollständig. Kein Wunder, dass du damit nicht klar kommst.
> Und zudem MUSS der kleine AVR zu langsam sein Für den relativ kleinen Mikrocontroller sind diese vielen float Operationen ein großer Brocken Arbeit, aber das ist 100% sicher nicht die Problemursache. Wie gesagt ist das Timing der Kommunikation AVR<->Ethernet Controller sehr entspannt. Es wäre völlig egal, wenn der AVR sich zwischendurch mehrere hundert Millisekunden Rechenpausen genehmigt. Problemursache ist hier, dass der ganze Ethernet Treiber nach dem Erzeugen der Webseite gar nicht mehr aufgerufen wird. Das ist aber kein Timing Problem, sondern ein Designfehler im Programmablauf. > Zum Testen habe ich mal alles einzeln zusammen gebaut bis es nicht mehr > lief und über geblieben ist das auslesen der 18b20 nehme ich das raus > und ändere sonst nix läuft es super. Das könnte auf einen Heap oder Stack Speicherüberlauf hindeuten. Was mich nicht wundert, da ja die Interruptroutine (LAN) ebenfalls sehr umfangreich ist. > Wäre meine Schlussfolgerung... Die ist falsch. Verzichte auf den Interrupt und benutze einen Zustandsautomaten. Mit etwas Glück löst sich dadurch auch dein Speicherproblem in Luft auf. Es könnte helfen, eine automatische Kontrolle des SPeichers einzubauen. Da wurde hier schonmal ausführlich diskutiert (-> Suchfunktion nutzen). > würde es reichen alle float werte der Berechnung auf int zu ändern Auch das könnte dein Speicherproblem lösen. Ich würde den Code erstmal auf weniger reduzieren. Lies einen Sensor aus, zeige dessen Wert auf dem Display an und mach eine minimale LAN Ausgabe (ohne Aktions-Buttons und dem entsprechenden Code zu Auswertung). Und erst wenn das zuverlässig läuft, erweitere den Code.
Um das Verständnis für uIP zu Vertiefen, könnte ein Blick in die Quelltexte der Arduino Library und der uIP Dokumentation helfen. Auf der Seite https://github.com/adamdunkels/uip/blob/master/doc/example-mainloop-with-arp.c findest du eine Hauptschleife für uIP, so wie dessen Entwickler Adam Dunkels es empfiehlt. So sehen auch meine uIp basierten Programme aus. In deiner Arduino Library findest du den entsprechenden Code in der tick() Funktion wieder. Und da kannst du auch sehen, welche anderen Library Funktione tick() aufrufen. Wichtig ist letztendlich, das tick() immer wieder aufgerufen wird - auch wenn der Server gerade nichts zu tun hat oder auf eine Verbindung wartet. Ohne regelmäßige tick() Aufrufe kann uIP nicht funktionieren.
Vielen DANK für deine ausführlichen Beschreibung die ist sehr gut ! Ich bin jetzt nach vielen andren versuchen und deiner großen Hilfe zum erfolg gekommen. nämlich mit (t++); //(Zählt t immer eins hinzu) if ( t > 1000) //(fragt ab ob 1000 erreicht sind dann wird gelesen) { temp1 = getTemperature(sensor1); temp2 = getTemperature(sensor2); temp3 = getTemperature(sensor3); temp4 = getTemperature(sensor4); temp5 = getTemperature(sensor5); temp6 = getTemperature(sensor6); temp7 = getTemperature(sensor7); temp8 = getTemperature(sensor8); temp9 = getTemperature(sensor9); temp10 = getTemperature(sensor10); temp11 = getTemperature(sensor11); temp12 = getTemperature(sensor12); (t = 0); } Damit jagt der 2560 durch sein Programm das ist ganz neu :-) Jetzt muss ich noch bremsen einbauen sonst zeigen die Displays nur Striche :-) ahh ist das toll ein erfolg. Sind solch großen zahlen 1000 oder mehr eigentlich ein großes Problem ?(belasten den RAM zustark) ? Ich mache noch die spannungs abfrage anderes zurzeit liege ich noch gut bei: Der Sketch verwendet 31622 Bytes (12%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes. Globale Variablen verwenden 5782 Bytes (70%) des dynamischen Speichers, 2404 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes. Stefan Us du bist mein Held ! Eine frage noch was genau bewirk eigentlich delay ? Ja klar es wird eine pause gemacht aber pausen gibt es doch eigentlich nicht ? Wird das was sinnloses gerechnet oder was macht der Chip da genau ? Vielen dank!
:
Bearbeitet durch User
> Sind solch großen zahlen 1000 oder mehr eigentlich ein großes Problem?
Integer belegen 2 Bytes.
Floats belegen 4 Bytes.
Mit deinem Zähler löst du das Problem aber nicht wirklich. Du hast damit
lediglich die Wahrscheinlichkeit des Aufhängens um Faktor 1000
reduziert.
Wie wäre es, wenn du nur bis 12 Zählst und bei jedem Durchlauf nur einen
Sensor abfragst?
1 | DeviceAddress sensor[] = { |
2 | /*1*/ { 0x28, 0xFF, 0x86, 0x2E, 0x74, 0x16, 0x3, 0xAF } |
3 | /*2*/ { 0x28, 0xFF, 0x5, 0x72, 0x74, 0x16, 0x3, 0xE0 }, |
4 | ...
|
5 | };
|
6 | |
7 | float temp[12]; |
8 | |
9 | ...
|
10 | |
11 | t++; |
12 | temp[i] = getTemperature(sensor[i]); |
13 | if (t>12) t=0; |
Du müsstest dann die 12 temp Variablen und die 12 Sensor Variablen durch Arrays ersetzen. Aaaaber: Das geht völlig an meinem Verbesserungsvorschlag vorbei! Es wird dein Programm nicht wirklich zuverlässig machen. Du wirst auf den Interrupt verzichten müssen und einen Zustandsautomaten verwenden müssen. Aber das kennen wir, eine gewisse Beratungsresistenz ist bei gewissen leuten ja bekannt.
Was mit bei dieser Arduino Library noch völlig unklar ist, wie deren Entwickler sich vorstellen, mehrere Connections gleichzeitig zu bedienen. Denn das machen Web Browser ja. Sie bauen mehrere Verbindungen gleichzeitig auf, um Dateien/Webseiten herunterzuladen. Soweit ich beim schnellen durchschauen der Quelltexte und Beispiele sehen konnte, ist aber wohl nur eine gleichzeitige Verbindung vorgesehen. Ich habe daher Zweifel, ob die Library überhaupt geeignet ist, Webbrowser zu bedienen.
Stefan U. schrieb: > Was mit bei dieser Arduino Library noch völlig unklar ist, wie deren > Entwickler sich vorstellen, mehrere Connections gleichzeitig zu > bedienen. Denn das machen Web Browser ja. Sie bauen mehrere Verbindungen > gleichzeitig auf, um Dateien/Webseiten herunterzuladen. > > Soweit ich beim schnellen durchschauen der Quelltexte und Beispiele > sehen konnte, ist aber wohl nur eine gleichzeitige Verbindung > vorgesehen. Ich habe daher Zweifel, ob die Library überhaupt geeignet > ist, Webbrowser zu bedienen. Um die Browser muss man sich keinen Kopf machen. Die machen die Verbindungen auch nacheinander, wenns gleichzeitig nicht gelingt. Streckt sich dann halt nur.... Und irgendwann hagelt es Timeouts, wenn es gar nicht gelingt, aber auch das dauert etwas...
Sorry das es so lange gedauert hat aber. Die Idee mit dem immer nur ein Sensor auslesen klingt auch gut und sinnvoll. werde noch mal drüber nachdenken. Und auf den interrupt pin verzichte ich schon. Hat wie du auch angedeutet hast nur ärger gemacht. Und nur weil ich es nicht gleich verstehe oder ich ein andern weg der für mich auch ok ist gefunden habe, Bin ich nicht gleich beratungsresistent ok ? DANKE Wäre auch sehr nett wenn für noch jemand die frage von oben beantworten könnte. >>Eine frage noch was genau bewirk eigentlich delay ? >>Ja klar es wird eine pause gemacht aber pausen gibt es doch eigentlich nicht ? >>Wird das was sinnloses gerechnet oder was macht der Chip da genau ? Ich bedanke mich bei allen die mir geholfen haben. VIELEN LIEBEN DANK!!
Hi Das delay(x); lässt wohl eine Schleife laufen, Die x ms Zeit braucht. In der Zeit macht der µC aber nichts Anderes - außer vll. auf Interrupts reagieren. MfG
> Wird das was sinnloses gerechnet Genau das. In der Regel lässt man einfach ein paar zahlen in verschachtelten Wiederholschleifen hoch zählen, bis der gewünschte Zählwert (=zeit) erreicht ist. Im Prinzip funktioniert das wie ein mechanischer Küchentimer, nur mit Zählern statt Zahnrädern. http://thumbs4.picclick.com/d/l400/pict/400660001207_/Kr%C3%A4hender-K%C3%BCchentimer-Hahn-Kikeriki-K%C3%BCchenwecker-Eieruhr-Kurzzeitmesser-Kr%C3%A4ht.jpg
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.