diff --git a/boards/arduino-atmega-common/Makefile.features b/boards/arduino-atmega-common/Makefile.features
index 92b1f77884725bafe9ee7b23e80f56c63a17a682..7b4cdf7eb9b54837279b7f8d7412e56e6f1a74dd 100644
--- a/boards/arduino-atmega-common/Makefile.features
+++ b/boards/arduino-atmega-common/Makefile.features
@@ -1,4 +1,5 @@
 # Put defined MCU peripherals here (in alphabetical order)
+FEATURES_PROVIDED += periph_adc
 FEATURES_PROVIDED += periph_gpio
 FEATURES_PROVIDED += periph_i2c
 FEATURES_PROVIDED += periph_spi
diff --git a/boards/arduino-atmega-common/include/arduino_board.h b/boards/arduino-atmega-common/include/arduino_board.h
index 3a8d7b958ea4de825f912ed8c693b72bccdf8fbc..de5c4c82df4ceb8ae3ace5ea5129cfd1df881d43 100644
--- a/boards/arduino-atmega-common/include/arduino_board.h
+++ b/boards/arduino-atmega-common/include/arduino_board.h
@@ -109,6 +109,30 @@ static const gpio_t arduino_pinmap[] = {
 #endif
 };
 
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
+    ARDUINO_A4,
+    ARDUINO_A5,
+    ARDUINO_A6,
+    ARDUINO_A7,
+#ifdef CPU_ATMEGA2560
+    ARDUINO_A8,
+    ARDUINO_A9,
+    ARDUINO_A10,
+    ARDUINO_A11,
+    ARDUINO_A12,
+    ARDUINO_A13,
+    ARDUINO_A14,
+    ARDUINO_A15,
+#endif
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/arduino-atmega-common/include/arduino_pinmap.h b/boards/arduino-atmega-common/include/arduino_pinmap.h
index feac1c5bc2e0e1f27076a516daa89bc0621f8c4f..842a2d72bd10dfbb44b8e5d6c9a2642b241f208c 100644
--- a/boards/arduino-atmega-common/include/arduino_pinmap.h
+++ b/boards/arduino-atmega-common/include/arduino_pinmap.h
@@ -25,6 +25,9 @@
 #ifndef ARDUINO_PINMAP_H
 #define ARDUINO_PINMAP_H
 
+#include "periph/gpio.h"
+#include "periph/adc.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -155,9 +158,27 @@ extern "C" {
 #define ARDUINO_PIN_A14         ARDUINO_PIN_68
 #define ARDUINO_PIN_A15         ARDUINO_PIN_69
 #endif
-
 /** @ */
 
+#define ARDUINO_A0              ADC_LINE(0)
+#define ARDUINO_A1              ADC_LINE(1)
+#define ARDUINO_A2              ADC_LINE(2)
+#define ARDUINO_A3              ADC_LINE(3)
+#define ARDUINO_A4              ADC_LINE(4)
+#define ARDUINO_A5              ADC_LINE(5)
+#define ARDUINO_A6              ADC_LINE(6)
+#define ARDUINO_A7              ADC_LINE(7)
+#ifdef CPU_ATMEGA2560
+#define ARDUINO_A8              ADC_LINE(8)
+#define ARDUINO_A9              ADC_LINE(9)
+#define ARDUINO_A10             ADC_LINE(10)
+#define ARDUINO_A11             ADC_LINE(11)
+#define ARDUINO_A12             ADC_LINE(12)
+#define ARDUINO_A13             ADC_LINE(13)
+#define ARDUINO_A14             ADC_LINE(14)
+#define ARDUINO_A15             ADC_LINE(15)
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/arduino-atmega-common/include/periph_conf.h b/boards/arduino-atmega-common/include/periph_conf.h
index af5e5bdcbef0a83858ebd863ed3ffff7ce16a2fd..4a1681fde33d2f8649b0a1128c64c52bdd81ad5b 100644
--- a/boards/arduino-atmega-common/include/periph_conf.h
+++ b/boards/arduino-atmega-common/include/periph_conf.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2014 Freie Universität Berlin, Hinnerk van Bruinehsen
  *               2016 Laurent Navet <laurent.navet@gmail.com>
