繁体   English   中英

通过 arduino 的 ENC28J60 模块发布 JSON 时的奇怪行为

[英]Weird behaviour while POSTing a JSON through arduino's ENC28J60 module

我设法设置了一个函数来通过我的 Arduino POST JSON 数据。 我正在使用 webhook 来测试它,但我遇到了一些奇怪的行为。 JSON 数据未在我期望的位置创建。 任何解释这一点的帮助将不胜感激。

#include <EtherCard.h>

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

byte Ethernet::buffer[700];
static uint32_t timer;

const char website[] PROGMEM = "webhook.site"; //my router's address

// called when the client request is complete
static void my_callback (byte status, word off, word len) {
  Serial.println(">>>");
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

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

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
      Serial.println("x{\"city\":\"Paris\",\"temp\":18.5}"); /// << JSON message is created here, and the first character of the message is removed
  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() + 5000;
    Serial.println();
    Serial.print("<<< REQ ");
    ether.httpPost(PSTR("/fe6f00eb-30ed-4b59-8908-fa3ec13c2485"), website, PSTR("Content-Type: application/json"),
       PSTR(""), my_callback); // PSTR("") because the message is created after .begin function is called
    }
}

Arduino 有两个完全独立的地址空间:程序存储器和 RAM。 通常,指针指向 RAM。

PSTR("hello")将字符串“hello”放入程序存储器并返回其在程序存储器中的地址。 如果从这个指针中读取,实际上是从同一位置的数据存储器中读取,并得到一些完全不相关的数据。 您需要使用pgm_read_byte从程序存储器中读取(ENC28J60 库不这样做)。

您的PSTR("")恰好与您在setup中打印的字符串的第二个字节具有相同的地址。

解决方案是删除 POST 数据周围的PSTR()

我不确定是否记录了哪些参数需要在程序内存中,但我在这里找到了读取它们的函数。 看起来$F意味着从程序存储器中读取一个字符串,而$S意味着从 RAM 中读取一个字符串。 client_postval使用$S读取。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM