简体   繁体   English

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

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

I've managed to set up a function to POST JSON data through my Arduino.我设法设置了一个函数来通过我的 Arduino POST JSON 数据。 I'm using webhook to test it and I'm experiencing some weird behaviour with it.我正在使用 webhook 来测试它,但我遇到了一些奇怪的行为。 The JSON data is not created where I would expect it to. JSON 数据未在我期望的位置创建。 Any help with explaining this would be appreciated.任何解释这一点的帮助将不胜感激。

#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
    }
}

The Arduino has two completely separate address spaces: program memory, and RAM. Arduino 有两个完全独立的地址空间:程序存储器和 RAM。 Normally, pointers point to RAM.通常,指针指向 RAM。

PSTR("hello") puts the string "hello" into program memory and returns its address within program memory. PSTR("hello")将字符串“hello”放入程序存储器并返回其在程序存储器中的地址。 If you read from this pointer, you actually read from data memory at the same location, and get some completely unrelated data.如果从这个指针中读取,实际上是从同一位置的数据存储器中读取,并得到一些完全不相关的数据。 You need to use pgm_read_byte to read from program memory (which the ENC28J60 library doesn't do).您需要使用pgm_read_byte从程序存储器中读取(ENC28J60 库不这样做)。

Your PSTR("") happens to have the same address as the second byte of the string you are printing in setup .您的PSTR("")恰好与您在setup中打印的字符串的第二个字节具有相同的地址。

The solution is to remove PSTR() around the POST data.解决方案是删除 POST 数据周围的PSTR()

I'm not sure if it is documented which parameters need to be in program memory, but I found the function here which reads them.我不确定是否记录了哪些参数需要在程序内存中,但我在这里找到了读取它们的函数。 It appears that $F means to read a string from program memory and $S means to read a string from RAM.看起来$F意味着从程序存储器中读取一个字符串,而$S意味着从 RAM 中读取一个字符串。 client_postval is read using $S . client_postval使用$S读取。

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

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