+ *               2017 HAW Hamburg, Dimitri Nahm
  *
  * This file is subject to the terms and conditions of the GNU Lesser
  * General Public License v2.1. See the file LICENSE in the top level
@@ -17,6 +18,7 @@
  * @author      Hinnerk van Bruinehsen <h.v.bruinehsen@fu-berlin.de>
  * @author      Laurent Navet <laurent.navet@gmail.com>
  * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ * @author      Dimitri Nahm <dimitri.nahm@haw-hamburg.de>
  */
 
 #ifndef PERIPH_CONF_H
@@ -136,9 +138,29 @@ extern "C" {
 /** @} */
 
 /**
- * @brief    I2C configuration
+ * @name    I2C configuration
+ * @{
  */
 #define I2C_NUMOF           1
+/** @} */
+
+/**
+ * @name    ADC configuration
+ *
+ * The number of ADC channels of the atmega328p depends on the package:
+ *  - 6-channel 10-bit ADC in PDIP package
+ *  - 8-channel 10-bit ADC in TQFP and QFN/MLF package
+ * Arduino UNO / Duemilanove has thereby 6 channels. But only 5 channels can be
+ * used for ADC, because the pin of ADC5 emulate a software triggered interrupt.
+ *  -> boards -> arduino-atmega-common -> include -> board_common.h
+ * @{
+ */
+#if defined (CPU_ATMEGA328P) || defined (CPU_ATMEGA1281)
+#define ADC_NUMOF       (8U)
+#elif defined (CPU_ATMEGA2560)
+#define ADC_NUMOF       (16U)
+#endif
+/** @} */
 
 #ifdef __cplusplus
 }
diff --git a/boards/arduino-due/include/arduino_board.h b/boards/arduino-due/include/arduino_board.h
index 2a08f2c4f4a71953df3f8761b09c196ffd3334da..e9a8657351a6fd12461f8211597fff707d2ba036 100644
--- a/boards/arduino-due/include/arduino_board.h
+++ b/boards/arduino-due/include/arduino_board.h
@@ -115,6 +115,24 @@ static const gpio_t arduino_pinmap[] = {
     ARDUINO_PIN_78,
 };
 
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
+    ARDUINO_A4,
+    ARDUINO_A5,
+    ARDUINO_A6,
+    ARDUINO_A7,
+    ARDUINO_A8,
+    ARDUINO_A9,
+    ARDUINO_A10,
+    ARDUINO_A11,
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/arduino-mkr-common/include/arduino_board.h b/boards/arduino-mkr-common/include/arduino_board.h
index 9d7325eac8a1382273386a23c6857fda97e6fc31..41c8fc8796d0f5232c8647720082a40efb81d6ab 100644
--- a/boards/arduino-mkr-common/include/arduino_board.h
+++ b/boards/arduino-mkr-common/include/arduino_board.h
@@ -55,6 +55,19 @@ static const gpio_t arduino_pinmap[] = {
     ARDUINO_PIN_A6,
 };
 
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
+    ARDUINO_A4,
+    ARDUINO_A5,
+    ARDUINO_A6,
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/arduino-mkr-common/include/arduino_pinmap.h b/boards/arduino-mkr-common/include/arduino_pinmap.h
index 7a869771df052abaa754934b9881923131836648..b48a11f88630957e2002cb854605a2e2f2fd4788 100644
--- a/boards/arduino-mkr-common/include/arduino_pinmap.h
+++ b/boards/arduino-mkr-common/include/arduino_pinmap.h
@@ -23,6 +23,7 @@
 #define ARDUINO_PINMAP_H
 
 #include "periph/gpio.h"
+#include "periph/adc.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -58,6 +59,19 @@ extern "C" {
 #define ARDUINO_PIN_A6          GPIO_PIN(PA, 7)  /* AIN7 */
 /** @} */
 
