# WiFi Smart Connect with OLED Integration

This guide demonstrates how to integrate a standard 128x64 I2C OLED display with your ConsentiumThings Dalton board using the **U8g2** library.

By following this example, you can provide real-time visual feedback on your device's physical screen. It covers how to display the automatically generated WiFi Access Point (AP) credentials during the setup phase, show the assigned IP address upon successful connection, and indicate when data is actively being sent to the Consentium IoT Cloud.

### Prerequisites

#### Hardware Setup

* **ConsentiumThings Dalton Board** (or compatible Edge board).
* **I2C OLED Display** (e.g., SSD1306 128x64).
* Jumper wires connecting the OLED to the board's I2C pins (SDA and SCL).

#### Software & Libraries

Ensure you have the following libraries installed in your Arduino IDE:

* `ConsentiumThings`: The core library for the edge board.
* `U8g2`: A fast, highly customizable library for monochrome displays.
* `Wire`: Standard Arduino I2C library (usually built-in).

***

### Code Walkthrough

#### 1. Initialisation and Setup

First, include the necessary libraries and initialise the `U8g2` object for your specific display. You must also define your Consentium API keys.

```cpp
#include <ConsentiumThings.h>
#include <U8g2lib.h>
#include <Wire.h>

// Initialize the U8g2 object for a standard 128x64 I2C OLED
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// Create ConsentiumThings object
ConsentiumThingsDalton board;

// Define API keys
const char *SendApiKey = "YOUR_SEND_API_KEY";      
const char *BoardApiKey = "YOUR_BOARD_API_KEY"; 
constexpr int interval = 5000; 
```

#### 2. The Display Callback Function

The board.smartConnect() function is a blocking function, meaning the code pauses while it waits for a user to connect to the generated WiFi Access Point. To display the generated SSID and Password on the OLED before the code blocks, we pass a callback function.

```cpp
void showCredentialsOnOLED(const char* ssid, const char* password) {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr); 

  u8g2.drawStr(4, 10, "WiFi Setup Mode");
  u8g2.drawStr(4, 25, "Connect to:");

  u8g2.setCursor(4, 40);
  u8g2.print("SSID: ");
  u8g2.print(ssid);

  u8g2.setCursor(4, 55);
  u8g2.print("Pass: ");
  u8g2.print(password);

  u8g2.sendBuffer();
}
```

#### 3. The Setup Loop

In the setup() function, initialise the OLED and pass the callback function to smartConnect(). Once the connection is successful, the screen clears and displays the newly acquired IP address.

```cpp
void setup() {
  Serial.begin(115200);
  u8g2.begin(); // Start the OLED

  // Initialise WiFi, passing the OLED callback
  board.smartConnect(showCredentialsOnOLED);

  // Connection successful - Update OLED
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(4, 20, "WiFi Connected!");
  u8g2.setCursor(4, 40);
  u8g2.print("IP: ");
  u8g2.print(board.getIPAddress()); 
  u8g2.sendBuffer();

  // Initialise the board for sending data
  board.enableSend(SendApiKey, BoardApiKey);
  
  delay(2000); // Pause for 2 seconds so the user can read the IP
}
```

#### 4. The Main Loop (Data Transmission)

During normal operation, the board reads sensor data, sends it to the Consentium Cloud, and updates the OLED to confirm the transmission.

```cpp
void loop() {
  double data_0 = 1.0;  // Sample temperature data
  vector<double> sensorValues = {data_0};  
  const char* sensorInfo[] = {"Temperature"}; 

  // Send over REST
  board.pushData(sensorValues, sensorInfo, LOW_PRE);  

  // Update OLED
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(4, 20, "Data Sent to Cloud");
  u8g2.sendBuffer();

  delay(interval);
}
```

## Complete Example Code&#x20;

Copy and paste the entire block below into your Arduino IDE to get started quickly. Remember to replace the empty API keys with your actual Consentium credentials.

