{"id":4726,"date":"2019-06-25T20:13:40","date_gmt":"2019-06-26T03:13:40","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=4726"},"modified":"2019-06-25T20:14:30","modified_gmt":"2019-06-26T03:14:30","slug":"using-the-esp32-camera-interface-from-arduino-projects","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/esp32\/camera\/","title":{"rendered":"Using the ESP32 Camera Interface from Arduino-based Projects"},"content":{"rendered":"<p>This tutorial shows how to create a basic project for the <a href=\"https:\/\/www.seeedstudio.com\/ESP32-CAM-Development-Board-with-camer-p-3153.html\">ESP32-CAM<\/a> module and use the JTAG interface to debug it.<\/p>\n<p>We will use VisualGDB to clone the ESP32 Arduino Camera example and then modify it to automatically take pictures in a loop and upload them via HTTP to a specified server. Before you begin, ensure you have installed Visual Studio and VisualGDB 5.4.<\/p>\n<h1>Wiring<\/h1>\n<p>In order to get JTAG debugging to work, we would need to connect the following pins of the ESP32-CAM module to a compatible JTAG debugger (e.g. Olimex ARM-USB-OCD-H or Segger J-Link):<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"width: 33.3333%;\">ESP-CAM Pin<\/td>\n<td style=\"width: 33.3333%;\">JTAG signal<\/td>\n<td style=\"width: 33.3333%;\">JTAG20 pin<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">3.3V<\/td>\n<td style=\"width: 33.3333%;\">+3.3V<\/td>\n<td style=\"width: 33.3333%;\">1<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">GND<\/td>\n<td style=\"width: 33.3333%;\">GND<\/td>\n<td style=\"width: 33.3333%;\">4<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">GPIO12<\/td>\n<td style=\"width: 33.3333%;\">TDI<\/td>\n<td style=\"width: 33.3333%;\">5<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">GPIO14<\/td>\n<td style=\"width: 33.3333%;\">TMS<\/td>\n<td style=\"width: 33.3333%;\">7<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">GPIO13<\/td>\n<td style=\"width: 33.3333%;\">TCK<\/td>\n<td style=\"width: 33.3333%;\">9<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">GPIO15<\/td>\n<td style=\"width: 33.3333%;\">TDO<\/td>\n<td style=\"width: 33.3333%;\">13<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>See the picture below for details (courtesy of Seeed Studio):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/esp32-cam.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4727\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/esp32-cam.jpg\" alt=\"\" width=\"424\" height=\"236\" \/><\/a>As the ESP32-CAM board does not come with a USB connector, you would need to use an external 5V power source. In this tutorial we will use a Nucleo board from ST Microelectronics as a 5V source and will also use its 3.3V UART interface provided by the on-board ST-Link to receive the text output from the ESP32-CAM module. If you are using the Nucleo board, remove the JP5 jumper (powering the STM32 microcontroler on the board) and connect the GND, +5V and RX signals to the ESP32-CAM module as shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/nucleo-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4729\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/nucleo-1.jpg\" alt=\"\" width=\"1400\" height=\"1016\" \/><\/a><\/p>\n<p>Note that due to the limitations of the ST-Link programmer, you won&#8217;t be able to use it to debug the ESP32 device and hence will need a low-level debug probe.<\/p>\n<p>The final wiring setup used in this tutorial is shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/wiring.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4730\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/wiring.jpg\" alt=\"\" width=\"1280\" height=\"1364\" \/><\/a>Note that the ST Nucleo board is used to provide the 5V signal and the Olimex ARM-USB-OCD-H debugger is used for the actual JTAG debugging.<\/p>\n<h1>Software Setup<\/h1>\n<p>Now that we are done with the wiring, we can start with the software configuration necessary to debug the ESP32-CAM board. Follow the steps below to create a basic project, step through it and modify it to automatically upload the taken pictures:<\/p>\n<ol>\n<li>The best ready-to-use ESP32 camera example is included in the ESP32 Arduino package, so we will use the Arduino workflow in this tutorial. As long as you are using VisualGDB 5.4 or later, it will automatically install the necessary tools and packages for you as you create the project. Hence start Visual Studio and open the VisualGDB Arduino Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-newprj-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4731\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/01-newprj-3.png\" alt=\"\" width=\"907\" height=\"557\" \/><\/a><\/li>\n<li>As we will be starting with an existing camera example, select &#8220;Clone one of the sample sketches from Arduino platform&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/02-clone.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4732\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/02-clone.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>The ESP32 Arduino platform does not have a special target for the ESP32-CAM module, however it is compatible with the ESP32 Wrover module. Simply select it from the list:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/03-get-esp32.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4733\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/03-get-esp32.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>If you have not created ESP32 Arduino projects before, click &#8220;Install&#8221; and VisualGDB will automatically download and install the necessary packages:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/04-wrover.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4734\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/04-wrover.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>In this tutorial we will clone the CameraWebServer sample provided by Espressif, so simply select it from the list:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/05-camera.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4735\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/05-camera.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Connect your JTAG debugger via USB and select it on the Debug Method page. Then click &#8220;Test&#8221; to verify the wiring:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/06-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4736\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/06-debug.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>OpenOCD should confirm that it&#8217;s able to communicate to the ESP32 chip:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/07-test.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4737\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/07-test.png\" alt=\"\" width=\"786\" height=\"593\" \/><\/a>Once the wiring is verified, press &#8220;Finish&#8221; to create the project.<\/li>\n<li>Before you can build the project, comment out the CAMERA_MODEL_WROVER_KIT definition and uncomment the CAMERA_MODEL_AI_THINKER line to enable the pinout specific to the board you are using: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/08-thinker.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4738\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/08-thinker.png\" alt=\"\" width=\"1308\" height=\"773\" \/><\/a><\/li>\n<li>If you try building the project now, the Arduino tools will fail stating that the sketch is too big:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/09-toobig.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4739\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/09-toobig.png\" alt=\"\" width=\"1308\" height=\"773\" \/><\/a><\/li>\n<li>This happens because the default partition configuration is too small to fit the camera example. Open VisualGDB Project Properties and change the Partition Scheme to Huge APP:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/10-partition.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4740\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/10-partition.png\" alt=\"\" width=\"901\" height=\"534\" \/><\/a>If you have connected the serial output of the ESP32-CAM module to the ST Nucleo board (or another UART-to-USB adapter), select its COM port in the &#8220;COM port for uploading the sketch&#8221; field. If not, leave the field empty. As ESP32 projects are programmed via JTAG, the COM port is not actually necessary, although it&#8217;s useful for viewing the diagnostic output.<\/li>\n<li>If you have connected the serial port, go to the Arduino Serial Terminal page of VisualGDB Project Properties and check the &#8220;Open a raw terminal&#8221; checkbox:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/11-terminal.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4741\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/11-terminal.png\" alt=\"\" width=\"901\" height=\"534\" \/><\/a><\/li>\n<li>Finally, set the <strong>ssid<\/strong> and <strong>password<\/strong> variables at the beginning of the sketch to match your network configuration. Then press Ctrl-Shift-B to build the project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/12-build.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4742\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/12-build.png\" alt=\"\" width=\"1308\" height=\"773\" \/><\/a><\/li>\n<li>Start debugging by pressing F5. VisualGDB will automatically program the FLASH memory and start the program. If you have connected the serial output of the module, you will see the IP address of the camera displayed there:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/13-connected.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4743\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/13-connected.png\" alt=\"\" width=\"1308\" height=\"773\" \/><\/a>If you are not using a serial port, set a breakpoint inside the <strong>WiFiSTAClass::localIP()<\/strong> function before starting the debugger and then evaluate the &#8220;ip&#8221; expression to check the IP address assigned to the board.<\/li>\n<li>Go to the IP address of the board in your browser. You will see a basic web interface provided by the Arduino sample that lets you set various parameters and take pictures:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/14-picture.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4744\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/14-picture.jpg\" alt=\"\" width=\"1257\" height=\"967\" \/><\/a><\/li>\n<li>Now we will use the code navigation functions of VisulaGDB and the debugger to understand the components involved in taking the pictures and sending them to the browser. First of all, go to the definition of the <strong>startCameraServer()<\/strong> function: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/15-server.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4745\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/15-server.png\" alt=\"\" width=\"1201\" height=\"796\" \/><\/a><\/li>\n<li>The <strong>startCameraServer()<\/strong> function defines several handlers for various pages of the built-in web server. Opening the &#8220;\/capture&#8221; page results in capturing one frame from the camera and outputting it via HTTP. Select the <strong>capture_handler<\/strong> function and click &#8220;Go to definition&#8221; to view its source: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/16-capture.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4746\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/16-capture.png\" alt=\"\" width=\"1201\" height=\"796\" \/><\/a><\/li>\n<li>Set a breakpoint inside the <strong>capture_handler()<\/strong> function and try capturing a single frame from the browser. The breakpoint will trigger, allowing you to check the captured frame parameters:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/17-bkpt-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4747\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/17-bkpt-1.png\" alt=\"\" width=\"1201\" height=\"796\" \/><\/a><\/li>\n<li>You can use the Memory window to verify that the <strong>bb-&gt;buf<\/strong> buffer contains a properly encoded JPEG image (see the JFIF signature):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/18-data.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4748\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/18-data.png\" alt=\"\" width=\"1201\" height=\"796\" \/><\/a>From the code of the <strong>capture_handler()<\/strong> function we can reconstruct the steps involved in capturing pictures from the camera:\n<ul>\n<li><strong>esp_camera_fb_get()<\/strong> is used to get a single picture.<\/li>\n<li><strong>esp_camera_fb_return()<\/strong> must be used to free the memory allocated by <strong>esp_camera_fb_get().<\/strong><\/li>\n<li>The format of the captured picture will be stored in the <strong>format<\/strong> field of the structure returned by <strong>esp_camera_fb_get().<\/strong><\/li>\n<li>The actual data will be stored in a buffer pointed by the <strong>buf<\/strong> field.<\/li>\n<\/ul>\n<\/li>\n<li>We will now the example to automatically capture frames as fast as possible and upload them to an external server via HTTP. First of all, edit the <strong>setup()<\/strong> function to automatically set the frame size and quality and comment out the call to <strong>startCameraServer()<\/strong>:\n<pre class=\"\">\ts-&gt;set_framesize(s, FRAMESIZE_SXGA);\r\n\ts-&gt;set_quality(s, 20);<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/19-quality.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4749\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/19-quality.png\" alt=\"\" width=\"1201\" height=\"796\" \/><\/a><\/li>\n<li>Then include the <strong>&lt;esp_http_client.h&gt;<\/strong> file and replace the<strong> loop()<\/strong> function with the following code:\n<pre class=\"\">void loop()\r\n{\r\n\tcamera_fb_t *fb = NULL;\r\n\tesp_err_t res = ESP_OK;\r\n\tfb = esp_camera_fb_get();\r\n\tif (!fb)\r\n\t{\r\n\t\tSerial.println(\"Camera capture failed\");\r\n\t\tesp_camera_fb_return(fb);\r\n\t\treturn;\r\n\t}\r\n\r\n        size_t fb_len = 0;\r\n\tif (fb-&gt;format != PIXFORMAT_JPEG)\r\n\t{\r\n\t\tSerial.println(\"Non-JPEG data not implemented\");\r\n\t\treturn;\r\n\t}\r\n\r\n\tesp_http_client_config_t config = {\r\n\t\t.url = \"http:\/\/192.168.0.3:8888\/upload\",\r\n\t};\r\n\r\n\tesp_http_client_handle_t client = esp_http_client_init(&amp;config);\r\n\tesp_http_client_set_post_field(client, (const char *)fb-&gt;buf, fb-&gt;len);\r\n\tesp_http_client_set_method(client, HTTP_METHOD_POST);\r\n\tesp_http_client_set_header(client, \"Content-type\", \"application\/octet-stream\");\r\n\tesp_err_t err = esp_http_client_perform(client);\r\n\tif (err == ESP_OK)\r\n\t\tSerial.println(\"Frame uploaded\");\r\n\telse\r\n\t\tSerial.printf(\"Failed to upload frame, error %d\\r\\n\", err);\r\n\r\n\tesp_http_client_cleanup(client);\r\n\r\n\tesp_camera_fb_return(fb);\r\n}<\/pre>\n<p>Also replace <strong>192.168.0.3<\/strong> with the address of your Windows machine.<\/li>\n<li>Now we will create a very basic Web server that will display the pictures received from the ESP32-CAM module. Create a new C# WPF Application in Visual Studio and replace the contents of the Window element in the XAML file with the following code:\n<pre class=\"\">    &lt;Grid&gt;\r\n        &lt;Image x:Name=\"img\"\/&gt;\r\n    &lt;\/Grid&gt;<\/pre>\n<p>Then add the following code to the MainWindow.cs file:<\/p>\n<pre class=\"\">\u00a0   public partial class MainWindow : Window\r\n    {\r\n        HttpListener _Listener = new HttpListener();\r\n\r\n        public MainWindow()\r\n        {\r\n            _Listener.Prefixes.Add(\"http:\/\/192.168.0.3:8888\/\");\r\n            _Listener.Start();\r\n            InitializeComponent();\r\n            new Thread(ThreadBody).Start();\r\n        }\r\n\r\n        void ThreadBody()\r\n        {\r\n            for (; ;)\r\n            { \r\n                HttpListenerContext context = _Listener.GetContext();\r\n                byte[] receivedData = new byte[(int)context.Request.ContentLength64];\r\n                int done = 0;\r\n                for (; ; )\r\n                {\r\n                    int read = context.Request.InputStream.Read(receivedData, done, receivedData.Length - done);\r\n                    if (read &lt;= 0)\r\n                        break;\r\n                    done += read;\r\n                }\r\n\r\n                byte[] reply = System.Text.Encoding.UTF8.GetBytes(\"Done\");\r\n                context.Response.ContentLength64 = reply.Length;\r\n                context.Response.OutputStream.Write(reply, 0, reply.Length);\r\n                context.Response.OutputStream.Close();\r\n\r\n                Dispatcher.BeginInvoke(new Action(() =&gt;\r\n                {\r\n                    var imageSource = new BitmapImage();\r\n                    imageSource.BeginInit();\r\n                    imageSource.StreamSource = new MemoryStream(receivedData);\r\n                    imageSource.EndInit();\r\n                    img.Source = imageSource;\r\n                }));\r\n            }\r\n        }\r\n    }<\/pre>\n<p>Don&#8217;t forget to update the IP address inside the MainWindow.cs file and temporarily disable your firewall (or add port 8888 to exceptions).<\/li>\n<li>Build and start the C# web server and run the modified Arduino sketch on the ESP32-CAM module. As soon as the board starts up, the web server will begin displaying the pictures it receives from the ESP32 camera:\u00a0 <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/20-server.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4750\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/06\/20-server.jpg\" alt=\"\" width=\"894\" height=\"651\" \/><\/a><\/li>\n<\/ol>\n<p>You can modify the URL used in the Arduino sketch to upload the taken pictures into the cloud, or to any other location accessible to the board. You can limit the frame rate of this example bycalling the <strong>delay()<\/strong> function before exiting from <strong>loop()<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to create a basic project for the ESP32-CAM module and use the JTAG interface to debug<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[142],"tags":[103,138,56,143],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4726"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=4726"}],"version-history":[{"count":4,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4726\/revisions"}],"predecessor-version":[{"id":5010,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4726\/revisions\/5010"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=4726"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=4726"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=4726"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}