通过 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" 放入程序存储器,returns 将其地址放入程序存储器。如果你从这个指针读取,你实际上是从同一位置的数据存储器读取,并得到一些完全不相关的数据。您需要使用 pgm_read_byte
从程序内存中读取(ENC28J60 库不会这样做)。
您的 PSTR("")
恰好与您在 setup
中打印的字符串的第二个字节具有相同的地址。
解决方案是删除 POST 数据周围的 PSTR()
。
我不确定是否记录了哪些参数需要在程序内存中,但我找到了读取它们的函数 here。看起来 $F
意味着从程序存储器中读取一个字符串,而 $S
意味着从 RAM 中读取一个字符串。使用 $S
.
读取 client_postval
我已经成功地通过我的 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" 放入程序存储器,returns 将其地址放入程序存储器。如果你从这个指针读取,你实际上是从同一位置的数据存储器读取,并得到一些完全不相关的数据。您需要使用 pgm_read_byte
从程序内存中读取(ENC28J60 库不会这样做)。
您的 PSTR("")
恰好与您在 setup
中打印的字符串的第二个字节具有相同的地址。
解决方案是删除 POST 数据周围的 PSTR()
。
我不确定是否记录了哪些参数需要在程序内存中,但我找到了读取它们的函数 here。看起来 $F
意味着从程序存储器中读取一个字符串,而 $S
意味着从 RAM 中读取一个字符串。使用 $S
.
client_postval