【问题标题】:sending arduino data to my database using EtherCard.h library使用 EtherCard.h 库将 arduino 数据发送到我的数据库
【发布时间】:2014-01-01 11:34:16
【问题描述】:

我在将 Arduino 数据发送到我的数据库时遇到问题。我目前正在使用WAMPSERVER。我有一个 arduino mini w/ ATMEGA 328,我正在使用 ENC28J60。问题是我尝试了不同的库和示例将数据发送到服务器,但我失败了。我只是注意到有些库与我的 enc28J60 不兼容。我尝试过 UIPEthernet.h、Ethernet.h、etherShield.h 和 EtherCard.h。 etherShield.h 和 EtherCard.h 似乎工作得很好。但我更喜欢使用 EtherCard.h,因为我听说 etherShield 是较旧的库。我懂一点php。

我认为可能指导我的事情是查看一个使用 EtherCard.h 库的工作示例,该示例演示如何将传感器数据从 arduino 发送到我的数据库。我目前正在处理的网络设置是,ENC28J60 连接在我的家庭网络中,IP 地址为 192.168.10.10。我放置数据库的服务器是我的笔记本电脑,IP 地址为 192.168.10.2。我将 php 文件放在此目录 C:\wamp\www 中。我希望我已经解释清楚了。对不起我的英语。

