{"id":4335,"date":"2026-09-30T08:36:46","date_gmt":"2026-09-30T00:36:46","guid":{"rendered":"https:\/\/saludpcb.com\/zh\/?p=4335"},"modified":"2026-09-30T23:13:03","modified_gmt":"2026-09-30T15:13:03","slug":"esp32-a2dp-bluetooth-audio-player-esp-idf","status":"publish","type":"post","link":"https:\/\/saludpcb.com\/zh\/esp32-a2dp-bluetooth-audio-player-esp-idf\/","title":{"rendered":"ESP32 A2DP \u85cd\u7259\u97f3\u8a0a\u5b8c\u5168\u6307\u5357 | \u57fa\u65bc ESP-IDF \u539f\u751f\u67b6\u69cb\u6253\u9020 Hi-Fi \u64ad\u653e\u5668"},"content":{"rendered":"\n<hr class=\"wp-block-separator alignwide has-text-color has-palette-color-1-color has-alpha-channel-opacity has-palette-color-1-background-color has-background is-style-wide\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>ESP32 A2DP<\/strong> \u662f\u76ee\u524d\u4ee5\u6975\u4f4e\u786c\u9ad4\u6210\u672c\u6253\u9020\u9ad8\u54c1\u8cea\u7121\u7dda\u97f3\u8a0a\u63a5\u6536\u7aef\uff08Audio Sink\uff09\u7684\u6700\u4f73\u67b6\u69cb\u65b9\u6848\u3002\u5e02\u9762\u4e0a\u73fe\u6210\u7684\u85cd\u7259\u97f3\u8a0a\u6a21\u7d44\u5f80\u5f80\u5b58\u5728\u5e95\u566a\u904e\u5927\u3001\u7121\u6cd5\u52d5\u614b\u5207\u63db\u63a1\u6a23\u983b\u7387\u4ee5\u53ca\u7f3a\u4e4f\u81ea\u8a02\u63a7\u5236\u4ecb\u9762\u7684\u7f3a\u9ede\uff1b\u800c ESP32 \u6676\u7247\u5167\u5efa\u7d93\u5178\u85cd\u7259\uff08Bluetooth Classic\uff09\u96d9\u6a21\u5c04\u983b\u8207\u786c\u9ad4 I2S\uff08Inter-IC Sound\uff09\u63a7\u5236\u5668\uff0c\u53ea\u8981\u642d\u914d\u5408\u9069\u7684\u5916\u90e8 DAC\uff0c\u5373\u53ef\u76f4\u63a5\u8f38\u51fa CD \u7d1a\uff0816-bit 44.1kHz \/ 48kHz\uff09\u7d14\u6de8\u97f3\u8a0a\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u96d6\u7136\u958b\u6e90\u793e\u7fa4\u63d0\u4f9b\u4e86 Arduino \u5c01\u88dd\u7684 A2DP \u51fd\u5f0f\u5eab\uff0c\u4f46\u5728\u5546\u696d\u5316\u91cf\u7522\u8207\u56b4\u82db\u7a69\u5b9a\u5ea6\u8981\u6c42\u4e0b\uff0c\u4f7f\u7528\u6a02\u946b\u539f\u5ee0\u539f\u751f <strong>ESP-IDF\uff08Espressif IoT Development Framework\uff09<\/strong> \u662f\u552f\u4e00\u80fd\u5b8c\u6574\u638c\u63a7\u5e95\u5c64\u8a18\u61b6\u9ad4\u3001 FreeRTOS \u4efb\u52d9\u6392\u7a0b\u3001\u97f3\u8a0a\u4f47\u5217\u7de9\u885d\uff08RingBuffer\uff09\u4ee5\u53ca\u52d5\u614b SBC \u63a1\u6a23\u7387\u5354\u5546\u7684\u958b\u767c\u65b9\u5f0f\u3002\u672c\u6587\u9075\u5faa\u6a02\u946b\u5b98\u65b9 A2DP API \u898f\u7bc4\uff0c\u5f9e\u67b6\u69cb\u539f\u7406\u3001\u786c\u9ad4\u96fb\u8def\u3001<code>sdkconfig<\/code> \u914d\u7f6e\uff0c\u4e00\u8def\u5be6\u4f5c\u5230\u300c\u4e8b\u4ef6\u9a45\u52d5\u72c0\u614b\u6a5f + \u74b0\u5f62\u7de9\u885d\u5340\uff08RingBuffer\uff09\u89e3\u8026\u300d\u7684\u5b8c\u6574\u5de5\u696d\u7d1a\u7a0b\u5f0f\u78bc\u3002<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1408\" height=\"768\" src=\"https:\/\/saludpcb.com\/zh\/wp-content\/uploads\/2026\/09\/ESP32-A2DP-Bluetooth-Audio-Guide-Building-a-Hi-Fi-Player-with-Native-ESP-IDF-1.jpg\" alt=\"ESP32 A2DP\" class=\"wp-image-4347\" title=\"\" srcset=\"https:\/\/saludpcb.com\/zh\/wp-content\/uploads\/2026\/09\/ESP32-A2DP-Bluetooth-Audio-Guide-Building-a-Hi-Fi-Player-with-Native-ESP-IDF-1.jpg 1408w, https:\/\/saludpcb.com\/zh\/wp-content\/uploads\/2026\/09\/ESP32-A2DP-Bluetooth-Audio-Guide-Building-a-Hi-Fi-Player-with-Native-ESP-IDF-1-766x418.jpg 766w\" sizes=\"auto, (max-width: 1408px) 100vw, 1408px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>\u5167\u5bb9<\/h2><nav><ul><li class=\"\"><a href=\"#\u4ec0\u9ebc\u662f-openclaw-ai\">ESP32 A2DP \u6838\u5fc3\u67b6\u69cb<\/a><\/li><li class=\"\"><a href=\"#\u70ba\u4f55\u7528-openclaw-\u5beb-esp32\">ESP32 \u6838\u5fc3\u6676\u7247\u9078\u578b<\/a><\/li><li class=\"\"><a href=\"#\u958b\u767c\u74b0\u5883\">\u96fb\u8def\u914d\u7dda\u6307\u5357<\/a><\/li><li class=\"\"><a href=\"#\u5c08\u6848\u7d50\u69cb\">\u958b\u767c\u74b0\u5883\u8207\u5efa\u7f6e\u5de5\u5177<\/a><\/li><li class=\"\"><a href=\"#\u89c0\u5ff5\u8f49\u8b8a\">\u5c08\u6848\u7d50\u69cb<\/a><\/li><li class=\"\"><a href=\"#\u4e3b\u5143\u4ef6-main-c-make-lists-txt-\u8a2d\u5b9a\">CMake \u8a2d\u5b9a<\/a><\/li><li class=\"\"><a href=\"#c\">\u7a0b\u5f0f\u78bc<\/a><\/li><li class=\"\"><a href=\"#y\">\u71d2\u9304\u548c\u8f38\u51fa<\/a><\/li><li class=\"\"><a href=\"#\u7d50\u8ad6\">\u7d50\u8ad6<\/a><\/li><\/ul><\/nav><\/div>\n\n\n\n<h2 id=\"\u4ec0\u9ebc\u662f-openclaw-ai\" class=\"wp-block-heading\">ESP32 A2DP \u6838\u5fc3\u67b6\u69cb<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ESP32 A2DP \u5728 ESP-IDF \u67b6\u69cb\u4e0b\uff0c\u672c\u8cea\u662f\u63a1\u7528\u300c\u85cd\u7259\u89e3\u78bc\u70ba\u751f\u7522\u8005\u3001\u786c\u9ad4 I2S DMA \u70ba\u6d88\u8cbb\u8005\u300d\u7684\u975e\u540c\u6b65\u7de9\u885d\u7ba1\u7dda\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u89d2\u8272\u5b9a\u4f4d\uff08Audio Sink\uff09<\/strong>\uff1aESP32 \u4f5c\u70ba\u97f3\u8a0a\u63a5\u6536\u7aef\uff0c\u900f\u904e\u7d93\u5178\u85cd\u7259\uff08Bluetooth Classic\uff09\u63a5\u6536\u624b\u6a5f\u50b3\u9001\u7684 SBC \u5c01\u5305\uff0c\u4e26\u7531 Bluedroid \u5354\u5b9a\u68e7\u89e3\u78bc\u70ba PCM \u539f\u59cb\u97f3\u8a0a\u3002<\/li>\n\n\n\n<li><strong>\u96d9\u8ecc\u56de\u547c\u67b6\u69cb<\/strong>\uff1aESP32 A2DP \u63a1\u7528\u96d9\u8ecc\u56de\u547c\u67b6\u69cb\u5be6\u73fe\u63a7\u5236\u8207\u8cc7\u6599\u7684\u89e3\u8026\uff1b\u63a7\u5236\u5c64\uff08<code>esp_a2d_cb_t<\/code>\uff09\u8ca0\u8cac\u76e3\u807d\u9023\u7dda\u72c0\u614b\u8207\u97f3\u8a0a\u914d\u7f6e\u4e8b\u4ef6\uff08<code>ESP_A2D_AUDIO_CFG_EVT<\/code>\uff09\uff0c\u7528\u4ee5\u52d5\u614b\u5354\u5546\u5207\u63db\u786c\u9ad4\u63a1\u6a23\u7387\uff0844.1kHz \u6216 48kHz\uff09\uff1b\u8cc7\u6599\u5c64\uff08<code>esp_a2d_sink_data_cb_t<\/code>\uff09\u5247\u5c08\u6ce8\u65bc\u5373\u6642\u63a5\u6536\u89e3\u78bc\u5f8c\u7684 PCM \u97f3\u8a0a\u4e32\u6d41\uff0c\u78ba\u4fdd\u7cfb\u7d71\u63a7\u5236\u908f\u8f2f\u8207\u97f3\u8a0a\u4e32\u6d41\u8655\u7406\u5206\u5de5\u660e\u78ba\u4e14\u4e92\u4e0d\u5e72\u64fe\u3002<\/li>\n\n\n\n<li><strong>BTC \u57f7\u884c\u7dd2\u975e\u963b\u585e\u539f\u5247\uff08\u95dc\u9375\uff09<\/strong>\uff1a\u97f3\u8a0a\u56de\u547c\u51fd\u5f0f\u76f4\u63a5\u904b\u884c\u5728\u85cd\u7259\u63a7\u5236\uff08BTC\uff09\u57f7\u884c\u7dd2\u5167\uff0c\u56b4\u7981\u4efb\u4f55\u963b\u585e\u5f0f\u547c\u53eb\uff1b\u82e5\u76f4\u63a5\u5beb\u5165 I2S \u6703\u5c0e\u81f4\u85cd\u7259\u56de\u61c9\u8d85\u6642\uff0c\u5f15\u767c Watchdog \u91cd\u555f\u6216\u7834\u97f3\u3002<\/li>\n\n\n\n<li><strong>RingBuffer \u4efb\u52d9\u89e3\u8026<\/strong>\uff1a\u8cc7\u6599\u56de\u547c\u4ee5\u96f6\u8d85\u6642\uff08<code>timeout = 0<\/code>\uff09\u5c07 PCM \u5beb\u5165 FreeRTOS \u74b0\u5f62\u7de9\u885d\u5340\uff0c\u518d\u7531\u7368\u7acb\u7684 I2S \u64ad\u653e\u4efb\u52d9\uff08\u5efa\u8b70\u56fa\u5b9a\u5728 Core 1\uff09\u8ca0\u8cac\u963b\u585e\u5f0f\u8b80\u53d6\u3002<\/li>\n\n\n\n<li><strong>\u786c\u9ad4 DMA \u96f6\u62f7\u8c9d\u8f38\u51fa<\/strong>\uff1a\u97f3\u8a0a\u8cc7\u6599\u7531 I2S \u63a7\u5236\u5668\u900f\u904e DMA \u9023\u7e8c\u9001\u5f80\u5916\u90e8 DAC\uff08\u5982 PCM5102A\uff09\uff0c\u78ba\u4fdd\u9ad8\u8ca0\u8f09\u4e0b\u8072\u97f3\u5b8c\u5168\u4e0d\u6389\u5e40\u3002<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32 \u6838\u5fc3\u6676\u7247\u9078\u578b<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u552f\u4e00\u652f\u63f4<\/strong>\uff1a\u539f\u59cb <strong>ESP32 \u7cfb\u5217<\/strong>\uff08\u5982 ESP32-WROOM-32\u3001WROVER\uff09\uff0c\u5177\u5099\u7d93\u5178\u85cd\u7259\uff08BR-EDR\uff09\u5c04\u983b\u3002<\/li>\n\n\n\n<li><strong>\u4e0d\u652f\u63f4<\/strong>\uff1a<strong>ESP32-S3\u3001ESP32-C3\u3001ESP32-C6<\/strong> \u50c5\u652f\u63f4 BLE\uff0c<strong>\u7121\u6cd5<\/strong>\u57f7\u884c A2DP \u97f3\u8a0a\u5354\u5b9a\u3002<\/li>\n<\/ul>\n\n\n\n<h2 id=\"undefined-1\" class=\"wp-block-heading\">\u96fb\u8def\u914d\u7dda\u6307\u5357<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5916\u90e8 I2S DAC \u6a21\u7d44\u63a8\u85a6\n<ul class=\"wp-block-list\">\n<li><strong>PCM5102A\uff08\u9996\u9078\uff09<\/strong>\uff1a32-bit \/ 384kHz \u89e3\u78bc\u3001SNR \u9054 112dB\uff0c\u9069\u5408\u8f38\u51fa\u81f3 3.5mm \u8033\u6a5f\u5b54\u6216\u5bb6\u7528\u64f4\u5927\u6a5f\u3002<\/li>\n\n\n\n<li><strong>MAX98357A<\/strong>\uff1a\u5167\u5efa 3.2W D \u985e\u529f\u653e\uff0c\u9069\u5408\u76f4\u63a8 4\u03a9 \/ 8\u03a9 \u8ff7\u4f60\u5587\u53ed\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u96fb\u8def\u63a5\u7dda\u8868\uff08ESP32 \u9023\u63a5 PCM5102A\uff09<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>ESP32 \u8173\u4f4d<\/strong><\/td><td><strong>PCM5102A \u8173\u4f4d<\/strong><\/td><td><strong>\u8173\u4f4d\u529f\u80fd<\/strong><\/td><td><strong>\u786c\u9ad4\u8a2d\u5b9a\u8207\u8aaa\u660e<\/strong><\/td><\/tr><\/thead><tbody><tr><td><strong>3V3<\/strong><\/td><td>VCC<\/td><td>\u7cfb\u7d71\u4f9b\u96fb<\/td><td>\u5efa\u8b70\u52a0\u96fb\u5bb9\u6ffe\u6ce2\u4ee5\u9694\u96e2\u5c04\u983b\u5e95\u566a<\/td><\/tr><tr><td><strong>GND<\/strong><\/td><td>GND<\/td><td>\u96fb\u6e90\u63a5\u5730<\/td><td>\u985e\u6bd4\u8207\u6578\u4f4d\u5171\u5730\u9ede<\/td><\/tr><tr><td><strong>GPIO 26<\/strong><\/td><td>BCK (BCLK)<\/td><td>\u4f4d\u5143\u6642\u8108<\/td><td>\u540c\u6b65\u50b3\u8f38\u6bcf\u500b\u97f3\u8a0a bit<\/td><\/tr><tr><td><strong>GPIO 25<\/strong><\/td><td>LCK (LRCK\/WS)<\/td><td>\u8072\u9053\u5207\u63db<\/td><td>\u5de6\u53f3\u8072\u9053\u6642\u8108\uff0844.1kHz \/ 48kHz\uff09<\/td><\/tr><tr><td><strong>GPIO 22<\/strong><\/td><td>DIN (DATA)<\/td><td>\u97f3\u8a0a\u8cc7\u6599<\/td><td>\u4e32\u6d41\u50b3\u9001 PCM \u97f3\u8a0a<\/td><\/tr><tr><td><strong>GND<\/strong><\/td><td>SCK<\/td><td>\u7cfb\u7d71\u6642\u8108<\/td><td><strong>\u5fc5\u9808\u63a5\u5730<\/strong>\uff1a\u555f\u7528\u5167\u90e8 PLL \u81ea\u52d5\u7522\u751f\u6642\u8108<\/td><\/tr><tr><td><strong>GND<\/strong><\/td><td>FMT<\/td><td>\u683c\u5f0f\u9078\u64c7<\/td><td><strong>\u5fc5\u9808\u63a5\u5730<\/strong>\uff1a\u8a2d\u5b9a\u70ba\u6a19\u6e96 I2S \u683c\u5f0f<\/td><\/tr><tr><td><strong>3V3<\/strong><\/td><td>XMT<\/td><td>\u8edf\u9ad4\u975c\u97f3<\/td><td><strong>\u5fc5\u9808\u63a5 3.3V<\/strong>\uff1a\u89e3\u9664\u975c\u97f3\uff08\u61f8\u7a7a\u6216\u63a5\u5730\u6703\u7121\u8072\uff09<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u95dc\u9375\u914d\u7dda\u6ce8\u610f\u4e8b\u9805\n<ul class=\"wp-block-list\">\n<li><strong>\u89e3\u9664\u975c\u97f3<\/strong>\uff1a<code>XMT<\/code> \u52d9\u5fc5\u62c9\u81f3 3.3V \u9ad8\u96fb\u4f4d\uff0c\u5426\u5247\u6676\u7247\u6703\u4fdd\u6301\u975c\u97f3\u72c0\u614b\u3002<\/li>\n\n\n\n<li><strong>\u9396\u76f8\u74b0\u6642\u8108<\/strong>\uff1a<code>SCK<\/code> \u52d9\u5fc5\u63a5\u5730\u8b93\u5167\u90e8 PLL \u5de5\u4f5c\uff0c\u4e0d\u53ef\u61f8\u7a7a\u3002<\/li>\n\n\n\n<li><strong>\u6291\u5236\u6642\u8108\u6296\u52d5<\/strong>\uff1aI2S BCLK \u983b\u7387\u9054\u6578 MHz\uff0c\u675c\u90a6\u7dda\u8acb\u58d3\u5728 <strong>10 cm \u4ee5\u5167<\/strong>\uff0c\u907f\u514d\u9577\u7dda\u5929\u7dda\u6548\u61c9\u9020\u6210\u91d1\u5c6c\u7206\u97f3\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h2 id=\"undefined-1-1\" class=\"wp-block-heading\">\u958b\u767c\u74b0\u5883\u8207\u5efa\u7f6e\u5de5\u5177<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u6253\u9020 ESP32 A2DP \u5c08\u6848\uff0c\u5efa\u8b70\u63a1\u7528\u5b98\u65b9\u63a8\u85a6\u7684\u5de5\u5177\u93c8\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u6838\u5fc3\u6846\u67b6<\/strong>\uff1a<a href=\"https:\/\/saludpcb.com\/zh\/esp32-tutorial-how-to-create-an-esp32-project-with-vscode\/\">ESP-IDF v5.0 \u6216\u4ee5\u4e0a\u7248\u672c<\/a>\uff08\u5efa\u8b70\u4f7f\u7528 VSCode \u642d\u914d\u5b98\u65b9 <code>ESP-IDF Extension<\/code>\uff09\u3002<\/li>\n\n\n\n<li><strong>\u786c\u9ad4\u8a2d\u5099<\/strong>\uff1a\u6a19\u6e96 <strong>ESP32 \u958b\u767c\u677f<\/strong>\uff08\u96d9\u6838 WROOM-32 \u6216 WROVER\uff09\u53ca\u4e00\u689d\u9ad8\u54c1\u8cea Micro-USB \/ Type-C \u50b3\u8f38\u7dda\u3002<\/li>\n\n\n\n<li><strong>\u5efa\u7f6e\u8207\u71d2\u9304\u6307\u4ee4<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u8a2d\u5b9a\u76ee\u6a19\u6676\u7247\uff1a<code>idf.py set-target esp32<\/code><\/li>\n\n\n\n<li>\u7de8\u8b6f\u97cc\u9ad4\uff1a<code>idf.py build<\/code><\/li>\n\n\n\n<li>\u71d2\u9304\u4e26\u958b\u555f\u76e3\u63a7\u8996\u7a97\uff1a<code>idf.py -p (\u9023\u63a5\u57e0) flash monitor<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u7d44\u614b\u8a2d\u5b9a\uff08menuconfig\uff09<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u57f7\u884c <code>idf.py menuconfig<\/code>\uff0c\u9032\u5165 <code>Component config<\/code> \u2192 <code>Bluetooth<\/code> \u52fe\u9078\u555f\u7528 <strong>Bluedroid<\/strong> \u8207 <strong>Classic Bluetooth<\/strong>\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># Bluetooth &amp; Classic BT Configuration\nCONFIG_BT_ENABLED=y\nCONFIG_BT_BLUEDROID_ENABLED=y\nCONFIG_BT_CLASSIC_ENABLED=y\nCONFIG_BT_A2DP_ENABLE=y\nCONFIG_BT_AVRCP_CT_ENABLE=y\nCONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y\n\n# CPU Clock at 240MHz for SBC Decoding\nCONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y\nCONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240\n\n# Expand Partition Table for Bluedroid Stack\nCONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y<\/code><\/pre>\n\n\n\n<h2 id=\"\u5c08\u6848\u7d50\u69cb\" class=\"wp-block-heading\">\u5c08\u6848\u7d50\u69cb<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728 ESP-IDF \u67b6\u69cb\u4e0b\uff0c\u4e00\u500b\u6a19\u6e96\u4e14\u6a21\u7d44\u5316\u7684 <strong>ESP32 A2DP<\/strong> \u5c08\u6848\u7d50\u69cb\u5efa\u8b70\u5c07\u300c\u97f3\u8a0a\u7de9\u885d\u7ba1\u7dda\uff08I2S \/ RingBuffer\uff09\u300d\u8207\u300c\u85cd\u7259\u4e8b\u4ef6\u8655\u7406\uff08A2DP \/ AVRCP\uff09\u300d\u5206\u5c64\u89e3\u8026\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u6a19\u6e96\u7684 ESP-IDF \u5c08\u6848\u7d50\u69cb\u5982\u4e0b\uff0c\u5c07\u7cfb\u7d71\u521d\u59cb\u5316\u3001\u97f3\u8a0a\u786c\u9ad4\u9a45\u52d5\u8207\u85cd\u7259\u5354\u5b9a\u68e7\u8077\u8cac\u5206\u96e2\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">esp32_a2dp_sink\/\n\u251c\u2500\u2500 CMakeLists.txt               # \u5c08\u6848\u9802\u5c64\u5efa\u7f6e\u8a2d\u5b9a\n\u251c\u2500\u2500 sdkconfig.defaults          # \u7d93\u5178\u85cd\u7259\u8207\u6642\u8108\u9810\u8a2d\u53c3\u6578\n\u2514\u2500\u2500 main\/\n    \u251c\u2500\u2500 CMakeLists.txt          # \u4e3b\u5143\u4ef6\u8a3b\u518a\u8207\u4f9d\u8cf4\u9805\u8a2d\u5b9a\n    \u251c\u2500\u2500 main.c                  # \u7cfb\u7d71\u5165\u53e3\uff1aNVS \u521d\u59cb\u5316\u8207\u85cd\u7259\u555f\u52d5\n    \u251c\u2500\u2500 audio_pipeline.h \/ .c    # \u97f3\u8a0a\u7ba1\u7dda\uff1a\u786c\u9ad4 I2S DMA \u8207 RingBuffer \u4efb\u52d9\n    \u2514\u2500\u2500 bt_app_av.h \/ .c        # \u85cd\u7259\u4e8b\u4ef6\uff1aA2DP \u72c0\u614b\u6a5f\u8207 AVRCP \u6b4c\u66f2\u89e3\u6790<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6838\u5fc3\u6a21\u7d44\u8aaa\u660e\n<ul class=\"wp-block-list\">\n<li><strong><code>audio_pipeline.c \/ .h<\/code><\/strong>\uff1a\u5c01\u88dd <code>esp_driver_i2s<\/code> \u8207 FreeRTOS \u74b0\u5f62\u7de9\u885d\u5340\uff0c\u5c08\u9580\u8ca0\u8cac\u5c07 PCM \u97f3\u8a0a\u4ee5 DMA \u5beb\u5165\u5916\u90e8 DAC\uff0c\u5fb9\u5e95\u5c07\u786c\u9ad4\u64ad\u653e\u8207\u85cd\u7259\u89e3\u78bc\u4efb\u52d9\u89e3\u8026\u3002<\/li>\n\n\n\n<li><strong><code>bt_app_av.c \/ .h<\/code><\/strong>\uff1a\u8655\u7406 A2DP \u9023\u7dda\u72c0\u614b\u3001\u52d5\u614b\u89e3\u6790 SBC \u63a1\u6a23\u983b\u7387\uff0c\u4e26\u76e3\u807d AVRCP \u63db\u66f2\u8207\u6b4c\u540d\u4e2d\u7e7c\u8cc7\u6599\u3002<\/li>\n\n\n\n<li><strong><code>sdkconfig.defaults<\/code><\/strong>\uff1a\u5c07\u7d93\u5178\u85cd\u7259\u555f\u7528\u8a2d\u5b9a\u8207 240MHz \u6642\u8108\u56fa\u5316\uff0c\u907f\u514d\u57f7\u884c\u6e05\u7406\u5efa\u7f6e\uff08<code>idf.py fullclean<\/code>\uff09\u5f8c\u8a2d\u5b9a\u88ab\u8986\u84cb\u91cd\u7f6e\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h2 id=\"\u4e3b\u5143\u4ef6-main-c-make-lists-txt-\u8a2d\u5b9a\" class=\"wp-block-heading\">CMake \u8a2d\u5b9a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728 <code>main\/CMakeLists.txt<\/code> \u4e2d\u5fc5\u9808\u660e\u78ba\u5f15\u5165\u85cd\u7259\u5354\u5b9a\u68e7\uff08<code>bt<\/code>\uff09\u3001\u975e\u63ee\u767c\u6027\u5132\u5b58\uff08<code>nvs_flash<\/code>\uff09\u8207\u65b0\u7248 I2S \u9a45\u52d5\uff08<code>esp_driver_i2s<\/code>\uff09\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">idf_component_register(\n    SRCS \"main.c\" \"audio_pipeline.c\" \"bt_app_av.c\"\n    INCLUDE_DIRS \".\"\n    REQUIRES bt nvs_flash esp_driver_i2s\n)<\/code><\/pre>\n\n\n\n<h2 id=\"c\" class=\"wp-block-heading\">\u7a0b\u5f0f\u78bc<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u97f3\u8a0a\u7ba1\u7dda\u8207 RingBuffer\uff08<code>main\/audio_pipeline.c<\/code>\uff09<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#<strong>include<\/strong> \"freertos\/FreeRTOS.h\"\n#<strong>include<\/strong> \"freertos\/task.h\"\n#<strong>include<\/strong> \"freertos\/ringbuf.h\"\n#<strong>include<\/strong> \"driver\/i2s_std.h\"\n#<strong>include<\/strong> \"esp_log.h\"\n\n#<strong>define<\/strong> I2S_BCLK_PIN    GPIO_NUM_26\n#<strong>define<\/strong> I2S_LRCK_PIN    GPIO_NUM_25\n#<strong>define<\/strong> I2S_DOUT_PIN    GPIO_NUM_22\n#<strong>define<\/strong> RINGBUF_SIZE    (1024 * 32) \/\/ 32KB \u7de9\u885d\u9632\u6b62\u7206\u97f3\n\nstatic const char *TAG = \"AUDIO_PIPE\";\nstatic i2s_chan_handle_t s_tx_handle = NULL;\nstatic RingbufHandle_t s_ringbuf = NULL;\n\n\/\/ \u7368\u7acb\u7684 FreeRTOS \u64ad\u653e\u4efb\u52d9\uff08\u6d88\u8cbb\u8005\uff09\nstatic void i2s_writer_task(void *arg) {\n    size_t item_size = 0;\n    while (1) {\n        uint8_t *data = (uint8_t *)xRingbufferReceive(s_ringbuf, &amp;item_size, portMAX_DELAY);\n        if (data != NULL) {\n            size_t bytes_written = 0;\n            i2s_channel_write(s_tx_handle, data, item_size, &amp;bytes_written, portMAX_DELAY);\n            vRingbufferReturnItem(s_ringbuf, (void *)data);\n        }\n    }\n}\n\n\/\/ \u4f9b\u85cd\u7259\u56de\u547c\u5beb\u5165\u7684\u975e\u963b\u585e\u51fd\u5f0f\uff08\u751f\u7522\u8005\uff0ctimeout = 0\uff09\nsize_t audio_pipeline_write(const uint8_t *data, size_t size) {\n    if (!s_ringbuf) return 0;\n    BaseType_t res = xRingbufferSend(s_ringbuf, data, size, 0);\n    return (res == pdTRUE) ? size : 0;\n}\n\n\/\/ \u52d5\u614b\u5207\u63db\u63a1\u6a23\u983b\u7387\uff08\u652f\u63f4 44.1kHz \u8207 48kHz\uff09\nesp_err_t audio_pipeline_set_sample_rate(uint32_t rate) {\n    ESP_LOGI(TAG, \"\u52d5\u614b\u8a2d\u5b9a\u786c\u9ad4\u63a1\u6a23\u7387: %lu Hz\", rate);\n    i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(rate);\n    return i2s_channel_reconfig_std_clock(s_tx_handle, &amp;clk_cfg);\n}\n\n\/\/ \u521d\u59cb\u5316 I2S \u8207 RingBuffer\nesp_err_t audio_pipeline_init(void) {\n    s_ringbuf = xRingbufferCreate(RINGBUF_SIZE, RINGBUF_TYPE_BYTEBUF);\n    if (!s_ringbuf) return ESP_ERR_NO_MEM;\n\n    i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);\n    chan_cfg.dma_desc_num = 8;\n    chan_cfg.dma_frame_num = 256;\n    chan_cfg.auto_clear = true;\n    ESP_ERROR_CHECK(i2s_new_channel(&amp;chan_cfg, &amp;s_tx_handle, NULL));\n\n    i2s_std_config_t std_cfg = {\n        .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(44100),\n        .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),\n        .gpio_cfg = {\n            .mclk = I2S_GPIO_UNUSED,\n            .bclk = I2S_BCLK_PIN,\n            .ws = I2S_LRCK_PIN,\n            .dout = I2S_DOUT_PIN,\n            .din = I2S_GPIO_UNUSED,\n            .invert_flags = {0},\n        },\n    };\n\n    ESP_ERROR_CHECK(i2s_channel_init_std_mode(s_tx_handle, &amp;std_cfg));\n    ESP_ERROR_CHECK(i2s_channel_enable(s_tx_handle));\n\n    \/\/ \u5efa\u7acb\u7368\u7acb\u64ad\u653e\u4efb\u52d9\u4e26\u56fa\u5b9a\u5728 Core 1\n    xTaskCreatePinnedToCore(i2s_writer_task, \"i2s_writer\", 4096, NULL, 5, NULL, 1);\n    return ESP_OK;\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A2DP \u72c0\u614b\u6a5f\u8207 SBC \u63a1\u6a23\u7387\u89e3\u6790\uff08<code>main\/bt_app_av.c<\/code>\uff09<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#<strong>include<\/strong> \"esp_log.h\"\n#<strong>include<\/strong> \"esp_a2dp_api.h\"\n#<strong>include<\/strong> \"esp_avrc_api.h\"\n\nstatic const char *TAG = \"BT_A2DP\";\n\nextern size_t audio_pipeline_write(const uint8_t *data, size_t size);\nextern esp_err_t audio_pipeline_set_sample_rate(uint32_t rate);\n\n\/\/ A2DP \u97f3\u8a0a\u8cc7\u6599\u63a5\u6536\u56de\u547c\uff08BTC \u57f7\u884c\u7dd2\uff09\nvoid bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) {\n    audio_pipeline_write(data, len);\n}\n\n\/\/ A2DP \u4e8b\u4ef6\u56de\u547c\uff08\u72c0\u614b\u6a5f\uff09\nvoid bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) {\n    switch (event) {\n    case ESP_A2D_CONNECTION_STATE_EVT:\n        if (param-&gt;conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) {\n            ESP_LOGI(TAG, \"\u624b\u6a5f\u5df2\u6210\u529f\u9023\u7dda\uff01\");\n        } else if (param-&gt;conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {\n            ESP_LOGI(TAG, \"\u624b\u6a5f\u4e2d\u65b7\u9023\u7dda\u3002\");\n        }\n        break;\n\n    \/\/ \u52d5\u614b\u89e3\u6790 SBC \u63a1\u6a23\u7387\uff0c\u907f\u514d\u97f3\u983b\u8dd1\u901f\n    case ESP_A2D_AUDIO_CFG_EVT: {\n        esp_a2d_cb_param_t *a2d = (esp_a2d_cb_param_t *)(param);\n        if (a2d-&gt;audio_cfg.mcc.type == ESP_A2D_MCT_SBC) {\n            int sample_rate = 16000;\n            char oct0 = a2d-&gt;audio_cfg.mcc.cie.sbc[0];\n            if (oct0 &amp; (0x01 &lt;&lt; 6)) sample_rate = 32000;\n            else if (oct0 &amp; (0x01 &lt;&lt; 5)) sample_rate = 44100;\n            else if (oct0 &amp; (0x01 &lt;&lt; 4)) sample_rate = 48000;\n\n            ESP_LOGI(TAG, \"\u5354\u5546\u5b8c\u6210\uff0c\u52d5\u614b\u8a2d\u5b9a I2S \u63a1\u6a23\u7387\u70ba: %d Hz\", sample_rate);\n            audio_pipeline_set_sample_rate(sample_rate);\n        }\n        break;\n    }\n    default:\n        break;\n    }\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7cfb\u7d71\u5165\u53e3\u555f\u52d5\uff08<code>main\/main.c<\/code>\uff09<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#<strong>include<\/strong> \"nvs_flash.h\"\n#<strong>include<\/strong> \"esp_log.h\"\n#<strong>include<\/strong> \"esp_bt.h\"\n#<strong>include<\/strong> \"esp_bt_main.h\"\n#<strong>include<\/strong> \"esp_bt_device.h\"\n#<strong>include<\/strong> \"esp_gap_bt_api.h\"\n#<strong>include<\/strong> \"esp_a2dp_api.h\"\n\n#<strong>define<\/strong> BT_DEVICE_NAME \"SaludPCB-HiFi-Sink\"\n\nextern esp_err_t audio_pipeline_init(void);\nextern void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);\nextern void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len);\n\nvoid app_main(void) {\n    \/\/ 1. \u521d\u59cb\u5316 NVS\n    esp_err_t ret = nvs_flash_init();\n    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {\n        ESP_ERROR_CHECK(nvs_flash_erase());\n        ret = nvs_flash_init();\n    }\n    ESP_ERROR_CHECK(ret);\n\n    \/\/ 2. \u555f\u52d5 I2S \u8207 RingBuffer \u97f3\u8a0a\u7ba1\u7dda\n    ESP_ERROR_CHECK(audio_pipeline_init());\n\n    \/\/ 3. \u91cb\u653e BLE \u8a18\u61b6\u9ad4\uff0c\u53ea\u555f\u7528 Classic BT\n    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE));\n\n    \/\/ 4. \u555f\u52d5\u85cd\u7259\u63a7\u5236\u5668\u8207 Bluedroid \u5354\u5b9a\u68e7\n    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();\n    ESP_ERROR_CHECK(esp_bt_controller_init(&amp;bt_cfg));\n    ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT));\n    ESP_ERROR_CHECK(esp_bluedroid_init());\n    ESP_ERROR_CHECK(esp_bluedroid_enable());\n\n    \/\/ 5. \u8a2d\u5b9a\u5ee3\u64ad\u540d\u7a31\u4e26\u8a3b\u518a A2DP Sink\n    esp_bt_dev_set_device_name(BT_DEVICE_NAME);\n    ESP_ERROR_CHECK(esp_a2d_register_callback(bt_app_a2d_cb));\n    ESP_ERROR_CHECK(esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb));\n    ESP_ERROR_CHECK(esp_a2d_sink_init());\n\n    \/\/ 6. \u958b\u555f\u53ef\u88ab\u641c\u5c0b\u9023\u7dda\u6a21\u5f0f\n    esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);\n    ESP_LOGI(\"MAIN\", \"ESP32 A2DP Sink \u5df2\u555f\u52d5\uff0c\u5ee3\u64ad\u540d\u7a31: %s\", BT_DEVICE_NAME);\n}<\/code><\/pre>\n\n\n\n<h2 id=\"y\" class=\"wp-block-heading\">\u71d2\u9304\u548c\u8f38\u51fa<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u97cc\u9ad4\u7de8\u8b6f\u8207\u71d2\u9304\u6307\u4ee4<br>\u78ba\u8a8d\u786c\u9ad4\u9023\u63a5\u81f3\u96fb\u8166\u5f8c\uff0c\u57f7\u884c\u4e00\u9375\u7de8\u8b6f\u3001\u71d2\u9304\u4e26\u958b\u555f\u5e8f\u5217\u57e0\u76e3\u63a7\u8996\u7a97\uff1a<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># \u71d2\u9304\u4e26\u555f\u52d5 Monitor \u76e3\u807d\uff08\u9023\u63a5\u57e0\u8acb\u4f9d\u7cfb\u7d71\u6539\u70ba COMx \u6216 \/dev\/ttyUSB0\uff09\nidf.py -p \/dev\/ttyUSB0 flash monitor<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7d42\u7aef\u6a5f\u9810\u671f\u958b\u6a5f\u8207\u9023\u7dda Log<br>\u7cfb\u7d71\u555f\u52d5\u5f8c\uff0c\u4f9d\u5e8f\u5b8c\u6210 NVS\u3001I2S DMA \u8207\u85cd\u7259\u5354\u8b70\u68e7\u521d\u59cb\u5316\uff1b\u7576\u624b\u6a5f\u914d\u5c0d\u4e26\u958b\u59cb\u64ad\u653e\u97f3\u6a02\u6642\uff0c\u76e3\u63a7\u8996\u7a97\u6703\u8f38\u51fa\u5982\u4e0b\u65e5\u8a8c\uff1a<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">I (1120) MAIN: \u7cfb\u7d71\u521d\u59cb\u5316\u5b8c\u6210\uff0c\u555f\u52d5 I2S \u97f3\u8a0a\u7ba1\u7dda...\nI (1150) I2S_PIPELINE: I2S DMA \u901a\u9053\u5df2\u5efa\u7acb (44.1kHz, 16-bit, \u7acb\u9ad4\u8072)\nI (1380) MAIN: ESP32 A2DP Sink \u5df2\u555f\u52d5\uff0c\u5ee3\u64ad\u540d\u7a31: SaludPCB-HiFi-Sink\nI (8420) BT_A2DP: \u624b\u6a5f\u5df2\u6210\u529f\u9023\u7dda\uff01\nI (8510) BT_A2DP: \u5354\u5546\u5b8c\u6210\uff0c\u52d5\u614b\u8a2d\u5b9a I2S \u63a1\u6a23\u7387\u70ba: 44100 Hz\nI (9100) BT_A2DP: \u97f3\u8a0a\u4e32\u6d41\u64ad\u653e\u4e2d...<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5be6\u6a5f\u6e2c\u8a66\u8207\u9a57\u8b49\u8981\u9ede\n<ul class=\"wp-block-list\">\n<li><strong>\u85cd\u7259\u641c\u5c0b\u8207\u914d\u5c0d<\/strong>\uff1a\u958b\u555f\u624b\u6a5f\u85cd\u7259\u8a2d\u5b9a\uff0c\u641c\u5c0b\u4e26\u9ede\u64ca <strong><code>SaludPCB-HiFi-Sink<\/code><\/strong> \u5373\u53ef\u76f4\u63a5\u9023\u7dda\uff0c\u7121\u9808 PIN \u78bc\u3002<\/li>\n\n\n\n<li><strong>\u52d5\u614b\u983b\u7387\u9a57\u8b49<\/strong>\uff1a\u5207\u63db\u4e0d\u540c\u4f86\u6e90\u7684\u97f3\u6a02\uff08\u5982 44.1kHz CD \u97f3\u6e90 vs 48kHz \u8996\u8a0a\u97f3\u8a0a\uff09\uff0c\u6aa2\u67e5\u7d42\u7aef\u6a5f\u662f\u5426\u5373\u6642\u5370\u51fa\u53d6\u6a23\u7387\u91cd\u914d\u8a0a\u606f\uff0c\u78ba\u8a8d\u8072\u97f3\u901f\u5ea6\u6b63\u5e38\u4e14\u7121\u8b8a\u8abf\u3002<\/li>\n\n\n\n<li><strong>\u97f3\u8cea\u8207\u7de9\u885d\u6aa2\u9a57<\/strong>\uff1a\u5c07\u624b\u6a5f\u97f3\u91cf\u8abf\u81f3\u6700\u5927\uff0c\u78ba\u8a8d\u8033\u6a5f\u5728\u7121\u64ad\u653e\u6642\u7121\u5c04\u983b\u5e95\u566a\uff0c\u64ad\u653e\u9ad8\u52d5\u614b\u97f3\u6a02\u6642\u4ea6\u7121\u91d1\u5c6c\u65b7\u88c2\u8072\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h2 id=\"\u7d50\u8ad6\" class=\"wp-block-heading\">\u7d50\u8ad6<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u900f\u904e <a href=\"https:\/\/docs.espressif.com\/projects\/esp-idf\/en\/stable\/esp32\/api-reference\/bluetooth\/index.html\" target=\"_blank\" rel=\"noopener\">ESP-IDF<\/a> \u539f\u751f\u7684 <code>esp_a2dp<\/code> \u8207 <code>driver\/i2s_std<\/code> \u9a45\u52d5\uff0c\u7d50\u5408 FreeRTOS \u74b0\u5f62\u7de9\u885d\u5340\u67b6\u69cb\uff0c\u80fd\u5920\u5145\u5206\u767c\u63ee ESP32 \u786c\u9ad4\u96d9\u6838\u8207 DMA \u96f6\u62f7\u8c9d\u7684\u6548\u80fd\u512a\u52e2\u3002\u9019\u5957\u67b6\u69cb\u4e0d\u50c5\u7a69\u5b9a\u8010\u7528\uff0c\u9084\u80fd\u96a8\u6642\u52a0\u5165 I2C OLED \u87a2\u5e55\u986f\u793a\u3001\u786c\u9ad4\u97f3\u91cf\u7de8\u78bc\u5668\u3001\u6216\u662f FreeRTOS \u8edf\u9ad4 EQ \u7b49\u5316\u5668\u6f14\u7b97\u6cd5\uff0c\u662f\u9081\u5411\u5546\u7528\u97f3\u8a0a\u7522\u54c1\u958b\u767c\u7684\u6a19\u6e96\u6838\u5fc3\u9aa8\u5e79\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator alignwide has-text-color has-palette-color-1-color has-alpha-channel-opacity has-palette-color-1-background-color has-background is-style-wide\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ESP32 A2DP \u662f\u76ee\u524d\u4ee5\u6975\u4f4e\u786c\u9ad4\u6210\u672c\u6253\u9020\u9ad8\u54c1\u8cea\u7121\u7dda\u97f3\u8a0a\u63a5\u6536\u7aef\uff08Audio Sink\uff09\u7684\u6700\u4f73\u67b6\u69cb\u65b9\u6848\u3002\u5e02\u9762 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4347,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,19,53,83],"tags":[27,21,44,9,11],"class_list":["post-4335","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-module","category-arduino","category-esp32","category-featured","tag-c","tag-ide","tag-programming-language","tag-python","tag-tutorial"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":8}},"_links":{"self":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts\/4335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/comments?post=4335"}],"version-history":[{"count":16,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts\/4335\/revisions"}],"predecessor-version":[{"id":4357,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts\/4335\/revisions\/4357"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/media\/4347"}],"wp:attachment":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/media?parent=4335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/categories?post=4335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/tags?post=4335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}