Forum: Mikrocontroller und Digitale Elektronik Arduino Webserver mit Diagramm


von Kilian K. (kellermaaan)


Lesenswert?

Schönen guten Morgen,

momentan arbeite ich mit dem Arduino Taijiuino auf Basis des Arduino 
Due. Auf diesem läuft der lwIP Stack mit einem Webserver. Jetzt möchte 
ich über einen Analogen Eingang Werte einlesen und diese dann als 
Diagramm auf einer Webseite darstellen. Nur weiß ich nicht genau wie ich 
das anstellen soll...
Vielleicht ist hier ja jemand der mir helfen kann?

MfG Kilian

von PittyJ (Gast)


Lesenswert?

Die Graphik aus dem Messwerten auf dem Arduino erzeugen, z.B. als PNG.
Dieses dann dem Webserver bereitstellen. Und in der HTML-Hauptseite dann 
das Bild einfügen.

Wo liegt denn das Problem genau?

von Noch einer (Gast)


Lesenswert?

So ein Arduino hat dafür nicht genug Speicher.

In diesem Fall dürfte eine der Javascript-Libraries besser sein, die mit 
HTML 5 die Grafik im Browser erzeugen.

von Noch einer (Gast)


Lesenswert?

... wenn die Libraries mit ihren 5000 Features nicht zu groß sind :-(

Wahrscheinlich wird es einfacher, du arbeitest ein HTML-Canvas Tutorial 
durch und schreibst eine kleine Library selbst.

von Kilian K. (kellermaaan)


Lesenswert?

Noch einer schrieb:
> In diesem Fall dürfte eine der Javascript-Libraries besser sein, die mit
> HTML 5 die Grafik im Browser erzeugen.

Darüber hab ich auch nachgedacht. Nur da bin ich mir noch nicht wirklich 
sicher welche man da am besten nimmt... Und desweiteren weiß ich noch 
nicht genau wie ich der Library die Daten übergebe, diese werden nämlich 
in keiner Datenbank abgespeichert. Es wird ne bestimmte Anzahl an Werten 
eingelesen und diese sollen dann direkt in einem Diagramm dargestellt 
werden.

von Borislav B. (boris_b)


Lesenswert?

Noch einer schrieb:
> ... wenn die Libraries mit ihren 5000 Features nicht zu groß sind :-(

Die library muss ja nicht auf dem Arduino liegen. Sie kann auch von 
externen Servern referenziert werden.

von Noch einer (Gast)


Lesenswert?

Kommt hat drauf an, ob du scrollen und zoomen willst.

Im ersten Schritt würde ich drauf verzichten. Einfach eine dynamische 
Seite mit den Daten als JSON, einem <script src="makeimage.js"> und 
etwas Html mit den Buttons und dem Anker für die Grafik.

von Kilian K. (kellermaaan)


Lesenswert?

Aber wenn ich mit dem Arduino die Werte einlesen, wie bekomme ich diese 
dann in die .js/.php Datei?

von Noch einer (Gast)


Lesenswert?

PHP Seite?

Die HTTP-Server für Mikrocontroller sind alle recht umständlich. Du 
registrierst eine C-Funktion im Server. Die musst dann hart kodiert 
Parameter auswerten und Text ausgeben. Ein C-Programm, das HTML 
zusammenstellt ist locker der 10 Fache Aufwand wie eine PHP-Seite.

von PittyJ (Gast)


Lesenswert?

Noch einer schrieb:
> So ein Arduino hat dafür nicht genug Speicher.
>

Der Arduino Due hat einen 32Bit Arm Core mit 96 Kbyte Ram.
Damit lässt sich auch schon ein kleines Bild zeichnen.

von Alex (Gast)


Lesenswert?

Hallo,

ich hab sowas ähnliches mal auf einem MSP-Devboard umgesetzt. Da lag 
dann eine Index.html/php drauf und ein javascript, dass über CGI die 
Daten aus dem speicher des ARM gezogen hat. Zum Diagramm zeichen 
könntest du die Charts.js benutzen ist nur ein paar kb groß. Das 
Diagramm lässt sich dann in HTML beliebig verändern und anpassen.

Alex

von 234897897676878844 (Gast)


Lesenswert?

ja aber ich hab grad mal geschaut ...

wenn er nun per JSON oder über SSI/CGI
daten auf die HTML zaubert ...
diese dann in ein canvas zu legen ist dann recht einfach

zumal man die seite am PC bearbeiten/erstellen kann
wenn die Daten auf dem µC per JSON erzeugt  werden.
später konvertiert man die seite und ruft sie über den webserver auf.

zudem kann man die JSON daten pollen
oder per websocket eventbasiert aktualisieren.
der graph wird dann auch immer aktualisiert

der einzigste datentransfer ist dann ein HTTP GET auf die JSON daten
und diese kann man recht einfach mit einem snprintf()  ausgeben

auch websocket ist kein großes thema ...

von Karl Käfer (Gast)


Lesenswert?

Hallo Noch,

Noch einer schrieb:
> ... wenn die Libraries mit ihren 5000 Features nicht zu groß sind :-(

Der Webbrowser muß solche Libraries wie  flot oder jqPlot ja nicht 
unbedingt vom Arduino laden, die kann man auch ganz einfach extern 
referenzieren und hat dann zudem den Vorteil, immer die aktuellste 
Version zu benutzen.

HTH,
Karl

von Karl Käfer (Gast)


Lesenswert?

Hallo Kilian,

Kilian K. schrieb:
> Darüber hab ich auch nachgedacht. Nur da bin ich mir noch nicht wirklich
> sicher welche man da am besten nimmt...

Ich habe gute Erfahrungen mit jqPlot und flot gemacht, flot gefällt mir 
allerdings etwas besser -- ist aber Geschmackssache. An der 
Dokumentation könnten beide noch ein wenig arbeiten... ;-)

> Und desweiteren weiß ich noch
> nicht genau wie ich der Library die Daten übergebe, diese werden nämlich
> in keiner Datenbank abgespeichert. Es wird ne bestimmte Anzahl an Werten
> eingelesen und diese sollen dann direkt in einem Diagramm dargestellt
> werden.

Die Daten werden über Javascript als Array von Tupeln übergeben, in 
JSON-Notation etwa so:
1
[[1, 1], [2, 1], [3, 2], [4, 1]]

Bei den beiden obengenannten Libraries kannst Du die Daten auch einfach 
dynamisch per AJAX abrufen; ein Beispiel dafür kannst Du auf der 
Eingangsseite von flot sehen: http://www.flotcharts.org/

HTH,
Karl

von Kilian K. (kellermaaan)


Lesenswert?

Hallo Karl,

Karl Käfer schrieb:
> Die Daten werden über Javascript als Array von Tupeln übergeben, in
> JSON-Notation etwa so:[[1, 1], [2, 1], [3, 2], [4, 1]]
>
> Bei den beiden obengenannten Libraries kannst Du die Daten auch einfach
> dynamisch per AJAX abrufen; ein Beispiel dafür kannst Du auf der
> Eingangsseite von flot sehen: http://www.flotcharts.org/

also flot sieht schon mal ganz gut aus aber wie die Daten da rein 
bekomme habe ich immer noch nicht ganz verstanden. Könntest du das 
vielleicht noch einmal genauer erklären??? Momentan ist es so, wenn ich 
auf der Website auf einen Button klicke wird per CGI eine Funktion 
ausgeführt, die dann den analogen Eingang einließt. In der Funktion habe 
ich dann ein Array mit den Werten. Nur dann weiß ich nicht weiter...

von Karl Käfer (Gast)


Lesenswert?

Hallo Kilian,

Kilian K. schrieb:
> Karl Käfer schrieb:
>> Die Daten werden über Javascript als Array von Tupeln übergeben, in
>> JSON-Notation etwa so:[[1, 1], [2, 1], [3, 2], [4, 1]]
>>
>> Bei den beiden obengenannten Libraries kannst Du die Daten auch einfach
>> dynamisch per AJAX abrufen; ein Beispiel dafür kannst Du auf der
>> Eingangsseite von flot sehen: http://www.flotcharts.org/
>
> also flot sieht schon mal ganz gut aus aber wie die Daten da rein
> bekomme habe ich immer noch nicht ganz verstanden. Könntest du das
> vielleicht noch einmal genauer erklären??? Momentan ist es so, wenn ich
> auf der Website auf einen Button klicke wird per CGI eine Funktion
> ausgeführt, die dann den analogen Eingang einließt. In der Funktion habe
> ich dann ein Array mit den Werten. Nur dann weiß ich nicht weiter...

Grundsätzlich gibt es da zwei Möglichkeiten: entweder Du bettest die 
Daten "plain" direkt in die Webseite ein, also statisch beim Aufruf der 
Seite, oder Du verwendest AJAX und lädtst die Daten dynamisch im 
Hintergrund.

Bei der ersten Variante schreibst Du Deine Webseite ganz normal wie 
sonst auch und splittest Sie dann an der Stelle auf, wo die Daten hin 
sollen. Die Datei "oben.html" kann dann etwa so aussehen:
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2
<html>
3
<head>
4
<title>System Activity Reporter</title>
5
<script language="javascript" type="text/javascript" src="/static/jquery.js"></script>
6
<script language="javascript" type="text/javascript" src="/static/jquery.flot.js"></script>
7
<link rel="stylesheet" type="text/css" h_r_e_f="/static/main.css" />
8
</head>
9
<body>
10
<div id="diagram"></div>
11
<script type="text/javascript">
12
$(document).ready( function() {
13
    plotobject = $('#diagram').plot( 
14
        [
15
          {
16
            'data':

und die Datei "unten.html" so:
1
, 'label': "CPU"
2
          }
3
     ], {
4
       /* configuration goes here */
5
    });
6
});
7
</script>
8
</body>
9
</html>

Beim Aufruf der Seite führst Du dann etwa Folgendes aus (Pseudocode):
1
print file("oben.html").read()
2
print convert_to_JSON(data)
3
print file("unten.html").read()

Bei der zweiten Variante kannst Du die Daten zu einem Dir genehmen 
Zeitpunkt, etwa auf Knopfdruck oder regelmäßig aktualisiert, per AJAX 
(siehe hier: https://de.wikipedia.org/wiki/Ajax_%28Programmierung%29 und 
hier: http://api.jquery.com/category/ajax/) über JavaScript vom Server 
abholen, dem "plotobject" oben mit der Methode "plotobject.setData()" 
übergeben und hinterher jeweils einmal "plotobject.setupGrid()" sowie 
"plotobject.draw()" aufrufen.

Ach so: in meinem Beispiel ziehe ich die JS-Bibliotheken und die 
CSS-Datei jeweils vom lokalen Webserver, weil der Cluster, auf dem das 
läuft, nicht ins Internet darf. In einer so kleinen Umgebung, wie Du sie 
hier planst, würde ich die JS-Libs hingegen von einer externen Quelle 
einbinden und das CSS anstelle einer eigenen Datei direkt in "oben.html" 
einbinden.

HTH,
Karl

von Karl H. (kbuchegg)


Lesenswert?

Für Diagramme wäre ein SVG Bild noch eine Möglichkeit.

Das sollte auch ein kleiner Arduino noch stemmen können, so ein Diagramm 
auf Anforderung zu generieren.

von Karl Käfer (Gast)


Lesenswert?

Hallo Karl,

Karl H. schrieb:
> Für Diagramme wäre ein SVG Bild noch eine Möglichkeit.
>
> Das sollte auch ein kleiner Arduino noch stemmen können, so ein Diagramm
> auf Anforderung zu generieren.

Nichts anderes machen ja die genannten JavaScript-Bibliotheken: sie 
nutzen das Canvas-Element von HTML5 und zeichnen eine SVG-Grafik hinein.

Man kann das natürlich auch direkt ohne solche Bibliotheken machen, aber 
dann muß man die Achsen selbst berechnen. Das kann man mit einem Arduino 
sicher auch noch machen. Aber IMHO ist es hier einfacher, das vom 
Browser auf dem Client erledigen zu lassen. Der merkt meist gar nichts 
von seinem Glück, während die Serverseite dadurch spürbar entlastet 
wird.

Liebe Grüße,
Karl

von Karl H. (kbuchegg)


Lesenswert?

Karl Käfer schrieb:
> Hallo Karl,
>
> Karl H. schrieb:
>> Für Diagramme wäre ein SVG Bild noch eine Möglichkeit.
>>
>> Das sollte auch ein kleiner Arduino noch stemmen können, so ein Diagramm
>> auf Anforderung zu generieren.
>
> Nichts anderes machen ja die genannten JavaScript-Bibliotheken: sie
> nutzen das Canvas-Element von HTML5 und zeichnen eine SVG-Grafik hinein.

Ah, das wusste ich nicht. Mit JavaScript hab ich mich noch nicht so 
intensiv beschäftigt.

> Man kann das natürlich auch direkt ohne solche Bibliotheken machen, aber
> dann muß man die Achsen selbst berechnen.

Na ja.
Das sollte aber nicht das ganz grosse Problem sein. Der Wertebereich am 
analogen Eingang eines Arduino ist überschaubar :-)

> Browser auf dem Client erledigen zu lassen. Der merkt meist gar nichts
> von seinem Glück, während die Serverseite dadurch spürbar entlastet
> wird.

Wohl wahr.

von Karl Käfer (Gast)


Lesenswert?

Hallo Karl H.,

Karl H. schrieb:
>> Man kann das natürlich auch direkt ohne solche Bibliotheken machen, aber
>> dann muß man die Achsen selbst berechnen.
>
> Na ja.
> Das sollte aber nicht das ganz grosse Problem sein. Der Wertebereich am
> analogen Eingang eines Arduino ist überschaubar :-)

Das ist natürlich richtig. Aber bei Datums- und Zeitangaben sieht die 
Sache dann schon etwas anders aus. Wenn Du mit Sekunden seit UNIX-Epoch 
rechnest, brauchst Du heute schon 31 Bit. ;-)

