W
WOWCube Docs
Filters
vSDK
Navigation
infoWOWConnect_BluetoothWOWConnect_EnumsWOWConnect_UPNPDeviceInformationWOWConnect_WOWCubeDevice
changelogindex
Made byMcKay Seamons
GitHub

WOWConnect

In the rapidly evolving landscape of technology, the integration of wireless communication has become increasingly prevalent, unlocking new possibilities for seamless connectivity. One such breakthrough is the introduction of the WOWConnect library, designed specifically for the WOWCube device, to facilitate efficient data transfer over Bluetooth Low Energy (BLE).

At its core, WOWConnect serves as a robust conduit between applications and WOWCube devices, ensuring a fluid and efficient exchange of data. WOWCube, with its unique cubic design and individual screens on each face, demands a sophisticated communication mechanism, and WOWConnect rises to the occasion.


Key Features of WOWConnect

  • Bluetooth Low Energy (BLE) Integration:

Harnessing the prowess of BLE, WOWConnect establishes a low-power wireless connection between applications and WOWCube devices. This strategic implementation ensures minimal power consumption, a critical consideration for the energy-efficient operation of WOWCube.

  • Efficient Data Transfer:

WOWConnect has been optimized to facilitate swift and efficient data transfer. By streamlining the exchange of data packets, the library guarantees a seamless and responsive communication channel between applications and the WOWCube.

  • Device Discovery and Connection:

The library simplifies the process of discovering nearby WOWCube devices and establishing connections. WOWConnect streamlines the pairing procedure, enhancing user-friendliness for both developers and end-users.

  • Cross-Platform Compatibility:

A noteworthy aspect of WOWConnect is its cross-platform compatibility. Developers can seamlessly integrate WOWConnect into applications developed in C++, C#, Swift and Kotlin, providing a unified interface across various platforms.


Implementation Guidelines for WOWConnect

Embarking on the integration of WOWConnect into your application involves a structured approach:

  • Library Installation:

Begin by integrating the WOWConnect library into your development environment. Comprehensive installation instructions are available below.

  • Initialization and Configuration

Initialize WOWConnect within your application and configure the library according to specific requirements. This includes setting connection parameters and defining preferences related to data handling.

  • Data Transfer Implementation:

Implement functions for data transfer, utilizing WOWConnect's streamlined API. This empowers developers to seamlessly send and receive data packets, fostering a harmonious interaction between applications and the WOWCube.

  • Testing and Optimization:

Rigorously test the integration of your application with WOWConnect to ensure a smooth and responsive user experience. Optimize the code as necessary to enhance performance.


WOWConnect and Emulation Mode

In addition to its primary functions, WOWConnect introduces a noteworthy feature – compatibility with the WOWCube Emulator that comes with WOWCube Development Kit. This feature allows developers to test and debug their applications in a simulated environment, providing a valuable tool for refining the user experience before deploying to physical WOWCube devices.


Writing your first WOW-connected cubeapp

So, let’s begin. The first thing to note is the following: unlike conventional WOWCube applications that hold all program logic in a single file installed on WOWCube, the use of the WOWConnect library requires the presence of two applications – one to be installed on the device, the other – an application launched on the “host” system, used to transmit and receive data via BLE. That is, there are always two applications.

Writing an application that supports WOWConnect is practically no different from creating a regular application for WOWCube. Support for receiving and transmitting data via BLE is a standard feature provided by WOWCube SDK version 6.0 or higher, supplied as a part of the WOWCube Development Kit. The only difference, in fact, is the need to implement a data handler, which will be used from the callback called when the device receives data via BLE. Working with data transmitted via BLE is no fundamentally different from working with network data: when receiving data, a dedicated callback function is called, and if you need to send data back to the “host” application, a special send function is used.

On the “host” side of the application, everything is also simple, although there are some nuances.

First of all, in order to send something via BLE to WOWCube, you need to find out the address of the device in order to know where to send the data. The WOWConnect library provides an interface for automatic searching for available WOWCube devices, both physical and virtual. However, the “host” application must be responsible for processing the list of detected devices, selecting and storing the address of the current device. In other words, the library allows you to find a device, but the “host” application decides what to do with it next.

