C语言 使用 Arduino 和 ENC28J60 以太网 LAN 网络模块发送 HTTP POST 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17791876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:59:20  来源:igfitidea点击:

Sending HTTP POST Request with Arduino and ENC28J60 Ethernet LAN Network Module

carduinorequesthttp-postethernet

提问by Jakub Pastuszuk

I just bought new ENC28J60 Ethernet LAN Network Module on Ebay, and I want to send POST Data with this module to specified web address eg. www.mydomain.com/example.php

我刚刚在 Ebay 上购买了新的 ENC28J60 以太网 LAN 网络模块,我想将带有此模块的 POST 数据发送到指定的网址,例如。www.mydomain.com/example.php

I resereached google for some examples, but all I could saw were examples for arduino shield, not module I have. With this module I'm using following libraries:

我在谷歌上搜索了一些例子,但我所能看到的只是 arduino shield 的例子,而不是我拥有的模块。在这个模块中,我使用了以下库:

"etherShield.h"
"ETHER_28J60.h"

"etherShield.h"
"ETHER_28J60.h"

I want to send one/two specified POSTS (variables) to the php formular, but i don't know how to do this.

我想将一/两个指定的 POSTS(变量)发送到 php 公式,但我不知道如何执行此操作。

采纳答案by nethead

First of all you need to install following library: https://github.com/jcw/ethercard

首先你需要安装以下库:https: //github.com/jcw/ethercard

connect your module to arduino with 6 pins:

使用 6 个引脚将您的模块连接到 arduino:

  • ENC SO -> Arduino pin 12
  • ENC SI -> Arduino pin 11
  • ENC SCK -> Arduino pin 13
  • ENC CS -> Arduino pin 8
  • ENC VCC -> Arduino 3V3 pin
  • ENC GND -> Arduino Gnd pin
  • ENC SO -> Arduino 引脚 12
  • ENC SI -> Arduino 引脚 11
  • ENC SCK -> Arduino 引脚 13
  • ENC CS -> Arduino 引脚 8
  • ENC VCC -> Arduino 3V3 引脚
  • ENC GND -> Arduino Gnd 引脚

then use following code:

然后使用以下代码:

#include <EtherCard.h>

// your variable

#define PATH    "example.php"
#define VARIABLE    "test"

// ethernet interface mac address, must be unique on the LAN
byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

char website[] PROGMEM = "www.mydomain.com";

byte Ethernet::buffer[700];
uint32_t timer;
Stash stash;

void setup () {
  Serial.begin(57600);
  Serial.println("\n[webClient]");

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);  
  ether.printIp("DNS: ", ether.dnsip);  

  if (!ether.dnsLookup(website))
    Serial.println("DNS failed");

  ether.printIp("SRV: ", ether.hisip);
}

void loop () {
  ether.packetLoop(ether.packetReceive());

  if (millis() > timer) {
    timer = millis() + 10000;

    byte sd = stash.create();
    stash.print("variable=");
    stash.print(VARIABLE);
    stash.print("&action=Submit");
    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("POST http://$F/$F.csv HTTP/1.0" "\r\n"
                "Host: $F" "\r\n"
                "Content-Length: $D" "\r\n"
                "Content-Type: application/x-www-form-urlencoded" "\r\n"
                "\r\n"
                "$H"),
    website, PSTR(PATH), website, stash.size(), sd);

    // send the packet - this also releases all stash buffers once done
    ether.tcpSend();
  }
}

回答by Halil Bülbül

Arduino v1.6.12

Arduino v1.6.12

 #include <EtherCard.h>

// your variable

#define PATH    "example.php"
#define VARIABLE    "test"

// ethernet interface mac address, must be unique on the LAN
byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };

const char website[] PROGMEM = "www.google.com";

byte Ethernet::buffer[700];
uint32_t timer;
Stash stash;

void setup () {
  Serial.begin(57600);
  Serial.println("\n[webClient]");

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);  
  ether.printIp("DNS: ", ether.dnsip);  

  if (!ether.dnsLookup(website))
    Serial.println("DNS failed");

  ether.printIp("SRV: ", ether.hisip);
}

void loop () {
  ether.packetLoop(ether.packetReceive());

  if (millis() > timer) {
    timer = millis() + 10000;

    byte sd = stash.create();
    stash.print("variable=");
    stash.print(VARIABLE);
    stash.print("&action=Submit");
    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("POST http://$F/$F.csv HTTP/1.0" "\r\n"
                        "Host: $F" "\r\n"
                        "Content-Length: $D" "\r\n"
                        "\r\n"
                        "$H"),
            website, PSTR(PATH), website, stash.size(), sd);

    // send the packet - this also releases all stash buffers once done
    ether.tcpSend();
  }
}

回答by Sakthivel sockkalingam

If anyone is looking to call an API, you need to remove .csv in the request, Like this:

如果有人要调用 API,则需要删除请求中的 .csv,如下所示:

 byte sd = stash.create();
    stash.print("variable="); //change this to your post variable
    stash.print(VARIABLE);
    stash.print("&action=Submit");
    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"
//remove the .csv
Stash::prepare(PSTR("POST http://$F/$F HTTP/1.0" "\r\n"
            "Host: $F" "\r\n"
            "Content-Length: $D" "\r\n"
            "Content-Type: application/x-www-form-urlencoded" "\r\n"
            "\r\n"
            "$H"),
website, PSTR(PATH), website, stash.size(), sd);

Additional information, if you are using local server to test, you can view the Access Log of Wampp or Xampp Server to know weather your request has reached the server or not.

附加信息,如果您使用本地服务器进行测试,您可以查看 Wampp 或 Xampp 服务器的访问日志以了解您的请求是否已到达服务器。

And use const in this line:

并在这一行中使用 const:

char const website[] PROGMEM = "www.mydomain.com";

回答by ntruchsess

you may want to try this library that is fully compatible to the stock Ethernet-lib:

您可能想尝试这个与库存以太网库完全兼容的库:

https://github.com/ntruchsess/arduino_uip

https://github.com/ntruchsess/arduino_uip

Examples from Arduino-IDE Ethernet work by installing this lib in [arduino-dir]/libraries/UIPEthernet, open the standard Ethernet-examples (e.g.: examples->Ethernet->WebServer) and replace the include "Ethenet.h" by "UIPEthernet.h".

Arduino-IDE 以太网示例通过在 [arduino-dir]/libraries/UIPEthernet 中安装此库来工作,打开标准以太网示例(例如:examples->Ethernet->WebServer)并将包含的“Ethenet.h”替换为“ UIPEthernet.h”。

回答by Tim Mudford

With regards to netheads answer, I was having trouble receiving the POST data at the server end. It was receiving header information, I just couldn't access the post data using $_POST or by any other means. I found that specifying the content type solved this problem. Just change the HTTP header part as follows:

关于 netheads 回答,我在服务器端接收 POST 数据时遇到问题。它正在接收标题信息,我只是无法使用 $_POST 或任何其他方式访问帖子数据。我发现指定内容类型解决了这个问题。只需按如下方式更改 HTTP 标头部分:

    Stash::prepare(PSTR("POST http://$F/$F.csv HTTP/1.0" "\r\n"
                    "Host: $F" "\r\n"
                    "Content-Length: $D" "\r\n"
                    "Content-Type: application/x-www-form-urlencoded" "\r\n"
                    "\r\n"
                    "$H"),
        website, PSTR(PATH), website, stash.size(), sd);