{"id":135894,"date":"2018-07-27T14:16:00","date_gmt":"2018-07-27T11:16:00","guid":{"rendered":"https:\/\/ruuvi.com\/ruuvi-firmware-part-1-sleep\/"},"modified":"2026-06-11T08:48:58","modified_gmt":"2026-06-11T05:48:58","slug":"ruuvi-firmware-part-1-sleep","status":"publish","type":"post","link":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/","title":{"rendered":"Ruuvi Firmware \u2013 Teil 1: Sleep"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"536\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep-1024x536.jpeg\" alt=\"\" class=\"wp-image-3521\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep-1024x536.jpeg 1024w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep-450x236.jpeg 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep-768x402.jpeg 768w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep-600x314.jpeg 600w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep.jpeg 1400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Dies ist der erste Teil der Ruuvi-Firmware-Serie, in dem beschrieben wird, wie du eine Sensor-Beacon-Software auf dem RuuviTag mit <a href=\"https:\/\/www.segger.com\/\">Segger Embedded Studio<\/a> erstellst.<\/p>\n\n<p class=\"wp-block-paragraph\">Der finale Code dieses Blogposts kann auf <a href=\"http:\/\/github.com\/ruuvi\/\">Ruuvi GitHub<\/a> im ruuviblog-Branch, Tag 3.1.1-alpha.1 heruntergeladen werden. Du kannst den Code mit Segger Embedded Studio kompilieren, nachdem du <\/p>\n\n<pre class=\"wp-block-code\"><code>git clone <a href=\"https:\/\/github.com\/ruuvi\/ruuvi.firmware.c\">https:\/\/github.com\/ruuvi\/ruuvi.firmware.c<\/a><br>cd ruuvi.firmware.c<br>git checkout 3.1.1-alpha.1<br>git submodule update --init --recursive<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">Stell sicher, dass das Nordic Semiconductor <a href=\"https:\/\/www.nordicsemi.com\/eng\/Products\/Bluetooth-low-energy\/nRF5-SDK\">nRF15 SDK<\/a> zusammen mit dem Repository installiert ist. Folge <a href=\"https:\/\/lab.ruuvi.com\/ses\">diesen Anweisungen<\/a>, um Segger Embedded Studio zu installieren. Nachdem du das Repository geklont hast, findest du die Projektdatei in <em>targets\/ruuvitag_b\/ses<\/em>.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"207\" height=\"327\" src=\"https:\/\/ruuvi.com\/i\/u\/project-structure-after-setup.png\" alt=\"Projektstruktur nach dem Setup\" class=\"wp-image-3522\"\/><figcaption>Projektstruktur nach dem Setup<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Hinweis: Wenn du die Beispiele auf dem RuuviTag ausf\u00fchrst, musst du den Tag m\u00f6glicherweise komplett l\u00f6schen, um den Bootloader zu entfernen, der mit dem RuuviTag ausgeliefert wird. Die aktuelle Factory-Firmware zum Wiederherstellen der Original-Firmware findest du auf <a href=\"https:\/\/github.com\/ruuvi\/ruuvitag_fw\/releases\/download\/1.3.6.1\/ruuvi_firmware_full_1.2.12.hex\">Ruuvi GitHub<\/a>. <\/p>\n\n<h2 class=\"wp-block-heading\">Das Wichtigste zuerst<\/h2>\n\n<p class=\"wp-block-paragraph\">Wenn jemand ein neues Ger\u00e4t bekommt, um darauf eine Anwendung zu entwickeln, ist der erste Schritt meistens, eine LED blinken zu lassen. Schlie\u00dflich hei\u00dft es: Wenn du eine LED zum Blinken bringen kannst, kannst du alles damit machen. <\/p>\n\n<p class=\"wp-block-paragraph\">Wir gehen hier allerdings anders vor. Da wir ein batteriebetriebenes Ger\u00e4t verwenden, legen wir zun\u00e4chst eine Basis fest, wie niedrig der Stromverbrauch werden kann. Das erreichen wir, indem wir in einen Low-Power-Zustand wechseln und dort bleiben, bis etwas das Ger\u00e4t aufweckt. In diesem Fall bleiben wir f\u00fcr immer im Low-Power-Zustand, da unser Programm noch keine weitere Funktionalit\u00e4t hat.   <\/p>\n\n<p class=\"wp-block-paragraph\">Eines der schwierigsten Dinge in der Informatik ist das Benennen von Dingen. Unsere <strong>enter-low-power-state<\/strong>-Funktion nennen wir <em>yield<\/em> statt <em>sleep. <\/em>Damit signalisieren wir, dass es keinen festen Zeitpunkt gibt, wann die Programmausf\u00fchrung weitergeht: Der Programmablauf wartet, bis ein Ereignis eintritt. In einer Multithreading-Umgebung w\u00fcrden wir in der Zwischenzeit andere Tasks ausf\u00fchren, aber da unsere Umgebung Single-Threaded ist, warten wir einfach, bis etwas passiert ist, bevor wir mit der Ausf\u00fchrung fortfahren. <\/p>\n\n<p class=\"wp-block-paragraph\">Schauen wir uns unsere kommende Architektur an:<\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"361\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-architecture-implemented.png\" alt=\"Architekturstruktur\" class=\"wp-image-3523\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-architecture-implemented.png 741w, https:\/\/ruuvi.com\/i\/u\/ruuvi-architecture-implemented-450x219.png 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-architecture-implemented-600x292.png 600w\" sizes=\"auto, (max-width: 741px) 100vw, 741px\" \/><figcaption>Ausgegraute Bereiche sind noch nicht implementiert, wir starten mit den gr\u00fcnen Bereichen.<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Anwendung<\/h2>\n\n<p class=\"wp-block-paragraph\">An diesem Punkt ist unsere Anwendung extrem simpel. Wir m\u00fcssen die externen Sensoren abschalten und die GPIO-Leitungen in klar definierte Zust\u00e4nde bringen und dann in den Sleep-Modus wechseln. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"782\" height=\"664\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c.png\" alt=\"Ruuvi Firmware main.c\" class=\"wp-image-3524\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c.png 782w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-450x382.png 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-768x652.png 768w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-main-c-600x509.png 600w\" sizes=\"auto, (max-width: 782px) 100vw, 782px\" \/><figcaption>main.c<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Um unsere Anwendung zu erstellen, brauchen wir ein paar Dinge. Wir brauchen Board-Definitionen, die das Pinout enthalten. Sobald die Pinouts definiert sind, brauchen wir einen GPIO-Treiber, um sie zu steuern. Und schlie\u00dflich brauchen wir die Yield-Funktion, die in den Sleep-Modus geht, bis das n\u00e4chste Ereignis eintritt. Der Programmablauf ist nichts Besonderes: Wir f\u00fchren Init-Funktionen aus und richten die GPIOs ein, und dann schlafen wir in der <em>while(1)<\/em>-Schleife.     <\/p>\n\n<h2 class=\"wp-block-heading\">Boards<\/h2>\n\n<p class=\"wp-block-paragraph\">Wir beginnen damit, das Board-Pinout zu definieren. Um unsere Anwendung nicht von Anfang an an RuuviTag_B zu binden, orientieren wir uns am Nordic SDK und erstellen einen Header <em>ruuvi_boards.h<\/em>. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"130\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-boards.png\" alt=\"ruuvi_boards.h\" class=\"wp-image-3525\"\/><figcaption>ruuvi_boards.h<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\" id=\"a9f0\">Als Erstes f\u00e4llt auf, dass wir keine Header <strong>#include<\/strong>n; die Definition muss direkt als Flag an den Compiler \u00fcbergeben werden. Das liegt daran, dass wir in unserem Anwendungscode nicht gezwungen sein wollen, die verf\u00fcgbaren Targets nachzuverfolgen, sondern stattdessen <strong>BOARD_RUUVITAG_B<\/strong> in unseren Target-Skripten definieren. <\/p>\n\n<p class=\"wp-block-paragraph\" id=\"b666\">Das gibt dir au\u00dferdem die Flexibilit\u00e4t, ein eigenes Boards-Repository zu pflegen, z. B. <em>proprietary.boards.c<\/em>, und deine Board-Definitionen dort zu verwalten. \u00dcbergib einfach <strong>BOARD_PROPRIETARY<\/strong> und <strong>BOARD_NAME<\/strong> im Target-Skript an den Compiler und implementiere deine Board-Liste in <em>proprietary_boards.h.<\/em> Darauf schauen wir im Abschnitt <strong>targets<\/strong> genauer. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"736\" height=\"985\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-boards-ruuvitag-b-h.png\" alt=\"ruuvi_boards_ruuvitag_b.h\" class=\"wp-image-3528\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-boards-ruuvitag-b-h.png 736w, https:\/\/ruuvi.com\/i\/u\/ruuvi-boards-ruuvitag-b-h-336x450.png 336w, https:\/\/ruuvi.com\/i\/u\/ruuvi-boards-ruuvitag-b-h-600x803.png 600w\" sizes=\"auto, (max-width: 736px) 100vw, 736px\" \/><figcaption>ruuvi_boards_ruuvitag_b.h<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Wie der Header vermuten l\u00e4sst, orientieren wir uns erneut am Nordic Semiconductor SDK. Wir verwenden <strong>PCA10040<\/strong>, auch bekannt als <strong>nRF52-DK<\/strong>, als Basis, entfernen alles, was noch nicht n\u00f6tig ist, und benennen die Pin-Definitionen in <strong>RUUVI_BOARD_PIN<\/strong> um. <\/p>\n\n<h2 class=\"wp-block-heading\">Yield<\/h2>\n\n<h3 class=\"wp-block-heading\">Yield-Schnittstelle<\/h3>\n\n<p class=\"wp-block-paragraph\">Definieren wir die Yield-Funktionen. Wir brauchen die Initialisierung und Yield selbst, und wenn wir schon dabei sind, f\u00fcgen wir auch Delay-Funktionen hinzu. Die Funktionen geben Statuscodes zur\u00fcck, aber die lassen wir vorerst au\u00dfen vor und kommen im n\u00e4chsten Teil der Serie darauf zur\u00fcck.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"365\" height=\"421\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-yield-h.png\" alt=\"ruuvi_interface_yield.h\" class=\"wp-image-3530\"\/><figcaption>ruuvi_interface_yield.h<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Nichts Besonderes. Wir \u00fcbergeben keine Parameter an die Yield-Funktionen, da diese Parameter vermutlich implementationsspezifisch w\u00e4ren und die Anwendung mit Implementierungsdetails unn\u00f6tig verkomplizieren w\u00fcrden. <\/p>\n\n<h3 class=\"wp-block-heading\">Yield-Implementierung<\/h3>\n\n<p class=\"wp-block-paragraph\">Die Implementierung der Funktionen ist einfach: Wir leiten die Aufrufe an das <a href=\"https:\/\/www.nordicsemi.com\/eng\/Products\/Bluetooth-low-energy\/nRF5-SDK\">Nordic SDK<\/a> weiter und lassen es den Rest erledigen. Statuscodes, die vom SDK zur\u00fcckgegeben werden, werden in Ruuvi-Statuscodes umgewandelt \u2013 darauf schauen wir im n\u00e4chsten Teil der Blogserie. <\/p>\n\n<p class=\"wp-block-paragraph\">Als Plausibilit\u00e4tscheck pr\u00fcfen wir die Definition <strong>NRF5_SDK15_YIELD_ENABLED<\/strong>. Wenn diese Funktionen in unser Programm kompiliert werden sollen, muss sie zu \u201enicht false\u201c auswerten. Unser Treiber kann nicht wissen, ob die Anwendung diese konkreten Implementierungen nutzen will, daher f\u00fcgen wir ein Include <em>ruuvi_platform_external_includes.h<\/em> hinzu, das die Konfiguration aus der Anwendung einbindet. Wir k\u00f6nnten C-Preprocessor-Flags verwenden, wie wir es bei <em>ruuvi_boards.h<\/em> gemacht haben, aber im Verlauf des Projekts ist mit vielen Konfigurationsoptionen zu rechnen. Explizite Includes erlauben es uns, die Bedeutung jedes Flags und jeder Option sowie g\u00fcltige Werte zu kommentieren.    <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"278\" height=\"421\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-yield-c-of-nrf5-sdk15-platform.png\" alt=\"ruuvi_platform_yield.c von nrf5_sdk15_platform\" class=\"wp-image-3532\"\/><figcaption>ruuvi_platform_yield.c von nrf5_sdk15_platform<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">GPIO<\/h2>\n\n<h3 class=\"wp-block-heading\">GPIO-Schnittstelle<\/h3>\n\n<p class=\"wp-block-paragraph\">Unsere <em>GPIO<\/em>-Definitionen sind an diesem Punkt schlicht und einfach. Wir haben den High-Impedance-Modus, Input ohne Pull-Widerst\u00e4nde, Input mit Pull-up oder Pull-down, Standard-Output f\u00fcr IO und High-Drive-Output zum Ansteuern von LEDs. <\/p>\n\n<p class=\"wp-block-paragraph\">Die Funktionen sind ebenso schlicht: <em>init<\/em>, <em>configure<\/em>, <em>toggle<\/em>, <em>write<\/em> und <em>read<\/em>. Wichtig ist, dass die Funktion <em>read<\/em> einen Pointer auf <em>ruuvi_interface_state_t<\/em> als Input nimmt; der Pointer-Wert wird auf den Zustand des Pins gesetzt. So k\u00f6nnen wir den Statuscode aus der Read-Funktion zur\u00fcckgeben.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"603\" height=\"1024\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-gpio-h-603x1024.png\" alt=\"ruuvi_interface_gpio.h\" class=\"wp-image-3533\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-gpio-h-603x1024.png 603w, https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-gpio-h-265x450.png 265w, https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-gpio-h-600x1019.png 600w, https:\/\/ruuvi.com\/i\/u\/ruuvi-interface-gpio-h.png 703w\" sizes=\"auto, (max-width: 603px) 100vw, 603px\" \/><figcaption>ruuvi_interface_gpio.h<\/figcaption><\/figure><\/div>\n\n<h3 class=\"wp-block-heading\">GPIO-Implementierung<\/h3>\n\n<p class=\"wp-block-paragraph\">Der Start der <em>GPIO<\/em>-Implementierung ist \u00e4hnlich wie bei der <em>yield<\/em>-Implementierung. Wir pr\u00fcfen, ob <strong>NRF15_SDK15_GPIO_ENABLED<\/strong> \u201enicht false\u201c ist, bevor wir das Programm kompilieren. Wie bei Yield leiten wir die Funktionsaufrufe an nRF5 SDK15 weiter und geben Statuscodes aus der Funktion zur\u00fcck.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"793\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-gpio-c-of-nrf5-sdk15-platform.png\" alt=\"ruuvi_platform_gpio.c von nrf5_sdk15_platform\" class=\"wp-image-3534\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-gpio-c-of-nrf5-sdk15-platform.png 414w, https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-gpio-c-of-nrf5-sdk15-platform-235x450.png 235w\" sizes=\"auto, (max-width: 414px) 100vw, 414px\" \/><figcaption>ruuvi_platform_gpio.c von nrf5_sdk15_platform<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Es gibt ein paar Stilentscheidungen, die vielleicht Stirnrunzeln ausl\u00f6sen, daher gehe ich hier darauf ein. Die erste betrifft R\u00fcckgabewerte: Es ist eine gute Praxis, in einer Funktion nur eine m\u00f6gliche Stelle zu haben, an der ein Wert zur\u00fcckgegeben wird. Die Begr\u00fcndung f\u00fcr mehrere m\u00f6gliche Return-Points h\u00e4ngt mit der Bedeutung des R\u00fcckgabewerts zusammen: Wir geben kein Ergebnis einer Berechnung zur\u00fcck, sondern einen Statuscode. Die Return-Werte werden eher wie geworfene Exceptions behandelt als etwas, das das Programm akzeptieren und weiterverarbeiten sollte.   <\/p>\n\n<p class=\"wp-block-paragraph\">Die zweite betrifft die If-Else-Strukturen. Viele Leser w\u00fcrden die Funktion <em>ruuvi_platform_gpio_read<\/em> so schreiben: <\/p>\n\n<pre class=\"wp-block-code\"><code>ruuvi_driver_status_t ruuvi_platform_gpio_read(uint8_t pin, ruuvi_interface_gpio_state_t* state)<br>{<br>  if(state == NULL)<br>  { <br>    return RUUVI_DRIVER_ERROR_NULL; <br>  }  bool high = nrf_gpio_pin_read(pin);<br>  if(high)<br>  { <br>    *state = RUUVI_INTERFACE_GPIO_HIGH;<br>  }<br>  else<br>  { <br>    *state = RUUVI_INTERFACE_GPIO_LOW;  <br>  }<br>  return RUUVI_DRIVER_SUCCESS;<br>}<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">Erstens: Meine Gewohnheit, die Konstante links im Vergleich zu platzieren, stammt von dem einen Mal, als ich versehentlich eine Zuweisung statt eines Vergleichs geschrieben habe \u2013 und das Chaos war perfekt. Mir ist auch klar, dass der Compiler warnen sollte, wenn in einer If-Klausel eine Zuweisung steht, und dass Warnungen als Fehler behandelt werden sollten. Leider gilt das nicht in allen Sprachen, mit denen ich arbeite.  <\/p>\n\n<p class=\"wp-block-paragraph\">Zweitens: Pr\u00fcfen, ob ein Boolean-Wert true ist, statt den Boolean-Wert einfach so zu verwenden. Das ist ebenfalls eine Gewohnheit und auch ein bisschen Pythonic Thinking: Explizit ist besser als implizit. <\/p>\n\n<p class=\"wp-block-paragraph\">Drittens: Zwei gegenseitig ausschlie\u00dfende If-Klauseln statt If-Else. Das h\u00e4ngt mit meiner Denkweise zusammen: Ich will den Zustand auf <strong>LOW<\/strong> setzen, <em>wenn<\/em> der Zustand <strong>LOW<\/strong> war. Welche Logik vorher passiert ist, bevor der Zustand auf <strong>LOW<\/strong> gesetzt wird, ist hier irrelevant. Die Zeile   <\/p>\n\n<pre class=\"wp-block-code\"><code>if(false == high) { *state = RUUVI_INTERFACE_GPIO_LOW;  }<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">ist in sich geschlossen; wir m\u00fcssen nichts anderes wissen, um sie zu beurteilen. Wenn wir schreiben <\/p>\n\n<pre class=\"wp-block-code\"><code>else<br>{ <br>  *state = RUUVI_INTERFACE_GPIO_LOW;  <br>}<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">wissen wir nicht wirklich, was hier passiert. Wir m\u00fcssten den vorherigen Kontext pr\u00fcfen, um zu verstehen, welche Logikbedingung in diese Klausel f\u00fchrt. Nat\u00fcrlich k\u00f6nnte man argumentieren, dass das f\u00fcr die erste Klausel genauso gilt, wenn die folgenden Klauseln erreicht werden k\u00f6nnen. Vielleicht sollte die ganze Funktion   <\/p>\n\n<pre class=\"wp-block-code\"><code>ruuvi_driver_status_t ruuvi_platform_gpio_read(uint8_t pin, ruuvi_interface_gpio_state_t* state)<br>{<br>  if(state == NULL){ return RUUVI_DRIVER_ERROR_NULL; }  bool high = nrf_gpio_pin_read(pin);<br>  if(true == high)<br>  { <br>    *state = RUUVI_INTERFACE_GPIO_HIGH;<br>    return RUUVI_DRIVER_SUCCESS;<br>  }<br>  if(false == high)<br>  { <br>    *state = RUUVI_INTERFACE_GPIO_LOW;<br>    return RUUVI_DRIVER_SUCCESS;<br>  }<br>  return RUUVI_DRIVER_ERROR_INTERNAL;<br>}<\/code><\/pre>\n\n<p class=\"wp-block-paragraph\">Ich sehe das als Geschmackssache: Wenn nichts schiefgelaufen ist, wurde die Funktion erfolgreich ausgef\u00fchrt. Jemand anderes w\u00fcrde den Code vielleicht lieber so strukturieren: \u201eWenn die Funktion nicht erfolgreich zur\u00fcckgegeben hat, ist ein Fehler aufgetreten\u201c. <\/p>\n\n<h2 class=\"wp-block-heading\">Konfiguration<\/h2>\n\n<p class=\"wp-block-paragraph\">Um den Code tats\u00e4chlich zu kompilieren, m\u00fcssen wir eine <em>sdk_configuration.h<\/em>-Vorlage zu unserem nrf5_sdk15_platform hinzuf\u00fcgen. Wir verwenden die Konfiguration von Nordics <em>ble_app_buttonless_dfu<\/em> als Basis. Um anwendungsspezifische Overrides zu erm\u00f6glichen, binden wir <em>ruuvi_platform_external_includes.h in sdk_config.h<\/em> ein.  <\/p>\n\n<p class=\"wp-block-paragraph\">Als N\u00e4chstes erstellen wir <em>ruuvi_platform_external_includes.h<\/em> und binden Header ein, um unseren Platform-Code sowie das Nordic SDK zu konfigurieren.<\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"328\" height=\"90\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-external-includes-h.png\" alt=\"ruuvi_platform_external_includes.h von nrf5_sdk15_platform\" class=\"wp-image-3535\"\/><figcaption>ruuvi_platform_external_includes.h von nrf5_sdk15_platform<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">An diesem Punkt brauchen wir keine Nicht-Standard-Konfiguration f\u00fcr das SDK, aber wir m\u00fcssen die <em>GPIO<\/em>&#8211; und <em>yield<\/em>-Funktionen in <em>ruuvi_platform_nrf5_sdk15_config.h<\/em> aktivieren. Zus\u00e4tzlich definieren wir <strong>NRF5_SDK15_PLATFORM_ENABLED<\/strong>.<\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"104\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-platform-nrf5-sdk15-config-h.png\" alt=\"ruuvi_platform_nrf5_sdk15_config.h\" class=\"wp-image-3536\"\/><figcaption>ruuvi_platform_nrf5_sdk15_config.h<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Target<\/h2>\n\n<p class=\"wp-block-paragraph\">Das Einrichten von SEGGER Embedded Studio (SES), um das Projekt zu kompilieren, w\u00e4re ein eigenes Tutorial wert \u2013 daher gehen wir hier nicht ins Detail. Kurz gesagt: Das SES-Projekt des Nordic SDK 15 <em>ble_app_buttonless_dfu<\/em> wurde als Basis genommen und Projektdateien wurden hinzugef\u00fcgt. Au\u00dferdem m\u00fcssen wir die Definition <strong>BOARD_RUUVITAG_B<\/strong> f\u00fcr den Preprocessor hinzuf\u00fcgen.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"913\" height=\"800\" src=\"https:\/\/ruuvi.com\/i\/u\/preprocessor-definitions.png\" alt=\"Preprocessor-Definitionen\" class=\"wp-image-3537\" srcset=\"https:\/\/ruuvi.com\/i\/u\/preprocessor-definitions.png 913w, https:\/\/ruuvi.com\/i\/u\/preprocessor-definitions-450x394.png 450w, https:\/\/ruuvi.com\/i\/u\/preprocessor-definitions-768x673.png 768w, https:\/\/ruuvi.com\/i\/u\/preprocessor-definitions-600x526.png 600w\" sizes=\"auto, (max-width: 913px) 100vw, 913px\" \/><figcaption>Preprocessor-Definitionen<\/figcaption><\/figure><\/div>\n\n<h2 class=\"wp-block-heading\">Flashen<\/h2>\n\n<p class=\"wp-block-paragraph\">Zeit, unsere neue Firmware auf das Board zu flashen und zu sehen, wie sie sich schl\u00e4gt! Beachte, dass <strong>SES<\/strong> beim Flashen nicht den gesamten Tag l\u00f6scht \u2013 es k\u00f6nnte also noch ein Bootloader auf dem Tag sein. F\u00fchre im <strong>SES<\/strong>-Connect-Men\u00fc \u201eErase all\u201c aus, um eine saubere Installation zu bekommen.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1025\" height=\"803\" src=\"https:\/\/ruuvi.com\/i\/u\/nrf-connect-v2-4-0-power-profile.png\" alt=\"Screenshot, der zeigt, dass es am Anfang fast 450 uA sind\" class=\"wp-image-3538\" srcset=\"https:\/\/ruuvi.com\/i\/u\/nrf-connect-v2-4-0-power-profile.png 1025w, https:\/\/ruuvi.com\/i\/u\/nrf-connect-v2-4-0-power-profile-450x353.png 450w, https:\/\/ruuvi.com\/i\/u\/nrf-connect-v2-4-0-power-profile-768x602.png 768w, https:\/\/ruuvi.com\/i\/u\/nrf-connect-v2-4-0-power-profile-600x470.png 600w\" sizes=\"auto, (max-width: 1025px) 100vw, 1025px\" \/><figcaption>Fast 450 uA am Anfang<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Nun, das ist nicht so gut. Ruuvi Firmware 1.2.12, die tats\u00e4chlich n\u00fctzliche Dinge tut, verbraucht im Schnitt weniger als 25 uA \u2013 wir liegen also schon etwa 18-mal \u00fcber dem Benchmark, bevor wir \u00fcberhaupt etwas tun. Aus einer Vermutung heraus lassen wir die Interrupt-Leitungen im High-Z-Modus.  <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"766\" height=\"692\" src=\"https:\/\/ruuvi.com\/i\/u\/fixed-main-c.png\" alt=\"Korrigierte main.c mit deaktivierten Pull-ups der Interrupt-Leitung.\" class=\"wp-image-3539\" srcset=\"https:\/\/ruuvi.com\/i\/u\/fixed-main-c.png 766w, https:\/\/ruuvi.com\/i\/u\/fixed-main-c-450x407.png 450w, https:\/\/ruuvi.com\/i\/u\/fixed-main-c-600x542.png 600w\" sizes=\"auto, (max-width: 766px) 100vw, 766px\" \/><figcaption>Korrigierte main.c mit deaktivierten Pull-ups der Interrupt-Leitung.<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Wie sieht es diesmal aus?<\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"801\" src=\"https:\/\/ruuvi.com\/i\/u\/power-consumption-4-uA.png\" alt=\"Screenshot, der zeigt, dass der Stromverbrauch nach dem Fix der Interrupt-Leitungen bei 4 uA liegt\" class=\"wp-image-3540\" srcset=\"https:\/\/ruuvi.com\/i\/u\/power-consumption-4-uA.png 1024w, https:\/\/ruuvi.com\/i\/u\/power-consumption-4-uA-450x352.png 450w, https:\/\/ruuvi.com\/i\/u\/power-consumption-4-uA-768x601.png 768w, https:\/\/ruuvi.com\/i\/u\/power-consumption-4-uA-600x469.png 600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Der Stromverbrauch liegt nach dem Fix der Interrupt-Leitungen bei 4 uA<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\">Nach dem Entfernen der Pull-ups liegen wir bei <strong>4 uA Verbrauch<\/strong>. Fr\u00fcher, beim Power-Profiling der FW im 1.x-Branch, sind wir zu dem Schluss gekommen, dass unsere <a href=\"https:\/\/ruuvi.com\/power-optimizing-your-application\/\">Baseline 8 uA<\/a> war \u2013 das hei\u00dft, wir liegen bei der H\u00e4lfte des vorherigen Levels. Bis hierhin: sehr gut!  <\/p>\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n<p class=\"wp-block-paragraph\">Im Moment sind wir funktional ungef\u00e4hr dort, wo wir Anfang 2016 waren: Wir k\u00f6nnen Software f\u00fcr den RuuviTag kompilieren und flashen und verifizieren, dass wir im Sleep-Modus einen sehr niedrigen Stromverbrauch erreichen. Wir haben eine Basisstruktur, auf der wir aufbauen k\u00f6nnen. <\/p>\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"671\" src=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-architecture-3-1-1.png\" alt=\"Die Ruuvi-Firmware-Architektur\" class=\"wp-image-3541\" srcset=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-architecture-3-1-1.png 741w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-architecture-3-1-1-450x407.png 450w, https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-architecture-3-1-1-600x543.png 600w\" sizes=\"auto, (max-width: 741px) 100vw, 741px\" \/><figcaption>Die gr\u00fcnen Teile wurden hier eingef\u00fchrt, die violetten Teile folgen sp\u00e4ter.<\/figcaption><\/figure><\/div>\n\n<p class=\"wp-block-paragraph\"><strong>Bleib dran und folge <\/strong><a href=\"https:\/\/twitter.com\/ojousima\"><strong>@ojousima<\/strong><\/a><strong> und <\/strong><a href=\"https:\/\/twitter.com\/ruuvicom\"><strong>@ruuvicom<\/strong><\/a><strong> auf Twitter<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dies ist der erste Teil der Ruuvi-Firmware-Serie, in dem beschrieben wird, wie du eine Sensor-Beacon-Software auf dem RuuviTag mit Segger Embedded Studio erstellst. Der finale Code dieses Blogposts kann auf Ruuvi GitHub im ruuviblog-Branch, Tag 3.1.1-alpha.1 heruntergeladen werden. Du kannst den Code mit Segger Embedded Studio kompilieren, nachdem du Stell sicher, dass das Nordic Semiconductor [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":135895,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[324],"tags":[],"class_list":["post-135894","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruuvi-software-artikel"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Ruuvi Firmware \u2013 Teil 1: Sleep \u2013 Ruuvi<\/title>\n<meta name=\"description\" content=\"Starte mit \u201eHow to build a beacon sensor firmware with Segger Embedded Studio\u201c. Lade den finalen Code kostenlos herunter.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ruuvi Firmware \u2013 Teil 1: Sleep \u2013 Ruuvi\" \/>\n<meta property=\"og:description\" content=\"Starte mit \u201eHow to build a beacon sensor firmware with Segger Embedded Studio\u201c. Lade den finalen Code kostenlos herunter.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/\" \/>\n<meta property=\"og:site_name\" content=\"Ruuvi\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ruuvi.cc\" \/>\n<meta property=\"article:published_time\" content=\"2018-07-27T11:16:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-11T05:48:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"1400\" \/>\n\t<meta property=\"og:image:height\" content=\"733\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Otso Jousimaa\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ruuvicom\" \/>\n<meta name=\"twitter:site\" content=\"@ruuvicom\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Otso Jousimaa\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"10\u00a0Minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/\"},\"author\":{\"name\":\"Otso Jousimaa\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\"},\"headline\":\"Ruuvi Firmware \u2013 Teil 1: Sleep\",\"datePublished\":\"2018-07-27T11:16:00+00:00\",\"dateModified\":\"2026-06-11T05:48:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/\"},\"wordCount\":1771,\"image\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-sleep.jpeg\",\"articleSection\":[\"Ruuvi-Software-Artikel\"],\"inLanguage\":\"de\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/\",\"name\":\"Ruuvi Firmware \u2013 Teil 1: Sleep \u2013 Ruuvi\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-sleep.jpeg\",\"datePublished\":\"2018-07-27T11:16:00+00:00\",\"dateModified\":\"2026-06-11T05:48:58+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\"},\"description\":\"Starte mit \u201eHow to build a beacon sensor firmware with Segger Embedded Studio\u201c. Lade den finalen Code kostenlos herunter.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/#primaryimage\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-sleep.jpeg\",\"contentUrl\":\"https:\\\/\\\/ruuvi.com\\\/i\\\/u\\\/ruuvi-firmware-sleep.jpeg\",\"width\":1400,\"height\":733,\"caption\":\"Titelbild f\u00fcr den Blogpost\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/ruuvi-firmware-part-1-sleep\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/front\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruuvi Firmware \u2013 Teil 1: Sleep\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/\",\"name\":\"Ruuvi\",\"description\":\"Measure Your World\",\"potentialAction\":[],\"inLanguage\":\"de\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/#\\\/schema\\\/person\\\/143b8e2a095f1e6484b9186673c9ec00\",\"name\":\"Otso Jousimaa\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g\",\"caption\":\"Otso Jousimaa\"},\"url\":\"https:\\\/\\\/ruuvi.com\\\/de\\\/author\\\/ojousima\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Ruuvi Firmware \u2013 Teil 1: Sleep \u2013 Ruuvi","description":"Starte mit \u201eHow to build a beacon sensor firmware with Segger Embedded Studio\u201c. Lade den finalen Code kostenlos herunter.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/","og_locale":"de_DE","og_type":"article","og_title":"Ruuvi Firmware \u2013 Teil 1: Sleep \u2013 Ruuvi","og_description":"Starte mit \u201eHow to build a beacon sensor firmware with Segger Embedded Studio\u201c. Lade den finalen Code kostenlos herunter.","og_url":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/","og_site_name":"Ruuvi","article_publisher":"https:\/\/www.facebook.com\/ruuvi.cc","article_published_time":"2018-07-27T11:16:00+00:00","article_modified_time":"2026-06-11T05:48:58+00:00","og_image":[{"width":1400,"height":733,"url":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep.jpeg","type":"image\/jpeg"}],"author":"Otso Jousimaa","twitter_card":"summary_large_image","twitter_creator":"@ruuvicom","twitter_site":"@ruuvicom","twitter_misc":{"Verfasst von":"Otso Jousimaa","Gesch\u00e4tzte Lesezeit":"10\u00a0Minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/#article","isPartOf":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/"},"author":{"name":"Otso Jousimaa","@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00"},"headline":"Ruuvi Firmware \u2013 Teil 1: Sleep","datePublished":"2018-07-27T11:16:00+00:00","dateModified":"2026-06-11T05:48:58+00:00","mainEntityOfPage":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/"},"wordCount":1771,"image":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/#primaryimage"},"thumbnailUrl":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep.jpeg","articleSection":["Ruuvi-Software-Artikel"],"inLanguage":"de"},{"@type":"WebPage","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/","url":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/","name":"Ruuvi Firmware \u2013 Teil 1: Sleep \u2013 Ruuvi","isPartOf":{"@id":"https:\/\/ruuvi.com\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/#primaryimage"},"image":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/#primaryimage"},"thumbnailUrl":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep.jpeg","datePublished":"2018-07-27T11:16:00+00:00","dateModified":"2026-06-11T05:48:58+00:00","author":{"@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00"},"description":"Starte mit \u201eHow to build a beacon sensor firmware with Segger Embedded Studio\u201c. Lade den finalen Code kostenlos herunter.","breadcrumb":{"@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/#primaryimage","url":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep.jpeg","contentUrl":"https:\/\/ruuvi.com\/i\/u\/ruuvi-firmware-sleep.jpeg","width":1400,"height":733,"caption":"Titelbild f\u00fcr den Blogpost"},{"@type":"BreadcrumbList","@id":"https:\/\/ruuvi.com\/de\/ruuvi-firmware-part-1-sleep\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ruuvi.com\/de\/front\/"},{"@type":"ListItem","position":2,"name":"Ruuvi Firmware \u2013 Teil 1: Sleep"}]},{"@type":"WebSite","@id":"https:\/\/ruuvi.com\/de\/#website","url":"https:\/\/ruuvi.com\/de\/","name":"Ruuvi","description":"Measure Your World","potentialAction":[],"inLanguage":"de"},{"@type":"Person","@id":"https:\/\/ruuvi.com\/de\/#\/schema\/person\/143b8e2a095f1e6484b9186673c9ec00","name":"Otso Jousimaa","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/fd52303e35b8b23c01cfeec7bb2636768de567cd33604f794ae86dd971e61645?s=96&d=mm&r=g","caption":"Otso Jousimaa"},"url":"https:\/\/ruuvi.com\/de\/author\/ojousima\/"}]}},"_links":{"self":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135894","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/comments?post=135894"}],"version-history":[{"count":1,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135894\/revisions"}],"predecessor-version":[{"id":135897,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/posts\/135894\/revisions\/135897"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/media\/135895"}],"wp:attachment":[{"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/media?parent=135894"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/categories?post=135894"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ruuvi.com\/de\/wp-json\/wp\/v2\/tags?post=135894"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}