Neo smartpen SDK for Windows Platform
Windows SDK
Windows SDK for Windows. This open-source library allows you to integrate the Neo smartpen - Neo smartpen N2 and M1 - into your Windows program.
About Neo smartpen
The Neo smartpen is designed to seamlessly integrate the real and digital worlds by transforming what you write on paper - everything from sketches and designs to business meeting notes - to your iOS, Android and Windows devices. It works in tandem with N notebooks, powered by NeoLAB Convergence's patented Ncode™ technology and the accompanying application, Neo Notes. Find out more at www.neosmartpen.com
- Tutorial video - https://goo.gl/MQaVwY
About Ncode™: service development guide
'Natural Handwriting' technology based on Ncode™(Microscopic data patterns containing various types of data) is a handwriting stroke recovery technology that digitizes paper coordinates obtained by optical pen devices such as Neo smartpen. The coordinates then can be used to store handwriting stroke information, analyzed to extract meaning based on user preferences and serve as the basis for many other types of services.
Click the link below to view a beginners guide to Ncode technology. https://github.com/NeoSmartpen/Documentations/blob/master/Ncode™ Service Development Getting Started Guide v1.01.pdf
Project Structure
| Project | Type | Description |
|---|---|---|
Neosmartpen.Net |
Class Library | Core SDK — Bluetooth communication, pen protocol implementation |
Neosmartpen.Net.Usb |
Class Library | USB communication support for Neo smartpen |
Neosmartpen.Demo |
WinForms App | Demo application using Neosmartpen.Net (Bluetooth) |
Neosmartpen.Net.Usb.Demo |
WinForms App | Demo application using Neosmartpen.Net.Usb (USB) |
Requirements
- Windows 10 or later
- Microsoft Visual Studio 2022 or later
- Microsoft .NET 8.0 SDK or later
- Standard Bluetooth Dongles (Bluetooth Specification Version 4.0 or later with Microsoft Bluetooth stack)
- SDK packages for Neo smartpen
Dependencies
- SharpZipLib (1.4.2)
- System.Management (8.0.0)
- System.IO.Ports (8.0.0)
- System.Drawing.Common (8.0.0)
Build & Run
Clone the repository and build using the .NET CLI:
git clone https://github.com/NeoSmartpen/Windows-SDK2.0.git
cd Windows-SDK2.0
# Restore NuGet packages
dotnet restore NeosmartpenSDK.sln
# Build the entire solution
dotnet build NeosmartpenSDK.sln -c Release
# Run the Bluetooth demo app
dotnet run --project Neosmartpen.Demo/Neosmartpen.Net.Demo.csproj
# Run the USB demo app
dotnet run --project Neosmartpen.Net.Usb.Demo/Neosmartpen.Net.Usb.Demo.csproj
Or open NeosmartpenSDK.sln directly in Visual Studio 2022 and press F5.
API References
SDK API references page : References
Getting started (Bluetooth)
Notice
SDK handles data and communication with the peer device on a separate thread. So if you want data received from the pen to appear in the UI, you must execute it on the UI thread.
Prerequisites
- Bluetooth adapter with Bluetooth 4.0 LE support (Microsoft Bluetooth stack)
- Windows 10 version 1803 or later recommended for full BLE support
Create GenericBluetoothPenClient and PenController instance
// create PenController instance.
// PenController control all pen event method
var controller = new PenController();
// Create GenericBluetoothPenClient instance. and bind PenController.
// GenericBluetoothPenClient is implementation of bluetooth function.
var client = new GenericBluetoothPenClient(controller);
Check if Bluetooth adapter are available
// If true, it can be used; if false, it cannot be used.
var available = await client.GetBluetoothIsEnabledAsync();
// Get detailed information about your Bluetooth adapter
var adapter = await client.GetBluetoothAdapter();
Find Bluetooth Devices
You can find bluetooth device using below methods. And get PenInformation object that has bluetooth device information.
Find device
List<PenInformation> penList = await client.FindDevices();
Using LE Advertisement Watcher
// bluetooth watcher event
client.onStopSearch += onStopSearch;
client.onUpdatePenController += onUpdatePenController;
client.onAddPenController += onAddPenController;
// start watcher
client.StartLEAdvertisementWatcher();
// Event that is called when a device is added by the watcher
private void onAddPenController(IPenClient sender, PenInformation args)
{
}
// Event that is called when a device is updated
private void onUpdatePenController(IPenClient sender, PenUpdateInformation args)
{
}
// Event that is called when the watcher operation has been stopped
private void onStopSearch(IPenClient sender, Windows.Devices.Bluetooth.BluetoothError args)
{
}
Connect with device
// penInfomation is PenInformation class object what can be obtained from find device method
bool result = await client.Connect(penInfomation);
After Connection is established.
// add event in init method
controller.Connected += connected;
controller.PasswordRequested += passwordRequested;
controller.Authenticated += authenticated;
// It is called when connection is established ( You cannot use function on your device without authentication )
private void connected(IPenClient sender, ConnectedEventArgs args)
{
Debug.WriteLine($"Mac : {args.MacAddress}\r\nName : {args.DeviceName}\r\nSubName : {args.SubName}\r\nFirmware Version : {args.FirmwareVersion}\r\nProtocol Version : {args.ProtocolVersion}");
}
// If your device is locked, it is called to input password.
private void passwordRequested(IPenClient sender, PasswordRequestedEventArgs args)
{
Debug.WriteLine($"Retry Count : {args.RetryCount}, ResetCount : {args.ResetCount }");
controller.InputPassword(password);
}
// If your pen is not locked, or authentication is passed, it will be called.
// When it is called, You can use all function on your device.
private void authenticated(IPenClient sender, object args)
{
}
Handling a handwriting data from peer device
// add event in init method
controller.DotReceived += dotReceived;
// Identifier of note(paper) (it is consist of section and owner, note)
int section = 1;
int owner = 1;
int note = 102;
// Requests to set your note type.
controller.AddAvailableNote(section, owner, note);
// event that is called when writing data is received
private void dotReceived(IPenClient sender, DotReceivedEventArgs args)
{
// TODO : You should implements code using coordinate data.
}
Querying list of offline data in Smartpen's storage
// add event in init method
controller.OfflineDataListReceived += offlineDataListReceived;
// Request offline data list
controller.RequestOfflineDataList();
// Event method to receive offline data list
private void offlineDataListReceived(IPenClient sender, OfflineDataListReceivedEventArgs args)
{
}
Downloading offline data in Smartpen's storage
// add event in init method
controller.OfflineDataDownloadStarted += offlineDataDownloadStarted;
controller.OfflineStrokeReceived += offlineStrokeReceived;
controller.OfflineDownloadFinished += offlineDownloadFinished;
// it is invoked when begins downloading offline data
private void offlineDataDownloadStarted(IPenClient sender, object args)
{
}
// it is invoked when it obtained offline data ( it can be called several times )
private void offlineStrokeReceived(IPenClient sender, OfflineStrokeReceivedEventArgs args)
{
}
// it is invoked when finished downloading
private void offlineDownloadFinished(IPenClient sender, SimpleResultEventArgs args)
{
}
Convert the page to JSON format
// Create a page model that can contain the generated strokes.
Page page = new Page();
// Add stroke
page.Add(stroke);
// Convert to json text
var json_page = page.ToJSON();
Page converted to JSON format
{
"section": 3,
"owner": 27,
"note": 388,
"pageNumber": 1,
"strokes": [
{
"color": 16777215,
"startTime": 1756632798584,
"endTime": 1756632798746,
"dotCount": 9,
"dots": "eFX8AQAACtf/Qa5HM0IAAACOVfwBAAAAAABCPQo0QgAAAKVVAAAA"
},
{
"color": 16777215,
"startTime": 1756632799118,
"endTime": 1756632799406,
"dotCount": 15,
"dots": "jlf8AQAAH4UhQmZmPUIAAACjV/wBAAAzMyRCKVw7QgAAALQpYQgAAAK5Y/AEAAGZmOkI9ClhCAAAA"
},
{
"color": 16777215,
"startTime": 1756632799617,
"endTime": 1756632799871,
"dotCount": 13,
"dots": "gVn8AQAA16NYQoXrM0IAAACXWfwBAAApXFtCKVwAAAA="
}
]
}
Structure of one dot item of dots (It repeats dotCount times)
| Name | Byte | Index | Description | etc |
|---|---|---|---|---|
| timeDelta | 2 | 0 | Time difference between previous dot and current dot | little endian |
| force | 4 | 2 | the pressure of the dot, float (0 ~ 1.0) | little endian |
| x | 4 | 6 | the x coordinates of NCode cell (float) | little endian |
| y | 4 | 10 | the y coordinates of NCode cell (float) | little endian |
| tx | 1 | 14 | the tilt x of the pen (0~180) | |
| ty | 1 | 15 | the tilt x of the pen (0~180) | |
| rotation | 1 | 16 | the rotation degree of the pen (0~180) |
Getting started (USB)
The Neosmartpen.Net.Usb library provides USB serial communication support for Neo smartpen devices.
using Neosmartpen.Net.Usb;
// Create UsbPenClient instance with the serial port name
var client = new UsbPenClient("COM3");
// Connect
client.Connect();
// Listen for data events
client.DotReceived += (sender, args) =>
{
// TODO: handle dot data
};
Refer to
Neosmartpen.Net.Usb.Demofor a complete working example.
LICENSE
Copyright©2017 by NeoLAB Convergence, Inc. All page content is property of NeoLAB Convergence Inc. https://neolab.net
GPL License v3 - for non-commercial purpose
For non-commercial use, follow the terms of the GNU General Public License.
GPL License v3 is a free software: you can run, copy, redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with the program. If not, see https://www.gnu.org/licenses/.
Commercial license - for commercial purpose
For commercial use, it is not necessary or required to open up your source code. Technical support from NeoLAB Convergence, inc is available upon your request.
Please contact our support team via email for the terms and conditions of this license.
- Global: global@neolab.net
- Korea: biz1@neolab.net
Opensource Library
Please refer to the details of the open source library used below.
1. SharpZipLib (https://github.com/icsharpcode/SharpZipLib)
This software is now released under the MIT License. Please see issue #103 for more information on the relicensing effort.
Previous versions were released under the GNU General Public License, version 2 with an exception which allowed linking with non-GPL programs.
Feel free to leave any comment or feedback here