Feelix
  • Feelix Documentation
  • Getting started
    • Designing Effects
      • Torque Effects
      • Position Effects
      • Velocity Effects
      • (In)dependent Effects
    • Effect Library
    • Creating Collections
  • Create and edit
    • Edit tools
    • Effect Settings
    • Layers
    • Grid
    • Export Effects
    • TensorFlow
  • Uploading files
    • Setting up STM32
    • Setting up ESP32
    • Connect and Upload
    • Hardware Settings
    • Troubleshooting Feelix
  • Hardware support
    • Hardware
    • PCB pinout
    • Setup
    • Dependencies
    • FeelixEffect Docs
      • Functions and Parameters
      • Setup
      • Motor control
      • Import Effects
        • Import Haptic Effect
        • Import Velocity Effect
      • I2C communication
        • One Way Communication
        • Two Way Communication
  • Downloads
    • Feelix Design Tool
    • Feelix Arduino Library
    • 3D Models
    • Old Library Releases
Powered by GitBook
On this page
  • ESP32 Master
  • Feelix I2C Master
  • Feelix I2C Slave

Was this helpful?

  1. Hardware support
  2. FeelixEffect Docs
  3. I2C communication

One Way Communication

PreviousI2C communicationNextTwo Way Communication

Last updated 3 days ago

Was this helpful?

Install in the Arduino IDE and open and run the code below from Examples > Feelix MiniDriver Effects > I2C communication > One way communication

The code below was tested with DOIT ESP32 DEVKIT V1 available at . Follow to add the board to the boards manager of your Arduino IDE.

ESP32 Master

Open this code from the 'Examples' folder within the Arduino IDE. Otherwise associated links and resources will not function correctly.

/* ESP32_i2c_comm_one_way_master v1.1
Example code to send data from a Master ESP32 (DOIT ESP32 DEVKIT V1) to Slave Feelix.
Slave address set to: 0x71
Uses a modified library of SerialTransfer
https://github.com/tommag/SerialTransfer/tree/i2c-request
*/
#include <Arduino.h>
#include <Wire.h>
#include "src/SerialTransfer/I2CTransfer.h"

#define define_I2C_master
#define SLAVE_01_ADDRESS 0x71
//#define SLAVE_02_ADDRESS 0x72

#define ESP32_SCL 22
#define ESP32_SDA 21

I2CTransfer transfer;

/* struct to store incoming data */
struct __attribute__((packed)) {
  char z;
  int angle;
  uint8_t count;
} dataToSend;

char arr[] = "hello";

uint8_t variable_PacketID;


void setup() {
  delay(1000);

  Serial.begin(115200);

  Wire1.begin(ESP32_SDA, ESP32_SCL);
  Wire1.setClock(100000);
  transfer.begin(Wire1);

  /* Some demo values */ 
  dataToSend.z = '$';
  dataToSend.angle = 0.0;

  variable_PacketID = 0;
}


void loop() {
  // use this variable to keep track of how many
  // bytes we're stuffing in the transmit buffer
  uint16_t sendSize = 0;

  // Stuff buffer with struct
  sendSize = transfer.txObj(dataToSend, sendSize);

  // Stuff buffer with array
  sendSize = transfer.txObj(arr, sendSize);

  // Send buffer
  transfer.sendData(sendSize, variable_PacketID, SLAVE_01_ADDRESS);

  Serial.println((String) "send\t" + dataToSend.count + "\t" + variable_PacketID +
                          "\t" + dataToSend.angle + "\t" + arr);

  // Generate some changing data
  dataToSend.count++;

  dataToSend.angle += 10;

  // toggle PacketID to show off the callbacks in slave example
  variable_PacketID++;
  if (variable_PacketID > 1) {
    variable_PacketID = 0;
  }
  
  delay(500);
}

Feelix I2C Master

When you are using a Feelix as Master instead of another 3v3 logic microcontroller, connect Feelix MASTER to Master input in Feelink and follow the example below.

/* Feelix_i2c_comm_one_way_master v1.1
Example code to send data from a Master Feelix to Slave Feelix.
One way direction. 
Slave address set to: 0x71
Uses a modified library of SerialTransfer
https://github.com/tommag/SerialTransfer/tree/i2c-request
*/

#include <Feelix.h>

/* define which SLAVES to send data to */
#define SLAVE_01_ADDRESS 0x71
//#define SLAVE_02_ADDRESS 0x72

/* define speed at which data is send to SLAVE*/
#define COMMUNICATION_SPEED 200

/* initialize Feelix */
Feelix feelix = Feelix();

/* struct to setup data structure of outgoing data */
struct __attribute__((packed)) {
  char z;
  int angle;
  uint8_t count;
} dataToSend;

/* more example data to send (remove or adapt to your needs) */
char arr[] = "hello";

int last_send_time = 0; /* variable to keep track of last time data was sent */
bool SEND_DATA = true; /* TRUE when sending data FALSE when requesting data*/
uint8_t variable_PacketID; /* id to select callback function at SLAVE */