Secondly, the WOWConnect library provides interfaces for different programming languages depending on the target operating system. The following programming languages are currently supported:

  • Microsoft Windows 10 (version 21H2 or higher)
  • Microsoft Windows 11
    • C# (.Net Framework 4.8)
    • C++
  • MacOS 11 (Big Sur)
  • MacOS 12 (Monterey)
  • MacOS 13 (Ventura)
  • MacOS 14 (Sonoma)
  • iOS/iPadOS 14 or higher
    • Swift 5 (XCode 14.3 or higher)
  • Android (version 26 or higher)
    • Kotlin

And finally, depending on the type of operating system, it may be necessary to supply some special files along with your project.

The process of creation of a WOW-connected application begins, as for any other WOWCube application, with generation of an empty project in Visual Studio Code.

It should be noted that at this stage only projects written in C++ are supported.

Upon completion of generating a new project, the following files will be created:

MyNewConnectedApp.h

info
1//
2// Application UUID: 9GB-j2VoUe
3//
4#pragma once
5#include "Gfx.h"
6
7class MyNewConnectedApp: public Cubios::Application
8{
9public:
10 MyNewConnectedApp();
11 virtual ~ MyNewConnectedApp();
12
13 virtual void on_PhysicsTick(const std::array<Cubios::Screen, 3>& screens) override;
14 virtual void on_Twist(const Cubios::TOPOLOGY_twistInfo_t& twist) override;
15 virtual void on_Message(uint32_t type, uint8_t* pkt, u32_t size) override;
16 virtual void on_ExternalMessage(uint8_t* pkt, u32_t size) override;
17 virtual void on_Tap(uint32_t count) override;
18 virtual void on_Render(std::array<Cubios::Screen, 3>& screens) override;
19 virtual void on_Tick(uint32_t currentTime, uint32_t deltaTime) override;
20 virtual void on_Timer(uint8_t timerID) override;
21
22private:
23 static void drawModuleNumber();
24};
25

MyNewConnectedApp.cpp

info
1//
2// Application UUID: 9GB-j2VoUe
3//
4
5#include <stdint.h>
6#include <string>
7#include <vector>
8#include <string>
9#include <memory>
10
11#include "AppManager.h"
12#include "MyNewConnectedApp.h"
13
14//Applicaton initialization callback. Called once when CUB application starts
15void OnInit(Cubios::AppManager& appMgr)
16{
17 appMgr.SetApplication(new MyNewConnectedApp,"9GB-j2VoUe");
18}
19
20MyNewConnectedApp::MyNewConnectedApp()
21{
22}
23
24MyNewConnectedApp::~MyNewConnectedApp()
25{
26}
27
28//This callback is called every "tick" of cubeapp application loop
29void MyNewConnectedApp::on_Tick(uint32_t currentTime, uint32_t deltaTime)
30{
31}
32
33//This callback is called every time device is about to render visuals. Use it for calling your rendering code.
34void MyNewConnectedApp::on_Render(std::array<Cubios::Screen, 3>& screens)
35{
36 for(auto it = screens.begin(); it != screens.end(); ++it)
37 {
38 Cubios::GFX_setRenderTarget(it->ID());
39
40 switch(it->ID())
41 {
42 case 0:
43 Cubios::GFX_clear(Cubios::Gfx::Colors::darkRed);
44 Cubios::GFX_drawText(120,100, 8, 0, Cubios::text_align_t::TEXT_ALIGN_CENTER, Cubios::Gfx::Colors::white, "SCREEN 1");
45 break;
46 case 1:
47 Cubios::GFX_clear(Cubios::Gfx::Colors::darkGreen);
48 Cubios::GFX_drawText(120,100, 8, 0, Cubios::text_align_t::TEXT_ALIGN_CENTER, Cubios::Gfx::Colors::white, "SCREEN 2");
49 break;
50 case 2:
51 Cubios::GFX_clear(Cubios::Gfx::Colors::darkBlue);
52 Cubios::GFX_drawText(120,100, 8, 0, Cubios::text_align_t::TEXT_ALIGN_CENTER, Cubios::Gfx::Colors::white, "SCREEN 3");
53 break;
54 }
55
56 drawModuleNumber();
57 Cubios::GFX_render();
58 }
59}
60
61//The "physics" callback. Gets called recurrently with at least 33ms resolution or less depending on the load.
62void MyNewConnectedApp::on_PhysicsTick(const std::array<Cubios::Screen, 3>& screens)
63{
64}
65
66//This callback is called on programmable timer (if any)
67void MyNewConnectedApp::on_Timer(uint8_t timerID)
68{
69}
70
71//The cube topology change callback. Gets called when cube is twisted and its topological desctiption has been changed
72void MyNewConnectedApp::on_Twist(const Cubios::TOPOLOGY_twistInfo_t& twist)
73{
74}
75
76//The "inner network" callback. Gets called when WOWCube module receives a data packet from other module
77void MyNewConnectedApp::on_Message(uint32_t type, uint8_t* pkt, u32_t size)
78{
79}
80
81//The external data transfer callback. Gets called when WOWCube module receives a data over BLE from an external source
82void MyNewConnectedApp::on_ExternalMessage(uint8_t* pkt, u32_t size)
83{
84}
85
86//Screen tap callback
87void MyNewConnectedApp::on_Tap(uint32_t count)
88{
89}
90
91void MyNewConnectedApp::drawModuleNumber()
92{
93 std::string s = "MOUDLE "+std::to_string(Cubios::cubeN);
94 Cubios::GFX_drawText(120,140, 8, 0, Cubios::text_align_t::TEXT_ALIGN_CENTER, Cubios::Gfx::Colors::white, s.c_str());
95}
96

