Browse Source

IMU doesn't clear interrupt source mask on reset. I needed to manually clear it. I also wrote a lot of code for the ideasX interface

curiousmuch 6 years ago
parent
commit
97871eefb3

+ 78 - 0
.vscode/c_cpp_properties.json

@@ -0,0 +1,78 @@
+{
+    "configurations": [
+        {
+            "name": "Mac",
+            "includePath": [
+                "/usr/include",
+                "/usr/local/include",
+                "${workspaceRoot}"
+            ],
+            "defines": [],
+            "intelliSenseMode": "clang-x64",
+            "browse": {
+                "path": [
+                    "/usr/include",
+                    "/usr/local/include",
+                    "${workspaceRoot}"
+                ],
+                "limitSymbolsToIncludedHeaders": true,
+                "databaseFilename": ""
+            },
+            "macFrameworkPath": [
+                "/System/Library/Frameworks",
+                "/Library/Frameworks"
+            ]
+        },
+        {
+            "name": "Linux",
+            "includePath": [
+                "/usr/include/newlib/c++/5.4.1",
+                "/usr/include/x86_64-linux-gnu/c++/7",
+                "/usr/include/c++/7",
+                "/usr/local/include",
+                "/usr/include/newlib",
+                "/usr/include/x86_64-linux-gnu",
+                "/usr/include",
+                "${workspaceRoot}",
+                "${workspaceRoot}/include"
+            ],
+            "defines": [],
+            "intelliSenseMode": "clang-x64",
+            "browse": {
+                "path": [
+                    "/usr/include/newlib/c++/5.4.1",
+                    "/usr/include/x86_64-linux-gnu/c++/7",
+                    "/usr/include/c++/7",
+                    "/usr/local/include",
+                    "/usr/include/newlib",
+                    "/usr/include/x86_64-linux-gnu",
+                    "/usr/include",
+                    "${workspaceRoot}"
+                ],
+                "limitSymbolsToIncludedHeaders": true,
+                "databaseFilename": ""
+            }
+        },
+        {
+            "name": "Win32",
+            "includePath": [
+                "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
+                "${workspaceRoot}"
+            ],
+            "defines": [
+                "_DEBUG",
+                "UNICODE"
+            ],
+            "intelliSenseMode": "msvc-x64",
+            "browse": {
+                "path": [
+                    "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
+                    "${workspaceRoot}"
+                ],
+                "limitSymbolsToIncludedHeaders": true,
+                "databaseFilename": ""
+            }
+        }
+    ],
+    "version": 3
+}

+ 5 - 0
.vscode/settings.json

@@ -0,0 +1,5 @@
+{
+    "files.associations": {
+        "ideasx_interface.h": "c"
+    }
+}

+ 2 - 1
Makefile

@@ -148,7 +148,7 @@ endif
 #endif
 
 
-ESPTOOL_OPTS=--port $(ESPPORT) --baud $(ESPBAUD)
+ESPTOOL_OPTS= --port $(ESPPORT) --baud $(ESPBAUD) 
 
 #32m
 ESP_INIT_DATA_DEFAULT_ADDR = 0xfc000
@@ -234,6 +234,7 @@ flash:
 wipe:
 	python2 $(ESPTOOL) $(ESPTOOL_OPTS) erase_flash
 
+
 fast: all flash openport
 
 openport:

+ 16 - 2
hal/io.c

@@ -89,9 +89,19 @@ void ICACHE_FLASH_ATTR IO_SetIMUCallback(imu_function_t imu_cb)
      ETS_GPIO_INTR_DISABLE();
  }
 
+ void ICACHE_FLASH_ATTR IO_ActivateDebounceTimer(void)
+ {
+     io_config.debounce_timer = true; 
+ }
+
 void ICACHE_FLASH_ATTR IO_DisableDebounceTimer(void)
 {
+    io_config.debounce_timer = false; 
+}
 