+/**
+ * @name    Mapping of Ardunino analog pins to RIOT ADC lines
+ * @{
+ */
+#define ARDUINO_A0              ADC_LINE(0)
+#define ARDUINO_A1              ADC_LINE(1)
+#define ARDUINO_A2              ADC_LINE(2)
+#define ARDUINO_A3              ADC_LINE(3)
+#define ARDUINO_A4              ADC_LINE(4)
+#define ARDUINO_A5              ADC_LINE(5)
+#define ARDUINO_A6              ADC_LINE(6)
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/arduino-zero/include/arduino_board.h b/boards/arduino-zero/include/arduino_board.h
index 620a6cebe7072942d1e4d209c90b61b1b86ee4f6..ece5c3b1cf38977c6b972184e2c17c2edaa58b6c 100644
--- a/boards/arduino-zero/include/arduino_board.h
+++ b/boards/arduino-zero/include/arduino_board.h
@@ -58,6 +58,18 @@ static const gpio_t arduino_pinmap[] = {
     ARDUINO_PIN_A5,
 };
 
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
+    ARDUINO_A4,
+    ARDUINO_A5,
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/arduino-zero/include/arduino_pinmap.h b/boards/arduino-zero/include/arduino_pinmap.h
index 77d7310fbbba0755a97deef479ab955a93b2e41c..d8ae6f0c1a0a2584f6fe66fdc72a5b0960bba329 100644
--- a/boards/arduino-zero/include/arduino_pinmap.h
+++ b/boards/arduino-zero/include/arduino_pinmap.h
@@ -23,6 +23,7 @@
 #define ARDUINO_PINMAP_H
 
 #include "periph/gpio.h"
+#include "periph/adc.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -56,6 +57,18 @@ extern "C" {
 #define ARDUINO_PIN_A5          GPIO_PIN(PB, 2)
 /** @ */
 
+/**
+ * @name    Mapping of Ardunino analog pins to RIOT ADC lines
+ * @{
+ */
+#define ARDUINO_A0              ADC_LINE(0)
+#define ARDUINO_A1              ADC_LINE(1)
+#define ARDUINO_A2              ADC_LINE(2)
+#define ARDUINO_A3              ADC_LINE(3)
+#define ARDUINO_A4              ADC_LINE(4)
+#define ARDUINO_A5              ADC_LINE(5)
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/nucleo-common/include/arduino_board.h b/boards/nucleo-common/include/arduino_board.h
index fe2e0232ff14fc1c41bb68300e5118d7473be32e..2cdd599e2d76141834ddf2885346d844f5c2f903 100644
--- a/boards/nucleo-common/include/arduino_board.h
+++ b/boards/nucleo-common/include/arduino_board.h
@@ -58,6 +58,18 @@ static const gpio_t arduino_pinmap[] = {
     ARDUINO_PIN_A5,
 };
 
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
+    ARDUINO_A4,
+    ARDUINO_A5,
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/nucleo-common/include/arduino_pinmap.h b/boards/nucleo-common/include/arduino_pinmap.h
index 86752c71c632305658c810688a51687410dd7173..75bd8aa18cd78c299a98d4dbbebdc98ec3cd7d7c 100644
--- a/boards/nucleo-common/include/arduino_pinmap.h
+++ b/boards/nucleo-common/include/arduino_pinmap.h
@@ -23,6 +23,7 @@
 #define ARDUINO_PINMAP_H
 
 #include "periph/gpio.h"
+#include "periph/adc.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -64,6 +65,18 @@ extern "C" {
 #define ARDUINO_PIN_A5          GPIO_PIN(PORT_C, 0)
 /** @ */
 
