diff --git a/src/demo_tasks.rs b/src/demo_tasks.rs
index f900b5a374b5dd6a20173ba0097852e03c861202..329cb1a70ade964de2295bfbbb6d097deebcc43a 100644
--- a/src/demo_tasks.rs
+++ b/src/demo_tasks.rs
@@ -9,14 +9,13 @@ use embedded_graphics::{
     primitives::{PrimitiveStyle, Rectangle, StyledDrawable},
     text::Text,
 };
-use embedded_hal_async::digital::Wait;
 use esp_backtrace as _;
 use esp_println::println;
 use tinybmp::Bmp;
 
 use smart_leds::SmartLedsWrite;
 
-use crate::flow3r::input::{FlowerInputEventSource, InputHandler};
+use crate::flow3r::input::InputHandler;
 
 #[embassy_executor::task]
 pub async fn leds_fade(mut leds: crate::flow3r::leds::Leds) -> ! {
diff --git a/src/flow3r/badgelink/mod.rs b/src/flow3r/badgelink/mod.rs
index b3cab2b21b16361305d218c0c93069d3336a4739..eb46d3e0df6ebcde8425daae69c8922414e0da26 100644
--- a/src/flow3r/badgelink/mod.rs
+++ b/src/flow3r/badgelink/mod.rs
@@ -1,19 +1,17 @@
 use hal::{i2c::I2C, peripherals::I2C0};
-use port_expander::{Max7321, dev::max7321::Driver};
-use shared_bus::{I2cProxy, XtensaMutex, NullMutex};
+use port_expander::{dev::max7321::Driver, Max7321};
+use shared_bus::{I2cProxy, NullMutex, XtensaMutex};
 
 pub mod badgenet;
 
 pub struct BadgeLink {
-    port_expander: Max7321<NullMutex<Driver<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>>>>
+    port_expander: Max7321<NullMutex<Driver<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>>>>,
 }
 
 impl BadgeLink {
     pub fn new(i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>) -> Self {
-        let mut port_expander = port_expander::Max7321::new(i2c, true, true, true, false);
-        Self {
-            port_expander
-        }
+        let port_expander = port_expander::Max7321::new(i2c, true, true, true, false);
+        Self { port_expander }
     }
 
     pub fn left_audio(&mut self) -> Result<(), hal::i2c::Error> {
diff --git a/src/flow3r/captouch.rs b/src/flow3r/captouch.rs
index ac57e163f240cd41e08f5f2899e5f5242896320a..e6c724c77849137923b4aae75b2b1d579fed370b 100644
--- a/src/flow3r/captouch.rs
+++ b/src/flow3r/captouch.rs
@@ -3,64 +3,317 @@ use ad7147::{
     stage::{CapInput, CdcInput, InputConnection},
     Ad7147, DeviceConfiguration, Initialized, StageConfiguration,
 };
+use embassy_futures::select::select;
 use embassy_time::{Delay, Duration, Timer};
 use embedded_hal_async::digital::Wait;
 use esp_println::println;
 use hal::{
-    gpio::{Gpio16, Unknown},
+    gpio::{Gpio15, Gpio16, Unknown},
     i2c::I2C,
-    peripherals::I2C0, prelude::_esp_hal_gpio_InputPin,
+    peripherals::I2C0,
 };
 use shared_bus::{I2cProxy, XtensaMutex};
 
 pub struct CapTouchHandler;
 
 fn init_captouch(
-    i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
+    i2c_bot: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
+    i2c_top: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
 ) -> Result<
-    Ad7147<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>, Initialized, 1>,
+    (
+        Ad7147<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>, Initialized, 12>,
+        Ad7147<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>, Initialized, 12>,
+    ),
     hal::i2c::Error,
 > {
-    let ad7147 = Ad7147::new(i2c, 0b00101100);
-    let config = DeviceConfiguration::builder()
+    let ad7147_bot = Ad7147::new(i2c_bot, 0b00101101);
+    let config_bot = DeviceConfiguration::builder()
         .decimation(DecimationFactor::Factor64)
-        .stages([StageConfiguration::builder()
-            .calibration_enabled(true)
-            .conversion_complete_interrupt_enabled(true)
-            .add_input_connection(InputConnection {
-                cin: CapInput::CIN0,
-                cdc: CdcInput::Positive,
-            })
-            .build()])
+        .stages([
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN0,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN1,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN2,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN3,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN4,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN5,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN6,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN7,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN8,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(2)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN9,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(30)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN10,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(26)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN11,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+        ])
         .build();
-    println!("device config: {:x?}", config.0.to_reg_value_for_init());
-    ad7147.init(config, &mut Delay)
+    let ad7147_top = Ad7147::new(i2c_top, 0b00101100);
+    let config_top = DeviceConfiguration::builder()
+        .decimation(DecimationFactor::Factor64)
+        .stages([
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(30)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN0,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(30)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN1,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(28)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN2,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(28)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN3,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(28)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN4,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(28)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN5,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(28)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN6,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(10)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN7,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(20)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN8,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(20)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN9,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(8)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN10,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+            StageConfiguration::builder()
+                .calibration_enabled(true)
+                .conversion_complete_interrupt_enabled(true)
+                .pos_afe_offset(20)
+                .add_input_connection(InputConnection {
+                    cin: CapInput::CIN11,
+                    cdc: CdcInput::Positive,
+                })
+                .build(),
+        ])
+        .build();
+    Ok((
+        ad7147_bot.init(config_bot, &mut Delay)?,
+        ad7147_top.init(config_top, &mut Delay)?,
+    ))
 }
 
 #[embassy_executor::task]
 pub async fn captouch_controller(
-    i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
-    cap_b_int: Gpio16<Unknown>,
+    i2c_bot: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
+    i2c_top: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>,
+    cap_bot_int: Gpio16<Unknown>,
+    cap_top_int: Gpio15<Unknown>,
 ) -> ! {
-    let mut cap_b_int = cap_b_int.into_pull_up_input();
-    let mut ad7147 = init_captouch(i2c).unwrap();
-
-    let device_id = ad7147.read_device_id().unwrap();
-    println!("captouch device id: {:016b}", device_id);
-
-    let ints = ad7147.read_interrupt_registers().unwrap();
-    println!("ints: {:?}", ints);
+    let mut cap_bot_int = cap_bot_int.into_pull_up_input();
+    let mut cap_top_int = cap_top_int.into_pull_up_input();
+    let (mut ad7147_bot, mut ad7147_top) = init_captouch(i2c_bot, i2c_top).unwrap();
 
-    println!("int pin: {}", cap_b_int.is_input_high());
+    let device_id = ad7147_bot.read_device_id().unwrap();
+    println!("captouch bot device id: {:016b}", device_id);
+    let device_id = ad7147_top.read_device_id().unwrap();
+    println!("captouch top device id: {:016b}", device_id);
     println!("initialized captouch");
     loop {
-        println!("int pin: {}", cap_b_int.is_input_high());
-        // cap_b_int.wait_for_low().await.unwrap();
-        println!("captouch interrupt");
-        let ints = ad7147.read_interrupt_registers().unwrap();
-        println!("ints: {:?}", ints);
-        let measurement = ad7147.read_all_stages().unwrap();
-        println!("{}", measurement[0]);
-        Timer::after(Duration::from_secs(10)).await;
+        //println!("int pin: {}", cap_b_int.is_input_high());
+        select(cap_bot_int.wait_for_low(), cap_top_int.wait_for_low());
+        let _ = ad7147_bot.read_interrupt_registers().unwrap();
+        let _ = ad7147_top.read_interrupt_registers().unwrap();
+        //println!("ints: {:?}", ints);
+        let measurement = ad7147_bot.read_all_stages().unwrap();
+        println!(
+            "{} {} {} {} {} {} {} {} {} {} {} {}",
+            measurement[0],
+            measurement[1],
+            measurement[2],
+            measurement[3],
+            measurement[4],
+            measurement[5],
+            measurement[6],
+            measurement[7],
+            measurement[8],
+            measurement[9],
+            measurement[10],
+            measurement[11]
+        );
+        let measurement = ad7147_top.read_all_stages().unwrap();
+        println!(
+            "{} {} {} {} {} {} {} {} {} {} {} {}",
+            measurement[0],
+            measurement[1],
+            measurement[2],
+            measurement[3],
+            measurement[4],
+            measurement[5],
+            measurement[6],
+            measurement[7],
+            measurement[8],
+            measurement[9],
+            measurement[10],
+            measurement[11]
+        );
+        Timer::after(Duration::from_millis(1000)).await;
     }
 }
diff --git a/src/flow3r/imu.rs b/src/flow3r/imu.rs
index 5038b55408a7c062db9fc9beb57331245d9ee287..b1ed43a13b6fca9e47462516896c4cd5490c2c08 100644
--- a/src/flow3r/imu.rs
+++ b/src/flow3r/imu.rs
@@ -1,4 +1,4 @@
-use bmi270::{interface::I2cInterface, Bmi270, PwrCtrl};
+use bmi270::{interface::I2cInterface, AuxData, AxisData, Bmi270, Error, PwrCtrl};
 use embassy_time::{Duration, Timer};
 use esp_println::println;
 use hal::{i2c::I2C, peripherals::I2C0};
@@ -8,30 +8,34 @@ pub struct ImuHandler {
     imu: Bmi270<I2cInterface<I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>>>,
 }
 
-impl ImuHandler {}
+impl ImuHandler {
+    pub fn new(i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>) -> Self {
+        let mut bmi270 = Bmi270::new_i2c(i2c, bmi270::I2cAddr::Default, bmi270::Burst::Max);
 
-#[embassy_executor::task]
-pub async fn imu_manager(i2c: I2cProxy<'static, XtensaMutex<I2C<'static, I2C0>>>) -> ! {
-    let mut bmi270 = Bmi270::new_i2c(i2c, bmi270::I2cAddr::Default, bmi270::Burst::Max);
+        let chip_id = bmi270.get_chip_id().unwrap();
+        println!("imu chip id: {}", chip_id);
 
-    let chip_id = bmi270.get_chip_id().unwrap();
-    println!("imu chip id: {}", chip_id);
+        bmi270.init().unwrap();
 
-    bmi270.init().unwrap();
-
-    let pwr_ctrl = PwrCtrl {
-        aux_en: false,
-        gyr_en: true,
-        acc_en: true,
-        temp_en: false,
-    };
-    bmi270.set_pwr_ctrl(pwr_ctrl).unwrap();
+        let pwr_ctrl = PwrCtrl {
+            aux_en: false,
+            gyr_en: true,
+            acc_en: true,
+            temp_en: false,
+        };
+        bmi270.set_pwr_ctrl(pwr_ctrl).unwrap();
+        Self { imu: bmi270 }
+    }
 
-    let data = bmi270.get_data().unwrap();
+    pub fn acceleration(&mut self) -> Result<AxisData, Error<hal::i2c::Error, ()>> {
+        self.imu.get_acc_data()
+    }
 
-    println!("imu data: {:?}", data);
+    pub fn rotation(&mut self) -> Result<AxisData, Error<hal::i2c::Error, ()>> {
+        self.imu.get_gyr_data()
+    }
 
-    loop {
-        Timer::after(Duration::from_secs(10)).await;
+    pub fn atmospheric_pressure(&mut self) -> Result<AuxData, Error<hal::i2c::Error, ()>> {
+        todo!()
     }
 }
diff --git a/src/flow3r/input.rs b/src/flow3r/input.rs
index 3546bf0b0be9db8faf03130e1137b9b23705cf37..ae557b14860b5eafa4d02ba83975efd217faadff 100644
--- a/src/flow3r/input.rs
+++ b/src/flow3r/input.rs
@@ -70,13 +70,11 @@ pub struct Flow3rInput(FlowerInputEventSource);
 
 impl Flow3rInput {
     pub async fn wait_for_release(&mut self) -> Result<(), embassy_sync::pubsub::Error> {
-        wait_for_event(self.0, Flow3rInputEventType::Press)
-            .await
+        wait_for_event(self.0, Flow3rInputEventType::Press).await
     }
 
     pub async fn wait_for_press(&mut self) -> Result<(), embassy_sync::pubsub::Error> {
-        wait_for_event(self.0, Flow3rInputEventType::Press)
-            .await
+        wait_for_event(self.0, Flow3rInputEventType::Press).await
     }
 
     pub async fn wait_for_any(&mut self) -> Result<(), embassy_sync::pubsub::Error> {
diff --git a/src/flow3r/mod.rs b/src/flow3r/mod.rs
index a252d08e1a834b9cf509ed7530686ce16df4c25e..6551c92f820776ad4f768543843040f26c6fbbcf 100644
--- a/src/flow3r/mod.rs
+++ b/src/flow3r/mod.rs
@@ -1,5 +1,8 @@
 use self::badgelink::BadgeLink;
+use self::captouch::CapTouchHandler;
 use self::display::Display;
+use self::imu::ImuHandler;
+use self::input::InputHandler;
 use self::leds::Leds;
 
 pub mod badgelink;
@@ -11,13 +14,30 @@ pub mod leds;
 pub mod sdcard;
 
 pub struct Flow3r {
+    pub badgelink: BadgeLink,
+    pub captouch: CapTouchHandler,
     pub display: Display,
+    pub imu: ImuHandler,
+    pub inputs: InputHandler,
     pub leds: Leds,
-    pub badgelink: BadgeLink,
 }
 
 impl Flow3r {
-    pub fn new(display: Display, leds: Leds, badgelink: BadgeLink) -> Self {
-        Self { display, leds, badgelink }
+    pub fn new(
+        badgelink: BadgeLink,
+        captouch: CapTouchHandler,
+        display: Display,
+        imu: ImuHandler,
+        inputs: InputHandler,
+        leds: Leds,
+    ) -> Self {
+        Self {
+            badgelink,
+            captouch,
+            display,
+            imu,
+            inputs,
+            leds,
+        }
     }
 }
diff --git a/src/runtime.rs b/src/runtime.rs
index bc802f1d50e15ea576fd5eda3333d2c1cf5688fd..7834e7f0331c48b2e0cda0a3ffeb350aa6085b67 100644
--- a/src/runtime.rs
+++ b/src/runtime.rs
@@ -2,7 +2,7 @@ use embassy_executor::{Executor, Spawner};
 use embassy_time::{Duration, Timer};
 use hal::{
     clock::{ClockControl, Clocks},
-    cpu_control::{self, AppCoreGuard, CpuControl},
+    cpu_control::CpuControl,
     embassy,
     gdma::Gdma,
     i2c::I2C,
@@ -17,11 +17,13 @@ use hal::{
 use static_cell::StaticCell;
 
 use crate::flow3r::{
-    captouch::captouch_controller,
+    badgelink::BadgeLink,
+    captouch::{captouch_controller, CapTouchHandler},
     display::{display_refresh, Display},
-    input::input_controller,
+    imu::ImuHandler,
+    input::{input_controller, InputHandler},
     leds::init_leds,
-    Flow3r, badgelink::BadgeLink,
+    Flow3r,
 };
 use crate::main;
 
@@ -82,7 +84,7 @@ async fn init_runtime() {
 
     embassy::init(&clocks, SystemTimer::new(peripherals.SYSTIMER));
 
-    let cpu_control = CpuControl::new(system.cpu_control);
+    let _cpu_control = CpuControl::new(system.cpu_control);
 
     // Async requires the GPIO interrupt to wake futures
     hal::interrupt::enable(
@@ -101,7 +103,8 @@ async fn init_runtime() {
         0,
     )
     .unwrap();
-    let leds = init_leds(pulse.channel0, io.pins.gpio14);
+
+    // Init I2C
 
     let sda = io.pins.gpio2;
     let scl = io.pins.gpio1;
@@ -115,8 +118,12 @@ async fn init_runtime() {
         &clocks,
     );
 
+    // Create shared I2C Bus
+
     let i2c_busmanager = shared_bus::new_xtensa!(I2C<'static, I2C0> = i2c).unwrap();
 
+    // Init SPI + DMA
+
     let sck = io.pins.gpio41;
     let mosi = io.pins.gpio42;
     let spi = Spi::new_no_cs_no_miso(
@@ -132,13 +139,16 @@ async fn init_runtime() {
     let dma = Gdma::new(peripherals.DMA, &mut system.peripheral_clock_control);
     let dma_channel = dma.channel0;
 
-    // Display backlight control
+    // Init Display backlight control
+
     let ledc = LEDC::new(
         peripherals.LEDC,
         clocks,
         &mut system.peripheral_clock_control,
     );
 
+    // Init display early to clear pixel mash from screen
+
     let mut display = Display::new(
         spi,
         dma_channel,
@@ -150,6 +160,8 @@ async fn init_runtime() {
     .await;
     display.clear().await.unwrap();
 
+    // Init uart
+
     let mut uart0 = Uart::new(peripherals.UART0, &mut system.peripheral_clock_control);
     uart0.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16);
 
@@ -159,11 +171,19 @@ async fn init_runtime() {
     )
     .unwrap();
 
-    let rng = RNG.init(Rng::new(peripherals.RNG));
+    let _rng = RNG.init(Rng::new(peripherals.RNG));
+
+    // Init Flow3r components
 
     let badgelink = BadgeLink::new(i2c_busmanager.acquire_i2c());
+    let imu = ImuHandler::new(i2c_busmanager.acquire_i2c());
+    let inputs = InputHandler;
+    let captouch = CapTouchHandler;
+    let leds = init_leds(pulse.channel0, io.pins.gpio14);
 
-    let flow3r = Flow3r::new(display, leds, badgelink);
+    let flow3r = Flow3r::new(badgelink, captouch, display, imu, inputs, leds);
+
+    // Spawn background tasks
 
     let spawner = Spawner::for_current_executor().await;
     spawner
@@ -176,9 +196,13 @@ async fn init_runtime() {
         .ok();
     spawner
         .spawn(captouch_controller(
+            i2c_busmanager.acquire_i2c(),
             i2c_busmanager.acquire_i2c(),
             io.pins.gpio16,
+            io.pins.gpio15,
         ))
         .ok();
+
+    // Hand over to main task
     spawner.spawn(main(flow3r)).ok();
 }