+uint32_t ICACHE_FLASH_ATTR IO_GetStates(void)
+{
+    return GPIO_REG_READ(GPIO_IN_ADDRESS);
 }
 
 void ICACHE_FLASH_ATTR IO_Shutdown(void)
@@ -118,6 +128,7 @@ void ICACHE_FLASH_ATTR IO_GPIO_Handler(void)
 			{
 				case SWITCH_A:
                 {
+                    //ESP_LOGD(TAG, "GPIO_STATUS: %x", gpio_states);
                     LSM6DS3_Interrupt_et imu_interrupt;
                     imu_interrupt = LSM6DS3_Get_Interrupts();
                     if (imu_interrupt != LSM6DS3_NO_INT)
@@ -129,8 +140,9 @@ void ICACHE_FLASH_ATTR IO_GPIO_Handler(void)
                     }
                     else
                     {
+                        os_delay_us(10000);
                         if (io_config.switch_a_cb != NULL)
-                            io_config.switch_a_cb();
+                            io_config.switch_a_cb(GPIO_REG_READ(GPIO_IN_ADDRESS));
                         if (io_config.debounce_timer)
                             os_timer_arm(&io_config.switch_a_timer, io_config.debounce_delay, 0);
                     }
@@ -138,8 +150,10 @@ void ICACHE_FLASH_ATTR IO_GPIO_Handler(void)
 				}
 				case SWITCH_B:
                 {
+                    //ESP_LOGD(TAG, "GPIO_STATUS: %x", gpio_states);    
+                    os_delay_us(10000);                    
                     if (io_config.switch_b_cb != NULL)
-                        io_config.switch_b_cb();
+                        io_config.switch_b_cb(GPIO_REG_READ(GPIO_IN_ADDRESS));
                     if (io_config.debounce_timer)
                         os_timer_arm(&io_config.switch_b_timer, io_config.debounce_delay, 0);
                     break;

+ 10 - 3
hal/lsm6ds3.c

@@ -163,19 +163,26 @@ void ICACHE_FLASH_ATTR LSM6DS3_DisableMotion(void)
 {
 	LSM6DS3_Reset();
 	Sensor_IO_Set_Register(LSM6DS3_CTRL2_G, LSM6DS3_ODR_G_POWERDOWN);      // disable gyro
-	Sensor_IO_Set_Register(LSM6DS3_CTRL1_XL, LSM6DS3_ODR_XL_POWERDOWN);    // disable XL
+    Sensor_IO_Set_Register(LSM6DS3_CTRL1_XL, LSM6DS3_ODR_XL_POWERDOWN);    // disable XL
+    Sensor_IO_Set_Register(LSM6DS3_MD1_CFG, 0);                            // clear all interrupt vectors (the reset registers aren't cleared on reset?)
 	Sensor_IO_Set_Register(LSM6DS3_CTRL3_C, LSM6DS3_H_LACTIVE);
 }
 
 // determine if there has been a FIFO or significant motion interrupt
 LSM6DS3_Interrupt_et ICACHE_FLASH_ATTR LSM6DS3_Get_Interrupts(void)
 {
-    uint32_t fifo_status2, wake_up_src;
+    uint32_t fifo_status2, wake_up_src, md1_cfg;
     Sensor_IO_Read(LSM6DS3_FIFO_STATUS2, 1, &fifo_status2);
     Sensor_IO_Read(LSM6DS3_WAKE_UP_SRC, 1, &wake_up_src);
+    Sensor_IO_Read(LSM6DS3_MD1_CFG, 1, &md1_cfg);								     // set interrupt for INTX (1 is connected to PBA)
+    
 
+    // ESP_LOGV(TAG, "WAKE_UP: %x", wake_up_src);
+    // ESP_LOGV(TAG, "FIFO_STATUS: %x", fifo_status2);
+    // ESP_LOGV(TAG, "MD1 CFG: %x", md1_cfg);
+    
 
-    if (wake_up_src)
+    if ((wake_up_src & 0x0F) && (md1_cfg & LSM6DS3_INT1_WU))
     {
         ESP_LOGV(TAG, "significant motion interrupt");
         return LSM6DS3_SIGN_MOTION_INT;

+ 1 - 1
include/hal/io.h

@@ -29,7 +29,7 @@ typedef enum {
     IMU_MOTION
 } IMU_Interrupt_et;
 
-typedef void (* switch_function_t)(void);
+typedef void (* switch_function_t)(uint32_t);
 typedef void (* imu_function_t)(IMU_Interrupt_et);
 
 typedef struct {

+ 6 - 1
include/interface/encoder_interface.h

@@ -15,12 +15,17 @@
 #define Encoder_SetIMUCallback IO_SetIMUCallback
 #define Encoder_SetSwitchCallback IO_SetSwitchCallback
 #define Encoder_DisableDebounceTimer IO_DisableDebounceTimer
+#define Encoder_GetIOStates IO_GetStates
+
 #define Encoder_EnableMotion LSM6DS3_EnableMotion
 #define Encoder_DisableMotion LSM6DS3_DisableMotion
 #define Encoder_GetVoltage max17043_getVoltage
 #define Encoder_GetSOC max17043_getSOC
-
+#define Encoder_EnableIMUI2CInterface LSM6DS3_Enable_I2C_Bridge
 
 #define Encoder_InitUART uart_init
 
+void ICACHE_FLASH_ATTR Encoder_Shutdown(void);
+void ICACHE_FLASH_ATTR Encoder_Restart(void);
+
 #endif

+ 19 - 13
include/interface/ideasx_interface.h

@@ -81,6 +81,7 @@ typedef struct{
 typedef struct {
     uint8_t     health_topic[40];
     uint8_t     command_topic[40];
+    uint8_t     data_topic[40];
     uint8_t     device_id[40];
     uint8_t     mqtt_host[40];
     uint32_t    mqtt_port;
@@ -95,19 +96,10 @@ typedef struct {
 
 typedef struct {
     uint8_t topic[20];
-    uint32_t* function;
-} command_ota_t;
-
-typedef struct {
-    uint8_t topic[20];
-    uint32_t* function;
-} command_shutdown_t;
-
-typedef struct {
-    command_ota_t       ota;
-    command_shutdown_t  shutdown;
+    ideasX_function_t function;
 } IdeasX_Command_t;
 
+
 #define HW_VERSION_HEALTH_TOPIC    "hw_ver"
 #define FW_VERSION_HEALTH_TOPIC    "fw_ver"
 #define ALIVE_HEALTH_TOPIC         "alive"
@@ -122,13 +114,27 @@ typedef struct {
 #define RSSI_HEALTH_TOPIC          "rssi"
 #define AUTH_HEALTH_TOPIC          "auth"
 
+#define OTA_COMMAND_TOPIC          "ota"
+#define RESTART_COMMAND_TOPIC      "restart"
+#define SHUTDOWN_COMMAND_TOPIC     "shutdown"
+
+#define RESTART_COMMAND_INDEX   0 
+#define SHUTDOWN_COMMAND_INDEX  1
+#define NUMBER_OF_COMMANDS      2 
+#define COMMAND_QOS     1 
+#define COMMAND_RETAIN  0
 
 #define HEALTH_QOS      0
-#define HEALTH_RETAIN   0
+#define HEALTH_RETAIN   1
+#define HEALTH_REPORT_RATE_DEFAULT  120     // seconds
+
+#define DATA_QOS 0 
+#define DATA_RETAIN 0
+
+
 #define HW_VERSION_MAJOR_DEFAULT    0
 #define HW_VERSION_MINOR_DEFAULT    0
 #define FW_VERSION_MAJOR_DEFAULT    0
 #define FW_VERSION_MINOR_DEFAULT    0
-#define HEALTH_REPORT_RATE_DEFAULT  120     // seconds
 
 #endif

+ 1 - 0
include/interface/light_interface.h

@@ -16,5 +16,6 @@
 #define Light_AdaptiveBar()                 WS2812_SetColor(WS2812_ORANGE, WS2812_SOLID)
 
 void Light_Shutdown(void);
+void Light_Restart(void);
 
 #endif

+ 3 - 3
include/user_config.h

@@ -16,15 +16,15 @@
 #define MQTT_HOST_DEFAULT               "10.42.0.1" //or "mqtt.yourdomain.com"
 #define MQTT_PORT_DEFAULT               1883
 #define MQTT_BUF_SIZE                   1024
-#define MQTT_KEEPALIVE_DEFAULT          120             // seconds
+#define MQTT_KEEPALIVE_DEFAULT          20             // seconds
 #define MQTT_CLEAN_SESSION              1
 
 
 #define QUEUE_BUFFER_SIZE               2048
 #define MQTT_RECONNECT_TIMEOUT          5               // seconds
 #define DEFAULT_SECURITY                0
-#define PROTOCOL_NAMEv31
-//#define PROTOCOL_NAMEv311
+//#define PROTOCOL_NAMEv31
+#define PROTOCOL_NAMEv311
 
 //#define MQTT_SSL_ENABLE
 //#define MQTT_USER_DEFAULT               "USER"

+ 8 - 0
interface/encoder_interface.c

@@ -23,6 +23,14 @@ void ICACHE_FLASH_ATTR Encoder_Shutdown(void)
 {
     Light_Shutdown();
     IO_Shutdown();
+    
+    //system_deep_sleep(0);
+}
+
+void ICACHE_FLASH_ATTR Encoder_Restart(void)
+{
+    Light_Restart(); 
+    system_restart();   
 }
 
 /* Motion Functions */

+ 80 - 4
interface/ideasx_interface.c

@@ -6,15 +6,43 @@ MQTT_Client mqttClient;
 static IdeasX_Config_t ideasX_config;
 static IdeasX_Health_t ideasX_health;
 static os_timer_t health_timer;
+static IdeasX_Command_t command_array[NUMBER_OF_COMMANDS]; 
 
+void ICACHE_FLASH_ATTR IdeasX_Publish_Buttons(uint32_t button_states)
+{
+    ESP_LOGD(TAG, "publishing button states");
+    uint8_t topic[40];
+    uint8_t payload[4];
+
+    // convert uint32_t to array of uint8_t for MQTT_Publish
+    uint8_t * buttonp = (uint8_t *)&button_states; 
+    payload[0] = buttonp[0];
+    payload[1] = buttonp[1];
+    payload[2] = buttonp[2];
+    payload[3] = buttonp[3];
+
+    os_sprintf(topic, "%s%s", ideasX_config.data_topic, "button");
+    MQTT_Publish(&mqttClient, topic, payload, sizeof(payload) , DATA_QOS, DATA_RETAIN);    
+}
+
+static void ICACHE_FLASH_ATTR IdeasX_SetHealthInfo(uint16_t vcell, uint16_t soc, uint16_t rssi)
+{
+    ideasX_health.vcell.value = vcell;
+    ideasX_health.soc.value = soc;
+    ideasX_health.rssi.value = rssi; 
+}
 
 static void ICACHE_FLASH_ATTR ideasX_publish_health(void)
 {
     uint8_t topic[40], payload[40];
+    Encoder_EnableIMUI2CInterface(true);
     ideasX_health.vcell.value = Encoder_GetVoltage();
     ideasX_health.soc.value = Encoder_GetSOC();
     ideasX_health.rssi.value = wifi_station_get_rssi();
 
+    ESP_LOGI(TAG, "vcell: %d", Encoder_GetVoltage());
+    ESP_LOGI(TAG, "soc: %d", Encoder_GetSOC());
+    
     os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.vcell.topic);
     os_sprintf(payload, "%d", ideasX_health.vcell.value);
     MQTT_Publish(&mqttClient, topic, payload, os_strlen(payload), HEALTH_QOS, HEALTH_RETAIN);
@@ -39,6 +67,9 @@ static void ICACHE_FLASH_ATTR ideasX_connected_cb(uint32_t *args)
     if (ideasX_config.success_cb != NULL)
         ideasX_config.success_cb();
 
+    // subscribe to command topic 
+    MQTT_Subscribe(&mqttClient, ideasX_config.command_topic, COMMAND_QOS);
+
     // publish static health information
     os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.hw_ver.topic);
     os_sprintf(payload, "%d,%d", ideasX_health.hw_ver.major, ideasX_health.hw_ver.minor);
@@ -95,18 +126,21 @@ void ICACHE_FLASH_ATTR IdeasX_Connect(void)
 
 void ICACHE_FLASH_ATTR IdeasX_Disconnect(void)
 {
+    if (ideasX_config.fail_cb != NULL)
+        ideasX_config.fail_cb();
     MQTT_Disconnect(&mqttClient);
 }
 
-void ICACHE_FLASH_ATTR ideasX_system_config_init()
+void ICACHE_FLASH_ATTR ideasX_system_config_init(void)
 {
     uint8_t mac_address[6];
     wifi_get_macaddr(STATION_MODE, mac_address);
     os_sprintf(ideasX_config.device_id, MACSTR, MAC2STR(mac_address));
     os_sprintf(ideasX_config.mqtt_client_id, MACSTR, MAC2STR(mac_address));
 
-    os_sprintf(ideasX_config.command_topic, "encoder/%s/command/", ideasX_config.device_id);
+    os_sprintf(ideasX_config.command_topic, "encoder/%s/command/#", ideasX_config.device_id);
     os_sprintf(ideasX_config.health_topic, "encoder/%s/health/", ideasX_config.device_id);
+    os_sprintf(ideasX_config.data_topic, "encoder/%s/data/", ideasX_config.device_id);
     os_sprintf(ideasX_config.mqtt_host, "%s", MQTT_HOST_DEFAULT);
     ideasX_config.mqtt_port = MQTT_PORT_DEFAULT;
     os_sprintf(ideasX_config.mqtt_user, "%s", "");
@@ -123,6 +157,45 @@ void ICACHE_FLASH_ATTR ideasX_system_config_init()
 
 }
 
+void ICACHE_FLASH_ATTR ideasX_command_array_init(void)
+{
+    os_sprintf(command_array[SHUTDOWN_COMMAND_INDEX].topic, "%s", SHUTDOWN_COMMAND_TOPIC);
+    os_sprintf(command_array[RESTART_COMMAND_INDEX].topic, "%s", RESTART_COMMAND_TOPIC); 
+    command_array[SHUTDOWN_COMMAND_INDEX].function = Encoder_Shutdown;
+    command_array[RESTART_COMMAND_INDEX].function = Encoder_Restart;
+}
+
+static void ICACHE_FLASH_ATTR ideasX_data_cb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t data_len)
+{
+  uint8_t *topicBuf = (uint8_t*)os_zalloc(topic_len + 1),
+        *dataBuf = (uint8_t*)os_zalloc(data_len + 1);
+
+  MQTT_Client* client = (MQTT_Client*)args;
+  os_memcpy(topicBuf, topic, topic_len);
+  topicBuf[topic_len] = 0;
+  os_memcpy(dataBuf, data, data_len);
+  dataBuf[data_len] = 0;
+  ESP_LOGI(TAG, "Receive topic: %s, data: %s \r\n", topicBuf, dataBuf);
+
+  uint8_t len = os_strlen(ideasX_config.command_topic) - 1;
+  uint8_t* command_topic = topicBuf + len;
+
+  ESP_LOGD(TAG, "command topic: %s", command_topic);
+
+    uint8_t i; 
+    for (i=0; i<NUMBER_OF_COMMANDS; i++)
+    {
+        if (!strcmp(command_array[i].topic, command_topic))
+        {
+            ESP_LOGD(TAG, "Found the command: %s", command_array[i].topic);
+            command_array[i].function(); 
+        }
+    }
+
+  os_free(topicBuf);
+  os_free(dataBuf);
+}
+
 void ICACHE_FLASH_ATTR ideasX_health_config_init()
 {
     // setup ideasX topics
@@ -165,15 +238,18 @@ void ICACHE_FLASH_ATTR IdeasX_SetStatusCallbacks(ideasX_function_t success, idea
 
 void ICACHE_FLASH_ATTR IdeasX_Init(void)
 {
+    uint8_t topic[40];
     ideasX_system_config_init();
     ideasX_health_config_init();
+    ideasX_command_array_init();
 
     MQTT_InitConnection(&mqttClient, ideasX_config.mqtt_host, ideasX_config.mqtt_port, DEFAULT_SECURITY);
     MQTT_InitClient(&mqttClient, ideasX_config.mqtt_client_id, ideasX_config.mqtt_user, ideasX_config.mqtt_pass,
         ideasX_config.mqtt_keepalive, MQTT_CLEAN_SESSION);
-    MQTT_InitLWT(&mqttClient, ideasX_health.alive.topic, "0", 0, 0);
+    os_sprintf(topic, "%s%s", ideasX_config.health_topic, ideasX_health.alive.topic);
+    MQTT_InitLWT(&mqttClient, topic, "0", HEALTH_QOS, HEALTH_RETAIN);
     MQTT_OnConnected(&mqttClient, ideasX_connected_cb);
     MQTT_OnDisconnected(&mqttClient, ideasX_disconnected_cb);
     //MQTT_OnPublished(&mqttClient, mqttPublishedCb);
-    //MQTT_OnData(&mqttClient, mqttDataCb);
+    MQTT_OnData(&mqttClient, ideasX_data_cb);
 }

+ 14 - 1
interface/light_interface.c

@@ -1,6 +1,6 @@
 #include "interface/light_interface.h"
 
-void Light_Shutdown(void)
+void ICACHE_FLASH_ATTR Light_Shutdown(void)
 {
     uint8_t i;
     for(i=0;i<3;i++)
@@ -11,3 +11,16 @@ void Light_Shutdown(void)
         os_delay_us(500000);
     }
 }
+
+void ICACHE_FLASH_ATTR Light_Restart(void)
+{
+    uint8_t i;
+    for(i=0;i<3;i++)
+    {
+        WS2812_SetColor(WS2812_BLUE, WS2812_SOLID);
+        os_delay_us(500000);
+        WS2812_SetColor(WS2812_OFF, WS2812_SOLID);
+        os_delay_us(500000);
+    }
+}
+

+ 4 - 1
interface/uart_interface.c

@@ -7,6 +7,7 @@
 #include "interface/uart_interface.h"
 #include "interface/light_interface.h"
 #include "hal/io.h"
+#include "hal/lsm6ds3.h"
 
 static const char* TAG = "uart_interface.c";
 
@@ -40,7 +41,7 @@ static void show_IP(void)
  	wifi_get_ip_info(STATION_IF, &ipconfig);
  	if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0) {
  		os_printf("IP: %d.%d.%d.%d, MASK: %d.%d.%d.%d, GW: %d.%d.%d.%d\n",
- 			IP2STR(&ipconfig.ip), IP2STR(&ipconfig.netmask), IP2STR(&ipconfig.gw));
+ 		IP2STR(&ipconfig.ip), IP2STR(&ipconfig.netmask), IP2STR(&ipconfig.gw));
  	} else {
  		os_printf("Network Status: %d\n", wifi_station_get_connect_status());
  	}
@@ -99,6 +100,8 @@ static void show_info(void)
     os_printf("--------Network Status------------\n");
     show_IP();
     show_WiFi_current();
+    LSM6DS3_Get_Interrupts();
+    //os_printf("GPIO Interrupt Mask: %x", )
     // print broker information
 }
 

+ 26 - 2
user/user_main.c

@@ -72,6 +72,11 @@ void ICACHE_FLASH_ATTR imu_cb(IMU_Interrupt_et interrupt)
                 Light_AccessPointSearching();
                 WiFi_Connect(WIFI_TIMEOUT);
             }
+            // the LSM6DS3 retains and old interrupt that isn't cleared until the first time switch 1 is pressed. 
+            if (system_config.wifi_connected == true && system_config.motion_detector == false)
+            {
+                Encoder_EnableIOInterrupts();
+            }
             break;
         }
         default:
@@ -81,7 +86,7 @@ void ICACHE_FLASH_ATTR imu_cb(IMU_Interrupt_et interrupt)
     }
 }
 