+/**
+ * @name    Mapping of Ardunino analog pins to RIOT ADC lines
+ * @{
+ */
+#define ARDUINO_A0              ADC_LINE(0)
+#define ARDUINO_A1              ADC_LINE(1)
+#define ARDUINO_A2              ADC_LINE(2)
+#define ARDUINO_A3              ADC_LINE(3)
+#define ARDUINO_A4              ADC_LINE(4)
+#define ARDUINO_A5              ADC_LINE(5)
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/nucleo144-common/include/arduino_board.h b/boards/nucleo144-common/include/arduino_board.h
index 7d20e8b573e6c40f35b9ff4ad71b9e6acc5d3b0a..3dae69fc9d7e0aacdeef91044c0b0d979776d584 100644
--- a/boards/nucleo144-common/include/arduino_board.h
+++ b/boards/nucleo144-common/include/arduino_board.h
@@ -53,6 +53,18 @@ static const gpio_t arduino_pinmap[] = {
     ARDUINO_PIN_A5,
 };
 
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
+    ARDUINO_A4,
+    ARDUINO_A5,
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/nucleo144-common/include/arduino_pinmap.h b/boards/nucleo144-common/include/arduino_pinmap.h
index 80d4c5a436a9350b3417da28738e87cf6d0bb6c8..aceb56dbb16e313c2e224f934ae3541c8fac09c2 100644
--- a/boards/nucleo144-common/include/arduino_pinmap.h
+++ b/boards/nucleo144-common/include/arduino_pinmap.h
@@ -23,6 +23,7 @@
 #define ARDUINO_PINMAP_H
 
 #include "periph/gpio.h"
+#include "periph/adc.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -74,6 +75,18 @@ extern "C" {
 #endif
 /** @ */
 
+/**
+ * @name    Mapping of Ardunino analog pins to RIOT ADC lines
+ * @{
+ */
+#define ARDUINO_A0              ADC_LINE(0)
+#define ARDUINO_A1              ADC_LINE(1)
+#define ARDUINO_A2              ADC_LINE(2)
+#define ARDUINO_A3              ADC_LINE(3)
+#define ARDUINO_A4              ADC_LINE(4)
+#define ARDUINO_A5              ADC_LINE(5)
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/nucleo32-common/include/arduino_board.h b/boards/nucleo32-common/include/arduino_board.h
index 2f2b5e3f3d4b3ded003d7e3516e83dbdb6705295..3d0f7bac0e6a1b91c180e9685d4e749a1b52d815 100644
--- a/boards/nucleo32-common/include/arduino_board.h
+++ b/boards/nucleo32-common/include/arduino_board.h
@@ -58,6 +58,20 @@ static const gpio_t arduino_pinmap[] = {
     ARDUINO_PIN_A7
 };
 
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
+    ARDUINO_A4,
+    ARDUINO_A5,
+    ARDUINO_A6,
+    ARDUINO_A7,
+};
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/nucleo32-common/include/arduino_pinmap.h b/boards/nucleo32-common/include/arduino_pinmap.h
index 7b7db79fef7930950f4e816108440aa16d3ecabe..fa2ce17278435330c05408c88bed3be943f6e128 100644
--- a/boards/nucleo32-common/include/arduino_pinmap.h
+++ b/boards/nucleo32-common/include/arduino_pinmap.h
@@ -23,7 +23,7 @@
 #define ARDUINO_PINMAP_H
 
 #include "periph/gpio.h"
-
+#include "periph/adc.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -63,6 +63,20 @@ extern "C" {
 #define ARDUINO_PIN_A7          GPIO_PIN(PORT_A, 2)
 /** @ */
 
+/**
+ * @name    Mapping of Ardunino analog pins to RIOT ADC lines
+ * @{
+ */
+#define ARDUINO_A0              ADC_LINE(0)
+#define ARDUINO_A1              ADC_LINE(1)
+#define ARDUINO_A2              ADC_LINE(2)
+#define ARDUINO_A3              ADC_LINE(3)
+#define ARDUINO_A4              ADC_LINE(4)
+#define ARDUINO_A5              ADC_LINE(5)
+#define ARDUINO_A6              ADC_LINE(6)
+#define ARDUINO_A7              ADC_LINE(7)
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/boards/stm32f4discovery/include/arduino_board.h b/boards/stm32f4discovery/include/arduino_board.h
index dd0a3169b0eba17a15eec749ccb5d59817214d6e..1376f9bd9abf7645644a761e85f8323bec0618ba 100644
--- a/boards/stm32f4discovery/include/arduino_board.h
+++ b/boards/stm32f4discovery/include/arduino_board.h
@@ -19,7 +19,7 @@
 #ifndef ARDUINO_BOARD_H
 #define ARDUINO_BOARD_H
 
