# Feelix Documentation

Feelix is an application for the design of force feedback and precise motion control for high torque brushless motors. The application is available for Windows and Mac OS.

#### Feelix version 3.1.3 is now available for Windows and Mac OS 64 bit&#x20;

Featuring haptic design for brushless motors and pneumatic actuators. This version also includes new machine learning features build on TensorFlowJS.

{% embed url="<https://vimeo.com/726537054?share=copy#t=0>" %}

{% content-ref url="/pages/-M3N1R4\_iwIQhhCsxiKN" %}
[Feelix Design Tool](/downloads/feelix)
{% endcontent-ref %}

{% content-ref url="/pages/-M3N1XUC26icBSTAXNLf" %}
[Feelix Arduino Library](/downloads/c-library)
{% endcontent-ref %}

{% content-ref url="/pages/-M3N1tk5Qq\_UaIsqMQra" %}
[Hardware](/hardware-support/hardware)
{% endcontent-ref %}

{% content-ref url="/pages/-M3XniN1zf\_3VaYQjPaS" %}
[FeelixEffect Documentation](/downloads/arduino-library-documentation)
{% endcontent-ref %}

{% hint style="info" %}
Feelix C++ library builds on the SimpleFOClibrary. \
*Visit* [*SimpleFOC.com*](https://simplefoc.com/) *for documentation and theory regarding BLDC motor control using the Field Oriented Control (FOC) algorithm.*
{% endhint %}


# Getting started

Feelix consists of three elements (1) a [**canvas** ](/getting-started/designing-effects)for sketching effects, (2) a [**library** ](/getting-started/effect-library)where all the effects are stored, (3) a section where [**collections** ](/getting-started/creating-collections)of effects can be created and uploaded to the motor.

![Feelix version 2.0.3](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRNNJb6cPBjwEgksxK%2F-MlROFiYxevA7tcrViFo%2Ffeelix_v203.png?alt=media\&token=733450a5-8771-431f-afda-3d87d6d85484)


# Designing Effects

### [Torque Effects](/getting-started/designing-effects/torque-effects)

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRPdqVx3_4AFi3RxXg%2F-MlRPi5GJUi2yd8QDhTi%2Ftorque_canvas.png?alt=media\&token=c9ea3ec7-7a4b-4718-bb61-e51aa4c51e21)

### [Position Effects](/getting-started/designing-effects/position-effects)

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRPdqVx3_4AFi3RxXg%2F-MlRPi5AeLILtxZe9vl5%2Fposition_canvas.png?alt=media\&token=ae5299a1-b26c-4509-aa41-e87842d22a9d)

### [Velocity Effects](/getting-started/designing-effects/velocity-effects)

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRPdqVx3_4AFi3RxXg%2F-MlRPi5HvCiciA12-CaA%2Fcanvas-velocity.png?alt=media\&token=62528ba5-172a-4363-9225-8e73c5f29757)

### [(In)dependent Effects](/getting-started/designing-effects/effects)

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRI-R2lurMQjkl2n5J%2F-MlRK07MIuw5s20oasnL%2Findependent_effects_2.png?alt=media&amp;token=286309ff-15a7-473a-9b5b-0b3f49f798fd" alt=""><figcaption></figcaption></figure>


# Torque Effects

With torque effects, the intensity of the voltage is controlled on the y-axis from -100% to 100%. Negative values correspond to clockwise forces, and positive to counterclockwise or vise versa (depending on the rotational direction of the sensor). The position at which the force is experienced is displayed on the x-axis.

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRGnpQRyAyOZ7pi-bh%2F-MlRHfOSt63Zwh4TAHyG%2Fdependent_effects_2.png?alt=media\&token=9f776840-c1d3-48ee-a8c5-c9057f75a0a4)


# Position Effects

With position effects, two variables are designed: (1) the voltage intensity (0 - 100%), (2) direction of the force. For an example, see the visualization below. When the motor is at point (A) in the visualization the force will be directed towards point (A'). The effects can be fine-tuned with the PID Controller which will appear after rendering the collection.

![Visual representation of position-based effects.](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-Mk-efyDzBxwqLdiDJ5a%2F-Mk-fqxzJTbslBOjocxn%2Fgraph-1.png?alt=media\&token=f87c5500-0d4b-4448-a932-e84242aefa57)

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-Mk-efyDzBxwqLdiDJ5a%2F-Mk-fBHt9EDZC_HdOyQD%2Fposition_effects.png?alt=media\&token=dec66615-c16b-460e-b081-62154ac7dc19)


# Velocity Effects

Velocity effect can be designed in two forms (angle/time) and (velocity/time)

{% hint style="info" %}
Option available in v2.0.3^
{% endhint %}

### Playing velocity effects

After render and uploading the effect, the collection can be started with the play button. To play the collection in a loop, activite the button next to the play button as displayed in the example below.

![Example collection with velocity effect](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRFSsXZ90hcQlWK_br%2F-MlRFseskS5uLnDs_hR-%2Fvelocity-collection.png?alt=media\&token=f54ba0be-11cc-468d-bff9-0dd8fbe065a5)

### Velocity over time

Velocity effects can be drawn as velocity (y-axis) over time (x-axis). This option uses value between 0% and 100% of the maximum velocity. A negative velocity results in a rotation in the opposite direction.&#x20;

### Angle over time

The second option is specifying the angle (y-axis) over time (x-axis). For this option the range of the y-axis of the drawing canvas can be specified in degrees. The effect will start at the position the motor is at after uploading.&#x20;


# (In)dependent Effects

Haptic effects (torque and position) can be experienced dependent or independent of the motor position and rotational direction.

## Dependent Effects

Effects that depend on the position and rotational direction of the motor are only experienced when hovering over the effect itself. See the example below in which the forces and directions are visualized.&#x20;

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRGnpQRyAyOZ7pi-bh%2F-MlRHfOSt63Zwh4TAHyG%2Fdependent_effects_2.png?alt=media\&token=9f776840-c1d3-48ee-a8c5-c9057f75a0a4)

## Independent Effects

Effects that are independent of the position and rotational direction of the motor can be experienced over the full range. In the example below the motor will always have the tendency to move towards the center when it is rotated outwards.

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRI-R2lurMQjkl2n5J%2F-MlRJYLRzwstxdpcHBJ-%2Findependent_effects_1.png?alt=media\&token=6601e711-4aef-4e8f-a343-54a1488f3719)

![Example independent effects, which can be experienced regardless the position of the motor.](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRI-R2lurMQjkl2n5J%2F-MlRK07MIuw5s20oasnL%2Findependent_effects_2.png?alt=media\&token=286309ff-15a7-473a-9b5b-0b3f49f798fd)


# Effect Library

Effects are automatically stored in the Effect list (Effects tab). The effects that are stored in the Library (Library tab) can be used across different files. The effects can be stored in the Library using the save button in the toolbar on the left side, above the sketch canvas.

From the effect window, effects can be edited by clicking the edit button (only applies to effects in the Effect List). This will open the effect in the drawing canvas. The effect can also be exported from here as plain code (more details can be found [here](/create-and-edit-files/export)). Last, effects can be deleted from the list with the delete button.

{% hint style="info" %}
When dragging a library effect onto a collection, it will automatically be added to the Effect list
{% endhint %}

![Effect library](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRGnpQRyAyOZ7pi-bh%2F-MlRHyw5nviA82CQb4k3%2Flibrary.png?alt=media\&token=37e29474-87aa-4a1c-8da3-37df70d286a5)


# Creating Collections

## Designing collections

* [ ] Create a new collection with the 'new collection' button in the toolbar
* [ ] Set visible range, units, visualization method to your preferences. These settings are only visible when display mode is set to large (default), to change the display mode click the bottom icon in the toolbar of the collections section.
* [ ] Drag effects from the library window on top of the collection

{% hint style="info" %}
When the visualization method of effects does not match with the visualization method of collection, effects will be displayed as a box.
{% endhint %}

## Modify Effect Settings

{% hint style="success" %}
Hover over the question marks in Feelix to learn more about the different settings.
{% endhint %}

The details of the effects that have been added to the collection can be modified in the 'Details' tab.&#x20;

![Details tab](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRCGH7G7NQpJM4Xdpp%2F-MlRCpLZVe1yGnAotVYr%2FEffect_details.png?alt=media\&token=9815afcc-b09f-4a90-aa0a-33780b1d29bb)

## Render & Upload