Please note two important points here:

  1. Starting from WOWCube SDK 6.0, each new application gets automatically assigned with a unique identifier (UUID), which is used by the WOWConnect library to address data. In other words, so that the library “knows” which application on the cube it is sending data to. The values of UUID identifier can be found at the top of both files and used as a parameter for SetApplication function.

  2. A new callback function on_ExternalMessage has been added to the interface of the Cubios::Application class. It is the callback function that is called by the CubiOS operating system at the moment of registration of the arrival of BLE data to the device.


Let’s look at this callback function in more detail:

info
1void MyNewConnectedApp::on_ExternalMessage(uint8_t* pkt, u32_t size)
2

As you can see, the funciton takes two input parameters – a pointer to the data packet (pkt) and the size of the received data (size). This means that in order to receive data from the “host” application, you just need to copy the received number of bytes from the incoming buffer, and that’s it!

The library does not impose any special restrictions on what happens to the data after copying; a cubeapp may process the data as desired. However, as with network data processing, it is generally not recommended to perform complex calculations that require significant CPU time inside a given callback function.

Let’s consider a very simple example.

Say we have a “host” application that periodically sends 10 bytes of data to our cubeapp. Then, our handler code may look like this:

info
1void MyNewConnectedApp::on_ExternalMessage(uint8_t* pkt, u32_t size)
2{
3 if(size!=10) return;
4
5 uint8_t d[10];
6 memcpy(d,pkt,size);
7
8 LOG_i("BLE DATA RECEIVED, SIZE: %d",size);
9}
10

Transferring data from the cube to the “host” application is also not a big problem.

For that,

info
1void SendExternalMessage(uint32_t type, uint8_t* data, size_t size)
2

function is used.

But unlike the data callback function, this one has three input parameters: a pointer to the data to send (data), a size of the data to send (size) and a type of the data being sent. This parameter allows you to “tag” your data so that the receiving party (the “host” application) could distinguish between same size data packets which are coming from WOWCube.

As an elementary example, consider a situation where we want to send a packet of 10 random bytes to the “host” application every time someone taps the cube.

The code may look like this:

info
1#define SINGLE_TAP_DETECTED 24
2#define DOUBLE_TAP_DETECTED 25
3#define TRIPLE_TAP_DETECTED 26
4
5void MyNewConnectedApp::on_Tap(uint32_t count)
6{
7 uint8_t d[10];
8 memset(d,0x00,10);
9 d[0]=0xA1; d[1] = 0xA2; //this is just some random data
10
11 if(count==1) this->SendExternalMessage(SINGLE_TAP_DETECTED,d,10);
12 else
13 if(count==2) this->SendExternalMessage(DOUBLE_TAP_DETECTED,d,10);
14 else
15 if(count==3) this->SendExternalMessage(TRIPLE_TAP_DETECTED,d,10);
16}
17

Writing your “host” application for Windows

Ok, now when we’ve our cubeapp created let’s make an app that sends some data to it. Let’s see how an application that uses WOWConnect library is created for Windows operating system.

First, create a new C# project of Windows Application type with Microsoft Visual Studio. The version of your IDE may vary; however you should make sure .NET Framework 4.8 is supported.

Then set up application references. Add WOWConnect library to the list of referenced frameworks and make sure the following files are copied to your application’s executable folder:

  • WOWConnect.dll
  • Windows.winmd
  • System.Runtime.WindowsRuntime.dll

And finally, add