Liebe Grüße,
Karl

von Kilian K. (kellermaaan)


Lesenswert?

Hallo nochmal,

ich greife das Thema jetzt nocheinmal auf, da ich erstmal was anderes 
erledigen musste...

Ich habe mir die Libraries nochmal angeguckt und möchte jetzt gerne die 
chart.js library nutzen. Aber bislang habe ich leider noch nicht sehr 
viel.
1
<script>
2
    var lineChartData = {
3
      labels : [""],
4
      datasets : [
5
        {
6
          label: "Messung",
7
          fillColor : "rgba(220,220,220,0.2)",
8
          strokeColor : "rgba(220,220,220,1)",
9
          pointColor : "rgba(220,220,220,1)",
10
          pointStrokeColor : "#fff",
11
          pointHighlightFill : "#fff",
12
          pointHighlightStroke : "rgba(220,220,220,1)",
13
          data :[]
14
        }
15
      ]
16
    }
17
18
       document.getElementById('ButtonDosierung').onclick = function(){
19
            var ctx = document.getElementById("diagrammMessung").getContext("2d");
20
            window.myLine = new Chart(ctx).Line(lineChartData, {
21
                responsive: true
22
            });
23
        }
24
        </script>

Die Frage ist jetzt, wie bekomme ich meine Daten vom MC dort hinein und 
wie passe ich dazu die Achsen den Ergebnissen an? Die Daten hole ich 
vermutlich am besten per CGI, da meine Seite viel damit arbeitet. 
Vielleicht könnte mir ja einer erklären, wie genau ich das anstellen 
soll?

Gruß Kilian

von chris_ (Gast)


Lesenswert?


von Kilian K. (kellermaaan)


Lesenswert?

chris_ schrieb:
> Vielleicht sollte man direkt eine SVG-Grafik erzeugen:
> 
https://batchloaf.wordpress.com/2011/11/23/simple-data-plotting-from-a-c-console-application-using-svg/

Wäre auch eine Möglichkeit, ich würde aber doch schon lieber mit der 
chart.js Library arbeiten...

von 234897897676878844 (Gast)


Lesenswert?

der µC stellt ebenso wie die HTML und das CSS  eine weitere Datei zur 
verfügung.
Da sind eben die Daten drin...
dan kann zB JSON sein .. oder XML ... oder HTML ... oder TXT ...


der Broswer holt die datei und in der callback ( wenn HTTP 200 )
verarbeitest du die daten und packst sie in dein chart

von 234897897676878844 (Gast)


Lesenswert?

die "datei" wird vom µC mit den daten gefüllt und dann übertragen.
oder wenn kein platz ist musst du die "datei" zur laufzeit erzeugen.

quasi einen stream von deinen daten

ich mache sowas mit JSON
dabei erzeuge ich die resultierende datei zur laufzeit
und fülle das eben nach und nach

von Kilian K. (kellermaaan)


Lesenswert?

234897897676878844 schrieb:
> ich mache sowas mit JSON
> dabei erzeuge ich die resultierende datei zur laufzeit
> und fülle das eben nach und nach

Wie machst du das denn genau? Hast du eine .json Datei irgendwo 
abgespeichert und greifst dann per ajax darauf zu oder wie?

von 234897897676878844 (Gast)


Lesenswert?

ich habe eine tabelle wo ich dateinamen ablege

zb config.json

wenn die datei abgerufen wird
werden die ersten 1460( tcp MMS beachten!! )
bytes erzeugt ( durch snprintf( ... ) )
diese werden dann versendet.