* [ ] Select a microcontroller from the microcontrollers that have been added ([see connect](/uploading-files/connect) [to learn how to add a microcontroller](/uploading-files/connect#connect))
* [ ] Make sure the microcontroller settings are inline with your hardware setup ([see hardware settings](broken://pages/-M3NHh5uT6JPoz0noj15))
* [ ] Click the render button (next to microcontroller dropdown and motor identifier) to render the collection\
  \
  After rendering effects are converted to data points, the number of data points can be adjusted (go to 'Quality' in the 'Details' tab, see image above). Linear interpolation is used to derive the values from the set of data points (see image below).

![Example effect after the collection has been rendered](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRAloiBBZ2JuvvZh0n%2F-MlRBMX1ISNFqnfnD703%2Feffect_quality_example.jpg?alt=media\&token=b209861d-39eb-42e0-a4ec-d42e28b19baa)

* [ ] Make sure the motor is connected to the computer via usb
* [ ] Click upload (next to the render button)
* [ ] The settings that appear above the collection after rendering are related to the chosen visualization type. With torque effects, the maximum voltage can specified. All values above the threshold will be cut-off. For position and velocity effect the PID control values can be modified. The changes to these values are instantly updated on the microcontroller (when connected).

{% hint style="info" %}
Changes are not automatically updated. Render/upload again to update the changes made to the collection or sketch on the microcontroller.
{% endhint %}

![Example collection. The render button is highlighted.](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRCqz80sbgVKTERftJ%2F-MlRDO1lqJq2YDCFuxG8%2Fcollections.png?alt=media\&token=78bab9c7-199d-4e90-b6e3-eb636ca8a1ef)

![Velocity collection. ](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRFSsXZ90hcQlWK_br%2F-MlRFseskS5uLnDs_hR-%2Fvelocity-collection.png?alt=media\&token=f54ba0be-11cc-468d-bff9-0dd8fbe065a5)

## Combining Effects

{% hint style="danger" %}
Torque and position effects can be positioned next to each other, but cannot be positioned on top of one another.
{% endhint %}

{% hint style="warning" %}
Velocity effects can only be dropped onto collections with visualization type 'velocity'.
{% endhint %}

Different effect types:

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-Mk1AxJNRy4awOiXnjpF%2F-Mk1EfwtgoI5j1MRpplJ%2Feffects_collection_using_combinations.png?alt=media\&token=bd088c28-cdf6-4d99-8480-6e7ae44cd505)

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-Mk1AxJNRy4awOiXnjpF%2F-Mk1Efx-9hMI1Q49Q42o%2Feffects_collection_using_combinations2.png?alt=media\&token=2d568131-141b-443d-813d-82f847b07c74)

Effects of the same type can be combined into one effect

![](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-Mk1AxJNRy4awOiXnjpF%2F-Mk1Efx0kBG4TMzGUqFc%2Feffects_collection_using_combinations3.png?alt=media\&token=2cef28e8-9a53-4051-98e4-a312c4f4b1b6)


# Edit tools

The tool window can be selected from the toolbar (view > show toolbar (Ctrl + T)).

![Edit tools](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-M6bCd3rX_V79slyCoKD%2F-M6fPSSlxJB6rpS0-5uI%2Ftools.png?alt=media\&token=2086c5db-6d88-46c3-856b-73100c556d89)

{% hint style="info" %}
**Hold the space bar to enable zoom with the mouse wheel or touchpad**
{% endhint %}

#### Selection tool (V)

The selection tool can be used to select and transform paths. In combination with the SHIFT key, transformations with constant aspect ratio can be performed.

#### Direct selection tool (A)

The direct selection tool is used to change the position of anchor and control points to modify existing paths.

#### Brush tool (B)

Paths can be drawn with the brush tool, collection of generated points will be transformed into a simplified Bezier curve.

#### Pen tool (P)

The pen tool is used to draw Bezier curves, add and delete anchor points on a path, or connect two paths.

#### Anchor tool (Q)

The anchor tool can be used to change the position of a control point without changing the position of the opposite control point, and to delete the control points of an anchor point.

#### Scissors tool (S)

The scissor tool can be used to divide a path in two separate paths.&#x20;

#### Line-thickness tool (F)

For the design of haptic effects, the line-thickness tool can be used to change the line-thickness of a Bezier curve to indicate the direction of the force. Anchor points on the path can be pulled to left or right with the tool and new anchor points can be added on the path when holding shift.

#### Zoom tool (Z)

Zooming can be achieved with the zoom tool, or by scrolling the mouse wheel while holding the space bar.


# Effect Settings

Effect settings of the selected collection effect appear in the 'details' tab of the effect library section on the right.

{% hint style="info" %}
Changes made to the effect settings are only effective after upload
{% endhint %}

![Effect settings window](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRCGH7G7NQpJM4Xdpp%2F-MlRCpLZVe1yGnAotVYr%2FEffect_details.png?alt=media\&token=9815afcc-b09f-4a90-aa0a-33780b1d29bb)

#### Position

The offset of the effect from the x and y axis in the collection

#### Transform

Scale effect on x and/or y axis

#### Rotation

Haptic effects can be experienced when rotating either clockwise or counterclockwise or in both directions. Effects can also be repeated every rotation.

#### Repeat

Effects can also be repeated, changes made to the original effect will be copied to the other instances.

#### Quality

The quality value changes the render resolution of the effect, which affects the data size. The values in between the data points will be derived using linear interpolation. A lower quality value will result in a higher render resolution and larger data size.


# Layers

Layers are used to distinguish between **force feedback** effects for **clockwise** and **counterclockwise** rotation. Force feedback effects can be experienced in both direction or only in clockwise or counterclockwise rotation. To adjust these settings go to the [**effect settings**](/create-and-edit-files/effect-settings) and change the **'rotation'** settings of the selected effect.&#x20;

Use the icons to hide/show or lock/unlock the layers.

![collection layers CW and CCW](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MjioAJerc-vkVxAIOfO%2F-MjjLPCxKUyG8Zd6Nek0%2Flayers.png?alt=media\&token=02aff3f3-27af-498b-a71d-d0d8c46dab20)

<div align="center"><figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlRCGH7G7NQpJM4Xdpp%2F-MlRCpLZVe1yGnAotVYr%2FEffect_details.png?alt=media&amp;token=9815afcc-b09f-4a90-aa0a-33780b1d29bb" alt="" width="375"><figcaption><p>Turn effects on and off in clockwise or counter clockwise direction <br>from the Effect Details. Select every rotation to repeat an effect<br>every rotation.</p></figcaption></figure></div>


# Grid

A grid can be used to draw precise effects

To show the grid go to View > Grid > Show grid (Ctrl + G).

To modify the grid settings go to View > Grid > Grid settings

{% hint style="info" %}
Add guides to the drawing canvas. Hold mousedown on the one of the rulers and drag the mouse over the canvas.
{% endhint %}

![Grid settings](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FeCjYGFFdi1wbAq4CbgUK%2Fgrid-settings.png?alt=media\&token=cd742045-d154-4fa2-8f47-00b8b09678a1)


# Export Effects

The effects designed with Feelix can be exported as plain text and used in combination with the Feelix C++ library.

### Export effects designed with Feelix

In order to export an effect go to the effects tab of the library window and click the export button next to the effect (see image below).

![Effect library](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlG4oqRacfsW6HYrAJC%2F-MlG5DDXoRhVc0MbeazD%2Fexport-button.png?alt=media\&token=eb186036-4d17-4f71-b85d-165c4a6706ff)

An export window will appear.  The render quality of the export can be modified, increasing the value will reduce the number of data points.

![Export window](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MlG4oqRacfsW6HYrAJC%2F-MlG5DDRlax22nyZlUxo%2Fexport.png?alt=media\&token=fd906c74-22ec-4594-aa31-86c9ff71631d)

### Import effects designed with Feelix

Paste the code above the setup function in your Arduino code.

```cpp
/* initialize */ 
EffectConfig_s sawtooth_config {
	.data_size = 4,
	.angle = 120,
	.quality = 40,
	.effect_type = Effect_type::DEPENDENT,
	.control_type = Control_type::TORQUE
};

float data_sawtooth[] = {0.0, 0.95, -0.95, 0.0};
FeelixEffect sawtooth = FeelixEffect(sawtooth_copy_config, data_sawtooth_copy);
```

{% hint style="info" %}
More information about how to use these effects can be found in the [documentation](/downloads/arduino-library-documentation/effect-functions)
{% endhint %}


# TensorFlow

Machine Learning with TensorFlow JS

{% hint style="warning" %}
ML Feature has been updated in v3.1.2 more information will follow soon.
{% endhint %}

{% hint style="info" %}
supported in v2.1.0^
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FwrI7ubsfid9IDYCwFd9U%2FMLV3.png?alt=media&amp;token=bc389968-e6d4-42b9-a6ff-8e340cd1a704" alt=""><figcaption><p>Machine Learning window Feelix v3.0.0</p></figcaption></figure>

### Collecting Data

The sensor data from the motor can be collected and used to train a Neural Network. The data can be stored for lated used or exported.\
\
Play your effects in the main window, add the **Microcontroller** *(bottom left)* you want to record from , select the input variables you want to collect below **Inputs** *(top, middle)* and hit **Record** *(toolbar on the right)*. Now the interactions with the motor will be recorded and added to the data set. \
\
The data sets can be trimmed into smaller sections using the **trim** button *(toolbar on the right: scissors)*. Each set is associated with a classifier to label the data for training purposes, the classifier can be changed using the dropdown in the toolbar above the data graph.&#x20;

Datasets can be **saved** locally using the buttons in the toolbar *(right)*. They can also be **exported** and imported as json file. All datasets that are included in the list will be included in the training process.

### Initializing and Training a Model

The basic settings of the model can be adjusted to improve the output of the model. \
All the data listed below files will be used as training data. \
Select the **Open File** button to add data sets that have been saved earlier.&#x20;

### Classifying Data

When the model has been trained with the data, the interactions with the motor can be classified using predefined labels. Select **Deploy** to test the model.

{% hint style="info" %}
Filters are not working yet. More features will be added to explore with machine learning in haptic and shape changing interfaces.
{% endhint %}


# Setting up STM32

Follow the steps bellow to setup programming STM32 microcontrollers with the Arduino IDE (Option 1, top) or Visual Studio and Platform IO (Option 2, bottom).

### Prepare

{% stepper %}
{% step %}
**Install the** [**STM32CubeProgrammer**](< https://www.st.com/en/development-tools/stm32cubeprog.html >) to upload to the STM32 microcontroller (available for Windows and MacOS 64 bit).

Check the [troubleshoot page](/uploading-files/troubleshoot#stm32-cube-programmer-installation) if you experience issues with installing the STM32CubeProgrammer on MacOS
{% endstep %}

{% step %}
**Install the** [**Dependencies**](/uploading-files/simplefoc)
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
Make sure the device is in **BOOT mode** when uploading with Arduino IDE / Platform IO
{% endhint %}

{% hint style="info" %}
The **RESET** button on the STM32 micrcontroller needs to be pressed after switching between **BOOT** and **RUN mode** in order to read the change
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FO9k1eygfqsDQnRmqfwE8%2Fuploading.png?alt=media&amp;token=274e5c9e-8c5f-42ef-8040-9c2963eacda8" alt=""><figcaption></figcaption></figure>

### Option 1: Arduino IDE

{% stepper %}
{% step %}
Open Preferences > Additional Boards Manager URLs
{% endstep %}

{% step %}
Add a new line with the following URL: *<https://github.com/stm32duino/BoardManagerFiles/raw/main/package\\_stmicroelectronics\\_index.json>*

{% hint style="danger" %}
Installed Libaries and Boards Managers should match the version specified in the documentation below.
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FFAYPbZhE2BQ9rDkpQyCd%2Fpreference_boardsmanager.png?alt=media&amp;token=009eeae8-7dee-4c97-a68f-094d33d56620" alt=""><figcaption><p>Additional Boards Manager URLs window</p></figcaption></figure>
{% endstep %}

{% step %}
Open the **Boards Manager** from the Tools menu.
{% endstep %}

{% step %}
Search for '**STM32 MCU based boards**' and click **INSTALL v2.12.0**

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FAyHTdYRSwDS3JZiqzKIu%2Fboardsmanager.png?alt=media&amp;token=ab4077b5-cd16-4977-9811-f544a2dd7615" alt="" width="551"><figcaption></figcaption></figure>
{% endstep %}

{% step %}
Update the **Board Settings** in the Tools menu

* Set board to '**Generic STM32F4 series**'&#x20;
* Board part number to '**Generic F401RETx**'
* Upload method to '**STM32CubeProgrammer (DFU)**'
* USB support to '**CDC (generic 'Serial' supersede U(S)ART)**'
* U(S)ART support to '**Disabled (no Serial support)'**
* USB speed to '**Low/Full Speed**'

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2Fh68bQ4GwQAXYgRs0ceum%2Farduino_stm32_settings.png?alt=media&amp;token=642ea3d1-67ba-4526-8760-c3b7839999aa" alt=""><figcaption><p>Arduino IDE Board Settings</p></figcaption></figure>

{% hint style="warning" %}
The USB Serial port is only used for **Serial Monitor**, when the device is in **RUN mode** the USB Serial port will appear in the Arduino IDE (Tools > Port)
{% endhint %}

{% hint style="info" %}
**The USB Serial port** **does&#x20;*****not*****&#x20;have to be specified** (having one specified should not cause any problems either).
{% endhint %}

{% endstep %}

{% step %}
Now you are ready to **upload** [**your program**](/downloads/c-library#library-for-exported-feelix-effects) using the upload button in the Arduino IDE&#x20;

After uploading the Arduino IDE or Platform IO will enable **RUN mode** automatically. \
If the board has been **RESET** or disconnected from the **POWER**, the switch should be manually changed to **RUN mode** in order to run the program.

After manually switching to **RUN mode** press the **RESET** button on the STM32 microcontroller.

The program should be running now, if not check out the [**troubleshoot page**](/uploading-files/troubleshoot).

{% hint style="info" %}
Press the **RESET** button when the device is not recognized by the computer. Make sure the switch is set to **RUN mode**.
{% endhint %}
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
Method with Platform IO has not been tested recently.
{% endhint %}

### Option 2: Visual Studio & Platform IO

{% stepper %}
{% step %}
Add STM32 boards (search for ST STM)
{% endstep %}

{% step %}
When starting a new project, select STM32F401RE with framework Arduino

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FpvMY17ppfHNo37e2t0Xf%2Fvisual_studio_board_setup.png?alt=media&amp;token=f534ac22-a6c2-46cd-8609-ae8a2d60e29e" alt=""><figcaption><p>Visual Studio Project Board Settings</p></figcaption></figure>
{% endstep %}

{% step %}
Make sure the settings in the platform.ini file are as follows

```scheme
[env:genericSTM32F401RE]
platform = ststm32
board = genericSTM32F401RE
framework = arduino
upload_protocol = dfu
monitor_speed = 115200
;only for monitoring serial data 
;the monitor port name can be read when the device is in RUN mode
;monitor_port = COM3
board_build.mcu = stm32f401ret6
board_build.f_cpu = 84000000L
board_build.core = ststm32
build_flags = 
	-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC
	-D USBCON
	-D USBD_VID=0x0483
	-D USBD_PID=0x0003
	-D USB_MANUFACTURER="Unknown"
	-D USB_PRODUCT="\"GENERIC_F401RETX\""
	-D HAL_PCD_MODULE_ENABLED
lib_deps = askuric/Simple FOC@^2.4.0
```

{% endstep %}

{% step %}
**Upload** your program using the upload button in Visual Studio

After uploading the Arduino IDE or Platform IO will enable **RUN mode** automatically. \
If the board has been **RESET** or disconnected from the **POWER**, the switch should be manually changed to **RUN mode** in order to run the program.

After manually switching to **RUN mode** press the **RESET** button on the STM32 microcontroller.

The program should be running now.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Press the **RESET** button when the device is not recognized by the computer. \
Check out the [troubleshoot page](/uploading-files/troubleshoot) when issues persist.
{% endhint %}


# Setting up ESP32

Follow the steps below if you want to use an ESP32 as Master device.

{% hint style="success" %}
See [FeelixEffect Docs](broken://pages/C7ArpfbROUnAbs36JOGo) for communication examples.
{% endhint %}

{% hint style="warning" %}
[**Install CP2102 drivers**](https://www.pololu.com/docs/0j7/all) if you experience issues with uploading to ESP32.
{% endhint %}

{% stepper %}
{% step %}

#### Install ESP32 boards manager URL

Go to Arduino IDE > file > preferences

Add the following URL to boards manager URLs\
<https://espressif.github.io/arduino-esp32/package_esp32_index.json>

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FPsBYH0dhfDgEBDSbEI4z%2Fpreferences_add_esp32.png?alt=media&amp;token=e8f8493f-1467-4149-83e8-c671d9660416" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Install ESP32 by Espressif Systems in Boards Manager

Open Tools > Board > Boards manager&#x20;

Search **Espressif**&#x20;

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2F55XdVXHEffjGcQCBa78f%2Fesp32-boardsmanager%20url.png?alt=media&amp;token=5ba356f0-9071-452e-8118-fc96b933a584" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Select Board

When using DOIT ESP32 DEVKIT V1 available at [TinyTronics](https://www.tinytronics.nl/nl/development-boards/microcontroller-boards/met-wi-fi/esp32-wifi-en-bluetooth-board-cp2102). Go to Tools > Board > esp32 and select **DOIT ESP32 DEVKIT V1**&#x20;
{% endstep %}

{% step %}

#### Connect ESP32 with Feelink

**DOIT ESP32 DEVKIT V1**\
I<sup>2</sup>C SCL GPIO 22\
I<sup>2</sup>C SDA GPIO 21

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FzK40IIDIsgjo0H9LRzr3%2Fconnect%20esp.svg?alt=media&amp;token=b36182cb-ef99-472e-9603-2685c6dd4c78" alt=""><figcaption><p>DOIT ESP32 DEVKIT V1 - Feelink </p></figcaption></figure>

{% endstep %}
{% endstepper %}


# Dependencies

The following dependencies have to be installed to run the Arduino Library: SimpleFOC, and SimpleFOCDrivers.

{% hint style="info" %}
The code used for Feelix is based on the **SimpleFOC library v2.4.0**. \
For more details visit [**SimpleFOC.com**](https://simplefoc.com/)&#x20;
{% endhint %}

{% hint style="danger" %}
Installed libraries should match the versions specified in the documentation text below.
{% endhint %}

### Installation process for Arduino IDE

{% stepper %}
{% step %}

#### Install SimpleFOC library

* [ ] Open the **Library Manager** (Sketch > Include Library > Manage Libraries)
* [ ] Search for the [**Simple FOC**](https://simplefoc.com/) library and click **INSTALL v2.4.0**&#x20;
  {% endstep %}

{% step %}

#### Install SimpleFOCDrivers library

The Feelix MiniDriver uses the DRV8316C which requires the **SimpleFOCDrivers** library

* [ ] Open the **Library Manager** (Sketch > Include Library > Manage Libraries)
* [ ] Search for [**SimpleFOCDrivers** ](https://github.com/simplefoc/Arduino-FOC-drivers)and click **INSTALL v1.0.9**&#x20;
  {% endstep %}
  {% endstepper %}

<div><figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FGn2KHfMg6xK0beWW2vd5%2FArduino_librarymanager.png?alt=media&amp;token=a56a94b2-5321-4287-98b6-7bc42de6d71a" alt=""><figcaption><p>Installing SimpleFOC libraries using Arduino IDE.</p></figcaption></figure> <figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FFTdOlU1vi3X76KsZqxoC%2FArduino_librarymanager2.png?alt=media&amp;token=ec78b6d2-a457-481d-9ef8-f9f442fb7a86" alt=""><figcaption></figcaption></figure></div>

### Installation process for Platform IO (Visual Code Studio)

{% hint style="danger" %}
This process has not been verified
{% endhint %}

{% stepper %}
{% step %}

#### Install SimpleFOC library

* [ ] Go to **Libraries**
* [ ] Search for **SimpleFOC** and click **INSTALL v2.4.0**
  {% endstep %}

{% step %}

#### Install SimpleFOCDrivers library

The Feelix Mini-Driver uses the DRV8316C which requires the SimpleFOCDrivers

* [ ] Go to **libraries**
* [ ] Search for **SimpleFOCDrivers** and click **INSTALL v1.0.9**&#x20;
  {% endstep %}
  {% endstepper %}

![Search SimpleFOC library Platform IO](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MjsSMBxA0wwUKPZ8cwk%2F-MjsTtW5FcIx3mPv5IsR%2FsimpleFOC_platformIO.png?alt=media\&token=2ee21782-3647-41e9-b55f-9e0aa81036fc)


# Connect and Upload

Instructions for connecting your motor with the Feelix Haptic Design Tool.

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FO9k1eygfqsDQnRmqfwE8%2Fuploading.png?alt=media&amp;token=274e5c9e-8c5f-42ef-8040-9c2963eacda8" alt=""><figcaption></figcaption></figure>

### Connect

{% stepper %}
{% step %}
Use a USB cable to connect the micro-controller to your computer
{% endstep %}

{% step %}
Open the microcontroller settings window by going to Hardware > Microcontroller Settings or click the settings icon in the toolbar on the left side
{% endstep %}

{% step %}
Click on the add button (+) and select the right port from the list. Use the refresh button next to the dropdown to list all available ports.

![Microcontroller settings](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MjioAJerc-vkVxAIOfO%2F-MjitLnCiLvYYoiy9GEk%2Fconnect_new_microcontroller.png?alt=media\&token=145c7d23-5cda-4c89-9dba-987b1b1a0785)
{% endstep %}

{% step %}
Select the corresponding vendor of the microcontroller and press the save button

A new microcontroller will be added to microcontroller list in the window
{% endstep %}

{% step %}
The number of pole-pairs needs to be specified for the motor to operate correctly (default: 7) [find the number of pole-pairs for your motor](/hardware-support/hardware)
{% endstep %}

{% step %}
The supply voltage should match the voltage used to power the motor (default: 12V)
{% endstep %}
{% endstepper %}

### Check hardware settings

{% stepper %}
{% step %}
Access the **settings window** by going to *Hardware > Microcontroller Settings* or click the *settings icon* in the toolbar on the left side. For each motor the settings can be specified here.
{% endstep %}

{% step %}

#### Pole-pairs&#xD;

Make sure to set the right number of pole-pairs in the hardware settings ([see connect and upload](https://docs.feelix.xyz/hardware-support/hardware)).
{% endstep %}

{% step %}

#### Calibration (optional)

To (re)calibrate the motor, use the **UPDATE** button next to **zero electric angle**. This method will calculate the offset between the motor poles and the sensor, and the orientation of the sensor in relation to the motor poles.

Calibration will be done automatically when uploading for the first time.

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FopcjcMsDSfmR8kaZIitA%2Fmicrocontroller_settings.png?alt=media&amp;token=6dc7705d-96d1-4738-9382-33df797667b3" alt=""><figcaption><p>Hardware settings</p></figcaption></figure>
{% endstep %}
{% endstepper %}

### Upload

{% stepper %}
{% step %}
**Select the desired port** from the dropdown

![The added microcontroller will be visible in the 'select port' dropdown above the collections. ](https://409642222-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3MZhIYg7iSyaPwgNKY%2F-MjioAJerc-vkVxAIOfO%2F-MjivCB4_BY9VlLKhG0G%2Fselect_mcu_collection.png?alt=media\&token=5da1d2bd-63e7-4659-921e-bb95c87734a7)
{% endstep %}

{% step %}
**Render** the collection (button: ↺)
{% endstep %}

{% step %}
Click **upload** (button: ⇑)

Uploading will start if the selected microcontroller is connected with USB.\
The upload progress is visible in the status bar at the bottom of the window.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
**Make sure the Serial Monitor of the Arduino IDE is closed**, otherwise the Feelix Haptic Design Tool will not be able to connect with the microcontroller.
{% endhint %}

{% content-ref url="/pages/-MJBqivZplkhGfeV4BLi" %}
[Troubleshooting](/uploading-files/troubleshoot)
{% endcontent-ref %}


# Troubleshooting

Solutions to common issues with Feelix.

{% hint style="danger" %}
The Feelix Mini-Driver board needs to be connected to the external power supply to work properly. The USB port can only be used to download/upload the Arduino code. The motor can **NOT** be powered through the USB port. *Hardware damage may occur.*
{% endhint %}

## General

#### Motor is not behaving as expected

* [ ] Check if the power supply is connected.
* [ ] The motor draws more current than the external power supply can provide.
* [ ] The motor temperature is **very hot**. Wrong settings could be applied to cause this. **Let the motor cool down** before continuing.
* [ ] Make sure the Feelix Mini-Driver is running the [latest code](/downloads/c-library#arduino-library-feelix-design-tool): If you are using your own code, please revert to the stock version to verify whether it is still functioning correctly.

#### **Code is not compiling**

* [ ] Check if [**all dependencies**](/uploading-files/simplefoc) are installed
* [ ] Check if you have selected the correct board in the Arduino IDE. *Feelix Mini-Driver uses the STM32F401RE*.

#### Feelix Mini-Driver is not recognized

* [ ] Check if your computer recognizes the microcontroller when its connected via USB. In windows this can be verified by the "Device Manager."&#x20;
* [ ] Make sure the port is not in use by another program (e.g. Serial monitor of the Arduino IDE).
* [ ] Try the **RESET** button.
* [ ] Check if **STM32CubeProgrammer** is still able to detect the device in **BOOT mode**.
* [ ] It is recommended to use the cable provided.
* [ ] Test it on a different USB port or computer if possible.&#x20;

## Feelix - Haptic Design Tool

#### The Feelix Mini-Driver does not connect with the Feelix Haptic Design Tool

* [ ] Make sure the device is in **RUN mode**. The pink colored LED in the Feelix logo should blink periodically
* [ ] Try to restart Feelix in case the microcontroller is recognized by the computer but not by Feelix. Otherwise follow the steps at "Feelix Mini-Driver is not recognized".&#x20;

#### Motor is not behaving as expected

* [ ] Try to [recalibrate ](broken://pages/-M3NHh5uT6JPoz0noj15)the motor
* [ ] Make sure the right number of pole-pairs are specified ([see hardware settings](broken://pages/-M3NHh5uT6JPoz0noj15))\
  If not, recalibrate the motor.

#### Motor cursor does not move

* [ ] Check if the magnetic encoder is still working:\
  Upload example code from the [FeelixEffect library](/downloads/c-library#arduino-library-for-exported-feelix-effects) to read the encoder value \
  *Arduino IDE > examples > Feelix MiniDriver Effects > test > sensor.*
* [ ] If the sensor value is not read, the issue is probably caused by a broken sensor.

#### Feelix is not loading properly

* [ ] ***Issue occured after update?*** Go to 'help' > 'development tools'.
* [ ] Search for 'application' in the development tools.
* [ ] Clear all data.
* [ ] Restart Feelix.

#### If nothing is working..

* [ ] Delete the Feelix Mini-Driver from microcontroller settings window.
* [ ] Restart Feelix Host software.
* [ ] Reconnect to Feelix Mini-Driver.

## STM32CubeProgrammer installation

Arduino uses STM32CubeProgrammer in the background to upload code via DFU. If the Arduino IDE cannot find STM32CubeProgrammer on MacOS, it is usually because the stm32\_cubeprogrammer\_CLI executable is not in the file path expected by the IDE. You can restore this in the terminal.&#x20;

Use the following command in the terminal:

```
sudo ln -s /Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/Resources/bin/STM32_Programmer_CLI /usr/local/bin/STM32_Programmer_CLI
```

You can verify if the path is restored with the following command:

```
STM32_Programmer_CLI --version
```

If you get a getopt error after uploading, you can install gnu-getopt with homebrew using the following command:

```
brew install gnu-getopt
```

If homebrew is not installed, run the following command:

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

## ESP32 is not recognized

Usually this issue is caused by a missing driver. [Download and install the CP2102 driver](https://www.pololu.com/docs/0j7/all) to resolve the issue.

{% hint style="success" %}
Is your issue not listed here? Report it on [GitHub](https://github.com/ankevanoosterhout/Feelix/issues).
{% endhint %}


# Hardware

{% hint style="danger" %}
Recommended voltage 12V - 20V
{% endhint %}

### Motors used in the courses

| motor  | pole-pairs | Configuration | Torsion | Weight |
| ------ | ---------- | ------------- | ------- | ------ |
| GB36-1 | 7          | 12N14P        | 0.24 Nm | 88g    |
| GB36-2 | 7          | 12N14P        | 0.36 Nm | 128g   |

<div><figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FXwInps92cYubWp6Fw0fX%2Fgb36-1.webp?alt=media&amp;token=bd1d664d-f97a-437f-8ad6-665a7b5e3638" alt=""><figcaption><p>T-Motor GB36-1</p></figcaption></figure> <figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FOJff7YC1cxTdvBec7MZw%2F442_P_1493357528151.webp?alt=media&amp;token=fc06ce36-f4eb-4c2c-b69c-f6d04cd17c08" alt=""><figcaption><p>T-Motor GB36-2</p></figcaption></figure></div>

{% hint style="danger" %}
**WARNING**

**Max thread depth 4mm.** Inserting bolts deeper will damage the coils of motor.\
Max torque: 0.72 Nm for M2.5 and 1.28 Nm for M3.\
**Keep magnetic residue away from the motor.**
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FgZSZBSahAiEqOZM15u0e%2Fdimensions.svg?alt=media&amp;token=e261709d-1e24-4244-ba06-8dd380df4380" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Your motor not listed here? Check the configuration of the motor in the specs. For example, a configuration of 12N14P has 14 poles and therefore 7 pole-pairs.
{% endhint %}

{% file src="/files/SWh5f03BYWapvypmajkK" %}
GB36-1 datasheet
{% endfile %}

{% file src="/files/HHw1DRH7tjSdOljZB42T" %}
GB36-2 datasheet
{% endfile %}

{% content-ref url="/pages/-MIZule11uoupTjN5M7g" %}
[3D Models](/hardware-support/3d-model)
{% endcontent-ref %}


# Setup

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2F9R6Rh1MgdSBVmeBmfnnV%2Fi2c%20warning.svg?alt=media&amp;token=6ea878a0-a572-494d-b46c-ee3c6976d6bf" alt="" width="515"><figcaption><p>setup communication between Feelix motors</p></figcaption></figure>

### Programming Mode

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FJ1OmRBmXSBrBJ8l0bfx8%2Fsetup-programming-mode.svg?alt=media&amp;token=2b408e83-e548-4783-bfb4-42cec05d1983" alt="" width="563"><figcaption></figcaption></figure>

### Standalone Mode

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FAZAga5Eati4w7HCFoJqo%2Fsetup-standalone-mode.svg?alt=media&amp;token=45a554d1-19ae-4bb3-a5a1-d4ebf7a6179b" alt="" width="563"><figcaption></figcaption></figure>

### Feelix - Arduino Setup

{% hint style="danger" %}
**Important:** Use a microcontroller with **3.3V logic**, such as the **ESP32**.\
❌ **Do NOT use** microcontrollers like the **Arduino UNO**, which use **5V logic** — this can **damage the components**.
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FW3MchTypYJO7sNN3gOL0%2Fsetup-feelix-arduino.svg?alt=media&amp;token=9c956644-7e97-439e-9bc7-c2d681c7e2f0" alt="" width="563"><figcaption></figcaption></figure>

### Feelink Setup

{% hint style="danger" %}
**Important:** Use a microcontroller with **3.3V logic**, such as the **ESP32**.\
❌ **Do NOT use** microcontrollers like the **Arduino UNO**, which use **5V logic** — this can **damage the components**.
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FgnMUzcCwkwwBQovRQPsq%2Fsetup-feelink.svg?alt=media&amp;token=cfb71d42-d1e5-4c89-aa97-9813cc90aba8" alt="" width="563"><figcaption></figcaption></figure>


# PCB pinout

{% hint style="danger" %}
**Important:** Use a microcontroller with **3.3V logic**, such as the **ESP32**.\
❌ **Do NOT use** microcontrollers like the **Arduino UNO**, which use **5V logic** — this can **damage the components**.
{% endhint %}

## Feelix Mini-Driver V3.1

The board is driven by an STM32F401RET and uses the DRV8316C 3-phase motor driver to control the brushless motor. The AS5047D magnetic rotary encoder is used to track the position of the motor and a temperature sensor LM75 on the back shuts the driver down when the motor gets to hot.

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2F9AmXBijSaG7NxuCQ42kX%2FFeelix-mini-driver-v3.1-pinout.svg?alt=media&amp;token=8c7c5761-a6f2-4203-ac51-772a5c0624a1" alt=""><figcaption><p>Feelix Mini-Driver V3.1 Pinout</p></figcaption></figure>

#### The Power Supply Input

When running the motor an external supply is required. Default power supply has been set to 12V. Custom applications can go up to **20V absolute maximum**. This can increase the temperature of the system and introduce overheating problems.

The maximum voltages and current draw needs to be taking in account, otherwise serious unrepairable hardware failure could occur.

The Feelix Mini-Driver has no fuse internally, connecting though the Feelink Powerboard is therefore recommended as it has an internal fuse.

#### USB-C Connector

This connector is mainly used for flashing the Arduino software onto the Feelix Mini-Driver and [Standalone Mode setups](/hardware-support/setup#standalone-mode).\
\
The communication and power supply is [USB 2.0 compatible](https://en.wikipedia.org/wiki/USB). Actuating the motor though the USB power is **NOT** recommended.

#### I2C1 connector

This connector provides communication though a [QWIIC standard](https://www.sparkfun.com/qwiic). \
The Feelix Mini-Driver output +3V3/100mA at I<sup>2</sup>C port is for Controller connection to a Peripheral device like a sensor.

When using the Feelink, Feelix Mini-Driver can connect as a Peripheral device. The +3V3 jumpers should  **NOT** be connected (default) for this setup.&#x20;

{% hint style="success" %}
Note: Every I<sup>2</sup>C device needs to have an unique address. [More info](https://docs.feelix.xyz/hardware-support/pcb-pinout#i2c1-connector) about the I2C bus
{% endhint %}

#### SPI1 Connector

This connection is currently under development, but it can be used on special request.

#### Aux GPIO header pins

* The pins provide a 3V3 100mA  power supply output.&#x20;
* Pins 2 to 5 can be used as an Digital input, output or and Analog input.

{% hint style="warning" %}
Note: The Analog input range is from 0 to 3 Volt.  The max resolution is 12 bits.
{% endhint %}

{% file src="/files/sfr2o27HM6yeEj3Uq1pe" %}

## Feelink Power Board V1.X

The Feelink PowerBoard provides the ability to connect up to 3 Feelix Mini-Driver boards with motors.&#x20;

The board consists of a power supply conditioning system, I<sup>2</sup>C distribution, and SPI distribution.

The power distribution has a maximum input current of 5 amps total and per output 3 amps per connector. For most applications this should be adequate. The voltage range should remain between 12 and 20 volts.&#x20;

#### Arduino Power Supply

For suppling your Arduino (or other MCU) a regulated power supply is also available. The **toggle switch** on top of the Feelink casing turns the power supply ON or OFF.

Internally the power supply is selectable for outputting 5 or 7 volts, depending on the power supply your MCU board requires. Default is set to 5V, please do not change this yourself. The total maximum output is 3 amps.

{% hint style="warning" %}
The switch on the top of the Feelink **ONLY** toggles the +5/7V regulated power supply ON or OFF. **This is not recommended as an emergency switch.**
{% endhint %}

#### I<sup>2</sup>C and SPI communication with Feelix Mini-Driver

The Feelix Mini-Drivers board provide there own 3V3 power on the I<sup>2</sup>C and SPI connectors. The Feelink I<sup>2</sup>C/SPI 3V3 power outputs are at default disabled.&#x20;

If you want to connect a device at one of these connectors and require a power output, this is settable with a internal solder jumper. Please request feedback when in doubt.&#x20;

{% hint style="danger" %}
When the Feelink is connected to one or more Feelix Mini-Drivers, its possible to feedback power from the USB port. **It is recommended to keep the external power supply always connected and powered.**
{% endhint %}

{% hint style="danger" %}
**IMPORTANT**\
Do **not** connect I2C or SPI +3V3 output to Feelix Mini-Driver boards.

The Feelix Mini-Driver output it’s own 3V3 to communicate with I2C or SPI sensors that require power.\
The solder jumpers are meant to be used for devices that do require +3V3.
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FOO5M7q6elyGkRbhmECKL%2FFeelink-pinout-front.svg?alt=media&amp;token=a05c1d38-5c89-49a0-8a0d-40f8b95dd0c6" alt=""><figcaption></figcaption></figure>

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FH0yabyo3aRqACrMmJX11%2FFeelink-pinout-back.svg?alt=media&amp;token=a74f352d-12c2-408a-ac2c-0767b55a5736" alt=""><figcaption><p>Feelink Power board V2.1</p></figcaption></figure>

{% hint style="info" %}
Please do not block the ventilation holes in the Feelink casing.
{% endhint %}

{% file src="/files/cEg1KzTIAklT6ZRHXNQb" %}


# 3D Models

<div><figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2Fu95qufbTVEN0KpNAvQzj%2FFeelix-MiniDriver-case.PNG?alt=media&amp;token=9e3493b6-747f-47b1-8d8f-dc7a153fefb2" alt="" width="248"><figcaption><p>Feelix Mini-Driver case bottom mount</p></figcaption></figure> <figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FczBOcRd4zUGAZtF8pM5t%2FFeelix-MiniDriver-case-sidemount.png?alt=media&amp;token=938bff4f-764a-403d-bde0-8849153d82dd" alt="" width="248"><figcaption><p>Feelix Mini-Driver case side mount</p></figcaption></figure></div>

{% hint style="danger" %}
Use a **heat resistant** material to print files that are connected to the motor (e.g., ABS or PC).
{% endhint %}

#### Fusion 360 file

{% file src="/files/Ua9t1avL5zC6y8htjzNr" %}

#### STL files

{% file src="/files/yPhGM1CPw1fBx69ikaSW" %}

#### STEP file

{% file src="/files/U4PYZGROYkCKmh2caeL5" %}

#### STEP file PCB

{% file src="/files/7QNS2ipvn52d0R077FWu" %}


# Feelix Design Tool

Download the application for Windows and Mac OS

#### Download Feelix from GitHub Releases

{% embed url="<https://github.com/ankevanoosterhout/Feelix/releases>" %}

{% hint style="warning" %}
Remove any old versions before installing a new version
{% endhint %}

{% hint style="success" %}
Check out the [troubleshoot](/uploading-files/troubleshoot) page in case you run into issues
{% endhint %}


# Feelix Arduino Library

{% hint style="info" %}
The code builds upon [**SimpleFOC** ](https://simplefoc.com)**v2.4.0** by Antun Skuric.\
[**How to install the SimpleFOC library.** ](/uploading-files/simplefoc#install-simplefoc-library-using-arduino-ide)
{% endhint %}

> #### If you want to design and upload effects with the Feelix Haptic Design tool, you need to upload the [Feelix Haptic Design Tool Firmware](#feelix-haptic-design-tool-firmware).
>
> #### If you want to write your own code or use exported effects from feelix you need to upload the [Arduino Library for Exported Effects](#arduino-library-for-exported-feelix-effects).

## Feelix Haptic Design Tool Firmware

Download the Feelix Core Firmware to connect with the Feelix Design Tool.

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2F9RMP66pmuMR9Law2RgPH%2Ffeelixtool2.svg?alt=media&amp;token=ac152de5-9623-4028-b1a1-8e874f5ed650" alt=""><figcaption></figcaption></figure>

{% file src="/files/nskpGLqTPKek5A47Nvv1" %}
Code for Feelix MiniDriver to connect with the Feelix Design Tool
{% endfile %}

#### Upload MiniDriver v3.x Core with STM32CubeProgrammer

{% stepper %}
{% step %}

#### Select USB

Change Feelix MiniDriver to BOOT mode and press RESET button

Select USB and click Connect (green button, top-right corner)
{% endstep %}

{% step %}

#### Select File

Click **Erasing and Programming** from the left menu

Extract Feelix\_v1.3\_MiniDriver\_v3.x\_Core.ino.zip

Select **Browse** to search for: Feelix\_v1.3\_MiniDriver\_v3.x\_Core.ino.elf
{% endstep %}

{% step %}

#### Upload

Click **Start Programming**
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Click [**here**](< https://www.st.com/en/development-tools/stm32cubeprog.html >) to download the STM32CubeProgrammer.
{% endhint %}

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FVXRzUGKVRvuwRmV5mSJP%2Fupload_core.png?alt=media&amp;token=e6086ead-d02a-4999-bb91-855c747caaa7" alt=""><figcaption><p>Upload Feelix Core with STM32CubeProgrammer</p></figcaption></figure>

#### Pneumatic Control

{% file src="/files/HJ3bFVKelDdxdBk5jmv4" %}
FeelixAir Library v4.0.0 compatible with Feelix v3.x.x
{% endfile %}

## Arduino Library for Exported Feelix Effects

After you exported effects in Feelix, you can use the FeelixEffect library to import them in your code. *You can no longer connect with Feelix when using this library.*

Want to learn about how to embed the effects in your Arduino code? \
Have a look at the [**FeelixEffect library**](/downloads/arduino-library-documentation/effect-functions)[ **documentation**](/downloads/arduino-library-documentation/effect-functions)

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FA3029iK6IqCOKvxfDrKu%2Ffeelixtool.svg?alt=media&amp;token=53bf9a6e-2079-4f06-894c-c10b80034490" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
This library **does not work with the Feelix Design Tool.** It only allows you to import and play exported effects created in Feelix.
{% endhint %}

{% hint style="success" %}
Extract this folder and place it in the **Arduino IDE's 'libraries' directory** to access the example sketches from the File menu. Be sure to **remove any older versions** of the library first.
{% endhint %}

{% file src="/files/QNIhDGhb0TezqzEiVYjE" %}

{% hint style="info" %}
Follow these [**instructions**](/uploading-files/setting-up-stm32) when **uploading to STM32** for the first time.
{% endhint %}

## Old releases

{% content-ref url="/pages/ioUmun5TLFlMR2bENjTn" %}
[Old Library Releases](/downloads/c-library/old-library-releases)
{% endcontent-ref %}


# Old Library Releases

### Old Releases Code Feelix Design Tool

{% hint style="info" %}
The code builds upon [SimpleFOC ](https://simplefoc.com)v2.2.1 by Antun Skuric\
[Information about how to install the SimpleFOC library. ](/uploading-files/simplefoc#install-simplefoc-library-using-arduino-ide)
{% endhint %}

{% file src="/files/JBII0BPZzonfhBdX5cn3" %}

{% file src="/files/AQW4rsCiMVlsslAIqqQx" %}

{% file src="/files/bHswjKNi21CBL0cOxJgg" %}

{% file src="/files/pLHubQQV5Yf6JMHXQYec" %}

{% file src="/files/ePORfoLdmQv9kcxmCNtI" %}

{% file src="/files/lGrYYQbfhNDdq8bNXiiN" %}

{% file src="/files/rLZjAXWzOKPJZnAOEZ4A" %}

#### Pneumatic Control

{% file src="/files/DlOu1VjIFLUeuLsWHkam" %}
FeelixAir Library v3.0.0 compatible with Feelix v3.x.x
{% endfile %}

### Old Releases Arduino Library for Exported Feelix Effects

#### Feelix MiniDriver

Compatible with [Feelix MiniDriver v3.1](/hardware-support/pcb-pinout)

{% file src="/files/k95lAHqvSa8teOP7P6mO" %}

{% file src="/files/r8VNt6TZ8G1wUyWG4uZx" %}

{% file src="/files/nWNXgUROOQTOzRn8vFbY" %}
Feelix Effect library to play exported effets (compatible with SimpleFOC v2.3.4)
{% endfile %}

{% file src="/files/WZ5K1witeJSGOwjtxwWa" %}

{% file src="/files/BR9huQQYZG9BCxbYNrmE" %}

{% file src="/files/0FEYRXmrwIyLAN7QtNBM" %}

{% file src="/files/JSRHSagZpFacIqffGTXJ" %}

#### BLDC DriverBoard

{% file src="/files/2bBOBWt6iRktd4GbgKVh" %}
Feelix Effect library to play exported effets (compatible with SimpleFOC v2.3.4)
{% endfile %}

{% file src="/files/VdP81Jsk6CsJYDDmZYJC" %}
Feelix Effect library to play exported effets (compatible with SimpleFOC v2.3.4)
{% endfile %}

{% file src="/files/LWSNTZg2S0H2EZ4niRof" %}
Feelix Effect library to play exported effects (compatible with SimpleFOC v2.1.1)
{% endfile %}

{% file src="/files/XCeWI2Zu83wRKnTZGuCI" %}
Feelix Effect library to play exported effects (compatible with SimpleFOC v2.1.1)
{% endfile %}


# FeelixEffect Documentation

Arduino Library to add FeelixEffects to your Arduino projects.

{% hint style="info" %}

#### **Download the** [FeelixEffect Arduino Library](/downloads/c-library#library-for-exported-feelix-effects-lite-version)

{% endhint %}

### Library Documentation

{% content-ref url="/pages/po5PkYGiUAmcHg9Rpwwh" %}
[Initialization](/downloads/arduino-library-documentation/initialization)
{% endcontent-ref %}

{% content-ref url="/pages/ctVxpMQ0NulYgzcUCdos" %}
[Sensing](/downloads/arduino-library-documentation/sensing)
{% endcontent-ref %}

{% content-ref url="/pages/-MIzqDeC2O9Zk5xoq0yq" %}
[Control](/downloads/arduino-library-documentation/motor-control-functions)
{% endcontent-ref %}

{% content-ref url="/pages/-MIzq8qCubLAp43cZT1R" %}
[Import Feelix Effects](/downloads/arduino-library-documentation/effect-functions)
{% endcontent-ref %}

{% content-ref url="/pages/cutlMQLE3xkeHe3IoCec" %}
[I2C Communication](/downloads/arduino-library-documentation/i2c-communication)
{% endcontent-ref %}


# Initialization

#### **Initialize Feelix globally in scope**

```cpp
Feelix feelix = Feelix();
```

#### **Initialize Feelix in setup**

Optional: Skip motor calibration by copying `zero_electric_angle` and `sensor_direction` from the microcontroller settings window in Feelix. Set variables before calling `feelix.init()` .

```cpp
feelix.bldc->sensor_direction = Direction::CCW;
feelix.bldc->zero_electric_angle = 1.7134552001953125;
```

Initialize Feelix

```c++
feelix.init();
```


# Sensing

**Read onboard sensors every loop** – call `feelix.run();` to update motor state and sensor values:

* **Angle** – `feelix.angle` *(float, radians)*
* **Angle in degrees** – `feelix.angleDeg` *(float, degrees)*&#x20;
* **Velocity** – `feelix.velocity` *(float, rad/s)*
* **Rotation direction** – `feelix.rotation_dir` *(enum `Direction : int8_t`)*

  ```cpp
  enum Direction : int8_t {
      CW      = 1,  // clockwise
      CCW     = -1, // counterclockwise
      UNKNOWN = 0   // invalid or not yet known
  };
  ```
* **Temperature** – `feelix.temperature` *(float, °C)*
* **Current time** – `feelix.current_time` *(long, ms since program start)*
  * Reset with `feelix.resetTime();`


# Control

These functions provide motor control without using effects from Feelix and are based on the SimpleFOC library. Visit simplefoc.com for more details.

## Functions and Parameters

#### Move Motor

{% hint style="success" %}
This code works with the [**Feelix Effect Arduino Library**](/downloads/c-library#library-for-exported-feelix-effects)
{% endhint %}

* In **torque** mode  `MotionControlType::torque`  the  `targetValue` sets the voltage.
* In **angle** mode  `MotionControlType::angle`  the  `targetValue` sets the target position (radians).
* In **velocity** mode  `MotionControlType::velocity`  the  `targetValue` sets the target speed (rad/s).

```cpp
feelix.move_feelix(float targetValue, MotionControlType controlType);
```

#### Disable driver

```c++
feelix.disable();
```

#### Enable driver

```c++
feelix.enable(); // enabled by default in feelix.init();
```

#### Set rotation range

```cpp
void setRange(float rangeMin, float rangeMax, bool updateStartPos = true);
```

* **rangeMin** – start position in degrees *(default: 0)*
* **rangeMax** – end position in degrees *(default: 360)*
* **updateStartPos** *(optional)* – set current position to zero *(default: true)*

#### **Constrain range within which effects can be played**

```cpp
bool constrain_range = true;  // default: false
```

#### Set voltage limit

```cpp
void setVoltageLimit(float limit);  // default: 12.0 V
```

#### Set velocity limit

```cpp
void setVelocityLimit(float limit);  // default: 22.0 rad/s
```

## Motor Control Parameters

**PID controller settings** (more [information](https://docs.simplefoc.com/pi_controller))

Angle PID

```cpp
feelix.bldc->P_angle.P = 14.0;
feelix.bldc->P_angle.I = 0.0;
feelix.bldc->P_angle.D = 0.0;
```

Velocity PID

```cpp
feelix.bldc->PID_velocity.P = 0.5;
feelix.bldc->PID_velocity.I = 10.0;
feelix.bldc->PID_velocity.D = 0.0;
```

## Variables

Variables updated in `feelix.run()`

```cpp
feelix.angle           // angle in radians
feelix.angleDeg        // angle in degrees
feelix.velocity        // velocity in rad/s
feelix.temperature     // temperature motor 
feelix.driverVoltage   // voltage used to drive the motor
feelix.status          // status of the motor (see below)
```

#### Status

```c++
enum STATUS {
  STANDBY             = 0, // default status
  ERROR_TEMP          = 1, // temperature exceeds 60.0 degrees
  ERROR_UNDERVOLTAGE  = 2, // voltage is below 6.0V
  RUN_HAPTIC          = 3, // playing a haptic effect 
  RUN_VELOCITY        = 4, // playing a velocity effect
  ROTATING            = 5, // moving towards a target position
  DISABLED            = 6, // driver disabled
  ENABLED             = 7  // driver enabled
};
```

#### Transmission Factor

Setting this factor lets you account for gear ratios so motion is calculated at the output shaft rather than just at the motor.

```cpp
float transmissionFactor = 1.0; //default 1.0
```

{% hint style="info" %}
**transmission factor = (teeth of driven gear) ÷ (teeth of driving gear)**
{% endhint %}


# Import Feelix Effects

{% hint style="success" %}
Include the [**Feelix Effect Arduino Library**](/downloads/c-library#library-for-exported-feelix-effects) to import Feelix effects.&#x20;

The library includes examples for different use cases.
{% endhint %}

## Initialize the Effect

Effect configuration includes:

* **data\_size** – length of the data array.
* **angle** – width of the effect (in degrees or ms).
* **quality** – spacing between data points in the array.
* **control type** – effect type (torque, angle, or velocity).\
  Haptic effects can be dependent or independent (see [**Getting Started**](/getting-started/designing-effects/effects)).

```cpp
EffectConfig_s zigzag_spring_config { 
	.data_size = 6,
	.angle = 100,
	.quality = 20,
	.effect_type = Effect_type::INDEPENDENT,
	.control_type = Control_type::TORQUE
 };

float data_zigzag_spring[] = {1.0, 0.4, 0.8, 0.2, 0.6, 0.0};
FeelixEffect zigzag_spring = FeelixEffect(zigzag_spring_config, data_zigzag_spring);
```

```cpp
enum Effect_type {
    INDEPENDENT  = 0, 
    DEPENDENT    = 1,
    NOTSET       = -12345 
};

enum Control_type {
    POSITION        = 3, 
    TORQUE          = 2,
    VELOCITY        = 1,
    VELOCITY_ANGLE  = 4,
    MOVE_TO         = 5,
    UNDEFINED       = -12345   //not yet known or invalid state
};
```

## Play a Haptic Effect

Call `playHapticEffectAtAngle(FeelixEffect effect, float angle_deg)` in every loop to check the torque or angle based on the motor’s current position. Pass the `FeelixEffect` and the effect’s start position (in degrees) as arguments. Multiple effects can run in parallel or alternate using `if` statements.

Call `move_feelix()` to send data to the motor, it automatically sums overlapping effects.

```cpp
feelix.playHapticEffectAtAngle(zigzag_spring, 80.0);
   
feelix.move_feelix();
```

## Play a Velocity Effect

Call `playVelocityEffect(FeelixEffect effect, void (*callback)() = NULL)` in every loop to check the velocity based on the motor’s current speed. The optional callback is executed when the effect finishes.

Call `move_feelix()` to send data to the motor.

```cpp
feelix.playVelocityEffect(velocity_effect);

feelix.move_feelix();
```

## Change Feelix Effect Settings

Effect settings can be adjusted in the setup or main loop at run time.<br>

* **Enable effect** – `effect.enable();` *(enabled by default)*
* **Disable effect** – `effect.disable();`
* **Check if enabled** – `effect.isEnabled();` *(returns true if enabled, false if not)*
* **Start / Stop velocity effect**

  ```cpp
  effect.play(true, feelix.current_time);  //(time can be used for start delay)
  effect.play(false);                      // stop
  ```

  * `play = true` starts the effect
  * `time` can delay the start (default is `millis()`)
  * `play = false` stops the effect
* **Check if velocity effect is playing** - `effect.isPlaying();`  *(returns true if playing, false if not)*
* **Change effect scale**&#x20;

  * `scale.x` controls angle (for position/torque effects) or duration (for velocity effects).
  * `scale.y` controls intensity (%)

  ```cpp
  effect.scale.x = 1.5; // default 1.0 scale from -1.0 to 1.0 
  effect.scale.y = 0.5; // default 1.0 scale from -1.0 to 1.0 
  ```
* **Change vertical position effect**

  * `position.y`&#x20;

  ```cpp
  effect.position.y = -1.0; // default 0.0 scale from -1.0 to 1.0 
  ```
* **Repeat effect** – `effect.infinite = true;` *(default is false, works for both velocity and haptic effects)*
* **Disable effect by direction** *(haptic only)*&#x20;

  ```cpp
  effect.direction.cw = false;  // default true (clockwise)
  effect.direction.ccw = false; // default true (counterclockwise)
  ```


# I2C Communication

### Master request/send data

The master sends data to and requests data from slaves, including an 8-bit packet ID. Each slave uses this ID as an index into its callback function array to determine which function to execute.

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FvJl3gnjspOEH0dFonTJJ%2Fi2c_communication.svg?alt=media&amp;token=018c9fd2-8f9b-4a01-a22b-5b58cd69465a" alt=""><figcaption></figcaption></figure>

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FM03n6lXEB0yNlOq9fRJn%2Fmaster_slave.svg?alt=media&amp;token=68770635-7e52-43ed-a92d-7ffb76b86f57" alt=""><figcaption></figcaption></figure>

### Slave Return

Upon a request, the slave responds with a message containing a slaveCallbackIndex. The master uses this ID to select the corresponding callback function.&#x20;

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2Fr72mNCveelDnbPAmjeBw%2Fslave_master.svg?alt=media&amp;token=9b759bd9-8765-4e9e-b67d-11815247f9ff" alt=""><figcaption></figcaption></figure>

### I2C Setup Master

The examples use the DOIT ESP32 DEVKIT V1 as the master. The ESP32 is connected to the Feelix motors through the Feelink board.

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FzK40IIDIsgjo0H9LRzr3%2Fconnect%20esp.svg?alt=media&amp;token=b36182cb-ef99-472e-9603-2685c6dd4c78" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Default I2C pins on DOIT ESP32 DEVKIT are \
SCL GPIO22 \
SDA GPIO21\
\
Alternatively you can use \
SCL GPIO32 \
SDA GPIO33
{% endhint %}

### I2C Setup Slaves

The slaves can be connected with JSH cables to the FeeLink board.\
The **3.3V outputs** do **not** have to be connected.

<figure><img src="https://409642222-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M3MZhIYg7iSyaPwgNKY%2Fuploads%2FIddwxn3fC4y1Co98UFaR%2Fconnect%20slave%20i2c.svg?alt=media&amp;token=c6f194cd-aff9-47e8-ab0c-188606e1e587" alt=""><figcaption></figcaption></figure>


# Master Device

Overview of basic functions for I2C communication with Feelix

{% hint style="info" %}
Download the library with example codes [here](/downloads/c-library#arduino-library-for-exported-feelix-effects). Version 1.8 and later.
{% endhint %}

Define the addresses for each of the slaves that will be connected to the master.

```objective-cpp
#define SLAVE_0_ADDRESS 0x70
#define SLAVE_1_ADDRESS 0x71
#define SLAVE_2_ADDRESS 0x72
```

Create MasterDevice object. \
Pass an array with the addresses of all slaves as argument.

<pre class="language-c++"><code class="lang-c++"><strong>uint8_t slaves[] = { SLAVE_0_ADDRESS, SLAVE_1_ADDRESS };
</strong>
/* initialize master device */
MasterDevice I2C_Master(slaves);
</code></pre>

#### Initialization

Initialize master device in **void setup()**

```objective-cpp
/* initialize as Master device */
I2C_Master.init(
    ESP32_SDA,              //I2C Data (SDA)
    ESP32_SCL,              //I2C Clock (SCL)
    CLOCK_SPEED::SLOW_MODE, //Clock frequency 
                            // CLOCK_SPEED::SLOW_MODE = 100000 
                            // CLOCK_SPEED::FAST_MODE = 400000 
    DEBUG,                  //(optional) 
                            // bool debug (set to false before production)
    callbackArr,            //(optional)
                            // array with callback functions (functionPtr)
    callbackLength);        //(optional) size of array
```

#### Receiving motor parameters

Request motor parameters (angle, velocity, voltage, status) from slave device in **void loop()**

```c++
I2C_Master.requestDeviceParameters(SLAVE_0_ADDRESS)
```

Create a callback function to receive the device parameters from the slave. Call before **void setup()**

```c++
/* callback to receive parameters from slave */
void callBack_receiveParameter_slave() {
    I2C_Master.receiveDeviceParameters(); // masterCallbackIndex 0
}

/* array to store callback functions */
const functionPtr callbackArr[] = { 
    callBack_receiveParameter_slave //masterCallbackIndex 0
};
/* calculate length of array (do not change) */
uint8_t callbackLength = sizeof(callbackArr)/sizeof(functionPtr);
```

The received data is stored in the following variables

```c++
I2C_Master.slaves[slaveIndex].motor.angle
I2C_Master.slaves[slaveIndex].motor.velocity
I2C_Master.slaves[slaveIndex].motor.voltage
I2C_Master.slaves[slaveIndex].motor.status
```

#### Sending variables to slave

Send a **float** variable to the slave. The function triggers a callback at the slave side at slaveCallbackIndex of the callback array.

* float data,&#x20;
* uint8\_t slaveAddress,&#x20;
* uint8\_t slaveCallbackIndex

```c++
 float velocity = 3.0; 
 I2C_Master.sendFloat(velocity, SLAVE_0_ADDRESS, 0);
```

Send an **integer** variable to the slave. The function triggers a callback at the slave side at slaveCallbackIndex of the callback array.

* int16\_t data,&#x20;
* uint8\_t slaveAddress,&#x20;
* uint8\_t slaveCallbackIndex

```c++
 int16_t randomVariable = random(10000);
 I2C_Master.sendInt(randomVariable, SLAVE_0_ADDRESS, 1);
```

Send a **byte** variable to the slave. The function triggers a callback at the slave side at slaveCallbackIndex of the callback array.

* uint8\_t data,&#x20;
* uint8\_t slaveAddress,&#x20;
* uint8\_t slaveCallbackIndex

```c++
 uint8_t activeEffect = !activeEffect;
 I2C_Master.sendByte(activeEffect, SLAVE_0_ADDRESS, 2);
```

Send a **char array** to the slave. The function triggers a callback at the slave side at slaveCallbackIndex of the callback array.

* char (\&data)\[]&#x20;
* uint16\_t dataSize
* uint8\_t slaveAddress,&#x20;
* uint8\_t slaveCallbackIndex

```objective-cpp
char arr[] = "hello";
I2C_Master.sendCharArray(arr, sizeof(arr), SLAVE_0_ADDRESS, 3);
```


# Slave Device

Overview of basic functions for I2C communication with Feelix.

{% hint style="info" %}
Download the library with example codes [here](/downloads/c-library#arduino-library-for-exported-feelix-effects). Version 1.8 and later.
{% endhint %}

Define the address of the slave and index. The index should correspond to the position in the slaves array in the master code `uint8_t slaves[] = { SLAVE_0_ADDRESS }`

```c++
#define SLAVE_0_ADDRESS 0x70
#define SLAVE_INDEX     0
```

#### Initialization

Initialize Feelix as slave device after `Feelix.init()` in **void setup()**

```c++
/* initialize Feelix as slave device*/
feelix.init_I2C_Slave(
    SLAVE_0_ADDRESS,        //address of slave device
    SLAVE_INDEX,            //index of slave defined in initializer master device (uint8_t slaves[])
    &callback_I2C_Request,  //callback that fires when master requests data
    DEBUG,                  //(optional)
                            // bool debug (set to false before production)
    callbackArr,            //(optional)
                            // array with callback functions (functionPtr)
    callbackLength);        //(optional)
                            // size of array
```

Initialize Feelix as slave device after `Feelix.init()` in **void setup()**

```c++
/* initialize Feelix as slave device*/
feelix.init_I2C_Master(
    slaves[],               //index of slave defined in initializer master device (uint8_t slaves[])
    CLOCK_SPEED::SLOW_MODE, //Clock frequency 
    &callback_I2C_Request,  //callback that fires when master requests data
    DEBUG,                  //(optional)
                            // bool debug (set to false before production)
    callbackArr,            //(optional)
                            // array with callback functions (functionPtr)
    callbackLength);        //(optional)
                            // size of array
```

#### Reply to master

Reply with device parameters on master request

```c++
/* callback that fires when the master requests device parameters*/
void callback_I2C_Request() {

    /* return device parameters 
     * function takes masterCallbackIndex as argument
     */
    feelix.slave.returnDeviceParameters(0);
    feelix.toggleLED(STM32_LED_ORANGE);
}
```

#### Receive data from master

Create callback functions to receive data from master

```c++
/* callback that fires when the master sends float */
void callBack_receiveFloat() {
    variable_target = feelix.slave.receiveFloat();
}

/* callback that fires when the master sends int */
void callBack_receiveInt() {
    data = feelix.slave.receiveInt();
}

/* callback that fires when the master sends byte */
void callBack_receiveByte() {
    activeEffect = feelix.slave.receiveByte();
}

/* callback that fires when the master sends char array */
char arr[6]; /* allocation required */

void callBack_receiveCharArray() {
    feelix.slave.receiveCharArray(arr, sizeof(arr));
}
```

Create callback array to store all callbacks. The master can use the index of the callback function in the array to trigger a specific callback on the slave side.

```c++
/* array to store callback functions */
const functionPtr callbackArr[] = { 
    callBack_receiveFloat,    //slaveCallbackIndex 0
    callBack_receiveInt,      //slaveCallbackIndex 1
    callBack_receiveByte,     //slaveCallbackIndex 2
    callBack_receiveCharArray //slaveCallbackIndex 3
};
/* calculate length of array (do not change) */
uint8_t callbackLength = sizeof(callbackArr)/sizeof(functionPtr);
```