info
1using Cubios.WOWConnect;
2

at the beginning of your application to get access to the interfaces of WOWConnect library. Now everything is set, and we can start coding!

The life cycle of the WOWConnect library within a host application consists of four stages:

  • Initialization and configuration
  • Search for devices
  • Transmission and reception of data
  • De-initialization and cleanup

Let’s take a closer look at each stage.

Initialization

Since most of the library’s functionality operates asynchronously, communication with the user’s application occurs through delegates. For correct initialization, the library requires three delegates:

info
1public delegate void DetectedDevicesListChangedDelegate(WOWCubeDevice device)
2

this delegate is called when the list of detected devices is changed, i.e. new device is detected or previously detected device disappears

info
1public delegate void MessageReceivedDelegate(WOWCubeDevice sender, byte messaageType, byte[] data)
2

this delegate is called when the host application receives data via BLE

info
1public delegate void LogDelegate(LogLevel level, String text)
2

and this delegate is used to redirect the library log output.

A sample code for WOWCube library initialization is shown below:

info
1static void LogDelegate(Cubios.WOWConnect.LogLevel level, String text)
2{
3 switch (level)
4 {
5 case LogLevel.Info:
6 break;
7 case LogLevel.Error:
8 break;
9 default:
10 break;
11 }
12}
13
14static void DetectedDevicesListChangedDelegate(Cubios.WOWConnect.Bluetooth.WOWCubeDevice device)
15{
16 Console.Log("Detected WOWCube device: " + device.Name + " id:" + device.Id);
17}
18
19static void MessageReceivedDelegate(Cubios.WOWConnect.Bluetooth.WOWCubeDevice device, byte messageType, byte[] data)
20{
21 if (device != null)
22 {
23 if (data != null)
24 {
25 string hex = BitConverter.ToString(data);
26 Console.Log($"RECEIVED DATA from {device.Name} of type {messageType} : [{hex}]");
27 }
28 else
29 {
30 Console.Log($"RECEIVED NULL DATA from {device.Name}");
31 }
32 }
33 else
34 {
35 Console.Log($"RECEIVED DATA of type {messageType} from unidentified device");
36 }
37}
38
39
40private void Window_Loaded(object sender, RoutedEventArgs e)
41{
42 Console.Log("WOWConnect version: " + Cubios.WOWConnect.Bluetooth.Version);
43 Bluetooth.Open(DetectedDevicesListChangedDelegate, MessageReceivedDelegate, LogDelegate);
44}
45

Search for devices

When searching for available devices, everything is very simple: the WOWConnect library starts searching for WOWCube devices automatically upon successful initialization. In other words, you will start receiving DetectedDevicesListChangedDelegate callbacks right after calling Bluetooth.Open function.

Sending the data

In order to send the data to a cubeapp application that is running on WOWCube device, three simple steps are required:

  1. You have to find the device you want to send your data to by its name:

    info
    1 Bluetooth.WOWCubeDevice device = Bluetooth.GetDevice(“Wow_black_lamb_0”);
    2

In case if requested device is available, you will get a device descriptor object.

  1. Then, you should try to open the device providing a UUID of the cubeapp application to communicate with as a parameter:

    info
    1 device.Open("B6vkqVoi0H");
    2
  2. And finally, you can send your data to a successfully opened device using

    info
    1 device.Write(data_bytes);
    2

When the device is no longer in use, you should use

info
1device.Close();
2

function to terminate BLE connection to the device and clean up the memory.

Оf course, the above is a simplification to some extent, in a real application additional checks on function return codes will be required. However, in essence, these three functions are necessary and sufficient for solving the task of data transfer over BLE to WOWCube device.

Cleaning up

Before closing the host application, we would want to disconnect from all currently connected BLE or virtual devices and free compter resources used by the library. To do that, simply call

info
1Bluetooth.Close();
2

Writing your “host” application for Mac and iOS

The method of using the WOWConnect library to create “host” applications for Mac and iOS is no different from that described above for Windows.

First, create a new App project in XCode. Please make sure you are using XCode version 14.3.1 or higher.

Then set up application references. Add WOWConnectCore.framework library to the list of referenced frameworks in the Frameworks, Libraries and Embedded Content section of General settings of your project.

Then navigate to Signing & Capabilites tab and select the following items from App Sandbox section:

  • Incoming Connections (Server)
  • Incoming Connections (Client)
  • Bluetooth

and the next item from Hardened Runtime section:

  • Disable Library Validation