da er durch das http eh eine art filesystem hat weiß er ja wo er war
also beim nähsten durchlauf wird der rest(weiteren bytes gesendet bis 
alles gesendet wurde.
die .json  existiert also nur virtuell und der inhalt wird dynamisch 
erzeugt.

für das content-lenght:   im HTTP muss man die dateilänge vorher 
durchparsen und zusammenrechnen

von 234897897676878844 (Gast)


Lesenswert?

Kilian K. schrieb:
> Wie machst du das denn genau? Hast du eine .json Datei irgendwo
> abgespeichert und greifst dann per ajax darauf zu oder wie?

EDIT: vergessen :


im prinzip ja ...
der client macht einen ajax request
alternativ kannst das auch über websocket machen ...

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ich würde Diagramme heutzutage immer per SVG und nicht als Pixelgrafik 
erzeugen, beruht auf XML. Der Speicherbedarf ist nur ein Bruchteil einer 
Pixelgrafik.

Das meiste (Diagrammfläche, Gitter, Beschriftung usw.) kann man bequem 
aus dem ROM per F()-Funktion erstellen. Und davon hat sogar ein UNO 32K.

Die par Linien für einen Graphen "klatscht" man per Funktion live 
während des Abrufens der Webseite hinein ...

: Bearbeitet durch User
von Kilian K. (kellermaaan)


Lesenswert?

Wenn ich das richtig verstanden habe, schreibt man bei svg Diagrammen 
während der Laufzeit in eine Datei, die dan angezeigt wird.

chris_ schrieb:
> https://batchloaf.wordpress.com/2011/11/23/simple-...

Das hier hab ich mal ausprobiert aber funktioniert nicht. Es liegt 
daran, dass ich ohne eine SD-Karte nicht in die Datei schreiben kann...
Wie könnte ich das denn noch anders lösen???

von chris_ (Gast)


Lesenswert?

>Das hier hab ich mal ausprobiert aber funktioniert nicht.
Ich hab's mit MSVC kompiliert und ich konnte die Datei im IE ansehen. 
Beim compilieren gab es nur das Problem, dass er trotz Einbinden von 
"math.h" den cosinus nicht gefunden hatte. Nachdem ich die Verwendung 
von "vorkomplierten Headern " ausgesschaltet hatte, ging es.

>Wenn ich das richtig verstanden habe, schreibt man bei svg Diagrammen
>während der Laufzeit in eine Datei, die dan angezeigt wird.
Ja. Der Ram-Speicher des Arduino Due könnte für eine SVG-Datei reichen, 
da hier nur die Vektoren der Grafik gespeichert werden.

von Kilian K. (kellermaaan)


Lesenswert?

Also der lwIP-Stack kann SSI. Ist es nicht möglich, das Array mit den 
Werten mittels SSI in das Script einzufügen und daraus dann das Diagramm 
zu erstellen???

von Karl H. (kbuchegg)


Lesenswert?

Kilian K. schrieb:

> Das hier hab ich mal ausprobiert aber funktioniert nicht. Es liegt
> daran, dass ich ohne eine SD-Karte nicht in die Datei schreiben kann...

Wie löst dann DEIN konkreter Webserver das Problem, dass er irgendwo 
HTML Text herkriegen muss, den er zum Browser schickt.

Dort musst du ansetzen.
Der Browser teilt dem Web Server mit, welche 'Resource' (normalerweise 
eine Datei) er haben will. Dein Web Server teilt das wiederrum deinem 
Programm mit und dein Programm muss eben den Text liefern. Wo auch immer 
dein Programm den Text her hat. Das kann von einer Datei sein, das kann 
aber auch ein zur Laufzeit generierter Text sein. Der Browser kann nicht 
unterscheiden wo der herkommt. FÜr den Browser sieht die Sache so aus, 
dass er vom Server eine Resource anfordert und vom Server den 
entpsrechenden Text aus dieser Resource geliefert bekommt.

> Wie könnte ich das denn noch anders lösen???
Indem du endlich mal die Doku bzw. den Source Code deines Web-Servers 
studierst, wie der den auszuliefernden Text serviert haben will.

von Karl H. (kbuchegg)


Lesenswert?

Karl H. schrieb:

>> Wie könnte ich das denn noch anders lösen???
> Indem du endlich mal die Doku bzw. den Source Code deines Web-Servers
> studierst, wie der den auszuliefernden Text serviert haben will.


Wenn das einigermassen so funktioniert, wie der Arduino Standard WEb 
Server
https://www.arduino.cc/en/Tutorial/WebServer

dann ist genau hier
1
void loop() {
2
  // listen for incoming clients
3
  EthernetClient client = server.available();
4
  if (client) {
5
    Serial.println("new client");
6
    // an http request ends with a blank line
7
    boolean currentLineIsBlank = true;
8
    while (client.connected()) {
9
      if (client.available()) {
10
        char c = client.read();
11
        Serial.write(c);
12
        // if you've gotten to the end of the line (received a newline
13
        // character) and the line is blank, the http request has ended,
14
        // so you can send a reply
15
        if (c == '\n' && currentLineIsBlank) {

der Punkt, an dem der Browser Zeichen für Zeichen übermittelt hat, 
welche Resource er haben will. Die Zeichen in c in einem String sammeln 
und wenn die komplette Zeile übertragen wurde, analysieren, was der 
Browser will.

Und je nach dem, wird dann eben ein anderer Text zurückgeschickt.

Wie das bei deinem Server genau funktioniert, musst du eben ergründen. 
Aber irgendwo gibt es eine Stelle, an der im Server die vom Browser 
übermittelte Anfrage komplett ist und die wird dann eben darauf hin 
untersucht, welche Resource der Browser haben will. Je nachdem wird dann 
im Programm reagiert.

Aber um Programmieren kommst du nicht herum.
Wenn du etwas brauchst, für das es jede Menge Tutorien gibt und das du 
nur konfigurieren brauchst, dann leg dir einen Raspberry Pi zu und 
installier einen Apache aber lass die Finger von den Teilen bei denen 
man selbst verantwortlich ist.
Ja, man kann mit einem Arduino einen Web-Server hochziehen. Aber es 
gibt da eine klitzekleine Voraussetzung: Man muss dazu auch was können.

Ich hab mir sowas ähnliches schon gedacht, als ich vor 2 Tagen eine 
Antwort geschrieben habe, die ich dann wieder zurückgezogen habe. Die 
Antwort hat geendet mit
1
>> und wie passe ich dazu die Achsen den Ergebnissen an?
2
>
3
> Bist du sicher, dass du nicht überfordert bist?
4
> Ohne da selbst etwas zu programmieren wirst du da nicht weit kommen.
5
> Du bist hier auf einem ARDUINO!
6
> 
7
>> Die Daten hole ich vermutlich am besten per CGI
8
> Nein. Auf dem Arduino hast du kein CGI.
9
>
10
>> da meine Seite viel damit arbeitet. Vielleicht könnte mir ja
11
>> einer erklären, wie genau ich das anstellen soll?
12
> Sorry. Aber wenn du da weiter kommen willst, dann sind deine
13
> 'einfach ein bischen was konfigurieren' Tage vorbei. Hier sind
14
> Männer gefragt, die auch nicht davor zurückschrecken, selbst mal
15
> ein wenig C++ zu programmieren.

: Bearbeitet durch User
von chris_ (Gast)


Lesenswert?

Ich habe leider kein Ethernetshield um es auszuprobieren, aber
wenn ich es richtig sehe, muss man im Arduino Webserver Example

https://www.arduino.cc/en/Tutorial/WebServer

nur die Zeilen

     client.println("...");

mit den Zeilen für die SVG-Grafik aus

https://batchloaf.wordpress.com/2011/11/23/simple-data-plotting-from-a-c-console-application-using-svg/

ersetzen.

von chris_ (Gast)


Lesenswert?

Wenn man ein wenig im Internet nach C code für SVG Grafiken sucht 
scheint es einige Versuche zu geben:

http://stackoverflow.com/questions/29504954/creating-a-svg-bar-graph
http://www.ibm.com/developerworks/library/x-svggrph/

Wenn ich ein Ethernetshield hätte, würde ich glatt versuchen, das zu 
integrieren.

von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

Karl H. schrieb:
> Hier sind
>> Männer gefragt, die auch nicht davor zurückschrecken, selbst mal
>> ein wenig C++ zu programmieren.

och c++ muss doch nicht sein

bei mir macht das ein Pollin NETIO mit m1284p mit 16 kB Ram könnte er 
auch schon die Webseite im Ram bereitstellen.

Momentan läuft aber seit 2010 immer noch die U.Radig und Schnell SW bei 
mir, erweitert um eigene "Grafik" on the fly die Balken für Voltage und 
Temperatur

von chris_ (Gast)


Lesenswert?

Jetzt musst Du nur noch verraten, wie Du es gemacht hast.

von Joachim B. (jar)


Lesenswert?

chris_ schrieb:
> wie Du es gemacht hast.

gerne welchen Teil?

es ist ziemlich unübersichtlich und ich habe schon nei weile nix mehr 
gemacht daran, Balkengrafik

mal Ausschnitte vom Code:

web.h HTML  (Grund)Kenntnisse sollten vorhanden sein, Trockentest kann 
ja lokal gemacht werden.
1
/*----------------------------------------------------------------------------
2
 Copyright:      Radig Ulrich  mailto: mail@ulrichradig.de
3
 Author:         Radig Ulrich
4
 Remarks:        
5
 known Problems: none
6
 Version:        09.11.2007
7
 Modifiziert     Sept. 2008 Axel Schnell
8
 Description:    Html Seiten
9
 Dieses Programm ist freie Software. Sie können es unter den Bedingungen der 
10
 GNU General Public License, wie von der Free Software Foundation veröffentlicht, 
11
 weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder 
12
 (nach Ihrer Option) jeder späteren Version. 
13
 Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, 
14
 daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, 
15
 sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT 
16
 FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. 
17
 Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 
18
 Programm erhalten haben. 
19
 Falls nicht, schreiben Sie an die Free Software Foundation, 
20
 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
21
------------------------------------------------------------------------------*/
22
#ifndef _WEBPAGE_H
23
  #define _WEBPAGE_H
24
//****************************************************************************
25
//Dateien und Webseiten am ende dieser Seite in Tabelle eintragen !!!!!!!
26
//****************************************************************************
27
#include "config.h"
28
//----------------------------------------------------------------------------
29
// meine HP
30
PROGMEM char Page1[] = {
31
  "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"
32
  "<html><head>\r\n"
33
    "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\r\n"
34
#ifdef WEBREFRESH
35
    "<meta http-equiv=\"refresh\" content=\"%VA@14\">\r\n"
36
#endif
37
#ifdef HOME_POWER_LED_ROT
38
    "<title>home  AVR mini Webserver j a r</title>\r\n"
39
#else
40
    "<title>work  AVR mini Webserver j a r</title>\r\n"
41
#endif
42
    "<style type=\"text/css\">\r\n"
43
      "<!--\r\n"
44
      "BODY {  margin: 2 2 2 2; background-color: white; text-align:center;}\r\n"
45
      "P,DIV,H1 {font-family: verdana, arial; font-size:11px;}\r\n"
46
      "H1 {background-color: #CCCCFF; padding-top:5px; padding-bottom:5px;"
47
      "font-size:20px; color: #004060; font-weight:bold; letter-spacing:8px;"
48
      "border-top:2px solid #EEEEEE; border-left:2px solid #EEEEEE;"
49
      "border-bottom:2px solid #004060; border-right:2px solid #004060;}\r\n"
50
      "-->\r\n"
51
    "</style>\r\n"
52
  "</head>\r\n"
53
  "<body><div align=\"center\">\r\n"
54
#ifdef HOME_POWER_LED_ROT
55
    "<h1>home  AVR mini Webserver j a r</h1>\r\n"
56
#else
57
    "<h1>work  AVR mini Webserver j a r</h1>\r\n"
58
#endif
59
    
60
    "<p style=\"line-height:1.2em; font-size:1em\"></p>\r\n"
61
    "<form name=\"form1\" method=\"post\" action=\"index.htm\">\r\n"
62
63
64
//   "<p align=\"left\">&nbsp;    </p>\r\n"
65
      "<p align=\"left\"></p>\r\n"
66
67
68
// 3 SPALTEN mit Rahmen
69
    "<table  border=\"1\" cellpadding=\"2\" cellspacing=\"3\">\r\n"  
70
      "<colgroup>\r\n"
71
          "<col width=\"150\">\r\n"
72
        "<col width=\"120\">\r\n"
73
        "<col width=\"640\">\r\n"
74
//        "<col width=\"700\">\r\n"
75
      "</colgroup>\r\n"
76
"<tr>\r\n"
77
        "<td>\r\n"
78
         //Port Schalten und Status %PORTC0 bedeutet PORTC PIN0      //jar
79
          "<p align=\"left\">\r\n"
80
           "<input type=\"checkbox\" name=\"OUT\" value=\"A\" %PORTC0>\r\n"
81
           "MOC(PC0) WZ_Licht\r\n"
82
        "</p>\r\n"
83
  
84
            //Port Schalten und Status %PORTC1 bedeutet PORTC PIN1
85
          "<p align=\"left\">\r\n"
86
            "<input type=\"checkbox\" name=\"OUT\" value=\"B\" %PORTC1>\r\n"
87
            "  MOC(PC1)\r\n"
88
          "</p>\r\n"
89
90
        //Port Schalten und Status %PORTC6 bedeutet PORTC PIN6
91
        "<p align=\"left\">\r\n"
92
            "<input type=\"checkbox\" name=\"OUT\" value=\"G\" %PORTC6>\r\n"
93
            //"Port C Pin 6\r\n"
94
            " PCres (PC6)\r\n"  //jar
95
          "</p>\r\n"  //jar
96
  
97
              //Port Schalten und Status %PORTC7 bedeutet PORTC PIN7
98
            "<p align=\"left\">\r\n"
99
              "<input type=\"checkbox\" name=\"OUT\" value=\"H\" %PORTC7>\r\n"
100
              //"Port C Pin 7\r\n"
101
              " PCpow(PC7)\r\n"  //jar
102
            "</p>\r\n"  //jar
103
104
105
        "<p align=\"center\"><input type=\"submit\" name=\"SUB\" value=\"Senden\"></p>\r\n"
106
//        "<input type=\"submit\" name=\"SUB\" value=\"Senden\"> \r\n"
107
        "</td>\r\n"  
108
109
110
        "<td>\r\n"
111
        "<p align=\"left\"><img src=\"%PINA1\" alt=\"\" width=\"17\" height=\"17\"> PCres (PA1)</p>\r\n"
112
        "<p align=\"left\"><img src=\"%PINA0\" alt=\"\" width=\"17\" height=\"17\"> PCpow (PA0)</p>\r\n"
113
        "<p align=\"center\"> Zählerscheibe 100mm Mittelloch 3mm</p>\r\n"
114
//        "<p align=\"center\">  %VA@70      </p>\r\n"
115
      "</td>\r\n"  
116
            
117
      "<td>\r\n"  
118
        //Balkendiagramm
119
        "<table width=\"638\" border=\"0\">\r\n"
120
          "<colgroup>\r\n"
121
             "<col width=\"139\">\r\n"
122
            "<col width=\"60\">\r\n"
123
            //"<col width=\"120\">\r\n"
124
            "<col width=\"439\">\r\n"
125
              "</colgroup>\r\n"
126
"<tr>\r\n"
127
128
//            "<tr>\r\n"
129
              "<th scope=\"col\"><p align=\"center\">UB</p></th>\r\n"
130
            "<th scope=\"col\"><p align=\"center\">Spannung</p></th>\r\n"
131
            "<th scope=\"col\"><p align=\"center\"></p></th>\r\n"
132
//            "</tr>\r\n"
133
134
            "<tr>\r\n"
135
            "<td>\r\n"
136
             " +12  V(ADC4/PA7)<br><br> \r\n"
137
            "  +5  V(ADC3/PA6)<br><br> \r\n"
138
             "  +3,3V(ADC2/PA5)</td> \r\n"
139
            
140
            "<td>\r\n"
141
            "%VA@07<br><br> \r\n"
142
            "%VA@06<br><br> \r\n"
143
            "%VA@05</td> \r\n"
144
145
            "<td><p align=\"left\">\r\n"
146
            "<img src=rt.gif alt=\"\" width=\"%VA@37\" height=\"10\"><img src=gr.gif alt=\"\" width=\"%VA@38\" height=\"10\"><img src=rt.gif alt=\"\" width=\"%VA@39\" height=\"10\"><br><br> \r\n"
147
            "<img src=rt.gif alt=\"\" width=\"%VA@47\" height=\"10\"><img src=gr.gif alt=\"\" width=\"%VA@48\" height=\"10\"><img src=rt.gif alt=\"\" width=\"%VA@49\" height=\"10\"><br><br> \r\n"
148
            "<img src=rt.gif alt=\"\" width=\"%VA@57\" height=\"10\"><img src=gr.gif alt=\"\" width=\"%VA@58\" height=\"10\"><img src=rt.gif alt=\"\" width=\"%VA@59\" height=\"10\"></td> \r\n"
149
          "</tr>\r\n"
150
          "<tr>\r\n"
151
              "<th scope=\"col\"><p align=\"center\">wo</p></th>\r\n"   // Temperatur
152
              "<th scope=\"col\"><p align=\"center\">Temperatur </p></th>\r\n"   // Wert
153
              "<th scope=\"col\"></th>\r\n"  // Balken
154
          "</tr>\r\n"

das sind die Variablen
%VA@59 die zur Laufzeit in Länge ersetzt werden


httpd.c
1
//----------------------------------------------------------------------------
2
3
4
//Daten Packete an Client schicken
5
6
7
void httpd_data_send (unsigned char index)
8
9
10
{  
11
12
13
  unsigned int a;
14
15
16
  char s_tmp[64];
17
18
19
  unsigned char str_len;
20
21
22
  unsigned char i=0;
23
24
25
26
#ifdef WEBREFRESH
27
  static unsigned long last_ip=0;    //jar
28
29
30
  static unsigned long last_time=0;  //jar
31
32
33
#endif
34
35
  char var_conversion_buffer[CONVERSION_BUFFER_LEN];
36
37
38
//  char tmp_buffer[TMP_BUFFER_LEN];
39
40
41
  //Passwort wurde im Header nicht gefunden
42
43
44
  if(!http_entry[index].http_auth)
45
46
47
  {
48
49
50
    http_entry[index].new_page_pointer = Page0;
51
52
53
#ifdef WEBREFRESH
54
    if(!( (last_time)<time && time<(last_time+(WEBREFRESH/4)) && last_ip==ext_dest_ip))
55
56
57
    {
58
59
60
      usart_write("%2i:%2i:%2i Anfrage von %i.%i.%i.%i abgelehnt\r\n",(unsigned char)((time/3600)%24),(unsigned char)((time/60)%60),(unsigned char)(time%60), (char)(ext_dest_ip),(char)(ext_dest_ip>>8),(char)(ext_dest_ip>>16),(char)(ext_dest_ip>>24));//jar
61
62
63
      last_time=time;
64
65
66
      last_ip=ext_dest_ip;
67
68
69
    }
70
71
72
    else
73
74
75
      last_time=time;
76
77
78
#endif
79
  }
80
81
82
  //kein Packet empfangen Retransmission des alten Packetes
83
84
85
  if(tcp_entry[index].status == 0) 
86
87
88
    http_entry[index].new_page_pointer = http_entry[index].old_page_pointer;
89
90
91
  http_entry[index].old_page_pointer = http_entry[index].new_page_pointer;
92
93
94
  for (a = 0;a<(MTU_SIZE-(TCP_DATA_START)-150);a++)
95
96
97
  {  unsigned char b;
98
99
100
    b = pgm_read_byte(http_entry[index].new_page_pointer++);
101
102
103
    eth_buffer[TCP_DATA_START + a] = b;
104
105
106
    //Müssen Variablen ins Packet eingesetzt werden? ===> %VA@00 bis %VA@09
107
108
109
    if (b == '%')
110
111
112
    {  if (strncasecmp_P("VA@",http_entry[index].new_page_pointer,3)==0)
113
114
115
      {  b = (pgm_read_byte(http_entry[index].new_page_pointer+3)-48)*10;
116
117
118
        b +=(pgm_read_byte(http_entry[index].new_page_pointer+4)-48);  
119
120
121
        switch(b)
122
123
124
        {
125
126
127
          case 9:
128
129
130
            strcpy(var_conversion_buffer, itoa(var_array[MAX_VAR_ARRAY-1], s_tmp, 10));
131
            break;
132
133
134
135
          case 7:
136
137
138
            strcpy(var_conversion_buffer, (char *)&u12_str[0]);
139
140
141
            break;
142
143
144
/*          case 40:
145
146
147
            strcpy(var_conversion_buffer, (char *)&u12_percent[0]);
148
149
150
            break;
151
152
153
*/          case 6:
154
155
156
            strcpy(var_conversion_buffer, (char *)&u5_str[0]);
157
158
159
            //strcat(var_conversion_buffer, bold_95prozent(trimm_string(' ', utoa( u5_last/5,s_tmp,10),3)));
160
161
162
            //strcat(var_conversion_buffer, "%");
163
164
165
            break;
166
167
168
/*          case 50:
169
170
171
            strcpy(var_conversion_buffer, (char *)&u5_percent[0]);
172
173
174
            break;
175
176
177
*/          case 5:
178
179
180
            strcpy(var_conversion_buffer, (char *)&u33_str[0]);
181
182
183
            //strcat(var_conversion_buffer, bold_95prozent(trimm_string(' ', utoa( u33_last/3.3,s_tmp,10),3)));
184
185
186
            break;
187
188
189
/*          case 60:
190
191
192
            strcpy(var_conversion_buffer, (char *)&u33_percent[0]);
193
194
195
            break;
196
197
198
*/          case 10:            // jar temp umrechnung gefunden
199
200
201
            strcpy(var_conversion_buffer, time_str);
202
203
            break;
204
205
206
          case 11:            // jar temp umrechnung gefunden
207
208
209
            strcpy(var_conversion_buffer, last_ntp_time);
210
211
212
            break;
213
214
215
          case 12:            // jar temp umrechnung gefunden
216
217
218
            strcpy(var_conversion_buffer, last_ntp_date);
219
220
221
            break;
222
223
224
          case 13:            // jar temp umrechnung gefunden
225
226
227
            (mesz) ? strcpy(var_conversion_buffer, "MESZ") : strcpy(var_conversion_buffer, " MEZ");
228
229
230
            break;
231
232
233
#ifdef WEBREFRESH
234
          case 14:            // jar temp umrechnung gefunden
235
236
237
            strcpy(var_conversion_buffer, itoa(WEBREFRESH,s_tmp,10));
238
239
240
            break;
241
242
243
#endif
244
          case 16:            // jar temp umrechnung gefunden
245
246
247
            strcpy(var_conversion_buffer, date_str);
248
249
            break;
250
251
252
          case 17:            // jar temp umrechnung gefunden
253
254
255
            strcpy(var_conversion_buffer, mesz_str);
256
257
            break;
258
259
260
261
          case 37:            // jar U12-Balken 10%
262
263
264
            strcpy(var_conversion_buffer, u12_vorrotbalken );
265
266
267
            break;
268
269
270
          case 38:            // jar U12-Balken 10%
271
272
273
            strcpy(var_conversion_buffer, u12_gruenbalken );
274
275
276
            break;
277
278
279
          case 39:            // jar U12-Balken 10%
280
281
282
            strcpy(var_conversion_buffer, u12_nachrotbalken );
283
            break;
284
285
286
287
288
          case 47:            // jar U5-Balken 5%
289
290
291
            strcpy(var_conversion_buffer, u5_vorrotbalken );
292
            break;
293
294
295
          case 48:            // jar U5-Balken 5%
296
297
298
            strcpy(var_conversion_buffer, u5_gruenbalken );
299
            break;
300
301
302
          case 49:            // jar U5-Balken 5%
303
304
305
            strcpy(var_conversion_buffer, u5_nachrotbalken );
306
            break;
307
308
309
310
311
          case 57:            // jar U33-Balken 5%
312
313
314
            strcpy(var_conversion_buffer, u33_vorrotbalken );
315
            break;
316
317
318
          case 58:            // jar U33-Balken 5%
319
320
321
            strcpy(var_conversion_buffer, u33_gruenbalken );
322
            break;
323
324
325
          case 59:            // jar U33-Balken 5%
326
327
328
            strcpy(var_conversion_buffer, u33_nachrotbalken );
329
            break;


usw. wer den ganze Code will kann sichja melden muss nur dann die PW 
rausnehmen und brauche etwas Zeit muss die ja "wiederfinden"

so leicht steigt man aber als Anfänger nicht durch, das hat bei mir auch 
ne Weile gedauert und ist gewachsen.

zum Einlesen:
http://www.ulrichradig.de/home/index.php/software/avr-webserver-software

: Bearbeitet durch User
von Karl Käfer (Gast)


Lesenswert?

Hallo chris_,

chris_ schrieb:
> Wenn man ein wenig im Internet nach C code für SVG Grafiken sucht

Warum sollte man das tun? Wir haben in diesem Thread bereits mehrmals 
festgestellt, daß es für so etwas schon fertige Libraries gibt.

Liebe Grüße,
Karl

von Karl Käfer (Gast)


Lesenswert?

Hallo Joachim,

Joachim B. schrieb:
> Karl H. schrieb:
>> Hier sind
>>> Männer gefragt, die auch nicht davor zurückschrecken, selbst mal
>>> ein wenig C++ zu programmieren.
>
> och c++ muss doch nicht sein

Doch, muß es. Arduinos werden in C++ programmiert.

> bei mir macht das

Egal. Wer den Thread überflogen hat, weiß, daß der OP einen Arduino hat. 
Steht sogar in der Überschrift.

Liebe Grüße,
Karl

von Jobst M. (jobstens-de)


Lesenswert?

Du könntest ein Pixel breite Grafiken fertig auf dem Server ablegen. Der 
Browser kann die auf Anweisung skalieren.

Du kannst beim Abruf eine Tabelle (ohne borders etc.) bauen, bei der Du 
jedem 1x1 Pixel großen Tabellenfeld eine andere Hintergrundfarbe nimmst. 
Nötigenfalls ein transparentes 1x1 gif dort hinein packen. Oder ein 
farbiges 1x1 gif, ohne Tabellenfeldhintergrundfarbe.


Gruß

Jobst

von Joachim B. (jar)


Lesenswert?

Karl Käfer schrieb:
> Doch, muß es. Arduinos werden in C++ programmiert.

echt wusste ich nicht, so ein Glück das meine Arduinos hier nichts 
lesen.

Karl Käfer schrieb:
> Egal. Wer den Thread überflogen hat, weiß, daß der OP einen Arduino hat.
> Steht sogar in der Überschrift.

und ist das ein Problem?

versteht ein Arduino m2560 nun keinen C-Code mehr?

: Bearbeitet durch User
von Karl Käfer (Gast)


Lesenswert?

Hallo Joachim,

Joachim B. schrieb:
> Karl Käfer schrieb:
>> Doch, muß es. Arduinos werden in C++ programmiert.
>
> echt wusste ich nicht, so ein Glück das meine Arduinos hier nichts
> lesen.

Was für ein Glück, daß Du nichts Besseres zu tun hast, als hier noch 
so eine selbstverliebte Sprachdiskussion anzufangen.

> Karl Käfer schrieb:
>> Egal. Wer den Thread überflogen hat, weiß, daß der OP einen Arduino hat.
>> Steht sogar in der Überschrift.
>
> und ist das ein Problem?
>
> versteht ein Arduino m2560 nun keinen C-Code mehr?

Nein. Genau genommen versteht er nicht einmal C++-Code. Es sei denn, Du 
schaffst es, einen C- oder C++-Interpreter darauf unterzubringen, was im 
Hinblick auf die zur Verfügung stehenden Ressourcen der Plattform ein 
sehr ambitioniertes Unterfangen sein dürfte. Ansonsten versteht der 
Arduino nur Maschinencode, weißt Du.

Liebe Grüße,
Karl

von Joachim B. (jar)


Lesenswert?

Karl Käfer schrieb:
> Arduinos werden in C++ programmiert.

Karl Käfer schrieb:
> Genau genommen versteht er nicht einmal C++-Code

Karl Käfer schrieb:
> eine selbstverliebte Sprachdiskussion anzufangen.

ohne Worte :-)

von hjoouguoguogouuo (Gast)


Lesenswert?

fur eimfache balkengrafik kann man rein css verwenden

es gibtvdann ein div mi einem überlagertem div
man stellt dann die width oder height ein die dem wert entsprechen soll


ist dann am ende nur html+css und evtl etas javascript

von Karl Käfer (Gast)


Lesenswert?

Hallo Joachim,

Joachim B. schrieb:
> ohne Worte :-)

Si tacuisses, philosophus mansisses. Genau das war ja der Punkt. :-)

Liebe Grüße,
Karl

von Joachim B. (jar)


Lesenswert?

Karl Käfer schrieb:
> Si tacuisses, philosophus mansisses. Genau das war ja der Punkt. :-)
>
> Liebe Grüße,
> Karl

wie oft musstest du dir das anhören?
"hättest du geschwiegen hätte ich dich für einen Weisen gehalten"

hast du das nie verstanden?

von Jobst M. (jobstens-de)


Angehängte Dateien:

Lesenswert?

So, ich habe da mal etwas vorbereitet. Reinstes html ...
Edit: Alle fünf Dateien herunter laden und ausprobieren ...


Gruß

Jobst

: Bearbeitet durch User
von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Mittlerweile bin ich auch Besitzer eines Ethernet-Shield geworden. 
Allerdings finde ich nicht richtig heraus, um welche Version es sich 
handelt. Hinten drauf steht

Board Model Ethernet R3

und es ist keine Aufsteckmodul für einen Arduino, sondern wohl 
stand-alone. Man sieht einen Atmega in der rechten oberen Ecke auf dem 
Board integriert. Es hat keinen USB-Stecker, sondern nur einen RJ45 
Anschluss für das Netzwerk. Weiß jemand, über welche Schnittstelle man 
das Ding programmiert oder wo es einen Schaltplan dafür gibt?

von Markus (Gast)


Lesenswert?

Nach einiger Suche und genauerem hinschauen bin ich jetzt doch fündig 
geworden: Das Ding ist kein Shield, sondern ein Arduino Ethernet. Was 
leider daraus folgt, dass man noch einen extra FDTI-Adapter braucht, um 
es zu programmieren.
Mist ... ich habe keinen.

von chris_ (Gast)


Lesenswert?

So, da ich die Sache ziemlich interessant finde, habe ich mir ein 
Ethernet Shield besorgt und ein wenig programmiert.
Es hat doch eine wenig Zeit gekostet, eine SVG-Grafik damit zu erzeugen, 
weil das Beispiel weiter oben mit Float-Werten gemacht war und ein 
Arduino Uno etwas schwachbrüstig dafür ist.

Hier das sehr einfache Beipiel:

https://github.com/ChrisMicro/ArduinoWebServerPlot/blob/master/simpleAnalogChannelSVGplot/simpleAnalogChannelSVGplot.ino

Ich hab's ein wenig mit Try- and Error gemacht, da ich kein HTML oder 
SVG Experte bin. Vielleicht habt ihr noch eine Anmerkung dazu, was zu 
viel ist.

von chris_ (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch das etwas "einfache" Ergebnis

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:
> Karl Käfer schrieb:
>> Doch, muß es. Arduinos werden in C++ programmiert.
>
> echt wusste ich nicht, so ein Glück das meine Arduinos hier nichts
> lesen.

Deinen Arduinos ist das ziemlich egal.
Aber wenn du in der Arduino IDE programmierst, wird der C++ Compiler 
drüber gejagt.
Wenn du in deinem C++ Programm nur Dinge verwendest, die es auch in C 
gibt, dann sieht das ganze dann eben auch wie ein C Programm aus. Selbst 
wenn es C++ ist.

Aber du kannst ja gerne mal ein paar Dinge probieren, die in C legal 
aber in C++ illegal sind. Dann siehst du ganz schnell, ob du C oder doch 
C++ programmierst, wenn der C++ Compiler drüber gejagt wird.

@chris

> Hier noch das etwas "einfache" Ergebnis

Na siehst du. Ist doch schon mal ein Anfang

von chris_ (Gast)


Lesenswert?

>Na siehst du. Ist doch schon mal ein Anfang

Ich erwarte natürlich ein Lob für meine Selbstlosigkeit, das Ganze für 
die Allgemeinheit gemacht zu haben ;-)

von Joachim B. (jar)


Lesenswert?

Karl H. schrieb:
> Deinen Arduinos ist das ziemlich egal.
> Aber wenn du in der Arduino IDE programmierst, wird der C++ Compiler
> drüber gejagt.
> Wenn du in deinem C++ Programm nur Dinge verwendest, die es auch in C
> gibt, dann sieht das ganze dann eben auch wie ein C Programm aus. Selbst
> wenn es C++ ist.

so siehts für mich halt aus wie C

Karl H. schrieb:
> Aber du kannst ja gerne mal ein paar Dinge probieren, die in C legal
> aber in C++ illegal sind. Dann siehst du ganz schnell, ob du C oder doch
> C++ programmierst, wenn der C++ Compiler drüber gejagt wird.

und ich wundere mich gelegentlich über "merkwürdige" Fehler die ich aus 
dem AVR Studio 4.18 SR3 nicht kenne.

Ich hatte ja in Studio begonnen eigene "Module" zu machen die ich von 
Projekt zu Projekt weiterverwende, manche wollen in der Arduino IDE so 
nicht funktionieren und ich wusste nie wo es klemmt.

Der C Code muss meiner Meinung nach OK sein nur in die Arduino IDE 
einbinden ist "merkwürdig" irgendwie schaffe ich es, aber warum manches 
so und manches anders läuft war mir nie klar.

Karl H. schrieb:
> Aber wenn du in der Arduino IDE programmierst, wird der C++ Compiler
> drüber gejagt.

das erklärt einiges, ich dachte immer gcc kann beides und macht es immer 
gleich, auch im Studio läuft ja gcc

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:

> das erklärt einiges, ich dachte immer gcc kann beides und macht es immer
> gleich, auch im Studio läuft ja gcc

der gcc kann beides.
Aber C ist keine echte Untermenge von C++ mehr. Da gibt es mittlerweile 
einige Dinge, die sich unterscheiden. Zb kann man in C jeden beliebigen 
Pointertyp an einen void Pointer zuweisen - in C++ geht das nicht. Ein 
undeclared identifier ist in C eine Warnung (die nicht gefordert wird), 
in C++ ist es ein Fehler. Die 'implicit int' Regel aus C ist in C++ 
gefallen, die meisten C99 Erweiterungen haben es nicht nach C++ 
geschafft, eine const Deklaration ist nur in C++ eine compile time 
Konstante, ...
Wenn der gcc C++ Code compiliert läuft er im C++ Modus. Compiliert er C, 
dann läuft er im C Modus. Selbst wenn wir uns nur auf den 
Funktionalitätsumfang von C beschränken, ist der aber nicht identisch 
zum funktionalitätsgleichen C++ Teil.

von chris_ (Gast)


Lesenswert?

Joachim schrieb
>Der C Code muss meiner Meinung nach OK sein nur in die Arduino IDE

Du könntest den Code hier als ZIP posten.

von Joachim B. (jar)


Lesenswert?

chris_ schrieb:
> Du könntest den Code hier als ZIP posten.

ich habe ja die Compiler oder Linkerfehlermeldungen irgendwie umgangen 
und bin froh das es läuft, um das zu provozieren fehlt mir die Zeit.

Wenn ich die Zeit hätte (und den passenden Kopf) würde ich lieber C++ 
lernen.
So bleibe ich bei meinem "Schmalspur" C, bin halt kein Progger.

Ich denke mal im wesentlichen liegt es daran das ich in der Arduino IDE 
zwar die *.C files im Projekt sehe, sie aber nicht eingebunden werden 
vom Linker.

Include ich die C-Files in den INOs gibts halt Mecker wegen doppelter 
Include der H files.

Benenne ich die C Files in INO um klemmts an anderer Stelle.

Ach was weiss ich, komisch dabei mal geht es mal nicht.

Ein Problem macht auch die Verschieberei filezilla winscp über die 
Netzwerkplatten und Internet, ich weiss nicht woran es liegt, aus

CR LF CR LF wird LF LF CR oder so, dann habe ich tierische doppelte 
Leerzeilen, dann jage ich das immer über den HEXeditor ersetze LF LF zu 
LF bis alle doppelten LF weg sind und nur noch eine LF CR übrig ist

: Bearbeitet durch User
von chris_ (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe noch ein wenig weiter gebastelt weil es so Spaß macht.

Jetzt kann man mehrere Graphen erzeugen.
Die Plots haben

- Titel
- Achsenbeschriftungen
- Autoscale einstellbar

Auf einem Arduino Uno reicht es für 2 Graphen, da als Datenarray 16bit 
Ints verwendet werden.
Ein Arduino Due hätte natürlich wesentlich mehr Speicher.

von chris_ (Gast)


Lesenswert?


von chris_ (Gast)


Lesenswert?

Hat jemand eine Idee, wie man einen Mausklick in den Browser zum Arduino 
weiterleiten könnte?
Welche Mechanismen werden da normalerweise verwendet?

von Joachim B. (jar)


Lesenswert?

chris_ schrieb:
> Ein Arduino Due hätte natürlich wesentlich mehr Speicher.

ich mag den mighty 1284p Arduino clone mit 128kB flash und 16kB SRAM

4 habe ich selber gebaut, Platinen von OSH Park, einen bestellt

http://www.ebay.com/itm/Mighty-Mini-ATMega1284p-compatible-with-Arduino-/331463717483

: Bearbeitet durch User
von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

chris_ schrieb:
> Hat jemand eine Idee, wie man einen Mausklick in den Browser zum Arduino
> weiterleiten könnte?
> Welche Mechanismen werden da normalerweise verwendet?

ich weiss das es geht, zumindest zum AVR NETIP Studio 4.18, nach Arduino 
habe ich das nie gemacht, ich müsste mich wieder komplett durch den 
Source wühlen

ich schau mal......

hier gibt es viel Code dwer nur passend gemacht werden muss
http://www.ulrichradig.de/home/index.php/software/avr-webserver-software

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

chris_ schrieb:
> Hat jemand eine Idee, wie man einen Mausklick in den Browser zum Arduino
> weiterleiten könnte?
> Welche Mechanismen werden da normalerweise verwendet?

Das kommt drauf an, was du willst.
Wenn der Mausklick auf so etwas ähnliches wie einen Link oder eine 
Imagemap hinauslauft, dann läuft es darauf hinaus, dass dir der Browser 
selbst in seiner nächsten Anfrage mitteilt, was geklickt wurde indem er 
eine andere URL anfordert.
Ansonsten wird es wohl browserseitig auf irgendwas mit JavaScript 
hinauslaufen. Der im Browser laufende Java Script Code krallt sich den 
Mausklick und veranlasst dann den Browser zb eine neue Seite von einem 
Server anzufordern, wobei er in den Anforderungsdaten dann eben die 
Mausposition mit reinschreibt. Der Server wertet diese Anforderung aus, 
generiert die entsprechende neue Seite und übergibt sie zum Browser.
Und dann gibt es noch die Möglichkeit, dass der Browser das alles selbst 
handhabt, indem im Browser ein Java Script Code auf der Seite arbeitet, 
der zb einen Zoom in einem Diagramm handhabt.

Du musst dir immer vergegenwärtigen, dass du 2 'Systeme' am laufen hast
1
   Server                              Browser
2
  +-------------+                    +-------------------------------+
3
  |             |                    |                               |
4
  |            <----------------------- Anforderung: "GET index.htm" |
5
  |    Grummel  |                    |                               |
6
  |    Grummel  |                    |                               |
7
  | Antwort auf Anforderung:         |                               |
8
  |    HTML Code rausgeben           |                               |
9
  |          --------------------------> HTML Code empfangen         |
10
  |             |                    |                               |
11
  |             |                    |   HTML decodieren             |
12
  |             |                    |   anzeigen                    |
13
  |             |                    |                               |
14
  |             |                    |  Benutzer klickt auf einen    |
15
  |             |                    |  Link                         |
16
  |             |                    |                               |
17
  |            <----------------------- neue Anforderung: "GET data.htm"
18
  |    Grummel  |                    |                               |
19
  |    Grummel  |                    |                               |
20
  | Antwort auf die Anforderung      |                               |
21
  | nach "data.htm" schicken         |                               |
22
  |    HTML Code für "data.htm"      |                               |
23
  |         ---------------------------> HTML Code empfangen         |
24
  |             |                    |                               |
25
  |             |                    |   HTML decodieren             |
26
  |             |                    |   .....

so geht das immer dahin.
Der Server kann von sich aus gar nichts tun.
Es ist immer der Browser, der den aktiven Part spielt. Er fordert Daten 
an (in Form von URL mglw. noch mit Zusatzinformationen) und der Server 
hat entsprechend zu liefern.
Der Server kann natürlich entsprechende Dinge in den HTML Code einbauen, 
die den Browser dann veranlassen werden, bestimmte Dinge zu tun.
Aber aktiv ist in dem ganzen Spiel nur der Browser. Der Server ist nur 
Befehlsempfänger und hat zu gehorchen und natürlich zu liefern.

Dann kann es natürlich noch sein, dass im Browser sich Java Script Code 
dazwischen klemmt, der wiederrum dafür sorgt, das der Browser bestimmte 
Anforderungen an den Server absetzt.

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:

> hier gibt es viel Code dwer nur passend gemacht werden muss
> http://www.ulrichradig.de/home/index.php/software/avr-webserver-software

Dein Ehrgeiz in allen Ehren.
Aber das löst sein Problem nicht.

Ob er jetzt in den Radig Server die Bearbeitung von Browser Requests 
einbaut oder in den Arduino Code - er steht immer vor dem gleichen 
Problem: Die Requests müssen erkannt und ausgewertet werden, der Server 
muss eine entsprechende Antwort senden.
Ob der HTML Text dann über den Radig Server raus geht oder über die 
Arduino Klasse, ist Jacke wie Hose.
Die erste Hürde, die sich jetzt für ihn stellt:
Was muss in den ausgelieferten HTML Text eingebaut werden, damit der 
Browser auf Mausklicks entsprechend reagiert? Und welche Anfrage 
entsteht dadurch beim Server (falls überhaupt, sofern nicht sowieso 
alles im Browser per Java Script gehandhabt werden kann. Aber auch das 
Java Script des Browsers muss ja irgendwo herkommen).
Der Teil des Puzzles ist völlig unabhängig davon, ob da jetzt eine Radig 
Server arbeitet, ein Arduino oder ein ausgewachsener Apache.

: Bearbeitet durch User
von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

Karl H. schrieb:
> Dein Ehrgeiz in allen Ehren.
> Aber das löst sein Problem nicht.
>
> Ob er jetzt in den Radig Server die Bearbeitung von Browser Requests
> einbaut oder in den Arduino Code - er steht immer vor dem gleichen
> Problem: Die Requests müssen erkannt und ausgewertet werden, der Server
> muss eine entsprechende Antwort senden.
> Ob der HTML Text dann über den Radig Server raus geht oder über die
> Arduino Klasse, ist Jacke wie Hose.
> Die erste Hürde, die sich jetzt für ihn stellt:
> Was muss in den ausgelieferten HTML Text eingebaut werden, damit der
> Browser auf Mausklicks entsprechend reagiert? Und welche Anfrage
> entsteht dadurch beim Server (falls überhaupt, sofern nicht sowieso
> alles im Browser per Java Script gehandhabt werden kann. Aber auch das
> Java Script des Browsers muss ja irgendwo herkommen).
> Der Teil des Puzzles ist völlig unabhängig davon, ob da jetzt eine Radig
> Server arbeitet, ein Arduino oder ein ausgewachsener Apache.

DU bist der Programmierer, ich bin nur wenn überhaupt einäugig

aber das hier läuft auf einem NETIO mit atmega1284p

eben man daheim den PC eingeschaltet wie man am Licht sieht

der AVR bekommt den Befehl aus dem Webbrowser IE oder FF egal
der AVR schaltet einen Port der einen OptoTRIAC und dieser den 
Zwischenstecker Stecker Schukodose, für 2,45 der Original Schalter wurde 
per Knopflochchirurgie entfernt und der S202S02 sowie eine DC Buchse für 
die IR Diode eingebaut.

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:

> aber das hier läuft auf einem NETIO mit atmega1284p


Ja, schön.
Aber das sind Standard Elemente mit einer Form.
Stink normales HTML

Ich geh aber davon aus, dass er mit Mausklick zb meint, dass er in 
seinem Diagramm auch Zoomen kann, dass er die Kurve irgendwo anklicken 
kann und dann taucht da irgendwo die Uhrzeit auf.

Das geht. Unzählige Web-Seiten machen das vor. Aber eben nicht mit einer 
Standard-HTML Form.

Im übrigen ist es etwas kontraproduktiv, wenn du ständig auf den Radig 
Server verweist. Für den Arduino gibt es einen Web Server der genau das 
gleiche macht, wie der Radig Server. Genauso funktionsfähig wie der 
Radig Server.
Du Krux liegt im Zusammenstellen des HTML, das der Server verschicken 
soll. Die darunter liegenden Schichten funktionieren da wie dort. Die 
sind nicht das Problem. Tauscht er gegen den Radig Server aus dann
a) hat er erst mal das Problem, dass er erst mal an seine Ethernet 
Hardware anpassen muss
b) hat er trotzdem nichts gewonnen. Denn der C-Code, der das zu 
versendende HTML zusammenstellt ist nach wie vor zu schreiben. Und zwar 
von ihm! Und das geht mit dem Radig Server auch nicht einfacher als beim 
Arduino Server. Eher im Gegenteil.

Er muss endlich akzeptieren, dass er hier
1
...
2
      if (client.available()) {
3
        char c = client.read();
4
        Serial.write(c);
5
        // if you've gotten to the end of the line (received a newline
6
        // character) and the line is blank, the http request has ended,
7
        // so you can send a reply
8
        if (c == '\n' ..... )
ansetzen muss, die einzelnen Character zu einem String zusammensetzen 
muss und erst mal auswerten muss, welche Anforderung der Browser 
eigentlich geschickt hat und dann entsprechend reagieren.
Und dann natürllich muss er sich überlegen, was in der HTML Seite stehen 
soll, damit der Browser genau die Anforderung schickt, die der Arduino 
Code braucht um das gewünschte zu liefern.

Was anderes hast du ja auch nicht gemacht.
Den Serverunterbau zu wechseln hilft da überhaupt nicht weiter, denn das 
eigentliche Problem vor dem er steht bleibt dasselbe.

: Bearbeitet durch User
von Frank (Gast)


Lesenswert?

chris_ schrieb:
> Hat jemand eine Idee, wie man einen Mausklick in den Browser zum Arduino
> weiterleiten könnte?
> Welche Mechanismen werden da normalerweise verwendet?

Der Browser verbindet sich mit der im Link angegebenen Adresse und wenn 
das klappt, sendet er ein GET-Statement. Dies muss der Server (Arduino) 
"durchlesen" und entsprechend reagieren.

Das einfach Server-Beispiel in der Arduino-IDE liest das HTTP-Statement 
eiegntlich garnicht, auch keine GET-Parameter, es wartet einfach nur auf 
zwei aufeinanderfolgende CR-LF, was für gewöhnlich das Ende des 
HTTP-Headers signalisiert. Egal, was dann noch käme, sendet der Arduino 
daraufhin seinen simplen Beispiel-HTML-Code und trennt die 
TCP-Verbindung ("keep alive" wird z.B. auch ignoriert).

Etwas aufwändiger ist das Auswerten von GET-Parametern, wenn man z.B. 
etwas schalten will. Browserseitig passiert das durch übertragen aus 
einem Formular heraus ("submit"). Dann muss man einen etwas größeren 
Teil der "einströmenden" Daten lesen und nach typischen Inhalten suchen, 
z.B. "...?pin1=1&pin2=0..." usw. und nat. entsprechend reagieren 
(Arduino setzt Pins entsprechend).

Ganz ohne sich etwas mit HTTP und HTML zu beschäftigen, führt das aber 
nur zu Frust oder blindem nachäffen.

Ich bastele z.Zt. an einer responsive gestalteten Lösung zur Steuerung 
meiner Rolläden im WE-Haus. Dazu habe ich zunächst fremden Code zum 
Steuern von Relais aus dem Web genommen und ihn nach und nach optimiert 
(z.B. durch eigene Funktionen, statt immer wieder den gleichen Code zu 
schreiben, wie die Vorlage). Dabei habe ich zunehmend verstanden, was da 
eigentlich passiert - war sehr lehrreich!

Vorher lief der Code nur auf einem Mega, nun habe ich selbst auf dem Uno 
noch jeweils 50% des ROM und RAM frei. Mit der F()-Funktion schafft man 
die große Menge der lästigen HTML-Ausgaben in den Flash, z.B. mit:

client.print(F("content-type='text/html')); usw. ...

von Frank (Gast)


Lesenswert?

Korrektur:

client.println(F("content-type='text/html'")); usw. ...

von chris_ (Gast)


Angehängte Dateien:

Lesenswert?

>Ich geh aber davon aus, dass er mit Mausklick zb meint, dass er in
>seinem Diagramm auch Zoomen kann, ..

Ich will einfach den Arduino vom Browser aus beeiflussen können ( z.B. 
Led An/Aus ).

Btw: Ich habe mal einen etwas "rudimentären" Temperaturlogger mit einem 
DS18s20 gemacht:

https://github.com/ChrisMicro/ArduinoWebServerPlot/tree/master/DS18x20_TemperatureGraphServer

Limitations:

- nur ganzzahlige Temperaturen
- Sample rate noch nicht definiert
- fehlender Ringbuffer
  ( Graph wird immer wieder von vorne überschrieben )

Gab es hier bei den Codebeispielen nicht mal eine Library für einen 
Ringbuffer?

von Joachim B. (jar)


Lesenswert?

Karl H. schrieb:
> Im übrigen ist es etwas kontraproduktiv, wenn du ständig auf den Radig
> Server verweist.

sorry, es wurde gefragt ob Webserver auf Atmel läuft und das besser als 
auf meine PI. (und bei mir Radig/Schnell)

Karl H. schrieb:
> Für den Arduino gibt es einen Web Server der genau das
> gleiche macht, wie der Radig Server. Genauso funktionsfähig wie der
> Radig Server.

fein nur kann ich dazu nix sagen und ich werde ohne Not mich da nun 
nicht reinfummeln, das muss jeder für sich selber machen auch wenn hier 
gerne mal die Anfrage kommt, ich baue ein Lunarmobil kann mir jemand mal 
den Code schicken?

Karl H. schrieb:
> Denn der C-Code, der das zu
> versendende HTML zusammenstellt ist nach wie vor zu schreiben. Und zwar
> von ihm! Und das geht mit dem Radig Server auch nicht einfacher als beim
> Arduino Server. Eher im Gegenteil.

stimmt, ich musste mich auch durch fast jede einzelne Zeile Code kämpfen 
und dabei lernen und verstehen was wer macht. Mein Code ist noch nicht 
fertig, wird das jemals? aber es reicht mir so wie es ist.

Frank schrieb:
> Ganz ohne sich etwas mit HTTP und HTML zu beschäftigen, führt das aber
> nur zu Frust oder blindem nachäffen.

Ganz genau, auch wollen eigene Webseiten wo auch immer gepflegt werden 
und ohne Minimalkenntnisse ist das nicht zu leisten.

Bevor es in die AVR Brennerei geht kann man das Design ja schon mal 
lokal auf dem PC testen ohne magic Bytes wie %@VA oder %PORT das sind ja 
nur Platzhalter die bei Antwort ersetzt werden.

von Karl H. (kbuchegg)


Lesenswert?

chris_ schrieb:

> Ich will einfach den Arduino vom Browser aus beeiflussen können ( z.B.
> Led An/Aus ).

Ja dann mach das.
Dein Stichwort lautet: HTML Forms

> Gab es hier bei den Codebeispielen nicht mal eine Library für einen
> Ringbuffer?

erstens bin ich mir ziemlich sicher, dass es bei den Ardino Sachen einen 
Ringbuffer gibt.

Zweitens wirst du den ja wohl noch alleine hinkriegen. Die interessante 
Sache ist ja nicht der Ringbuffer an sich (der ist trivial: ein Array 
und ein Zähler), sondern in welchen Zeitabständen du einen Wert loggst

Und diese Technik, in bestimmten Zeitabständen etwas zu tun, ist immer 
dieselbe
1
unsigned long lastSampled;
2
3
void loop()
4
{
5
  unsigned long now = millis();
6
7
  if( now - lastSampled > 1000 ) {   // alle 1000 Millisekunden
8
9
    lastSampled = now;
10
11
    Graph1_data[sampleIndex] = analogRead(A0);
12
    Graph2_data[sampleIndex] = analogRead(A1);
13
14
    sampleIndex++;
15
    if( sampleIndex == GRAPH1_LENGTH )
16
      sampleIndex = 0;
17
  }
18
19
...

fettich.
Inklusive 'Ringbuffer'.

Komisch. Dein auf GIT gezeigter Code ist eigentlich recht gut gebaut. 
Das du da mit dieser Basistechnik solche Schwierigkeiten hast.

von chris_ (Gast)


Lesenswert?

>Komisch. Dein auf GIT gezeigter Code ist eigentlich recht gut gebaut.
>Das du da mit dieser Basistechnik solche Schwierigkeiten hast

Danke der Nachfrage.
Ich habe überhaupt keine Schwierigkeiten, irgend etwas selber zu 
basteln. Aber mittlerweile gehe ich dazu über, auch einmal andere 
Codezeilen anzuschauen. Da entdeckt man manchmal auch bessere Lösungen.

Dazu gibt es übrigens auch eine Empfehlung in Clean-Code:

http://www.amazon.de/Clean-Code-Refactoring-Patterns-Techniken/dp/3826655486

von Karl H. (kbuchegg)


Lesenswert?

Nichts desto trotz.
Einer deiner nächsten Punkte auf der TODO Liste ist und bleibt der Teil 
hier
1
 ...
2
      if (client.available()) {
3
        char c = client.read();
4
        Serial.write(c);
5
        // if you've gotten to the end of the line (received a newline
6
        // character) and the line is blank, the http request has ended,
7
        // so you can send a reply
8
        if (c == '\n' ..... )

Du kannst es drehen wie du willst, du wirst um das Sammeln der Zeichen 
in einem String und die Auswertung dessen, was der Browser will, nicht 
umhin kommen.

Dein HTML Code veranlasst den Browser eine Form hinzumalen, indem er ihm 
zb schickt
1
.....
2
3
  <form action="light_on.html">
4
    <input type="submit" value="Submit">
5
  </form>
6
7
....

darauf hin zeigt der Browser Anzeigeelement(e) an, und wenn vom Benutzer 
eines betätogt wird, dann schickt der Browser eine erneute "GET" Anfrage 
an den Server.
1
    GET light_on.html

und die Tatsache, dass der Browser die Web-Seie namens 'light_on.html' 
anfordert, ist für dein Server Programm das Signal, das Licht 
einzuschalten und eine neue HTML Seite zu senden, in der zb eine Form 
ausgegeben wird, in der eine Web-Site 'light_off.html' als Action bei 
der Form angegeben wird.

Daher: -> Du musst deine Finger an die Anforderung vom Browser kriegen. 
Und dazu musst du die Character zusammensetzen, die aus dem 
client.read() rauskommen. Es reicht nicht, wenn du die nur auf der 
Seriellen Konsole siehst (auch wenn das zu Debug-Zwecken recht hilfreich 
sein kann).

http://www.w3schools.com/html/html_forms.asp

von Karl Käfer (Gast)


Lesenswert?

Hallo Joachim,

Joachim B. schrieb:
> Karl H. schrieb:
>> Deinen Arduinos ist das ziemlich egal.
>> Aber wenn du in der Arduino IDE programmierst, wird der C++ Compiler
>> drüber gejagt.
>
> so siehts für mich halt aus wie C

Situs vilate in isse tabernit. ;-)

Liebe Grüße,
Karl

von Karl Käfer (Gast)


Lesenswert?

Hallo Nicknamensvetter,

Karl H. schrieb:
> Ich geh aber davon aus, dass er mit Mausklick zb meint, dass er in
> seinem Diagramm auch Zoomen kann, dass er die Kurve irgendwo anklicken
> kann und dann taucht da irgendwo die Uhrzeit auf.
>
> Das geht. Unzählige Web-Seiten machen das vor. Aber eben nicht mit einer
> Standard-HTML Form.

Deswegen hatte ich, bei aller Bescheidenheit, auf die oben genannten 
Bibliotheken "flot" und "jqPlot" hingewiesen. Die können das nämlich 
vorgefertigt aus der Tüte, man muß nur die Module einbinden.

Liebe Grüße,
Karl

von chris_ (Gast)


Lesenswert?

1
unsigned long lastSampled;
2
3
void loop()
4
{
5
  unsigned long now = millis();
6
7
  if( now - lastSampled > 1000 ) {   // alle 1000 Millisekunden
8
9
    lastSampled = now;
10
11
    Graph1_data[sampleIndex] = analogRead(A0);
12
    Graph2_data[sampleIndex] = analogRead(A1);
13
14
    sampleIndex++;
15
    if( sampleIndex == GRAPH1_LENGTH )
16
      sampleIndex = 0;
17
  }
18
19
...

>fettich.
>Inklusive 'Ringbuffer'.

Danke für die Antwort. Die konstante Abtastrate ist gut gelöst.
Aber das vorgeschlagene Bufferverfahren reicht für die Anwendung nicht 
ganz aus.

Es gibt nämlich verschiedene Zustände der Applikation.

- ganz am Anfang sind noch keine Messdaten da, der Graph ist leer
- nach und nach füllt sich der Buffer, die Datenlänge ändert sich und 
der Graph muss "nachskalieren"
- Wenn der Buffer voll ist, muss er in den "Ring-Modus" übergehen, damit 
es einen "Rolling" Rolling Graph ( wie den entsprechenden Oszi 
Einstellungen) gibt.

Deshalb brauche ich
- eine Speicherung des aktuellen Füllstandes des Buffers
- eine Funktion zum lesen des Indices "n" für den Graph

Ich muss also folgende Funktionen implementieren

- rngBuf_init( *dataArray, size )
- rngBbuf_add                      //fügt einen Wert hinzu
- rngBuf_get(n)                    //liest einen Wert an der Stelle n
- rngBuf_getSize

Auf stackoverflow gibt es eine Sammlung von Ringbuffern:
http://stackoverflow.com/questions/827691/how-do-you-implement-a-circular-buffer-in-c

von Karl H. (kbuchegg)


Lesenswert?

chris_ schrieb:

> Deshalb brauche ich

Du bist der Programmierer.
Hau rein
Ich werde dir sicher nicht dein Projekt komplett durchziehen. Die Zeiten 
sind vorbei.

> Ich muss also folgende Funktionen implementieren
>
> - rngBuf_init( *dataArray, size )
> - rngBbuf_add                      //fügt einen Wert hinzu
> - rngBuf_get(n)                    //liest einen Wert an der Stelle n
> - rngBuf_getSize

Kann man machen.
Ein simpler Belegunszähler, der am Anfang mit 0 startet und dann solange 
erhöht wird, bis das erste mal GRAPH1_LENGTH erreicht wird, würde es 
aber auch tun.

Und komm mir nicht mit: Ich seh mir auch mal anderer Leute Code an. Das 
ist so dermassen trivial, dass jemand der programmieren kann, das 
schneller implementiert hat als die meisten Menschen Pap sagen können.

: Bearbeitet durch User
von chris_ (Gast)


Lesenswert?

>Und komm mir nicht mit: Ich seh mir auch mal anderer Leute Code an.

Oha, da scheint es Dir wohl zu warm zu werden. Cool down.
Programmierer sind eine schwierige Spezies zu sein, hier das passende 
Buch:

http://www.amazon.de/Katzen-h%C3%BCten-J-H-Rainwater/dp/3826613260

Wieder zurück zum Thema:
Der Server ist fertig. Die Daten werden alle 15 Minuten gelogt, deshalb 
muss ich jetzt lange warten, bis ich den Screenhot posten kann.

von chris_ (Gast)


Lesenswert?

Frank (Gast) schrieb
>Vorher lief der Code nur auf einem Mega, nun habe ich selbst auf dem Uno
>noch jeweils 50% des ROM und RAM frei. Mit der F()-Funktion schafft man
>die große Menge der lästigen HTML-Ausgaben in den Flash, z.B. mit:

>client.print(F("content-type='text/html')); usw. ...

Vielen Dank für diese Information.
Ich habe mich schon gewundert, wo das ganze RAM hin geht, obwohl ich nur 
150 Integer für meinen Datenbuffer benutze.

Für Serial.print funktioniert es auch:

  Serial.println(F("test"));

Ist die Option dem AVR-GCC geschuldet?
Ich habe gerade das Gleiche für einen Arduino-Due kompiliert. Es 
compiliert ohne Änderung.

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
Noch kein Account? Hier anmelden.