void setup()
{
  Serial.begin(115200);

  delay(1000);

  /* initialize Feelix as I2C_Master: Default NO_COMMUNICATION */
  feelix.init(State::I2C_MASTER);
  /* directly set motion control type of the simpleFOC bldc controller 
   *(https://docs.simplefoc.com/closed_loop_motion_control) 
   */
  feelix.bldc->controller = MotionControlType::torque;

  /* Some demo values */ 
  dataToSend.z = '$';
  dataToSend.angle = 0.0;

  variable_PacketID = 0;
}



void loop()
{
  /* read angle, velocity and direction
   * this function needs to update at a high frequency */
  feelix.run();

  if (millis() - last_send_time > COMMUNICATION_SPEED) {
    last_send_time = millis();

    feelix.blinkStatusLED();

    dataToSend.angle = (int) (feelix.angle * 1000);
    // use this variable to keep track of how many
    // bytes we're stuffing in the transmit buffer
    uint16_t sendSize = 0;

    // Stuff buffer with struct
    sendSize = feelix.transfer.txObj(dataToSend, sendSize);

    // Stuff buffer with array
    sendSize = feelix.transfer.txObj(arr, sendSize);

    // Send buffer
    feelix.transfer.sendData(sendSize, variable_PacketID, SLAVE_01_ADDRESS);

    feelix.toggleLED(STM32_LED_ORANGE);

    Serial.println((String) "send\t" + dataToSend.count + "\t" + variable_PacketID +
                            "\t" + dataToSend.angle + "\t" + arr);

    // Generate some changing data
    dataToSend.count++;
    
    // toggle PacketID to show off the callbacks in slave example
    variable_PacketID++;
    if (variable_PacketID > 1)
    {
      variable_PacketID = 0;
    }
  }
  
  feelix.bldc->loopFOC();
  feelix.bldc->move(0.0);
}

Feelix I2C Slave

For communication with ESP32 Master or Feelix Master, connect Feelix SLAVE to Slave input in Feelink and follow the example below.

/* Example code to send data from a Master Feelix to Slave Feelix.
One way direction.
Slave address set to: 0x71
Uses a modified library of SerialTransfer
https://github.com/tommag/SerialTransfer/tree/i2c-request
*/

#include <Feelix.h>

#define SLAVE_01_ADDRESS 0x71

Feelix feelix = Feelix();

/* struct to store incoming data */
struct __attribute__((packed)) {
  char z;
  int angle;
  uint8_t count;
} dataToSend;

/* array to store data arr sent by the MASTer */
char arr[6];

float masterAngle = 0.0;

const uint8_t loop_interval = 100;
uint8_t loop_count = 0;

// Callbacks
void variable_PacketID_0()
{
  // use this variable to keep track of how many
  // bytes we've processed from the receive buffer
  uint16_t recSize = 0;

  recSize = feelix.transfer.rxObj(dataToSend, recSize);
  recSize = feelix.transfer.rxObj(arr, recSize);

  feelix.toggleLED(STM32_LED_ORANGE);
 
  Serial.println((String) "PacketID 0:\t" + dataToSend.count + "\t" + feelix.velocity + 
                          "\t" + masterAngle + "\t" + arr);
}


void variable_PacketID_1()
{
  // use this variable to keep track of how many
  // bytes we've processed from the receive buffer
  uint16_t recSize = 0;

  recSize = feelix.transfer.rxObj(dataToSend, recSize);
  recSize = feelix.transfer.rxObj(arr, recSize);

  feelix.toggleLED(STM32_LED_ORANGE);

  Serial.println((String) "PacketID 1:\t" + dataToSend.count + "\t" + feelix.velocity + 
                          "\t" + masterAngle + "\t" + arr);
}

// supplied as a reference - persistent allocation required
const functionPtr callbackArr[] = { variable_PacketID_0, variable_PacketID_1 };


void setup()
{
  Serial.begin(115200);

  delay(100);

  /* callback settings */
  feelix.config.debug = true;
  feelix.config.callbacks = callbackArr;
  feelix.config.callbacksLen = sizeof(callbackArr) / sizeof(functionPtr);

  /* initialize Feelix as I2C_SLAVE: Default NO_COMMUNICATION */
  feelix.init(State::I2C_SLAVE, SLAVE_01_ADDRESS);
  /* directly set motion control type of the simpleFOC bldc controller 
   * https://docs.simplefoc.com/closed_loop_motion_control 
   */
  feelix.bldc->controller = MotionControlType::angle;
}



void loop()
{
  /* read angle, velocity and direction
   * this function needs to update at a high frequency */
  feelix.run();

  /* update angle variable based on received data */
  masterAngle = (float) dataToSend.angle / 100.00;

  /* If statement for functions within the loop that need to be called less frequently.
   * Adapt frequency by changing loop_interval variable
   * E.g. for printing values and reading sensors;
   */
  if (loop_count++ > loop_interval) {
    loop_count = 0;

    /* print angle and velocity (values are updated in feelix.run()) */
    //Serial.println((String) "angle: " + feelix.angle + "\t vel: " + feelix.velocity);
  }

  /* Move the motor to the same angle as master you can change this to your needs using the motion control functions in SimpleFOC 
   * or play haptic effects using the Feelix library. 
   * Motion control function (https://docs.simplefoc.com/closed_loop_motion_control) */
  feelix.bldc->loopFOC();
  feelix.bldc->move(masterAngle);
  
}
TinyTronics
these steps
Arduino Library for Feelix Effects