Pagina1 van 1

Arduino Ethernet – Data met PHP naar een server sturen (Push)

Arduino Ethernet – Data met PHP naar een server sturen (Push)
   29

In een voorgaand artikel beschreef ik hoe je m.b.v. “Data Pull” Arduino sensor data kon lezen via een computernetwerk, waarbij we gebruik maakten van een Arduino ENC28J60 Ethernet shield/module en een aantal sensoren (DS18B20 bijvoorbeeld). In dit artikel gaan we hete tegenovergestelde doen: Data Push.

Dit wil zeggen dat de Arduino data automatisch naar een computer of server sturen waar dan vervolgens de data opgeslagen wordt in een database. Voor dit doel gebruiken we een Apache, MySQL en PHP combinatie op onze computer (of server). Dit kan een volledige web-server zijn, maar kan ook een kleine en eenvoudige AMP zijn, zoals “WAMPServer”.

Een beetje ervaring met PHP en web-servers is wenselijk voor dit artikel, maar je hoeft geen expert te zijn.




Arduino en een ENC28J60 Ethernet Shield

In dit artikel gebruiken we een Arduino ENC28J60 Ethernet shield, zoals besproken in het “Hoe web-enable je een Arduino“, welke we zullen combineren met èèn of meer DS18B20 digitale temperatuur sensoren (je kunt natuurlijk ook andere sensoren gebruiken). Het doel: Data LEZEN van de Arduino over het netwerk.

  We gebruiken hier precies dezelfde opstelling als in het Data Pull artikel!

Hiervoor gebruiken we de “UIPEthernet” Library die je van Github kun downloaden of van Tweaking4All. Zoals gebruikelijk het advies om de Github versie te gebruiken aangezien deze meer recent kan zijn dan de versie op Tweaking4All.

Download - UIPEthernet 

Bestandsnaam:  arduino-uip.zip
Platform:  Undefined
Versie:  1.01
Omvang:  102 kB
Datum:  2014-03-23
 Download Nu  Stuur me Koffie    

 

Omdat we in ons voorbeeld de DS18B20 sensoren gaan gebruiken, hebben we ook de “OneWire” library nodig, welke te vinden is op de OneWire Project Website (aanbevolen) of natuurlijk van Tweaking4All.

Download - OneWire 

Bestandsnaam:  OneWire.zip
Platform:  Undefined
Versie:  2.2
Omvang:  15.1 kB
Datum:  2014-03-19
 Download Nu  Stuur me Koffie    

Gebruik maken van de standard Arduino Ethernet Shield