-void ICACHE_FLASH_ATTR switch_a_cb(void)
+void ICACHE_FLASH_ATTR switch_a_cb(uint32_t gpio_states)
 {
     if (system_config.wifi_connected == false)
     {
@@ -91,9 +96,14 @@ void ICACHE_FLASH_ATTR switch_a_cb(void)
         Light_AccessPointSearching();
         WiFi_Connect(WIFI_TIMEOUT);
     }
+    if (system_config.ideasX_connected)
+    {
+        ESP_LOGD(TAG, "GPIO_STATUS: %x", gpio_states);        
+        IdeasX_Publish_Buttons(gpio_states);
+    }
 }
 
-void ICACHE_FLASH_ATTR switch_b_cb(void)
+void ICACHE_FLASH_ATTR switch_b_cb(uint32_t gpio_states)
 {
     if (system_config.wifi_connected == false)
     {
@@ -103,16 +113,28 @@ void ICACHE_FLASH_ATTR switch_b_cb(void)
         Light_AccessPointSearching();
         WiFi_Connect(WIFI_TIMEOUT);
     }
+
+    if (system_config.ideasX_connected)
+    {
+        ESP_LOGD(TAG, "GPIO_STATUS: %x", gpio_states);
+        IdeasX_Publish_Buttons(gpio_states);
+    }
 }
 
 void ICACHE_FLASH_ATTR ideasX_success_cb(void)
 {
     Light_BrokerSuccess();
+    system_config.ideasX_connected = true; 
+    Encoder_EnableIOInterrupts();
+    IO_ActivateDebounceTimer(); 
 }
 
 void ICACHE_FLASH_ATTR ideasX_fail_cb(void)
 {
     Light_BrokerFailure();
+    system_config.ideasX_connected = false; 
+    Encoder_DisableIOInterrupts();
+    IO_DisableDebounceTimer();
 }
 
 void ICACHE_FLASH_ATTR wifi_success_cb(void)
@@ -188,6 +210,7 @@ void ICACHE_FLASH_ATTR wifi_fail_cb(wifi_failure_et failure_code)
 
 void user_init(void)
 {
+    os_delay_us(1000000);
     Encoder_InitUART(BIT_RATE_115200, BIT_RATE_115200, DISABLE_UART1); // this needs to be abstracted
 
     os_printf("\n\n----------------------------------------------------------\n");
@@ -199,6 +222,7 @@ void user_init(void)
     IdeasX_Init();
     Encoder_InitIO();
     Encoder_DisableIOInterrupts();
+    Encoder_EnableIMUI2CInterface(true);
     //IO_Shutdown();                       // set the shutdown pin for testing purporses
 
     WiFi_SetCallbacks(wifi_success_cb, wifi_fail_cb);