0

私の最終的な目標は、Wi-Fi を有効にするために ESP-01S を使用して Raspberry Pi Pico をセットアップすることです。Pico は定期的にサーバーにチェックインし、使用していないときは ESP をスリープ状態にします。2 つの間の通信は UART を介して行われます。ESP からの GET および POST HTTP リクエストの両方をサポートしたいと考えています。

これは、2 つのデバイス間で使用しているメッセージ構造です。

 | Always start with MSG    | Request Type     | Next message Size
 |      | Next message size |                  |       | URL
 V      V                   V                  V       V
|-----|-------------------|-----|-------------------|-----------|
[M|S|G|\x00\|x00\|x00\|x03|G|E|T|\x00|\x00|\x00|\x1f|h|t|t|p|...]
[M|S|G|\x00\|x00\|x00\|x04|P|O|S|T|URL SIZE...|URL...|\x00|\x00|\x006|POST Data...]
|-----|-------------------|-------|-----------|------|---------------|------------|
                                                        ^              ^
                                                        |              | Post Data
                                                        | Post data size               

テスト目的で、Python で文字列を生成し、それらを印刷して、ESP にフラッシュしている .cpp ファイルに直接貼り付けています。

メッセージを生成するために PC で使用しているコードのスニペットを次に示します。

import struct
import json
url = "http://192.168.X.X:8090/korok"
size_of_url = struct.pack('!I', len(url))
data = json.dumps({
    "serial": "12345",
    "sensor_data": {"0": 75, "1": 67}
})
size_of_data = struct.pack('!I', len(data))
print(f"{struct.pack('!I', len('GET'))}GET{size_of_url}{url}")
print(f"{struct.pack('!I', len('POST'))}POST{size_of_url}{url}{size_of_data}{data}")

>>>> ...
b'\x00\x00\x00\x03'GETb'\x00\x00\x00\x1f'http://192.168.X.X:8090/korok
b'\x00\x00\x00\x03'GETb'\x00\x00\x00\x1f'http://192.168.X.X:8090/korokb'\x00\x00\x006'{"serial": "12345", "sensor_data": {"0": 75, "1": 67}}

そして、これが ESP で実行されているコードです。私が経験しているいくつかの行動についてコメントを残しました。

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

#define GPIO_STATUS 2
#define BUFFER_SIZE 256
#define DATA_SIZE 4

char buf[BUFFER_SIZE];

void setup() {...}

...

// Struct is used so I can also get the size to use as an offset
// and read out part of the message in the buffer.
struct Message
{
  char *value;
  unsigned int size;
  unsigned int totalMessageSize;
};

Message readMessage(char *data)
{
  struct Message message;
  message.size = ntohl(*(unsigned int *)(data)); // Unable to read shorthand hex
  Serial.println(message.size);
  message.totalMessageSize = message.size + DATA_SIZE; // Shorthand is only 3 char
  message.value = (char *)malloc(message.size);
  Serial.println(message.size);
  int idx = DATA_SIZE;
  int jdx = 0;
  while (idx < message.size + DATA_SIZE && idx < BUFFER_SIZE)
  {
    message.value[jdx++] = data[idx++];
  }
  return message;
}

void loop()
{
  delay(3000);
  char * msg = "\x00\x00\x00\x03GET\x00\x00\x00\x1fhttp://192.168.X.X:8090/korok";
  // char *msg = read_message();
  if (msg)
  {
    Serial.print("\n");
    int bufferIdx = 0;

    struct Message request = readMessage(msg);
    bufferIdx = request.totalMessageSize;

    // This is odd and doing it due to odd behavior with ntohl and a variable
    // offset. See below.
    memcpy(msg, msg + bufferIdx, BUFFER_SIZE - bufferIdx);
    struct Message url = readMessage(msg);
    struct Message data;

    if (memcmp(request.value, "GET", 3) == 0)
    {
    }
    else if (memcmp(request.value, "POST", 4) == 0)
    {
      bufferIdx = url.totalMessageSize;
      memcpy(msg, msg + bufferIdx, BUFFER_SIZE - bufferIdx);
      struct Message data = readMessage(msg);
      Serial.println(data.value);
    }

    free(request.value);
    free(url.value);
    if (memcmp(request.value, "POST", 4) == 0)
    {
      free(data.value);
    }
  }
}

これは 2 つの問題のうちの 1 つですが、最初のインデックスをオフセットする元の char* の memcpy を実行することで回避策を見つけました。以下の最初の行は機能しますが、2 番目の行は LoadStoreAlignmentCause 例外をスローします。

理想的には、ここで何が起こっているのかを理解し、memcpy なしでこれを機能させたいと考えています。

ntohl(*(unsigned int *)(msg + 7)); // Works

int offset = 7;
ntohl(*(unsigned int *)(msg + offset)); // Throws Exception (9) LoadStoreAlignmentCause

私が経験している主な問題は、Python でサイズをパックしているときに、一部の 16 進数値が簡略化されていることです。例えばstruct.pack('!I', 54) == \x00\x00\x006

これが発生するntohl()と、読み取ってはならないアドレスを読み取ったように見え、635 が出力されます。

この問題に関するいくつかの質問。この簡略化された 16 進構文の名前は何ですか? この短い手を出力しないようにPythonを取得する方法はありますか? または、これを ESP で機能させる方法について何か提案はありますか?

4

0 に答える 0