Omdat “UIPEthernet” volledig compatible met de standaard “Ethernet” library is die bij de Arduino IDE zit, zou je de voorbeelden op deze pagina ook voor de Standaard Arduino Ethernet Shield (W5100 gebaseerd) kunnen gebruiken. Om dit te doen, vervang de include regel (#include <UIPEthernet.h> ) met deze twee regels:


1
2
#include <SPI.h>
#include <Ethernet.h>
Aansluiten van het Ethernet Shield

Aansluiten van het Ethernet shield is eenvoudig, voor meer details zie ook het “Hoe web-enable je een Arduino” artikel.

Een Ethernet module gebruikt altijd GND (aarde) en +3.3V of +5V, omdat we stroom nodig hebben.

 Voor mijn eBay module moest ik +5V gebruiken (het heeft een voltage regulator aan boord).

Hieronder een tabel voor Arduino Uno, Arduino Nano en de module die ik op eBay had gekocht, met de pin aansluitingen die we nodig hebben.

ENC28J60 Pins
Pin naam UIPEthernet Mijn eBay Module
 SS  10  10
 MOSI (SI)  11  11
 MISO (SO)  12  12
 SCK  13  13
Mijn ENC28J60 test opstelling

Mijn ENC28J60 test opstelling

Aansluiten van de Temperatuur sensor

De temperatuur sensor is ook eenvoudig aan te sluiten, en we gebruiken pin 2 als de data pin voor onze sensor(en). In mijn opstelling heb ik er 2 gebruikt, maar dit werkt ongewijzigd ook voor slechts èèn of meerdere sensoren.

Lees het artikel “Hoe temperaturen meten met een Arduino en een DS18B20” voor meer details.

Arduino, ENC28J60 en 2x DS18B20 test opstelling

Arduino, ENC28J60 en 2x DS18B20 test opstelling

Alle aansluitingen gecombineerd

Afhankelijk van het Arduino board en ENC28J60 Ethernet shield model dat je gebruikt, zouden de aansluitingen er als volgt uit kunnen zien. Bedenk dat ik hierbij een “Deek Robot – Nano Ethernet Shield” (van eBay) en een Arduino Uno heb gebruikt. De meegeleverde Arduino Nano is hierbij niet gebruikt en voor de pinnen D10 … D13 op de ethernet shield kun je bovenstaande tabel volgen.

Arduino, ENC28J60 en DS18B20 diagram

Arduino, ENC28J60 en DS18B20 diagram

Hoe gaan we de Data ophalen?

In dit voorbeeld gebruiken we dus de temperatuur sensor van het DS18B20 artikel en willen we de temperatuur waarneming van de sensor(en) naar onze computer sturen via het computer netwerk. Als ik zeg “computer” denk dan ook aan b.v. een laptop, desktop, server, smartphone of tablet, zolang ze maar in hetzelfde netwerk zitten.

Data Pull of Push

We hebben bij het uitwisselen van data twee opties, en de beste optie hangt af van jouw toepassing:
– Pull: Een applicatie op onze computer (of server) bepaalt wanneer data van de Arduino opgehaald gaat worden.
– Push: De Arduino bepaalt wanneer data naar onze computer (of server) gestuurd wordt.

  In dit artikel kijken we naar DATA PUSH van de Arduino, naar onze computer.

We gaan hierbij een Apache, MySQL en PHP combinatie gebruiken.

Mocht je een geschikte NAS hebben, b.v. een QNAP, lees dan het “QNAP – Installeer MySQL en phpMyAdmin” artikel voor installatie van Apache, MySQL en PHP.
Als je het beschikbaar hebt, dan werkt een “echte” web-server natuurlijk ook …

Installatie van een AMP op jouw desktop of laptop PC is relatief eenvoudig (vooral voor MacOS X en Windows):

Data Push – of te wel: Data duwen …

Data Push is, in tegenstelling tot Data Pull (ophalen), wat lastiger …

Waar we bij on Data Pull voorbeeld genoeg hadden aan een standaard web-browser, hebben we nu ineens een meer gecompliceerde “ontvangende partij” nodig, wat een programma of server kan zijn welke klaar staat om data te ontvangen.

Deze data ontvangende moet continue een “luisteren” op een bepaald IP adres zodat het binnenkomende data om kan zetten en kan opslaan in b.v. een MySQL database (gratis database server die bij AMP bundels zoals WAMPServer zitten).

Omdat een volledige Library voor direct MySQL toegang een beetje te gek is voor een kleine Arduino, is dit geen echte optie. Mocht je interesse hebben, dan is er wel zo’n Arduino MySQL library welke direct toegang geeft tot MySQL over Ethernet. Deze Library is echt niet klein en je zult al heel snel tegen geheugen problemen aanlopen als je bedenkt dat je ook nog eens een Ethernet Library nodig hebt en eventueel een OneWire library voor de digitale sensoren.

In mijn geval had mijn arme Arduino Uno niet genoeg geheugen beschikbaar. Deze optie is echter zeer interssant en ziet er veel belovend uit, kijk maar eens naar dit voorbeeld in Chuck’s Blog.

Data Push via PHP

Zoals eerder hints al aangaven: we kunnen natuurlijk ook handig gebruik maken van HTML forms en PHP, en waarom ook niet?
Een AMP installatie komt met alle onderdelen die we nodig hebben.

  Een beetje ervaring met basic web-server, PHP, HTML en MySQL is zeer wenselijk voor de volgende stappen!

In HTML kunnen we een <FORM> tag gebruiken om een formulier te maken welke met POST of GET naar de server gestuurd kan worden.
Nu is de POST zeker veiliger te noemen, maar het kan zaken wat moeilijker maken. We kijken hier dus naar de eenvoudigere GET methode.

Als we een dynamische aanpak willen gebruiken, dan kan een statisch formulier wat problematisch worden. In het formulier staat namelijk al vast hoeveel variabelen je door gaat sturen. Maar omdat we niet met een echt formulier gaan werken, en omdat we met PHP een trucje kunnen toepassen, kunnen we onze eind code toch dynamisch houden.

Het basis formaat van een “submit” (versturen) van data ziet er voor een GET formulier als volgt uit:


http://yourphpserver/add_data.php?variable1=value1&variable2=value2&variable3=value3...

Data wordt verstuurd in setjes van variabele naam en variable waarde (variable1=value1), waarbij elke setje door een ampersand (&) gescheiden is. Een formaat welke we gaan misbruiken voor onze toepassing.

Om dit te laten werken moeten we natuurlijk op onze “server” een PHP bestand hebben die dit kan ontvangen en verwerken. In dit voorbeeld zou dit het bestand “add_data.php” zijn, welke de data ontvangt en vervolgens in een MySQL tabel plaatst. Laten we dus eerst met deze tabel beginnen.

In dit voorbeeld staat “add_data.php” in de “root” van de WWW directory van jouw webserver. Onder WAMPServer is dit de “www” directory.

MySQL Tabel:

Voor het voorbeeld houden we het e.e.a. eenvoudig, dus ik stel voor dat we de volgende data gaan gebruiken:

  • Uniek ID (int),
  • Event datum en tijd (timestamp) zodat we weten wanneer de temperatuur is gemeten,
  • Sensor serie nummer (varchar) zodat we weten van welke sensor de data kwam,
  • Temperatuur in Celsius (varchar) om het eenvoudig te houden.

 

Het SQL statement om deze “temperature” tabel te maken (je kunt dit uitvoeren in b.v. phpMyAdmin):


1
2
3
4
5
6
7
8
CREATE TABLE `test`.`temperature` (

`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'unique ID',
`event` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Event Date and Time',
`sensor` VARCHAR( 30 ) NOT NULL COMMENT 'Unique ID of the sensor',
`celsius` VARCHAR( 10 ) NOT NULL COMMENT 'Measured Temperature in Celsius',
INDEX ( `event` , `sensor` )
) ENGINE = InnoDB;

Als we een INSERT doen voor de tabel, dan hoeven we alleen maar het serie nummer van de sensor en de waargenomen temperatuur op te geven. De velden “ID” en “Event” worden namelijk automatisch ingevuld door MySQL.

Een INSERT voorbeeld:


INSERT INTO test.temperature (sensor ,celsius) VALUES ('288884820500006a', '21.65');

In dit voorbeeld gebruik ik de “test” database die standaard te vinden is in een vers geïnstalleerde MySQL. Je kunt natuurlijk ook een andere database aanmaken/gebruiken.
De naam van de tabel is natuurlijk ook aan te passen. Zolang je de gekozen database en tabel naam maar consequent gebruikt in jouw code.

Nu dat we een tabel hebben, kunnen we beginnen met de PHP bestanden.

Aan de PHP kant van het verhaal gebruiken we 3 bestanden. Een bestand om data te bekijken, een bestand om data op te slaan en een derde die de database connectie opzet (welke door de eerste 2 PHP bestanden gebruikt gaat worden).

PHP: MySQL Verbinding

Dit bestand heeft maar èèn doel: verbinding opzetten met de MySQL database voor gebruik met PHP. Deze “routine” gebruiken we voor zowel opslaan als ophalen van data van de database.
Sla dit bestand op als “dbconnect.php” in de www directory die je gaat gebruiken.


1
2
3
4
5
6
7
8
<?php
$MyUsername = "jouw gebruikersnaam";  // mysql gebruikersnaam
$MyPassword = "jouw wachtwoord";  // mysql wachtwoord
$MyHostname = "localhost";      // dit is meestal "localhost" tenzij mysql op een andere server staat

$dbh = mysql_pconnect($MyHostname , $MyUsername, $MyPassword);
$selected = mysql_select_db("test",$dbh);
?>

PHP: Tabel inhoud weergave

In dit bestand geven we, eenvoudig, de inhoud van de gehele tabel weer. Ik wilde dit eenvoudig houden, maar ik kon het niet nalaten wat CSS toe te voegen om een eenvoudige tabel er netjes uit te laten zien.

Sla dit bestand op als “review_data.php” in jouw www directory, en als je wilt kun je het al in een browser oproepen. Als je wat dummy data in de tabel wilt hebben, voer dan eerder getoonde INSERT statement een paar keer uit in b.v. phpMyAdmin.

Voorbeeld link : http://jouwserver/review_data.php
(vervange “jouweserver” door het IP adres of de naam van jouw “server”, of gebruik “localhost” als de AMP software op dezelfde computer draaid)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
    // Start MySQL Verbinding
    include('dbconnect.php');
?>

<html>
<head>
    <title>Arduino Temperature Log</title>
    <style type="text/css">
        .table_titles, .table_cells_odd, .table_cells_even {
                padding-right: 20px;
                padding-left: 20px;
                color: #000;
        }
        .table_titles {
            color: #FFF;
            background-color: #666;
        }
        .table_cells_odd {
            background-color: #CCC;
        }
        .table_cells_even {
            background-color: #FAFAFA;
        }
        table {
            border: 2px solid #333;
        }
        body { font-family: "Trebuchet MS", Arial; }
    </style>
</head>

    <body>
        <h1>Arduino Temperature Log</h1>
    <table border="0" cellspacing="0" cellpadding="4">
      <tr>
            <td class="table_titles">ID</td>
            <td class="table_titles">Date and Time</td>
            <td class="table_titles">Sensor Serial</td>
            <td class="table_titles">Temperature in Celsius</td>
          </tr>
<?php
    // Retrieve all records and display them
    $result = mysql_query("SELECT * FROM temperature ORDER BY id ASC");

    // Used for row color toggle
    $oddrow = true;

    // process every record
    while( $row = mysql_fetch_array($result) )
    {
        if ($oddrow)
        {
            $css_class=' class="table_cells_odd"';
        }
        else
        {
            $css_class=' class="table_cells_even"';
        }

        $oddrow = !$oddrow;

        echo '<tr>';
        echo '   <td'.$css_class.'>'.$row["id"].'</td>';
        echo '   <td'.$css_class.'>'.$row["event"].'</td>';
        echo '   <td'.$css_class.'>'.$row["sensor"].'</td>';
        echo '   <td'.$css_class.'>'.$row["celsius"].'</td>';
        echo '</tr>';
    }
?>
    </table>
    </body>
</html>

PHP: Upload Data

In dit bestand gaan we de techniek achter HTML <FORM> met GET gebruiken om data te ontvangen.

De GET waarden worden in de database gezet en vervolgens wordt de pagina “review.data.php” geopend voor weergave van de tabel inhoud. Dat laatste is optioneel en voor Arduino gebruik niet nodig. In jouw eind product zou je regel 12 dus weg kunnen laten.

Sla die bestand op als “add_data.php” in jouw www directory.


1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
    // Connect to MySQL
    include("dbconnect.php");

    // Prepare the SQL statement
    $SQL = "INSERT INTO test.temperature (sensor ,celsius) VALUES ('".$_GET["serial"]."', '".$_GET["temperature"]."')";    

    // Execute SQL statement
    mysql_query($SQL);

    // Go to the review_data.php (optional)
    header("Location: review_data.php");
?>

 

We kunnen nu al testen of dit goed werkt. In een web-browser: Voer het adres van jouw “server” in gevolgd door “add_data.php”, welke gevolgd wordt door data, b.v.:

  http://yourserver/add_data.php?serial=288884820500006b&temperature=20.79  

Als je nu op de ENTER toets drukt, dan zal add_data.php geopend worden en de aangehangen data ingelezen worden. Na opslag in MySQL wordt dan het “review_data.php” bestand geopend en je zult zoiets als onderstaande afbeelding in jouw browser zien:

Arduino MySQL voorbeeld (review_data.php output)

Arduino MySQL voorbeeld (review_data.php output)

  Let wel op dat deze beschreven code verre van “veilig” is, je moet dus jouw eigen beveiliging tegen misbruik maken!

Nu dat onze “server” klaar is voor data ontvangst, tijd om naar de Arduino kant van het verhaal te gaan kijken.

Arduino Ethernet Test Code

Onze Arduino-Ethernet-Sensor combo is opgezet en de PHP documenten en MySQL tabel zijn klaar voor gebruik.

Als eerste gaan we kijken naar een eenvoudige opstelling zodat we een idee krijgen hoe het e.e.a. werkt, we gaan de sensoren nog niet aanspreken maar je kunt ze aangesloten laten in de Arduino opstelling.

In onderstaande Sketch gaan we een verbinding opzetten met onze “web-server” en elke 5 seconden gaan we data naar de server sturen. Als je “retrieve_data.php” in jouw web-browser open hebt en af-en-toe op refresh drukt, dan zul je de tabel zien groeien (zie de “Date and Time” kolom voor de tijden):

Arduino MySQL test data bekijken

Arduino MySQL test data bekijken

Laten we even de code gaan bestuderen

Network basics:

Regel 1: Include de benodigde Ethernet Library (UIPEthernet).
Regel 6: Definieer het MAC adres van jouw Ethernet shield (moet uniek zijn in jouw netwerk, de gegeven waarde is zeer waarschijnlijk al uniek).
Regel 9: Definieer de variabele “client” welke onze verbinding vast houdt.
Regel 10: De naam of het IP adres van onze web-server waar we data gaan dumpen. Dit is dus de server waar we add_data.php hebben staan. Laat “http:”, pad en “add_data.php” weg – dit hebben we later pas nodig (b.v. www.google.com). Gebruik hier NIET localhost!
Regel 11: Hier geven we de wachttijd aan tussen data dumps, hier dus 5 seconden (5000).

Setup():

Als eerst gaan we hier de seriële poort openen zodat we debug info in de Arduino IDE kunnen volgen (menu “Tools Serial Monitor” en zorg ervoor dat de snelheid rechts-onderin op “9600 baud“ staat).

Vervolgens initialiseren we de Ethernet Shield me iets wat we nog niet eerder gedaan hebben: We gebruiken DHCP!
Zo zie je hoe eenvoudig UIPEthernet in gebruik is! Je hoeft alleen maar een Mac adres op te geven en alles wordt verder voor je afgehandeld.

De reden waarom we DHCP gebruiken is eenvoudig: het maakt voor onze toepassing niet uit wat het IP Adres is, zolang het maar een IP adres is dat correct is voor ons netwerk. Dit in tegenstelling tot “Data Pull” waar de server precies moet weten welk IP Adres het moet benaderen.

Vervolgens dumpen we details naar de seriële poort zodat we in de  Arduino IDE zien wat de verbindingsdetails zijn.

Loop()

Regel 33 gaat proberen een verbinding te openen en als dat lukt dan gaan we in de regels 36 t/m 47 een HTTP request doen. Hier is een beetje uitleg handig.

In regel 36, beginnen we een GET request. Het basis formaat van de add_data.php URL is (als voorbeeld):

  http://192.168.1.100/testserver/arduino_temperatures/add_data.php?serial=288884820500006X&temperature=12.3  

Vergeet niet dat dit afhankelijk is van jouw opstelling, dus pas het aan zodat het overeenkomt met jouw opstelling.

  Vergeet niet dat als je een WAMPServer (of andere AMP variant) gebruikt, dat “http://localhost” in jouw browser prima werkt als beiden op dezelfde computer staan. Voor de Arduino werkt “localhost” NIET. Localhost is een dummy hostname van jouw computer, wanneer je het aanroept van jouw computer! Voor de Arduino zou “localhost” naar de Arduino wijzen en dus niet naar de web-server.

Het eerste deel van de URL  http://192.168.1.100  hadden we al gedefinieerd (regel 10) en al gebruikt (regel 33), dus dat deel hebben we niet meer nodig.

Het tweede deel van de URL, “add_data.php” en het pad waar het staat (  /testserver/arduino_temperatures/add_data.php  ) wordt gevolgd door een vraagteken ter voorbereiding dat we GET variabelen laten volgen, zoals eerder besproken.

Regel 37 t/m 41 gaat nu de variabelen “serial” en “temperature” toevoegen, gescheiden door een ampersand (&), wat dan in de volgende regel resulteert  serial=288884820500006X&temperature=12.3 welke aan de output wordt toegevoegd.

Regels 42 t/m 48 ronden de HTTP GET request af en sluit uiteindelijk de verbinding.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <UIPEthernet.h> // Used for Ethernet

// **** ETHERNET SETTING ****
// Arduino Uno pins: 10 = CS, 11 = MOSI, 12 = MISO, 13 = SCK
// Ethernet MAC address - must be unique on your network - MAC Reads T4A001 in hex (unique in your network)
byte mac[] = { 0x54, 0x34, 0x41, 0x30, 0x30, 0x31 };                                      
// For the rest we use DHCP (IP address and such)

EthernetClient client;
char server[] = "192.168.1.100"; // IP Adres (or name) of server to dump data to
int  interval = 5000; // Wait between dumps

void setup() {

  Serial.begin(9600);
  Ethernet.begin(mac);

  Serial.println("Tweaking4All.com - Temperature Drone - v2.0");
  Serial.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
  Serial.print("IP Address        : ");
  Serial.println(Ethernet.localIP());
  Serial.print("Subnet Mask       : ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Default Gateway IP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("DNS Server IP     : ");
  Serial.println(Ethernet.dnsServerIP());
}

void loop() {
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("-> Connected");
    // Make a HTTP request:
    client.print( "GET /testserver/arduino_temperatures/add_data.php?");
    client.print("serial=");
    client.print( "288884820500006X" );
    client.print("&&");
    client.print("temperature=");
    client.print( "12.3" );
    client.println( " HTTP/1.1");
    client.print( "Host: " );
    client.println(server)
    client.println( "Connection: close" );
    client.println();
    client.println();
    client.stop();
  }
  else {
    // you didn't get a connection to the server:
    Serial.println("--> connection failed/n");
  }

  delay(interval);
}

 

Toevoegen van Sensor Lezen aan de Arduino Ethernet Code

Als je hier bent aangekomen dan neem ik aan dat alles wat we voorheen hebben besproken al werkt – Prima!
In dit deel gaan we sensor data lezen en versturen, en we gaan de PHP code aanpassen zodat we meerdere sensoren kunnen afhandelen.

PHP Truc voor ontvangst van Data van Meerdere Sensoren

Om data te kunnen ontvangen van een onbekend aantal sensoren, gaan we gebruik maken van een PHP trucje zodat het data kan lezen van links zoals dit voorbeeld:


1
http://testserver/arduino_temperatures/add_data.php?serial1=28%2088%2084%2082%2005%2000%2000%206b&temperature1=11.1&serial2=28%2088%2084%2082%2005%2000%2000%206b&temperature2=22.2&serial3=28%2088%2084%2082%2005%2000%2000%206b&temperature3=33.3

Zoals je ziet hebben meteen na de variabele naam een nummer gezet: “serialx=1234567890&temperaturex=12.3″ waarbij “x” een nummer is { 1, 2, …. n }.
Dus 1 voor sensor 1, 2 voor sensor 2, etc.

Het aanroepen van de voorbeeld link moet resulteren zoiets als hieronder zichtbaar is in de tabel.

Merk op:
– het ID nummer is NIET hetzelfde als het nummer dat we achter de variabele plakken, dat ze overeenkomen is toeval.
– Ik heb spaties in het serie nummer gebruikt (%20).

Testing "add_data.php" AFTER the modiications

Testing “add_data.php” AFTER the modifications

Om dit te laten werken, moeten we een kleine aanpassing maken aan hetadd_data.php” bestand – de code past zich zelf automatisch aan de omstandigheden aan.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
    // Connect to MySQL
    include("dbconnect.php");

    $counter=1;

    while ( isset( $_GET["serial".$counter] ) )
    {
        // Prepare the SQL statement
        $SQL = "INSERT INTO test.temperature (sensor ,celsius) VALUES ('".$_GET["serial".$counter]."', '".$_GET["temperature".$counter]."')";    

        // Execute SQL statement
        mysql_query($SQL);

        // Increase counter
        $counter++;
    }

    // Go to the review_data.php
    header("Location: review_data.php");
?>

In de regel 7 t/m 17 zie je dat we een loop gemaakt hebben waarbij de loop blijft kijken naar een “serialx” variabele (x is een nummer) tot het geen van deze variabelen meer kan vinden. Om een indruk te krijgen, kun je dit het beste met de eerdere “add_data.php” code vergelijken.

Maximum aantal variabelen dat we kunnen doorgeven … 

De URL voor ons “add_data.php” PHP script heeft beperkingen. De meeste PHP installeties kunnen maar 512 karakters voor GET parameters verwerken. dit in tegenstelling tot wat een aantal browsers ondersteund (inclusief IE): tot 2000 karakters, en Apache kan zelfs 8000 karakters aan. (source)

Dit brengt ons tot een maximum van ongeveer 8 sensors, maar je sult zelf moeten experimenteren om te kijken waar jouw PHP installatie grenzen legt.

 

Aanpassen van de Arduino Sketch voor het Lezen van Sensor(en)

Nu dat we onze PHP code hebben aangepast voor het ontvangen van data van meerdere sensoren tegelijk, tijd om onze Arduino code aan te passen zodat het sensor data leest en de data van èèn of meerder sensoren (past zich allemaal automatisch aan) verstuurt naar ons PHP bestand.

Onderstaande Sketch werkte uitstekend voor mijn opstelling waarbij je misschien al ziet dat dit dezelfde code is als ons eerdere voorbeeld met wat aanpassingen voor het lezen van de sensoren.

Als je eerder met temperatuur sensoren hebt gewerkt dan zul je de code in “TemperaturesToGetVariables” wel herkenne. Het is de code van het “Temperatuur meten met de Arduino en een DS18B20” artikel. Ik heb was minder belangrijke zaken verwijderd zoals Fahrenheit etc, om het overzichtelijker te houden.

Ik heb ook de wachttijd wat opgeschroefd naar 10 seconden (10,000) en in dagelijks gebruik zou 60 seconden misschien beter zijn, tenzij je jouw database erg snel wilt vullen 

Onderstaand code is een aangepaste versie op basis van input van Norbert Truchsess (developer van UIPEthernet – Hartelijk dank Norbert!!), welke ook ander Ethernet verkeer afhandelt (Ethernet.maintain()). Verder heb ik de serial output zo opgezet dat dit alleen actief is als “#define DEBUG” bestaat (om onnodige seriele output te voorkomen in een productie omgeving).

Als laatste heb ik een stukje code toegevoegd (na veel experimenten – dank je wel Frank!) om ervoor te zorgen dat bij netwerk problemen, de netwerk controller herstart wordt. Vooral bij langdurig gebruik blijkt dit nodig te zijn.

De uiteindelijk code en PHP bestanden kun je kopiëren en plakken of downloaden:

Download - T4A Temperature Drone (Push) 

Bestandsnaam:  T4A-Temperature-Drone-push.zip
Platform:  Undefined
Versie:  2.3
Omvang:  5 kB
Datum:  2014-07-04
 Download Nu  Stuur me Koffie    

Let op de timing … 

Vergeet niet dat het lezen van een sensor tijd kost en in de standaard instelling ongeveer 750 ms duurt per sensor.
Hoe meer sensoren je gebruikt, hoe meer tijd het kost om ze allemaal te lezen wat consequenties kan hebben voor de verbinding!

Vergeet ook niet de eerder melding voor wat betreft de maximale lengte van GET parameters voor PHP.
Ik heb dit alleen maar met 2 sensoren kunnen testen, omdat ik er maar 2 heb. Stuur me gerust meer sensoren als je wilt dat ik het met meerdere sensoren probeer.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include <UIPEthernet.h> // Used for Ethernet
#include <OneWire.h>     // Used for temperature sensor(s)

// #define DEBUG

// **** ETHERNET SETTING ****
// Arduino Uno pins: 10 = CS, 11 = MOSI, 12 = MISO, 13 = SCK
// Ethernet MAC address - must be unique on your network - MAC Reads T4A001 in hex (unique in your network)
byte mac[] = { 0x54, 0x34, 0x41, 0x30, 0x30, 0x31 };                                      
// For the rest we use DHCP (IP address and such)

EthernetClient client;
char server[] = "192.168.1.100"; // IP Adres (or name) of server to dump data to
unsigned long PreviousMillis = 0;// For when millis goes past app 49 days.
//unsigned long interval = 10000;  // Wait between dumps (10000 = 10 seconds)
unsigned long interval = 300000;  // Wait between dumps (1 min)
unsigned long intervalTime;      // Global var tracking Interval Time

// **** TEMPERATURE SETTINGS ****
// Sensor(s) data pin is connected to Arduino pin 2 in non-parasite mode!
OneWire  ds(2);

void setup() {
  #ifdef DEBUG
    Serial.begin(9600); // only use serial when debugging
  #endif
 
  Ethernet.begin(mac);
 
  intervalTime = millis();  // Set initial target trigger time (right NOW!)
 
  #ifdef DEBUG
    Serial.println("Tweaking4All.com - Temperature Drone - v2.3");
    Serial.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
    Serial.print("IP Address        : ");
    Serial.println(Ethernet.localIP());
    Serial.print("Subnet Mask       : ");
    Serial.println(Ethernet.subnetMask());
    Serial.print("Default Gateway IP: ");
    Serial.println(Ethernet.gatewayIP());
    Serial.print("DNS Server IP     : ");
    Serial.println(Ethernet.dnsServerIP());
  #endif
}

void loop() {
  unsigned long CurrentMillis = millis();
 
  if ( CurrentMillis < PreviousMillis ) // millis reset to zero?
  {
    intervalTime = CurrentMillis+interval;
  }
 
  if ( CurrentMillis > intervalTime )  // Did we reach the target time yet?
  {
    intervalTime = CurrentMillis + interval;
   
    if (!client.connect(server, 80)) {
      #ifdef DEBUG
        Serial.println("-> Connection failure detected: Resetting ENC!");  // only use serial when debugging
      #endif
      Enc28J60.init(mac);
    } else {
      client.stop();
    }
   
    // if you get a connection, report back via serial:
    if (client.connect(server, 80))
    {
      #ifdef DEBUG
        Serial.println("-> Connected");  // only use serial when debugging
      #endif
     
      // Make a HTTP request:
      client.print( "GET /testserver/arduino_temperatures/add_data.php?");
     
      TemperaturesToGetVariables(); // send serial and temperature readings
   
      client.println( " HTTP/1.1");
      client.println( "Host: 192.168.1.100" );
      client.print(" Host: ");
      client.println(server);
      client.println( "Connection: close" );
      client.println();
      client.println();
      client.stop();
    }
    else
    {
      // you didn't get a connection to the server:
      #ifdef DEBUG
        Serial.println("--> connection failed !!");  // only use serial when debugging
      #endif
     
      //Enc28J60.init(mac);
    }
  }
  else
  {
    Ethernet.maintain();
  }
}

void TemperaturesToGetVariables(void)
{
  byte counter;
  byte present = 0;
  byte sensor_type;
  byte data[12];
  byte addr[8];
  float celsius;
  byte sensorcounter;
 
  ds.reset_search();
  sensorcounter = 1; // we start counting with sensor number 1
 
  while ( ds.search(addr) )
  {
    if (sensorcounter>1) client.print("&"); // add ampersand if not first sensor
   
    client.print("serial"); // print: sensorx=
    client.print(sensorcounter);
    client.print("=");
   
    #ifdef DEBUG
      // Print Serial number
      Serial.print("   Sensor     : ");
      Serial.println(sensorcounter);
      Serial.print("   Serial     : ");
    #endif
   
    for( counter = 0; counter < 8; counter++)
    {
      if (addr[counter]<0x10) client.print("0");
      client.print(String(addr[counter], HEX));
      if (counter<7) client.print("%20");
     
      #ifdef DEBUG
        if (addr[counter]<0x10) Serial.print("0");
        Serial.print(String(addr[counter], HEX));
        if (counter<7) Serial.print(" ");
      #endif
    }
   
    #ifdef DEBUG
      Serial.println();   // only use serial when debugging
    #endif
   
    client.print("&temperature");  // print: &temperaturex=
    client.print(sensorcounter);
    client.print("=");
   
    // Check CRC
    if (OneWire::crc8(addr, 7) != addr[7]) // print ERROR if CRC error
    {
        client.println("ERROR");
    }
    else // CRC is OK
    {    
        // Removed sensor type detection and assumed DS18B20 sensor
        ds.reset();
        ds.select(addr);
        ds.write(0x44);  // start conversion, with regular (non-parasite!) power
       
        delay(750);     // maybe 750ms is enough, maybe not
       
        present = ds.reset();
        ds.select(addr);    
        ds.write(0xBE);  // Read Scratchpad
       
        // Get Raw Temp Data
        for ( counter = 0; counter < 9; counter++)
        {           // we need 9 bytes
          data[counter] = ds.read();
        }
       
        // Convert the data to actual temperature
        int16_t raw = (data[1] << 8) | data[0];
   
        // at lower res, the low bits are undefined, so let's zero them
        byte cfg = (data[4] & 0x60);
       
        //// default is 12 bit resolution, 750 ms conversion time
        if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
        else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
        else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
   
   
        celsius = (float)raw / 16.0;
        client.print(celsius);
   
        #ifdef DEBUG
          Serial.print("   Temperature: ");
          Serial.print(celsius);
          Serial.println(" C");
        #endif
     }
     
     sensorcounter++;
  }
  return;
}

 

Als je de Arduino een tijdje laat draaien dan levert “retrieve_data.php” zoiets als dit op:

Arduino, ENC28J60 en meerder DS18B20 sensoren levert zoiets als dit op ...

Arduino, ENC28J60 en meerder DS18B20 sensoren levert zoiets als dit op …

Zoals je misschien al ziet in de “Date and Time” kolom, de tijdsafstand tussen twee metingen is meer dan de “interval” waarde (10,000 = 10 seconds).
Dit komt omdat de tijd tussen twee metingen de som is van interval, metingen van elke sensor en het opzetten van de verbinding.

In ons voorbeeld met 2 sensoren:  10 second wachttijd + 2x (750ms) ≈ 12 seconden.

Als je liever een 100% perfecte timing wilt hebben dan zul je een meer geavanceerde methode moeten toepassen en gebruik moeten van van de Arduino Time Library.
Let op dat de Arduino geen echte realtime klok heeft dus we moeten werken met zaken zoals start-tijd etc.

Ondersteun ons ...


Jouw ondersteuning wordt zeer gewaardeerd, en hoeft zelfs niets te kosten. Bijvoorbeeld door links naar ons te delen op social media, of andere websites.

Andere vormen kunnen ook gratis zijn (b.v. shoppen op Amazon).
Alle opbrengsten worden gebruikt voor web-hosting kosten, project hardware en software, koffie, etc.

Hartelijk dank voor wie al heeft bijgedragen!
Het is altijd geweldig om te zien hoe men mijn artikeltjes en applicaties weet te waarderen.

Merk op dat het klikken op affiliate links een kleine commissie voor ons kunnen genereren - dit wordt zeer gewaardeerd.

Reacties


Er zijn 29 reacties welke je hieronder kunt lezen.
Je kunt jouw eigen opmerkingen plaatsen m.b.v. dit formulier, of een reactie op een bestaande opmerking plaatsen door op de "Beantwoorden" knop te klikken.

  • 28 mei 2014 - 21:08 - Harm - Auteur: Reactie Link

    Hans,

    Na alle andere voorgaande artikels omtrent de temperatuur sensors met succes te hebben uitgevoerd is ook deze dankzij de geweldige uitleg en toelichtingen/opmerkingen gelukt.

    de sensors waren identiek alleen heb ik  het Standaard Arduino Ethernet Shield.

    juist wat ik zocht.

    Bedankt, Harm

    Beantwoorden

    Harm

    • 29 mei 2014 - 14:43 - hans Reactie Link

      Dank je wel Harm !

      Mooi om te horen dat andere gebruikers ook wat aan mijnartikeltjes hebben … 

      Beantwoorden

      hans

  • 29 aug 2014 - 9:47 - Peter Reactie Link

    Perfecte uitleg!!

    Alles werkt. Ik heb ook de w5100 ethernet module en heb daarom de regel “Enc28J60.init(mac);” vervangen door “Ethernet.begin(mac);”

    Ik moet uitzoeken of ik dit goed heb vervangen maar het werkt in ieder geval.

    Nu nog een tool om mooie grafiekjes / overzichten te maken te maken van de opgeslagen data.

    Beantwoorden

    Peter

    • 29 aug 2014 - 16:04 - hans - Auteur: Reactie Link

      Mooi om te horen Peter! 
      En Dank je wel dat je hier laat weten dat de W5100 ook werkt. 

      Onder de Engelstalige versie van dit artikel heeft iemand (spreekt ook Nederlands) al iets met grafieke gedaan (link) d.m.v. de Highcharts graphing API (JavaScript). Misschien helpt het je op weg.

      Beantwoorden

      hans

  • 27 mrt 2016 - 11:47 - hans - Auteur: Reactie Link

    UPDATE:

    Type fout in de code gecorrigeerd waar ik per ongeluk “<10” (regel 134 b.v.) schreef, terwijl dit “<0x10” had moeten zijn.

    Beantwoorden

    hans

  • 28 sep 2016 - 18:15 - nick Reactie Link

    Hallo, mijn arduino wil maar geen verbinding maken met mijn website, wat kan er fout lopen?

    mvg

    Beantwoorden

    nick

    • 28 sep 2016 - 18:18 - nick Reactie Link

      Hij doet dat wel met bv http://www.google.com.

      Beantwoorden

      nick

    • 1 okt 2016 - 11:42 - hans - Auteur: Reactie Link

      Hoi Nick,

      het hangt er een beetje vanaf hoe je verbinding maakt met jouw website.
      Gebruik je een URL (www.mijnwebsite.nl) or een IP adres?
      Bij websites die op een gesharede server staan, dan werk een IP adres niet. Je zult dan bij de host een dedicated IP adres moeten aanvragen.

      Beantwoorden

      hans

  • 2 dec 2016 - 16:49 - Marty Janssen Reactie Link

    Ik heb alles werkend hij kan event pushen naar mijn webserver alleen niet de serial van de sensor  en de temperatuur deze neemt hij niet mee las ik het met de hand doe via de test url dan werkt het wel.moet ik nog iets toevoegen aan de code voor de arduino

    b.v.

    hieronder: (ik zie hier geen velden voor sensor en temp , hoe werkt dit ????)

          // Make a HTTP request:
          client.print( “GET /arduinotemp_add_data/add_data.php?”);
         
          TemperaturesToGetVariables(); // send serial and temperature readings
       
          client.println( ” HTTP/1.1″);
          client.println( “Host: 192.168.1.102” );
          client.print(” Host: “);
          client.println(server);
          client.println( “Connection: close” );
          client.println();
          client.println();
          client.stop();

    Beantwoorden

    Marty Janssen

    • 3 dec 2016 - 21:37 - hans - Auteur: Reactie Link

      Hallo Marty,

      Als je een test URL doet, waar voer je dit dan in? In de web-browser waar ook WAMP op draait?
      In dat geval kan het zijn dat WAMP Server eerst “online” gezet moet worden.
      Test daarom test links bij voorkeur vanaf een andere computer.

      Voor wat betreft de functie “TemperaturesToGetVariables()” betreft:
      Je ziet en dat stukje code een aantal “client.print()” functies – welke een stukje tekst naar de “output” stuurt van de netwerk verbinding. 

      Ik heb hieronder de functie een beetje gestript zodat je ziet waar de “client.print()” statements staan.
      Niet de netste manier overigens.

      void TemperaturesToGetVariables(void) 
      {
        ...
        while ( ds.search(addr) ) 
        {
          ...
          client.print("serial"); // print: serialx=
          client.print(sensorcounter);
          client.print("=");
          
          for( counter = 0; counter < 8; counter++) 
          {
            if (addr[counter]<0x10) client.print("0");
            client.print(String(addr[counter], HEX));
            if (counter<7) client.print("%20");
            ...
          }
          
          client.print("&temperature"); // print: &temperaturex=
          client.print(sensorcounter);
          client.print("=");
          
          // Check CRC
          if (OneWire::crc8(addr, 7) != addr[7]) // print ERROR if CRC error
          {
              client.println("ERROR");
          }
          else // CRC is OK
          {    
              ...
              client.print(celsius);
           ..
           } 
           
           sensorcounter++;
        }
        return;
      }

      Beantwoorden

      hans

      • 4 dec 2016 - 12:55 - Marty Reactie Link

        Beste Hans,

        Zou je nog eens naar mijn code kunnen kijken het lukt helaas niet.
        (sorry dat ik het hier doe omdat het nogal wat tekst is)
        Ter info:
        De webserver staat op een andere pc, deze loopt daarop staat de mysql datbase met de velden: id , event, sensor, celsius.

        Als ik de onderstaande url invoer werkt het:

        http://192.168.1.102/arduinotemp_add_data/add_data.php?sensor=284444820502226b&celsius=10.00

        hieronder de php code die de data van de url naar de datbase schrijft

        <?php
        // Connect to MySQL

        include("connection.php");

        // LET GOED OP DE VELDNAMEN IN DE CODE DIE IN DE ARDUINO STAAT !!! DEZE KUNNEN ANDERS ZIJN,
        // INDIEN DAT ZO IS MOET JE ZE AANPASSEN.


        $sql = "INSERT INTO temperature (sensor ,celsius) VALUES ('".$_GET["sensor"]."','".$_GET["celsius"]."')";


        $conn = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);
        mysqli_query($conn, $sql);

        ?>

        hieronder de code van de arduino:

        #include <Ethernet.h> // Used for Ethernet
        #include <OneWire.h> // Used for temperature sensor(s)


        // define debug als je deze aanzet dan kun je de serial monitor gebruiken
        #define DEBUG

        // **** ETHERNET SETTING ****
        // Arduino Uno pins: 10 = CS, 11 = MOSI, 12 = MISO, 13 = SCK
        // Ethernet MAC address - must be unique on your network - MAC Reads T4A001 in hex (unique in your network)
        byte mac[] = { 0x00, 0xAF, 0xBB, 0xCC, 0xDE, 0x02 };
        // For the rest we use DHCP (IP address and such)

        EthernetClient client;
        char server[] = "192.168.1.102"; // IP Adres (or name) of server to dump data to
        unsigned long PreviousMillis = 0;// For when millis goes past app 49 days.
        unsigned long interval = 10000; // Wait between dumps (10000 = 10 seconds)
        //unsigned long interval = 300000; // Wait between dumps (1 min)
        unsigned long intervalTime; // Global var tracking Interval Time

        // **** TEMPERATURE SETTINGS ****
        // Sensor(s) data pin is connected to Arduino pin 2 in non-parasite mode!
        OneWire ds(2);

        void setup() {
        #ifdef DEBUG
        Serial.begin(9600); // only use serial when debugging
        #endif

        Ethernet.begin(mac);

        intervalTime = millis(); // Set initial target trigger time (right NOW!)

        #ifdef DEBUG
        Serial.println("Tweaking4All.com - Temperature Drone - v2.3");
        Serial.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
        Serial.print("IP Address : ");
        Serial.println(Ethernet.localIP());
        Serial.print("Subnet Mask : ");
        Serial.println(Ethernet.subnetMask());
        Serial.print("Default Gateway IP: ");
        Serial.println(Ethernet.gatewayIP());
        Serial.print("DNS Server IP : ");
        Serial.println(Ethernet.dnsServerIP());
        #endif
        }

        void loop() {
        unsigned long CurrentMillis = millis();

        if ( CurrentMillis < PreviousMillis ) // millis reset to zero?
        {
        intervalTime = CurrentMillis+interval;
        }

        if ( CurrentMillis > intervalTime ) // Did we reach the target time yet?
        {
        intervalTime = CurrentMillis + interval;

        if (!client.connect(server, 80)) {
        #ifdef DEBUG
        Serial.println("-> Connection failure detected: Resetting ENC!"); // only use serial when debugging
        #endif
        Ethernet.begin(mac);
        } else {
        client.stop();
        }

        // if you get a connection, report back via serial:
        if (client.connect(server, 80))
        {
        #ifdef DEBUG
        Serial.println("-> Connected"); // only use serial when debugging
        #endif

        // Make a HTTP request:
        client.print( "GET /arduinotemp_add_data/add_data.php?");

        TemperaturesToGetVariables(); // send serial and temperature readings

        client.println( " HTTP/1.1");
        client.println( "Host: 192.168.1.102" );
        client.print(" Host: ");
        client.println(server);
        client.println( "Connection: close" );
        client.println();
        client.println();
        client.stop();
        }
        else
        {
        // you didn't get a connection to the server:
        #ifdef DEBUG
        Serial.println("--> connection failed !!"); // only use serial when debugging
        #endif

        //Enc28J60.init(mac);
        }
        }
        else
        {
        Ethernet.maintain();
        }
        }

        void TemperaturesToGetVariables(void)
        {
        byte counter;
        byte present = 0;
        byte sensor_type;
        byte data[12];
        byte addr[8];
        float celsius;
        byte sensorcounter;

        ds.reset_search();
        sensorcounter = 1; // we start counting with sensor number 1

        while ( ds.search(addr) )
        {
        if (sensorcounter>1) client.print("&"); // add ampersand if not first sensor

        client.print("serial"); // print: sensorx=
        client.print(sensorcounter);
        client.print("=");

        #ifdef DEBUG
        // Print Serial number
        Serial.print(" Sensor : ");
        Serial.println(sensorcounter);
        Serial.print(" Serial : ");
        #endif

        for( counter = 0; counter < 8; counter++)
        {
        if (addr[counter]<10) client.print("0");
        client.print(String(addr[counter], HEX));
        if (counter<7) client.print("%20");

        #ifdef DEBUG
        if (addr[counter]<10) Serial.print("0");
        Serial.print(String(addr[counter], HEX));
        if (counter<7) Serial.print(" ");
        #endif
        }

        #ifdef DEBUG
        Serial.println(); // only use serial when debugging
        #endif

        client.print("&temperature"); // print: &temperaturex=
        client.print(sensorcounter);
        client.print("=");

        // Check CRC
        if (OneWire::crc8(addr, 7) != addr[7]) // print ERROR if CRC error
        {
        client.println("ERROR");
        }
        else // CRC is OK
        {
        // Removed sensor type detection and assumed DS18B20 sensor
        ds.reset();
        ds.select(addr);
        ds.write(0x44); // start conversion, with regular (non-parasite!) power

        delay(750); // maybe 750ms is enough, maybe not

        present = ds.reset();
        ds.select(addr);
        ds.write(0xBE); // Read Scratchpad

        // Get Raw Temp Data
        for ( counter = 0; counter < 9; counter++)
        { // we need 9 bytes
        data[counter] = ds.read();
        }

        // Convert the data to actual temperature
        int16_t raw = (data[1] << 8) | data[0];

        // at lower res, the low bits are undefined, so let's zero them
        byte cfg = (data[4] & 0x60);

        //// default is 12 bit resolution, 750 ms conversion time
        if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
        else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
        else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms


        celsius = (float)raw / 16.0;
        client.print(celsius);

        #ifdef DEBUG
        Serial.print(" Temperature: ");
        Serial.print(celsius);
        Serial.println(" C");
        #endif
        }

        sensorcounter++;
        }
        return;
        }

        De output van de serial  monitor kun je hieronder zien.
        Ik zit er volgens mij dicht.

        Tweaking4All.com - Temperature Drone - v2.3
        -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

        IP Address : 192.168.1.80
        Subnet Mask : 255.255.255.0
        Default Gateway IP: 192.168.1.1
        DNS Server IP : 8.8.8.8
        -> Connected
        Sensor : 1
        Serial : 28 ff a4 35 84 16 04 76
        Temperature: 15.50 C
        -> Connected
        Sensor : 1
        Serial : 28 ff a4 35 84 16 04 76
        Temperature: 15.50 C
        -> Connected
        Sensor : 1
        Serial : 28 ff a4 35 84 16 04 76
        Temperature: 15.50 C
        -> Connected
        Sensor : 1
        Serial : 28 ff a4 35 84 16 04 76
        Temperature: 15.50 C

        Beantwoorden

        Marty

        • 4 dec 2016 - 19:59 - hans - Auteur: Reactie Link

          Hi Marty,

          het posten van code zou in het vervolg beter in het forum geplaatst kunnen worden – om te voorkomen dat de opmerkingen hieronder uit de hand lopen 

          Nou, de sensor werkt, en de webserver is bereikbaar. Nou we gaan de goede kant op.
          Voor het geval dat; tijdens het testen even de interval wat hoger zetten, voor het geval het netwerk het e.e.a. niet bij kan houden;

          unsigned long interval = 300000;  // Wait between dumps (1 min)

          Ik kan zo 1-2-3 geen problemen zien in jouw code (met de uitzondering dat je Ethernet.h gebruikt ipv UIPEthernet.h – maar ik neem aan dat je dit doet omdat je de ENC28J60 gebruikt).
          Kun je de log van de webserver vinden en zien of daar iets te achterhalen is?

          Beantwoorden

          hans

  • 5 dec 2016 - 11:14 - Marty Reactie Link

    Hoi Hans,

    balen ik zie het op dit moment echt niet wat er fout gaat.

    alles geprobeerd mmmmmmh

    Beantwoorden

    Marty

    • 5 dec 2016 - 16:08 - hans - Auteur: Reactie Link

      Hi Marty,

      zie je iets in de Apache logs?
      Iedere poging zou daarin gelogd moeten worden en je kunt dan vaak proberen te achterhalen wat er fout gaat (bv. Connection denied).
      Mocht je de log willen posten – plaats dan een bericht in het forum onder het Arduino onderwerp (om te voorkomen dat de opmerkingen hier uit de hand beginnen te lopen). Ik kijk graag even met je mee.

      Wat gebruik je overigens als netwerk shield?

      Beantwoorden

      hans

      • 5 dec 2016 - 17:07 - Marty Reactie Link

        Hoi Hans,

        ik gebruik een W5100 ethernet shield.
        in de logfile zie ik tot nu toe niets , ik heb ook andere web pagina’s lopen (php) b.v. een mp3 database waar ik records naar mysql schrijf en weergeef via php

        het zou mooi zijn dat we het werkend krijgen ik  heb namelijk een mooi stukje php geschreven met grafieken voor dit project , ziet er echt gaaf uit als
        screenshot wil mail dan ff je mail adres

        Beantwoorden

        Marty

  • 6 dec 2016 - 10:21 - Marty Reactie Link

    Hoi Hans,

    Ik heb het op een andere webserver getest via XAMPP hier kon ik gemakkelijk de logs bekijken en vond het probleem
    Access.log hierin stond dat hij wilde schrijven naar veld serial1 en temperature1 dit heb ik aangepast in add_data.php
    hierna werkte het.

    <?php    // Connect to MySQL
        include(“connection.php”);
        $sql = “INSERT INTO temperature (sensor ,celsius) VALUES (‘”.$_GET[“serial1″].”‘,'”.$_GET[“temperature1″].”‘)”;

        $conn = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);    mysqli_query($conn, $sql);
    ?>

    Dank je wel voor je hulp.

    Beantwoorden

    Marty

  • 16 dec 2016 - 20:02 - Ivanderbos Reactie Link

    Hallo Hans,

    Een mooie tutorial welke zeer goed te volgen is.

    Ik heb het nu zover werkend dat wanneer ik in de webbrowser de url uitvoer waarmee je kunt zien of de verbinding met de database OK is en de data wordt verwerkt richting de database, er ook nieuwe data in de database komt.

    Connectie tussen de arduino en de webserver wordt opgebouwd en in de seriele monitor lijkt het er op, dat er data wordt weggeschreven. Alleen als ik de database bekijk dan bevat deze geen nieuwe data.

    Ik maak gebruik van Xampp.

    Als ik de acces.log bekijk staat daar wel een verbinding afkomstig van de arduino in. En als ik de betreffende url kopieer vanuit de log en in de browser plak, dan wordt er wel een nieuwe regel aan de database toegevoegd.

    Zou u mij misschien verder kunnen helpen?

    Beantwoorden

    Ivanderbos

    • 17 dec 2016 - 18:30 - hans - Auteur: Reactie Link

      Hallo Ivanderbos 

      Dank je wel voor het compliment.

      Als je de link uit de acces log in een browser plakt, is dat de browser op dezelfde computer als waar XAMPP draait?
      Zo ja: probeer het dan eens van een andere computer. Een aantal AMP distributies blokkeert verkeer van buiten af, tenzij je de AMP expliciet “online” zet.

      Staat er verder aanvullende informatie in de acces en/of error log m.b.t. de verbinding die de Arduino probeert op te zetten (b.v. een foutmelding, of een melding dat het geblokkeerd werd)?

      Beantwoorden

      hans

      • 18 dec 2016 - 14:09 - Ivanderbos Reactie Link

        Hallo Hans,

        Ik heb de link vanuit de acces-log ook geprobeerd vanaf een ander systeem. Dat gaat allemaal goed. Heb ook in de GET() function wat extra serial.prints toegevoegd om te kijken of de arduino de code wel goed uitvoert. En dat lijkt allemaal goed te gaan. Ook heb ik de delay al eens verlengt maar ook dat mocht niet baten.

        Hierbij de regels uit de acces log.

        192.168.0.102 – – [18/Dec/2016:14:05:51 +0100] “GET /192.168.0.7/logger/add_data.php?serial=288884820500006X&&temperature=12.3 HTTP/1.1” 404 1056 “-” “-“

        192.168.0.102 – – [18/Dec/2016:14:06:21 +0100] “GET /192.168.0.7/logger/add_data.php?serial=288884820500006X&&temperature=12.3 HTTP/1.1” 404 1056 “-” “-“

        192.168.0.102 – – [18/Dec/2016:14:06:52 +0100] “GET /192.168.0.7/logger/add_data.php?serial=288884820500006X&&temperature=12.3 HTTP/1.1” 404 1056 “-” “-“

        192.168.0.102 – – [18/Dec/2016:14:07:22 +0100] “GET /192.168.0.7/logger/add_data.php?serial=288884820500006X&&temperature=12.3 HTTP/1.1” 404 1056 “-” “-“

        192.168.0.102 – – [18/Dec/2016:14:07:52 +0100] “GET /192.168.0.7/logger/add_data.php?serial=288884820500006X&&temperature=12.3 HTTP/1.1” 404 1056 “-” “-“

        En in de error log staan momenteel geen foutmelding van dit tijdstip, dus ik neem aan dat dat allemaal wel goed.
        Heb jij nog suggesties?

        Beantwoorden

        Ivanderbos

        • 19 dec 2016 - 15:17 - hans - Auteur: Reactie Link

          Hmm, dat is vreemd. De access log geeft de indruk dat het goed moet werken (uitgaan van het feit dat 192.168.0.102 de Arduino is). 

          Kun je in de code de “&&” vervangen door een “&”?

          Beantwoorden

          hans

          • 19 dec 2016 - 16:21 - Ivanderbos Reactie Link

            Hallo Hans,

            Bedankt voor je reactie. 
            De arduino is inderdaad 192.168.0.102.
            Ik heb in de code de “&&” even vervangen door “&”.
            Helaas mocht dit niet helpen.
            Heb voor de zekerheid ook nog even gecontroleerd dat mijn virusscanner of firewall nog het een en ander tegenhoudt, ook dit is niet het geval.
            Heb jij nog meer suggesties? Of zou je bereid zijn om mijn code eens door te spitten? Om te kijken of ik iets verkeerd doe?

            Ivanderbos

          • 19 dec 2016 - 16:42 - hans - Auteur: Reactie Link

            Je kunt evt. de acces log (eerst even leeg maken en opnieuw testen, en graag een test vanaf een andere computer erbij) en de sketch in het forum plaatsen. Ik heb alvast een onderwerp voor je geopend: hier.

            hans

  • 3 feb 2017 - 11:07 - Jan Wouter Reactie Link

    Bedankt voor je goede uitleg. Dankzij deze heb ik het eindelijk voor elkaar gekregen om data vanaf mijn Arduino te versturen en te loggen op mijn eigen server.

    Een stapje verder naar mijn complete home-automation-system.

    Beantwoorden

    Jan Wouter

    • 3 feb 2017 - 15:03 - hans - Auteur: Reactie Link

      Dank je wel voor het compliment Jan!
      Mooi om te horen dat je er wat aan had – en zeker motivatie van mijn kant om te blijven schrijven.

      Mocht je leuke ideeën hebben, laat ze dan vooral horen (hier of in het forum). 

      Beantwoorden

      hans

  • 4 feb 2017 - 15:51 - Niels Reactie Link

    Dag Hans,

    Geweldige tutorial, bedankt! Vraagje: ik wil de sensor graag koppelen aan Domoticz (http://www.domoticz.com, van harte aanbevolen ), die een prima API heeft. Deze kun je aansturen met een http-request als bijvoorbeeld 192.168.0.5:8080/json.htm?type=command&param=udevice&idx=247&nvalue=0&svalue=99;99. GET/POST oid is niet nodig. Vanuit een browser werkt dit prima, maar ik krijg het niet voor elkaar om dit mbv de UIPEthernet-library te doen. De documentatie bij die library is (nog) niet heel uitgebreid.

    Dit:

    loop() {
      // if you get a connection, report back via serial:
      if (client.connect(server, 8080)) {
        Serial.println("-> Connected");
        // Make a HTTP request:
        client.print( "/json.htm?type=command&param=udevice&idx=247&nvalue=0&svalue=999;999"); client.stop();

    …is in ieder geval niet voldoende. Er wordt verbinding gemaakt, maar er komt niets in Domoticz terecht. Heb jij een idee wat er in de code toegevoegd moet worden?

    Beantwoorden

    Niels

    • 4 feb 2017 - 18:58 - hans - Auteur: Reactie Link

      Hallo Niels,

      als eerste natuurlijk hartelijk dank voor het compliment en voor de Domoticz link (ik zal me tzt daar eens in verdiepen).

      Voor wat jouw vraag betreft: de link dit je opgeeft is een GET request, dus je hebt dat deel wel degelijk nodig.
      Zodra je zoiets als “?xyz=123&abc=456” ziet, heb je met een GET te maken.
      Soms is dat natuurlijk verwarrend. Dit in tegenstelling tot een POST waarbij data overgestuurd wordt zonder de informatie in de link te zetten.

      Probeer dit eens: 

        if (client.connect(server, 8080)) {
          Serial.println("-> Connected");
          // Make a HTTP GET request:
          client.print( "GET /json.htm?type=command&param=udevice&idx=247&nvalue=0&svalue=999;999");
          client.println( " HTTP/1.1");
          client.print( "Host: " );
          client.println(server)
          client.println( "Connection: close" );
          client.println();
          client.println();
          client.stop();
        }
        else {
          // you didn't get a connection to the server:
          Serial.println("--> connection failed/n");
        }
      Beantwoorden

      hans

  • 5 feb 2017 - 18:00 - Niels Reactie Link

    Bedankt, dat werkt! Weer wat geleerd ;-)

    Beantwoorden

    Niels



Jouw Opmerking ...

Plaats hier geen grote bestanden (zoals source codes, log files of config files). Gebruik hiervoor het Forum.

Delen:
*
*
Laat me per email weten als er nieuwe reacties zijn.
       Je kunt jouw RSS reader gebruiken om reacties te volgen.


Tweaking4All gebruikt de gratis Gravatar dienst voor Avatar weergave.