{"id":4347,"date":"2018-11-14T20:00:00","date_gmt":"2018-11-14T19:00:00","guid":{"rendered":"https:\/\/msalamon.pl\/?p=4347"},"modified":"2025-12-27T20:07:25","modified_gmt":"2025-12-27T19:07:25","slug":"addressable-ws2812b-leds-on-stm32-part-2","status":"publish","type":"post","link":"https:\/\/msalamon.pl\/en\/addressable-ws2812b-leds-on-stm32-part-2\/","title":{"rendered":"Addressable WS2812B LEDs on STM32, Part 2"},"content":{"rendered":"\n<p>Recently I wrote about <a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-1\/\">how to drive WS2812B LEDs with STM32<\/a>. However, control alone is not enough to fully enjoy the possibilities offered by entire strips of these LEDs. Today I will present a library containing a range of interesting lighting effects. Let\u2019s get to work!<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>This article is part of the series:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-1\/\">Part 1<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-2\/\">Part 2<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-3\/\">Part 3<\/a><\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/kategoria-produktu\/dev-boardy\/stm32-nucleo\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=ws2812b&amp;utm_content=nucleo\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg\" alt=\"\" class=\"wp-image-1593\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-768x256.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Arduino libraries and STM32<\/h1>\n\n\n\n<p>There is one thing I like about Arduino. It\u2019s the abundance of ready-made libraries written for this platform. Sometimes they\u2019re written better, sometimes worse, but for the general idea of how to approach problems, I think they\u2019re good. It\u2019s no different with addressable LEDs and lighting effects for them. There is a neat WS2812FX library on GitHub written by user kitesurfer1404 (<a href=\"https:\/\/github.com\/kitesurfer1404\/WS2812FX\" target=\"_blank\" rel=\"noopener\">link<\/a>), which contains lots of interesting animations for our LEDs. Unfortunately, it\u2019s written in Arduino C++, so I decided to port a significant portion of it for STM32 and my HAL-based WS2812B library.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">HSV color space model<\/h2>\n\n\n\n<p>The WS2812FX library is entirely based on the RGB color space, where you provide the values of the red, green, and blue components. A very interesting alternative to RGB is the HSV space. It corresponds to how our eye perceives colors. The components of this model are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>H (hue) \u2013 the shade of light, i.e., the color. Takes values in degrees on the color wheel from 0 to 359.<\/li>\n\n\n\n<li>S (saturation) \u2013 color saturation. How much color is in the emitted light.<\/li>\n\n\n\n<li>V (value, brightness) \u2013 the intensity of white light.<\/li>\n<\/ul>\n\n\n\n<p>By default, S and V are fractions and lie in the range between 0 and 1. For microcontroller needs, I wrote conversion functions both ways (RGB-&gt;HSV and HSV-&gt;RGB) using the 0 \u2013 255 range for these components and, of course, 0-359 for the H component. It\u2019s a shame to waste clock cycles on floats when there can really be a lot of these operations \ud83d\ude09 After all, not every MCU has an FPU.<\/p>\n\n\n\n<p>The HSV model looks as follows graphically.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/HSV_cone.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"225\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/HSV_cone-300x225.jpg\" alt=\"\" class=\"wp-image-416\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/HSV_cone-300x225.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/HSV_cone-24x18.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/HSV_cone-36x27.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/HSV_cone-107x80.jpg 107w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/11\/HSV_cone.jpg 640w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The figure helps visualize how modifying individual components affects the resulting color. H is, of course, the base color. Turning the S component smoothly transitions the color toward white light. Turning V dims the color toward black. You can get interesting transition or pulsing effects from this.<\/p>\n\n\n\n<p>I added these two effects myself while porting the library. They are, respectively, a transition from white or black toward the user-set color. The duration of the entire transition&nbsp; (expressed in milliseconds) color-&gt;white-&gt;color is defined via the speed-setting function. I\u2019m mentioning this because for the remaining effects the <em>speed<\/em> value is interpreted differently and defines the time between successive steps in the effect (also in milliseconds).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the library works<\/h2>\n\n\n\n<p>The ported library operates on a software timer, which is decremented in the <em>SysTick timer<\/em> interrupt. When the <em>timer<\/em> reaches zero, the <em>WS2812BFX_Callback()<\/em> function calls the previously selected effects mode. There, the next step is performed to update the values of the LEDs in the strip and to set the software <em>timer<\/em>, the previously defined time until the next step. A simple example looks like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">WS2812B_Init(&amp;amp;hspi1);\nWS2812BFX_SetSpeed(5000);\nWS2812BFX_SetColorRGB(0, 0,255,0);\nWS2812BFX_SetColorRGB(1, 32,0,0);\nWS2812BFX_SetColorRGB(2, 0,64,0);\nWS2812BFX_SetMode(FX_MODE_WHITE_TO_COLOR);\nWS2812BFX_Start();\n\n\/* USER CODE END 2 *\/\n\n\/* Infinite loop *\/\n\/* USER CODE BEGIN WHILE *\/\nwhile (1)\n{\n\/* USER CODE END WHILE *\/\n\n\/* USER CODE BEGIN 3 *\/\n\tWS2812BFX_Callback();\n}<\/pre>\n\n\n\n<p>The first step is to initialize LED control with&nbsp;WS2812B_Init(&amp;hspi1). Just like in the <a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-1\/\">previous post<\/a>, I used SPI1 here. Next, you need to configure the strip\u2019s behavior.<\/p>\n\n\n\n<p>You need to set the speed using a function. You can also do this while the effect is running.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">WS2812BFX_SetSpeed(uint16_t Speed)<\/pre>\n\n\n\n<p>As I mentioned earlier, for all modes the <em>Speed<\/em> value defines the time between successive steps in milliseconds. Two modes \u2013&nbsp;<em>FX_MODE_WHITE_TO_COLOR and&nbsp;FX_MODE_BLACK_TO_COLOR <\/em>\u2013 are exceptions, and this value defines the duration of a full transition cycle.<\/p>\n\n\n\n<p>Next, set the colors that will be used in the mode using one of the dedicated functions.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void WS2812BFX_SetColorStruct(uint8_t id, ws2812b_color c);\nvoid WS2812BFX_SetColorRGB(uint8_t id, uint8_t r, uint8_t g, uint8_t b);\nvoid WS2812BFX_SetColorHSV(uint8_t id, uint16_t h, uint8_t s, uint8_t v);\nvoid WS2812BFX_SetColor(uint8_t id, uint32_t c);<\/pre>\n\n\n\n<p>Some modes use 2 or even 3 colors. The color number is specified by the <em>id<\/em> argument. I prepared 4 functions for convenience. You can set a color using the RGB or HSV space. Setting via a structure or a 32-bit variable sets the color in RGB in the given formatting.<\/p>\n\n\n\n<p>The next step is to choose the effect.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void WS2812BFX_SetMode(fx_mode mode);\n<\/pre>\n\n\n\n<p>As an argument, the function takes an enumeration value with the name of the selected function.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef enum {\n\tFX_MODE_STATIC,\n\tFX_MODE_WHITE_TO_COLOR,\n\tFX_MODE_BLACK_TO_COLOR,\n\tFX_MODE_BLINK,\n\tFX_MODE_BLINK_RAINBOW,\n\tFX_MODE_STROBE,\n\tFX_MODE_STROBE_RAINBOW,\n\tFX_MODE_BREATH,\n\tFX_MODE_COLOR_WIPE,\n\tFX_MODE_COLOR_WIPE_INV,\n\tFX_MODE_COLOR_WIPE_REV,\n\tFX_MODE_COLOR_WIPE_REV_INV,\n\tFX_MODE_COLOR_WIPE_RANDOM,\n\tFX_MODE_COLOR_SWEEP_RANDOM,\n\tFX_MODE_RANDOM_COLOR,\n\tFX_MODE_SINGLE_DYNAMIC,\n\tFX_MODE_MULTI_DYNAMIC,\n\tFX_MODE_RAINBOW,\n\tFX_MODE_RAINBOW_CYCLE,\n\tFX_MODE_FADE,\n\tFX_MODE_SCAN,\n\tFX_MODE_DUAL_SCAN,\n\tFX_MODE_THEATER_CHASE,\n\tFX_MODE_THEATER_CHASE_RAINBOW,\n\tFX_MODE_RUNNING_LIGHTS,\n\tFX_MODE_TWINKLE,\n\tFX_MODE_TWINKLE_RANDOM,\n\tFX_MODE_TWINKLE_FADE,\n\tFX_MODE_TWINKLE_FADE_RANDOM,\n\tFX_MODE_SPARKLE,\n\tFX_MODE_FLASH_SPARKLE,\n\tFX_MODE_HYPER_SPARKLE,\n\tFX_MODE_MULTI_STROBE,\n\tFX_MODE_CHASE_WHITE,\n\tFX_MODE_CHASE_COLOR,\n\tFX_MODE_CHASE_RANDOM,\n\tFX_MODE_CHASE_RAINBOW,\n\tFX_MODE_CHASE_FLASH,\n\tFX_MODE_CHASE_FLASH_RANDOM,\n\tFX_MODE_CHASE_RAINBOW_WHITE,\n\tFX_MODE_CHASE_BLACKOUT,\n\tFX_MODE_CHASE_BLACKOUT_RAINBOW,\n\tFX_MODE_RUNNING_COLOR,\n\tFX_MODE_RUNNING_RED_BLUE,\n\tFX_MODE_RUNNING_RANDOM,\n\tFX_MODE_LARSON_SCANNER,\n\tFX_MODE_COMET,\n\tFX_MODE_FIREWORKS,\n\tFX_MODE_FIREWORKS_RANDOM,\n\tFX_MODE_MERRY_CHRISTMAS,\n\tFX_MODE_FIRE_FLICKER,\n\tFX_MODE_FIRE_FLICKER_SOFT,\n\tFX_MODE_FIRE_FLICKER_INTENSE,\n\tFX_MODE_CIRCUS_COMBUSTUS,\n\tFX_MODE_HALLOWEEN,\n\tFX_MODE_BICOLOR_CHASE,\n\tFX_MODE_TRICOLOR_CHASE,\n\tFX_MODE_ICU\n} fx_mode;<\/pre>\n\n\n\n<p>At this point, the previously selected colors are assigned to the mode variables, and all the counter variables used in the library are reset. The library is now ready to start. To launch the effects, simply call<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void WS2812BFX_Start(void);\n<\/pre>\n\n\n\n<p>Place the <em>callback<\/em> to handle effects in the main loop.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void WS2812BFX_Callback(void);\n<\/pre>\n\n\n\n<p>To make the software timer work together with SysTick, you need to define the <em>callback<\/em> function.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* USER CODE BEGIN 4 *\/\nvoid HAL_SYSTICK_Callback(void)\n{\n  WS2812BFX_SysTickCallback();\n}\n\/* USER CODE END 4 *\/<\/pre>\n\n\n\n<p>As you can see, I placed it in section four for user code in the <em>main.c<\/em> file. This way, SysTick can handle more than just this. Note that&nbsp;void HAL_SYSTICK_Callback(void) is a <em>weak<\/em> function, just like the DMA <em>callbacks<\/em> used in the previous post. <strong>Without defining this function, the FX library will not work!<\/strong><\/p>\n\n\n\n<p>That\u2019s it. You can admire the selected effect. I recommend testing it out.<\/p>\n\n\n\n<div style=\"text-align: center;\"><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/X_HZRvoCR6s\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>By complementing the WS2812B code with a library of lighting effects, I\u2019m sure it will be used by many people during the upcoming holidays. Admit it, the effects are great!<\/p>\n\n\n\n<p>I continue to support the ported library, so if you find any bugs, let me know. In the original Arduino code, a split into independent segments was also implemented. I will take care of this soon and publish a relevant post.<\/p>\n\n\n\n<p>Thank you for reading this post. If you like this kind of topic, let me know in a comment. I would also appreciate suggestions for topics you would like me to cover.<\/p>\n\n\n\n<p>The code is, as usual, available on my GitHub: <a href=\"https:\/\/github.com\/lamik\/WS2812B_STM32_HAL\" target=\"_blank\" rel=\"noopener\">link<\/a><\/p>\n\n\n\n<p><span>If you noticed any error, disagree with something, would like to add something important, or simply feel like discussing this topic, write a comment. Remember that the discussion should be polite and in accordance with the rules of the Polish language.<\/span><\/p>\n\n\n\n<p>This article is part of the series:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-1\/\">Part 1<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-2\/\">Part 2<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/msalamon.pl\/adresowalne-diody-ws2812b-na-stm32-cz-3\/\">Part 3<\/a><\/li>\n<\/ul>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;4347&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;0&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;Addressable WS2812B LEDs on STM32, Part 2&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Recently I wrote about how to drive WS2812B LEDs with STM32. However, control alone is not enough to fully enjoy the possibilities offered by entire strips of these LEDs. Today I will present a library containing a range of interesting lighting effects. Let\u2019s get to work!<\/p>\n","protected":false},"author":1,"featured_media":3029,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[160],"tags":[176,174,177],"class_list":["post-4347","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","tag-programming","tag-stm32","tag-stm32cubemx"],"_links":{"self":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/comments?post=4347"}],"version-history":[{"count":3,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4347\/revisions"}],"predecessor-version":[{"id":4456,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4347\/revisions\/4456"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media\/3029"}],"wp:attachment":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media?parent=4347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/categories?post=4347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/tags?post=4347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}