```cpp
#include <ConsentiumThings.h>
#include <U8g2lib.h>
#include <Wire.h>

// Initialize the U8g2 object for a standard 128x64 I2C OLED
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// Create ConsentiumThings object
ConsentiumThingsDalton board;

// Define API keys
const char *SendApiKey = "";      // API key for sending data
const char *BoardApiKey = ""; // API key for the board

// Define the interval for data sending
constexpr int interval = 5000;  // Data transmission interval (5 seconds for free tier)

// ---------------------------------------------------------
// Callback Function: Shows AP credentials during setup
// ---------------------------------------------------------
void showCredentialsOnOLED(const char* ssid, const char* password) {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr); 

  u8g2.drawStr(4, 10, "WiFi Setup Mode");
  u8g2.drawStr(4, 25, "Connect to:");

  u8g2.setCursor(4, 40);
  u8g2.print("SSID: ");
  u8g2.print(ssid);

  u8g2.setCursor(4, 55);
  u8g2.print("Pass: ");
  u8g2.print(password);

  u8g2.sendBuffer();
}

void setup() {
  // Start serial communication for debugging
  Serial.begin(115200);

  //Initialise the OLED display
  u8g2.begin();

  // Consentium IoT branding message
  Serial.println("Consentium IoT - Edge Board Library");
  Serial.println("------------------------------------");
  Serial.println("Initializing ConsentiumThings Board...");

  //Initialise WiFi with auto-connect feature, passing the OLED callback
  board.smartConnect(showCredentialsOnOLED);

  // Once smartConnect finishes, update the OLED to show success
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(4, 20, "WiFi Connected!");
  u8g2.setCursor(4, 40);
  u8g2.print("IP: ");
  u8g2.print(board.getIPAddress()); 
  u8g2.sendBuffer();

  //Initialise the board for sending data
  board.enableSend(SendApiKey, BoardApiKey);

  // Enable battery monitoring on ADC_IN pin (optional)
  // board.enableBatteryMonitoring(ADC_IN);

  // Enable current and voltage industrial monitoring (optional)
  // board.startSensing();
  
  Serial.println("ConsentiumThings Board Initialized!");
  Serial.println("------------------------------------");
  Serial.println();
  
  delay(2000); // Pause for 2 seconds so the user can see the IP address
}

void loop() {
  // Prepare sample sensor data
  double data_0 = 1.0;  // Sample temperature data

  // Get data from 4-20mA current sensor, returns as mA (optional)
  // double cin_1_current = board.readCurrentBus(CIN_1);
  // double cin_2_current = board.readCurrentBus(CIN_2);
  // double cin_3_current = board.readCurrentBus(CIN_3);
  // double cin_4_current = board.readCurrentBus(CIN_4);

  // Get data from 0-10v voltage sensor, returns as volts (optional)
  // double vin_1_voltage = board.readVoltageBus(VIN_1);
  // double vin_2_voltage = board.readVoltageBus(VIN_2);
  // double vin_3_voltage = board.readVoltageBus(VIN_3);
  // double vin_4_voltage = board.readVoltageBus(VIN_4);

  vector<double> sensorValues = {data_0};  // Sensor data vector
  
  // Sensor info without units can be defined as
  const char* sensorInfo[] = {"Temperature"}; 

  // Sensor info with units can be defined as
  // const char* sensorInfo[] = {"Temperature/C"};

  // Send over REST with low precision
  board.pushData(sensorValues, sensorInfo, LOW_PRE);  

  // Update OLED to show we are sending data
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_ncenB08_tr);
  u8g2.drawStr(4, 20, "Data Sent to Cloud");
  u8g2.sendBuffer();

  // Wait before sending the next batch of data
  delay(interval);
}
```

Troubleshooting I2C & OLED Issues Hardware integrations don't always work perfectly on the first try. If your OLED screen remains blank or displays scrambled text, check the following common issues.

#### 1. Blank Screen / No Output

Wiring Check: Ensure the I2C pins are connected correctly. A very common mistake is swapping the SDA and SCL lines.

VCC -> 3.3V or 5V (Check your specific OLED module's rating)

GND -> GND

SDA -> SDA pin on your ConsentiumThings Dalton board

SCL -> SCL pin on your ConsentiumThings Dalton board

Power Supply: Ensure the board is providing enough power to the OLED. Sometimes running off a weak USB port can cause peripherals to fail.

#### 2. Incorrect I2C Address

Most 128x64 OLEDs use the I2C address 0x3C, but some use 0x3D. The U8g2 library usually handles the default 0x3C automatically based on the constructor, but if your screen has a different address or isn't being recognised, you should run an I2C Scanner sketch to verify the hardware is communicating.

I2C Scanner Code: Upload this temporary sketch to your board and open the Serial Monitor (115200 baud). It will tell you the exact address of your connected OLED.

```cpp
#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices = 0;

  Serial.println("Scanning...");

  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address<16) Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error==4) {
      Serial.print("Unknown error at address 0x");
      if (address<16) Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           
}
```

#### 3. Scrambled Display or "Snow"

If your display lights up but the pixels look like random noise or are shifted slightly to the right, you likely have an SH1106 controller instead of an SSD1306. These modules look physically identical.

To fix this, simply change your U8g2 constructor at the top of your code:

Change this:

```cpp
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
```

To this:

```cpp
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
```

#### 4. Code Hanging / Board Restarting

If the board continuously restarts or the code freezes immediately after u8g2.begin();, it usually means the I2C bus is hanging due to missing Pull-Up resistors. Most ready-made OLED modules have these resistors built-in, but if you are using a bare screen, you may need to add 4.7kΩ resistors between SDA/3.3V and SCL/3.3V.