【问题讨论】:

    标签: arduino ethernet


    【解决方案1】:

    我目前正在使用我的 homewatch server 端口从 Arduino Unow 以太网库到带有 Ethercard 库(或 UIPEthernet)的 AVR-NETIO。

    在服务器端有一个 Apache/PHP/MySQL 服务器。

    要更新网络服务器连接数据库上的数据,您可以使用 POST 或 GET 请求到 php 网页。然后可以轻松地将这些数据添加到数据库中,并且相同或另一个网页也可以显示数据库的数据。

    <?php
    require 'dbhelp.php';
    
    //header('Content-type: text/plain');
    echo "<html>";
    echo "<head>";
    echo "<meta name='viewport' content='width=device-width, user-scalable=false, initial-scale=1;'>";
    echo "</head>";
    echo "<body>" .        "<h2>Temperatur und Luftfeuchte</h2>";
    
    
    // GET requests are sent as a query string on the URL:
    // GET index.html?name1=value&name2=value HTTP/1.1
    // Host: about.com
    // http://192.168.0.40/homewatch/index.php?channel=1&temp=165&humidity=80&datetime=010120131234
    if($DEBUG){
           print("<pre>");
    print_r($_GET);
    print("</pre>");
    }
    
    openDB();
    
    if( isset($_GET['channel']) && isset($_GET['temp']) && isset($_GET['humidity']) )
    {
      if($DEBUG)
        echo "<p>addData()";
      $c=$_GET['channel'];
      $t=$_GET['temp'];
      $h=$_GET['humidity'];
      addData($c, $t, $h);
      if($DEBUG)
         echo "<p>all done";
      //listData();
      echo "<p>OK updated data for channel:" . $c . "</p>";
    }
    else
    {
      if($DEBUG)
        echo "listData()";
      //listData();
      //echo "<p>missing arg";
    }
    echo "<p><a href='linechart_hour.php'>Stunden-&Uuml;bersicht</a></p>";
    echo "<p><a href='barchart_days.php'>Tages-&Uuml;bersicht</a></p>";
    echo "<p><a href='http://www.unwetterzentrale.de/uwz/getwarning_de.php?plz=41363&uwz=UWZ-DE&lang=de'>Unwetterwarnungen J&uuml;chen</a></p>";
    
    echo showAllCharts();
    //#################################################################################
    // see http://code.google.com/p/googlechartphplib/wiki/GettingStarted
    //#################################################################################
    // don't forget to update the path here
    require './lib/GoogleChart.php';
    
    $chart = new GoogleChart('lc', 500, 200);
    
    // manually forcing the scale to [0,100]
    $chart->setScale(0,100);
    
    // add one line
    $data = new GoogleChartData(array(49,74,78,71,40,39,35,20,50,61,45));
    $chart->addData($data);
    
    // customize y axis
    $y_axis = new GoogleChartAxis('y');
    $y_axis->setDrawTickMarks(false)->setLabels(array(0,50,100));
    $chart->addAxis($y_axis);
    
    // customize x axis
    $x_axis = new GoogleChartAxis('x');
    $x_axis->setTickMarks(5);
    $chart->addAxis($x_axis);
    
    echo $chart->toHtml();
    //#################################################################################
    // END
    //#################################################################################
    
    echo "<p>v0.9" . "</body>" . "</html>";
    ?>
    

    dbhelp.php 文件如果不存在则自动创建数据库:

    <?php
    //global dbhelp.php file
    
    $server="localhost";
    $user="root";
    $passwd="password";
    $names=array(
    1 => "Aussen",
    2 => "Schlaf",
    3 => "Andreas");
    $DEBUG=false;
    
    function openDB(){
        global $DEBUG;
        global $user;
        global $passwd;
        $link = mysql_connect("localhost", $user, $passwd);
        if(!$link){
                echo "SqlConnect failed";
                echo mysql_error();
        }
        else
                if($DEBUG)
                        echo "SqlConnect OK";
    
        $query="CREATE database IF NOT EXISTS avrdb;";
                $result = mysql_query($query, $link);
        if(!$result){
                echo "CreateDB failed";
                echo mysql_error();
        }
        else
                if($DEBUG)
                        echo "CreateDB OK";
    
        $result = mysql_select_db("avrdb", $link);
        if(!$result){
                echo "SelectDB failed";
                echo mysql_error();
        }
        else
                if($DEBUG)
                        echo "SelectDB OK";
    
        $query="CREATE TABLE IF NOT EXISTS `avrtemp` (" .
        "`id` int(11) NOT NULL AUTO_INCREMENT, " .
        "`channel` int(11), " .
        "`temp` int(11), " .
        "`humidity` int(11), " .
        "`date_time` TIMESTAMP, " .
        "PRIMARY KEY (`id`) );";
        $result = mysql_query($query, $link);
        if(!$result){
                echo "CreateTable failed";
                echo mysql_error();
        }
        else
                if($DEBUG)
                        echo "CreateTable OK";
    
        return true;        
    }
    ...
    function addData($c,$t,$h){
            global $DEBUG;
            $lastStoredDateTime=getLastStoredDateTime();
            if($DEBUG){
                    echo "<p>" . $c . "</p>\n";
                    echo "<p>LastDateTime=".$lastStoredDateTime."</p>\n";
            }
            // add data but do not save seconds (use 00)
            $query="INSERT INTO avrtemp (`channel`,`temp`,`humidity`,`date_time`)".
                  " VALUES ( $c,$t,$h,".
    //                         " DATE_FORMAT(NOW()),".
                             " DATE_FORMAT('".$lastStoredDateTime."', ".
                  " '%Y-%c-%d %H:%i') )";
            if($DEBUG)
                    echo "<p>" . $query;
            $result = mysql_query($query);
            if(!$result){
                    echo "addData failed";
                    echo mysql_error();
            }
            else
                    if($DEBUG)
                            echo "addData OK";
    }
    

    Arduino 发布(使用 GET)每 5 分钟更新一次数据。数据每分钟左右通过 433MHz 无线传感器到达 Arduino。

    使用以太网库完成数据更新

    char cBuf[maxBuf+1];
    const char getHttpString[] =
      "GET /homewatch/index.php?channel=%i&temp=%i&humidity=%i&time=%i\0";
    ...
      // and send data: /index.php?channel=1&temp=165&humidity=80&datetime=010120131234
      if (client.connect(server, 80)) {
        Serial.println("connected. Send GET...");
        snprintf(cBuf, maxBuf,
          getHttpString,
          sensorData[idxChannel].channel,
          sensorData[idxChannel].temp,
          sensorData[idxChannel].humidity,
          sensorData[idxChannel].time_long
          );
    
    Serial.println(F("####"));
    Serial.println(cBuf);
    Serial.println(F("####"));
    
        client.println(cBuf);
    ...
    

    https://github.com/hjgode/homewatch/blob/master/arduino/SketchBook/WebClientTemperature/WebClientTemperature.ino:

    字符串“GET /homewatch/index.php?channel=%i&temp=%i&humidity=%i&time=%i\0”只是填充了实际的传感器数据,服务器将其保存到其数据库中。

    Ethercard 库带有类似的示例:请参阅示例 noipClient、pachube 和 webclient。不幸的是,我还不能将这些用于我的 AVR-NETIO。

    将一些数据发布(GET)到我当前工作的服务器的代码是

    void sendData(int idxChannel){
        Serial.print(F("in sendData for idx=")); Serial.println(idxChannel);
        byte sd;
        int channel=sensorData[idxChannel].channel;
        int temp=sensorData[idxChannel].temp;
        int humidity=sensorData[idxChannel].humidity;
        char* stime="201301011122";
        stime=printDateTime((char*)&stime, 13, sensorData[idxChannel].time_long);
    
        if(sensorData[idxChannel].bUpdated==0){
          //nothing new
          if (MYDEBUG==0){
            Serial.println(F("leaving for not updated channel data"));
            goto exit_sendData;
          }
          else
          {
            sensorData[idxChannel].channel=idxChannel;
            sensorData[idxChannel].temp=222;
            sensorData[idxChannel].humidity=55;
            sensorData[idxChannel].time_long=now();      
          }
        }
    
        // generate two fake values as payload - by using a separate stash,
        // we can determine the size of the generated message ahead of time
        sd = stash.create();
        stash.print("0,");
        stash.println((word) millis() / 123);
        stash.print("1,");
        stash.println((word) micros() / 456);
        stash.save();
    
        // generate the header with payload - note that the stash size is used,
        // and that a "stash descriptor" is passed in as argument using "$H"
        Stash::prepare(PSTR("GET http://$F/homewatch/index.php?channel=$D&temp=$D&humidity=$D&time=$S" "\r\n"
                            "Host: $F" "\r\n"
                            "Content-Length: $D" "\r\n"
                            "\r\n"
                            "$H"),
                website, 
                channel,
                temp,
                humidity,
                stime,
                website, stash.size(), sd);
    
        // send the packet - this also releases all stash buffers once done
        ether.tcpSend();
    exit_sendData:
      lastConnectionTime = now();//millis();
      Serial.println(F("...end of sendData()"));
    }
    

    如你所见,有一个格式化字符串

    PSTR("GET http://$F/homewatch/index.php?channel=$D&temp=$D&humidity=$D&time=$S"
    

    里面充满了变量。 $F 从闪存中填充,$D 是数字变量,$S 从 RAM 内存字符串中填充。在没有我的 SensorCode(使用中断)的情况下使用它是有效的。

    【讨论】:

    • 谢谢!.. 我没有访问过这个页面,但我使用 UIPEthernet 库使它工作。我使用了给出的示例并对其进行了调整。无论如何,如果我将使用 Ethercard 库,这将是一个很好的参考。谢谢。
    • 我也让它与 UIPEthernet 库一起使用,但结果是用法有点不同。
    • 您是否正在使用安卓应用程序来监控您的系统?我的数据库现在每 5 秒更新一次,目前我正在开发一个 android 应用程序来监控读数。只是我在以 textview 格式而不是表格格式显示值时遇到问题。
    • 抱歉,我的 homewatch 使用网页,可以在任何连接到我的网络的浏览器上显示。无需 Android 或 iOS 应用程序:github.com/hjgode/homewatch/blob/master/doc/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 2019-10-16
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多