The code is structured in a layered approach. This has multiple advantages. It's now possible to change microcontroller platform by only having to port the platform layer. Or if a different screen driver is used, only the software driver will have to be ported. Or of the application is meant to be changed, the application layer  has to be adjusted without any changes on the tightly integrated platform code.\\
Other advantages are the reduction of having to test the whole system time after time, as it is possible to rely on the underlying layer if that is tested accordingly.\\
\begin{figure}[H]
	\centering
	\label{fig:code_structure}
	\includegraphics[width=0.6\textwidth]{../block/code_structure.png}
	\caption{The layered approach.}
\end{figure}
In fig. \ref{fig:code_structure} the structure is visualized and it can be seen how every layer depends on a lower level layer. Every block can be swapped with different components while the system keeps running, if implemented well without breaches of layering.\newpar
To make this layered code structure a reality, a small operating system has been developed which allows event driven communication, and a modular approach for driver and sub-systems. This modular approach also makes power saving easier as a module will be uninitialized when it's not used anymore. Removing any possibility for the developer of the system to forget to disable the peripheral/module.\newpar
In fig.\ref{fig:block} the functions of the system can be observed, these functions can be translated into modules and a hierarchy can be created. Along with drivers for the hardware, some software drivers have been written as well. These software drivers provide support for internal development such as logging text in a proper fashion, and creating a way of executing commands on the device. All the platform drivers are interfaces to the system's peripheral. On top of this layer are the actual drivers. This houses the initialization code for the hardware drivers, and gives a way to access the functionality of the hardware without needing to know the registers/commands. The layer above this provides a more generic function set, where no knowledge of the hardware is needed anymore. This can then be used by the last layer, the Application layer. The application layer houses different applications, and a general state of the device can be found inside this layer.
\begin{figure}[H]
	\centering
	\label{fig:block_code}
	\includegraphics[width=0.9\textwidth]{../block/block_code.png}
	\caption{The system structure and hierarchy}
\end{figure}
above in fig. \ref{fig:block_code} this translation from system design to a more refined code structure is shown. A brief description of the required functionality for every block follows. 
\subsection{App layer} The core in the App layer takes care of putting the system in the right state, and decides when to show which application on the screen. Furthermore it establishes the Wi-Fi connection and requests the data from the Internet which is required for all the other applications. Also it translates commands coming from the UART port into actions. The weather application takes data that is fed from the core, and shows the weather at a given position on the screen. The clock application listens to second pulses and shows the time on the screen, together with an alarm. The time is shown both analogue and digital. The time can be read from the Time module, or be set trough the Core, when it synchronizes with the Internet. The Screen Terminal application redirects all the log output and shows it on the screen. This can be used for debugging. Facebook and mail notifications are shown with the Social application. Finally the Lamp application houses information about different sunsets, and accounts for the right amount of red, green and blue in the light when the alarm goes off.
\subsection{Module layer}
The Wi-Fi module makes it possible to translate actions as getting the weather and the current time, to UDP and TCP requests. The Command module interprets data given from the Terminal and executes a given function paired with the command sent. Everything is written to the terminal via the Log module, which adds extra information to every message, such as the file name, line number and time. The screen module contains functions to draw shapes and images. Time reads the latest known time from the EEPROM after a total power failure, and keeps track of the current time via second pulses. To allow fades in the light, and stable output, a Controller module is available. This reads out the current voltage with which the lamp is being driven, and adjusts the PWM signal accordingly. 
\subsection{Driver layer}
The ESP8266 Driver contains all the communication with the ESP8266 chip and keeps track of the network state. Its also possible to update the firmware of the ESP8266. Terminal is a software driver, with no external hardware dependencies by default. It can, however, use the SEP525F as output for text. The text can be formatted with the Terminal driver. In order to set up the screen and draw pixels, a screen driver is required. The OLED screen that is being used, has a SEP525F driver ic. For this a driver has been written.
\subsection{Platform layer}
Every required peripheral has a platform driver. The UART driver has an input and output buffer, and is being used with interrupts. Two UART channels are being used, one for the ESP8266 and one for the USB-Serial converter. The SEP525F has a SPI interface without a need or possibility to read, the SPI driver contains only blocking write. This should be changed to DMA and interrupt transfers. The EEPROM allows to save some settings and time and date on the clock. The timer sets up the real time counter for the second pulses, and has functions to set the PWM of every channel for the power board. And as last, the ADC peripheral. This scales the voltage read from the input pins and provides it to whoever needs the ADC values.