-#include "periph/gpio.h"
+#include "arduino_pinmap.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -28,14 +28,24 @@ extern "C" {
 #define ARDUINO_LED         (2)
 
 static const gpio_t arduino_pinmap[] = {
-    GPIO_PIN(PORT_D, 12),
-    GPIO_PIN(PORT_D, 13),
-    GPIO_PIN(PORT_D, 14),
-    GPIO_PIN(PORT_D, 15),
-    GPIO_PIN(PORT_A, 12),
-    GPIO_PIN(PORT_A, 15),
-    GPIO_PIN(PORT_B, 1),
-    GPIO_PIN(PORT_B, 2),
+    ARDUINO_PIN_0,
+    ARDUINO_PIN_1,
+    ARDUINO_PIN_2,
+    ARDUINO_PIN_3,
+    ARDUINO_PIN_4,
+    ARDUINO_PIN_5,
+    ARDUINO_PIN_6,
+    ARDUINO_PIN_7,
+};
+
+/**
+ * @brief   Look-up table for the Arduino's analog pins
+ */
+static const adc_t arduino_analog_map[] = {
+    ARDUINO_A0,
+    ARDUINO_A1,
+    ARDUINO_A2,
+    ARDUINO_A3,
 };
 
 #ifdef __cplusplus
diff --git a/boards/stm32f4discovery/include/arduino_pinmap.h b/boards/stm32f4discovery/include/arduino_pinmap.h
new file mode 100644
index 0000000000000000000000000000000000000000..dfa24aac6b41e7f913c65a6635c3a7531e753050
--- /dev/null
+++ b/boards/stm32f4discovery/include/arduino_pinmap.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C)  2017 HAW Hamburg
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup     boards_stm32f4discovery
+ * @{
+ *
+ * @file
+ * @brief       Mapping from MCU pins to Arduino pins
+ *
+ * You can use the defines in this file for simplified interaction with the
+ * Arduino specific pin numbers.
+ *
+ * @author      Sebastian Meiling <s@mlng.net>
+ */
+
+#ifndef ARDUINO_PINMAP_H
+#define ARDUINO_PINMAP_H
+
+#include "periph/gpio.h"
+#include "periph/adc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name   Mapping of MCU pins to Arduino pins
+ * @{
+ */
+#define ARDUINO_PIN_0           GPIO_PIN(PORT_D, 12)
+#define ARDUINO_PIN_1           GPIO_PIN(PORT_D, 13)
+#define ARDUINO_PIN_2           GPIO_PIN(PORT_D, 14)
+#define ARDUINO_PIN_3           GPIO_PIN(PORT_D, 15)
+#define ARDUINO_PIN_4           GPIO_PIN(PORT_A, 12)
+#define ARDUINO_PIN_5           GPIO_PIN(PORT_A, 15)
+#define ARDUINO_PIN_6           GPIO_PIN(PORT_B, 1)
+#define ARDUINO_PIN_7           GPIO_PIN(PORT_B, 2)
+/** @ */
+
+/**
+ * @name    Mapping of Ardunino analog pins to RIOT ADC lines
+ * @{
+ */
+#define ARDUINO_A0              ADC_LINE(0)
+#define ARDUINO_A1              ADC_LINE(1)
+#define ARDUINO_A2              ADC_LINE(2)
+#define ARDUINO_A3              ADC_LINE(3)
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ARDUINO_PINMAP_H */
+/** @} */
diff --git a/boards/waspmote-pro/Makefile.features b/boards/waspmote-pro/Makefile.features
index 4e3851d2b635b419ea0156619aecbb96f05320bd..abcd9925d9dab7cba488af33596c25ca88c209f7 100644
--- a/boards/waspmote-pro/Makefile.features
+++ b/boards/waspmote-pro/Makefile.features
@@ -1,4 +1,5 @@
 # Put defined MCU peripherals here (in alphabetical order)
+FEATURES_PROVIDED += periph_adc
 FEATURES_PROVIDED += periph_gpio
 FEATURES_PROVIDED += periph_i2c
 FEATURES_PROVIDED += periph_spi
diff --git a/boards/waspmote-pro/include/periph_conf.h b/boards/waspmote-pro/include/periph_conf.h
index 8c2476c53d7a88c3037fd4caf4ee4b68544ba64b..dd97b1ecc33a81799fd22a636e0a93ab84c65b3e 100644
--- a/boards/waspmote-pro/include/periph_conf.h
+++ b/boards/waspmote-pro/include/periph_conf.h
@@ -104,9 +104,18 @@ extern "C" {
 /** @} */
 
 /**
- * @brief    I2C configuration
+ * @name    I2C configuration
+ * @{
  */
 #define I2C_NUMOF           1
+/** @} */
+
+/**
+ * @name     ADC configuration
+ * @{
+ */
+#define ADC_NUMOF           (8U)
+/** @} */
 
 #ifdef __cplusplus
 }
diff --git a/cpu/atmega_common/periph/adc.c b/cpu/atmega_common/periph/adc.c
new file mode 100644
index 0000000000000000000000000000000000000000..fac2ad89184e9049e2f8ea0589a361746b66af87
--- /dev/null
+++ b/cpu/atmega_common/periph/adc.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2016 Laurent Navet <laurent.navet@gmail.com>
+ *               2017 HAW Hamburg, Dimitri Nahm
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser General
+ * Public License v2.1. See the file LICENSE in the top level directory for more
+ * details.
+ */
+
+/**
+ * @ingroup     drivers_periph
+ * @{
+ *
+ * @file
+ * @brief       Low-level ADC driver implementation for ATmega family
+ *
+ * @author      Laurent Navet <laurent.navet@gmail.com>
+ * @author      Dimitri Nahm <dimitri.nahm@haw-hamburg.de>
+ * @author      Sebastian Meiling <s@mlng.net>
+ * @}
+ */
+
+#include "cpu.h"
+#include "mutex.h"
+#include "assert.h"
+#include "periph/adc.h"
+#include "periph_conf.h"
+
+#define ADC_MAX_CLK         (200000U)
+
+static mutex_t lock = MUTEX_INIT;
+
+static inline void _prep(void)
+{
+    mutex_lock(&lock);
+    /* Enable ADC */
+    ADCSRA |= (1 << ADEN);
+}
+
+static inline void _done(void)
+{
+    /* Disable ADC */
+    ADCSRA &= ~(1 << ADEN);
+    mutex_unlock(&lock);
+}
+
+int adc_init(adc_t line)
+{
+    /* check if the line is valid */
+    if (line >= ADC_NUMOF) {
+        return -1;
+    }
+
+    _prep();
+
+    /* Disable corresponding Digital input */
+    if (line < 8) {
+        DIDR0 |= (1 << line);
+    }
+#if defined(CPU_ATMEGA2560)
+    else {
+        DIDR2 |= (1 << (line - 8));
+    }
+#endif
+
+    /* Set ADC-pin as input */
+#if defined(CPU_ATMEGA328P)
+    DDRC &= ~(1 << line);
+    PORTC &= ~(1 << line);
+#elif defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA1281)
+    if (line < 8) {
+        DDRF  &= ~(1 << line);
+        PORTF &= ~(1 << line);
+    }
+#if defined(CPU_ATMEGA2560)
+    else {
+        DDRK  &= ~(1 << (line-8));
+        PORTK &= ~(1 << (line-8));
+    }
+#endif /* CPU_ATMEGA2560 */
+#endif /* CPU_ATMEGA328P */
+
+    /* set clock prescaler to get the maximal possible ADC clock value */
+    for (uint32_t clk_div = 1; clk_div < 8; ++clk_div) {
+        if ((CLOCK_CORECLOCK / (1 << clk_div)) <= ADC_MAX_CLK) {
+            ADCSRA |= clk_div;
+            break;
+        }
+    }
+
+    /* Ref Voltage is Vcc(5V) */
+    ADMUX |= (1 << REFS0);
+
+    _done();
+
+    return 0;
+}
+
+int adc_sample(adc_t line, adc_res_t res)
+{
+    int sample = 0;
+
+    /* check if resolution is applicable */
+    if (res != ADC_RES_10BIT) {
+        return -1;
+    }
+
+    _prep();
+
+    /* set conversion channel */
+#if defined(CPU_ATMEGA328P) || defined(CPU_ATMEGA1281)
+    ADMUX &= 0xf0;
+    ADMUX |= line;
+#elif defined(CPU_ATMEGA2560)
+    if (line < 8) {
+        ADCSRB &= ~(1 << MUX5);
+        ADMUX &= 0xf0;
+        ADMUX |= line;
+    }
+    else {
+        ADCSRB |= (1 << MUX5);
+        ADMUX &= 0xf0;
+        ADMUX |= (line-8);
+    }
+#endif
+
+    /* Start a new conversion. By default, this conversion will
+       be performed in single conversion mode. */
+    ADCSRA |= (1 << ADSC);
+
+    /* Wait until the conversion is complete */
+    while (ADCSRA & (1 << ADSC)) {}
+
+    /* Get conversion result */
+    sample = ADC;
+
+    /* Clear the ADIF flag */
+    ADCSRA |= (1 << ADIF);
+
+    _done();
+
+    return sample;
+}
diff --git a/sys/arduino/base.cpp b/sys/arduino/base.cpp
index 4f61a81c4c653512f9bd745ee43099a8687b460e..4c800018ab20ff8f29977848bd390dec8259cdf0 100644
--- a/sys/arduino/base.cpp
+++ b/sys/arduino/base.cpp
@@ -21,10 +21,13 @@
 extern "C" {
 #include "xtimer.h"
 #include "periph/gpio.h"
+#include "periph/adc.h"
 }
 
 #include "arduino.hpp"
 
+#define ANALOG_PIN_NUMOF     (sizeof(arduino_analog_map) / sizeof(arduino_analog_map[0]))
+
 void pinMode(int pin, int mode)
 {
     gpio_mode_t m = GPIO_OUT;
@@ -58,3 +61,32 @@ void delay(unsigned long msec)
 {
     xtimer_usleep(1000 * msec);
 }
+
+/*
+ * Bitfield for the state of the ADC-channels.
+ * 0: Not initialized
+ * 1: Successfully initialized
+ */
+static uint16_t adc_line_state = 0;
+
+int analogRead(int arduino_pin)
+{
+    int adc_value;
+
+    /* Check if the ADC line is valid */
+    assert((arduino_pin >= 0) && (arduino_pin < (int)ANALOG_PIN_NUMOF));
+
+    /* Initialization of given ADC channel */
+    if (!(adc_line_state & (1 << arduino_pin))) {
+        if (adc_init(arduino_analog_map[arduino_pin]) != 0) {
+            return -1;
+        }
+        /* The ADC channel is initialized */
+        adc_line_state |= 1 << arduino_pin;
+    }
+
+    /* Read the ADC channel */
+    adc_value = adc_sample(arduino_analog_map[arduino_pin], ADC_RES_10BIT);
+
+    return adc_value;
+}
diff --git a/sys/arduino/include/arduino.hpp b/sys/arduino/include/arduino.hpp
index 5323012ad581ed02761914b6328a4339a24efea6..b94f17519f9759993dc1f13689004f5e385fc923 100644
--- a/sys/arduino/include/arduino.hpp
+++ b/sys/arduino/include/arduino.hpp
@@ -82,5 +82,15 @@ int digitalRead(int pin);
  */
 void delay(unsigned long msec);
 
+/**
+ * @brief   Read the current value of the given analog pin
+ *
+ * @param[in] pin       pin to read
+ *
+ * @return a value between 0 to 1023 that is proportionnal
+ * to the voltage applied to the pin
+ */
+int analogRead(int pin);
+
 #endif /* ARDUINO_H */
 /** @} */