Then switch to Info tab and add two new Key/Value pairs to the Custom macOS Application Target Properties list:

  • Privacy - Local Network Usage Description
  • Privacy - Bluetooth Always Usage Description

And finally, add

info
1import WOWConnectCore
2

at the beginning of your application's view controller code to get access to the interfaces of WOWConnect library.

And this would be it, your project's setup is done.

The life cycle of the WOWConnect library within a host application consists of four stages:

  • Initialization and configuration
  • Search for devices
  • Transmission and reception of data
  • De-initialization and cleanup

Let’s take a closer look at each stage.

Initialization

Since most of the library’s functionality operates asynchronously, communication with the user’s application occurs through delegates. For correct initialization, the library requires three delegates:

info
1 func OnDeviceListChanged(device:Cubios.WOWConnect.Bluetooth.WOWCubeDevice, lost:Bool)->Void
2

this delegate is called when the list of detected devices is changed, i.e. new device is detected or previously detected device disappears

info
1func OnMessageReceived(sender:Cubios.WOWConnect.Bluetooth.WOWCubeDevice,messageType:UInt8 ,data:Data?)->Void
2

this delegate is called when the host application receives data via BLE

info
1func OnLog(level:Cubios.WOWConnect.LogLevel,text:String)-> Void
2

and this delegate is used to redirect the library log output.

A sample code for WOWCube library initialization is shown below:

info
1func OnLog(level:Cubios.WOWConnect.LogLevel,text:String)-> Void
2{
3 switch(level)
4 {
5 case Cubios.WOWConnect.LogLevel.Info: do { print(text)}
6 case Cubios.WOWConnect.LogLevel.Error: do { print("ERROR: "+text)}
7 case Cubios.WOWConnect.LogLevel.Debug: do { print("DEBUG: "+text)}
8 }
9}
10
11func OnDeviceListChanged(device:Cubios.WOWConnect.Bluetooth.WOWCubeDevice, lost:Bool)->Void
12{
13 if(!lost)
14 {
15 print("APP: Device found:"+device.Name)
16 }
17 else
18 {
19 print("APP: Device lost:"+device.Name)
20 }
21}
22
23func OnMessageReceived(sender:Cubios.WOWConnect.Bluetooth.WOWCubeDevice,messageType:UInt8 ,data:Data?)->Void
24{
25 print("APP: Received message:")
26
27 if(data != nil)
28 {
29 for b:UInt8 in data!
30 {
31 print(b)
32 }
33 }
34}
35
36
37override func viewDidLoad()
38{
39 super.viewDidLoad()
40
41 // Do any additional setup after loading the view.
42 print("WOWConnect version:"+Cubios.WOWConnect.Version)
43
44 Cubios.WOWConnect.Bluetooth.Open(deviceListChangedDelegate: OnDeviceListChanged, dataReceivedDelegate: OnMessageReceived, logDelegate: OnLog)
45}
46

Search for devices

When searching for available devices, everything is very simple: the WOWConnect library starts searching for WOWCube devices automatically upon successful initialization. In other words, you will start receiving DetectedDevicesListChangedDelegate callbacks right after calling Bluetooth.Open function.

Sending the data

In order to send the data to a cubeapp application that is running on WOWCube device, three simple steps are required:

  1. You have to find the device you want to send your data to by its name:

    info
    1 Cubios.WOWConnect.Bluetooth.WOWCubeDevice device = Cubios.WOWConnect.Bluetooth.GetDevice(“Wow_black_lamb_0”);
    2

In case if requested device is available, you will get a device descriptor object.

  1. Then, you should try to open the device providing a UUID of the cubeapp application to communicate with as a parameter:

    info
    1 let resp = try await device!.Open(cubeappUUID:"N4Uh8CKWIz")
    2
  2. And finally, you can send your data to a successfully opened device using

    info
    1 let resp = try await device!.Write(data:dataToWrite)
    2

When the device is no longer in use, you should use

info
1device!.Close();
2

function to terminate BLE connection to the device and clean up the memory.

Оf course, the above is a simplification to some extent, in a real application additional checks on function return codes will be required. However, in essence, these three functions are necessary and sufficient for solving the task of data transfer over BLE to WOWCube device.

Cleaning up

Before closing the host application, we would want to disconnect from all currently connected BLE or virtual devices and free compter resources used by the library. To do that, simply call

info
1Cubios.WOWConnect.Bluetooth.Close();
2

WOWCube SDK Examples