Gravity: 360 Degree Rotary Encoder Module 20 PPR for Arduino Wiki - DFRobot Electronics

Introduction

This looks like a potentiometer, but it’s an encoder switch.

It is a cascadable 360 ° rotary encoder switch with 20 pulses per revolution, and each pulse corresponds to a detent. There are LED lights set for each detent to allow users visually check the real-time status of the encoder.

For ease of use, the module is designed with I2C data output and configurable accuracy within 1~51 for every detent (set in the program). For instance, when it is set to 1, turn on one LED light by rotating 2.5 revolutions; when set to 51, then one LED light can be switched on by rotating one detent.

In order to apply to more scenarios, the encoder is equipped with cascade function that enables to control multiple output devices by occupying only one I2C interface, such as, simultaneously controlling light brightness, color, volume, speed, etc.

Feature

Applications

Specification

Board Overview

Board Overview

Num Label Description
1 VCC/+ Power+
2 GND/- Power-
3 SCL/C I2C Clock line
4 SDA/D I2C Data line

I2C Address:

1 2 ADDR
0 0 0x54
0 1 0x55
1 0 0x56
1 1 0x57

Tutorial

Requirements

Connection Diagram

Connection 2

Main API Functions

 /* @brief Read module basic information
  * @param pbuf Address to store the readings
  *             The first element: Module PID
  *             The second element: Module VID
  *             The third element: Firmware version 
  *             The fourth element: Module communication address 
  */
  void readBasicInfo(uint16_t* pbuf);
  /**
  * @brief Get encoder current count value
  * @return Return value: 0-1023
  */
  uint16_t getEncoderValue(void);
  /**
  * @brief Set encoder count value 
  * @param value range[0, 1023], the setting is invalid when out of range
  */
  void setEncoderValue(uint16_t value);
  /**
  * @brief Get encoder current gain coefficient, accuracy value for rotating one detent. 
  * @n Accuracy range:1~51, max is 1(light up one LED about every 2.5 turns), max is 51(light up one LED every detent)
  * @return Return value: 1-51
  */
  uint8_t getGainCoefficient(void);
  /**
  * @brief Set encoder gain coefficient, accuracy value to rotate one detent 
  * @n Accuracy range: 1~51, max is 1(light up one LED about every 2.5 turns), max is 51(light up one LED every detent)
  * @param gainValue Range[1, 51], the setting is invalid when out of range
  */
  void setGainCoefficient(uint8_t gainValue);
  /**
  * @brief Detect if the button is pressed 
  * @return Return true if pressed, otherwise, return false
  */
  bool detectButtonDown(void);

Example 1 - Get encoder basic information

/*!
 * @file        getData.ino
 * @brief       This demo shows how to get basic encoder information, the current count and rotation gain
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license     The MIT License (MIT)
 * @author      [qsjhyy](yihuan.huang@dfrobot.com)
 * @version     V1.0
 * @date        2021-09-15
 * @url         https://github.com/DFRobot/DFRobot_VisualRotaryEncoder
 */
#include <DFRobot_VisualRotaryEncoder.h>

/**
 * Instantiate an object to drive our sensor;
 * Set address according to encoder DIP switch CH1 and CH2:
 * | 1 | 2 | ADDR |
 * |---|---|------|
 * | 0 | 0 | 0x54 |
 * | 0 | 1 | 0x55 |
 * | 1 | 0 | 0x56 |
 * | 1 | 1 | 0x57 |
 */
DFRobot_VisualRotaryEncoder_I2C sensor(/*i2cAddr = */0x54, /*i2cBus = */&Wire);

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

  // initialize sensor
  while( NO_ERR != sensor.begin() ){
    Serial.println("Communication with device failed, please check connection");
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
   * Retrieve basic information from the sensor and buffer it into basicInfo, the structure that stores information
   * Members of basicInfo structure: PID, VID, version, i2cAddr
   */
  sensor.refreshBasicInfo();

  /* Module PID, default value 0x01F6 (the highest two of the 16-bits data are used to judge SKU type: 00: SEN, 01: DFR, 10: TEL; The next 14 numbers are used as num)(SEN0502) */
  Serial.print("PID: 0x0");
  Serial.println(sensor.basicInfo.PID, HEX);

  /* Module VID, default value 0x3343(for manufacturer DFRobot) */
  Serial.print("VID: 0x");
  Serial.println(sensor.basicInfo.VID, HEX);

  /* Firmware version number: 0x0100 represents V0.1.0.0 */
  Serial.print("versions: 0x0");
  Serial.println(sensor.basicInfo.version, HEX);

  /* Module communication address, default value 0x54, module device address (0x54~0x57) */
  Serial.print("communication address:  0x");
  Serial.println(sensor.basicInfo.i2cAddr, HEX);

  /**
   * Get the encoder current gain factor, and the numerical accuracy for turning one step
   * Accuracy range:1~51,the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one step rotation)
   * Return value range: 1-51
   */
  uint8_t gainCoefficient = sensor.getGainCoefficient();
  Serial.print("Encoder current gain coefficient: ");
  Serial.println(gainCoefficient);

  Serial.println();
  delay(1000);
}

void loop()
{
  /**
   * Get the encoder current count
   * Return value range: 0-1023
   */
  uint16_t encoderValue = sensor.getEncoderValue();
  Serial.print("The encoder current counts: ");
  Serial.println(encoderValue);

  Serial.println();
  delay(1000);
}

Expected Results

Result 1

Example 2-Adjust encoder gain coefficient

Function: the encoder supports 51 accuracy values(1~51). Each time the encoder is rotated forward a detent, the corresponding analog value increases about 50. So, when the accuracy is set to 10, one LED will be switched on by rotating 5 detents.

/*!
 * @file        setSensor.ino
 * @brief       This demo shows how to adjust gain factor of the encoder
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license     The MIT License (MIT)
 * @author      [qsjhyy](yihuan.huang@dfrobot.com)
 * @version     V1.0
 * @date        2021-09-15
 * @url         https://github.com/DFRobot/DFRobot_VisualRotaryEncoder
 */
#include <DFRobot_VisualRotaryEncoder.h>

/**
 * Instantiate an object to drive our sensor;
 * Set address according to encoder DIP switch:
 * | 1 | 2 | ADDR |
 * |---|---|------|
 * | 0 | 0 | 0x54 |
 * | 0 | 1 | 0x55 |
 * | 1 | 0 | 0x56 |
 * | 1 | 1 | 0x57 |
 */
DFRobot_VisualRotaryEncoder_I2C sensor(/*i2cAddr = */0x54, /*i2cBus = */&Wire);

void setup()
{
  Serial.begin(115200);// Init serial port

  // initialize the sensor
  while( NO_ERR != sensor.begin() ){
    Serial.println("Communication with device failed, please check connection");
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
   * Set the current gain factor of the encoder, accuracy value to rotate one detent 
   * Accuracy range:1~51,the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * gainValue range[1, 51], the setting is invalid when out of range.
   */
  sensor.setGainCoefficient(10);// The currently set accuracy value: 10

  /**
   * Get the current gain factor of the encoder, accuracy value to rotate one detent
   * Accuracy range:1~51,the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * return value range: 1-51
   */
  uint8_t gainCoefficient = sensor.getGainCoefficient();
  Serial.print("Encoder current gain coefficient: ");
  Serial.println(gainCoefficient);

  Serial.println();
  delay(1000);
}

void loop()
{
  /**
   * Get the encoder current count value
   * return value range: 0-1023
   */
  uint16_t encoderValue = sensor.getEncoderValue();
  Serial.print("The encoder current counts: ");
  Serial.println(encoderValue);

  Serial.println();
  delay(1000);
}

Expected Results

Result 2

Example 3 - Reset encoder

Function: press the button to reset the encoder counts. All LEDs turn off this time.

/*!
 * @file        setSensor.ino
 * @brief       Reset the encoder value to zero when the button is detected to be pressed
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license     The MIT License (MIT)
 * @author      [qsjhyy](yihuan.huang@dfrobot.com)
 * @version     V1.0
 * @date        2021-09-15
 * @url         https://github.com/DFRobot/DFRobot_VisualRotaryEncoder
 */
#include <DFRobot_VisualRotaryEncoder.h>

/**
 * Instantiate an object to drive our sensor;
 * Set address according to encoder DIP switch:
 * | 1 | 2 | ADDR |
 * |---|---|------|
 * | 0 | 0 | 0x54 |
 * | 0 | 1 | 0x55 |
 * | 1 | 0 | 0x56 |
 * | 1 | 1 | 0x57 |
 */
DFRobot_VisualRotaryEncoder_I2C sensor(/*i2cAddr = */0x54, /*i2cBus = */&Wire);

void setup()
{
  Serial.begin(115200);// Init serial port 

  // Initialize the sensor
  while( NO_ERR != sensor.begin() ){
    Serial.println("Communication with device failed, please check connection");
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
   * Set the current gain factor of the encoder, accuracy value to rotate one detent
   * accuracy range:1~51,the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * gainValue range[1, 51], the setting is invalid when out of range.
   */
  sensor.setGainCoefficient(51);// The currently set accuracy value: 51

  /**
   * Get the current gain factor of the encoder, accuracy value to rotate one detent
   * accuracy range:1~51,the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * return value range: 1-51
   */
  uint8_t gainCoefficient = sensor.getGainCoefficient();
  Serial.print("Encoder current gain coefficient: ");
  Serial.println(gainCoefficient);

  Serial.println();
  delay(1000);
}

void loop()
{
  /**
   * Detect if the button is pressed
   * return true when the button pressed,otherwise, return false
   */
  if(sensor.detectButtonDown()){
    /**
     * Set the encoder count value
     * value range[0, 1023], the setting is invalid when out of range
     * In this example, set the encoder value to zero when detecting the button pressed, and you can see all the LEDs that light up before turning off
     */
    sensor.setEncoderValue(0);
  }

  /**
   * Get the encoder current count 
   * return value range: 0-1023
   */
  uint16_t encoderValue = sensor.getEncoderValue();
  Serial.print("The encoder current counts: ");
  Serial.println(encoderValue);

  Serial.println();
  delay(1000);
}

Expected Results

Result 3

Data on serial monitor:

Result 3

Example 4 - RGB LED color adjustment

Function: Adjust RGB LED ring color by three rotary encoders.

RBG LED Ring: to be updated.

Connection:

Connection 1

  /*!
 * @file        04.ino
 * @brief       Set encoder address and then adjust RGB light color through the three cascaded encoders.
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author      [qsjhyy](fengying.nie@dfrobot.com)
 * @version     V0.1
 * @date        2021-09-27
 * @get from    https://www.dfrobot.com
 * @url         
 */
 #include <DFRobot_NeoPixel.h>

// Dynamic variable
volatile float R, G, B;
// Function declaration 
uint32_t rgbToColor(uint8_t r, uint8_t g, uint8_t b);
// Create object 
DFRobot_NeoPixel neoPixel_2;
#include <DFRobot_VisualRotaryEncoder.h>
/*
Instantiate an object to drive our sensor;
Set address according to encoder DIP switch::
| 1 | 2 | ADDR |
|---|---|------|
| 0 | 0 | 0x54 |
| 0 | 1 | 0x55 |
| 1 | 0 | 0x56 |
| 1 | 1 | 0x57 |
*/
DFRobot_VisualRotaryEncoder_I2C sensor_1(/*iicAddr = */0x54, /*iicBus = */&Wire);
DFRobot_VisualRotaryEncoder_I2C sensor_2(/*iicAddr = */0x55, /*iicBus = */&Wire);
DFRobot_VisualRotaryEncoder_I2C sensor_3(/*iicAddr = */0x56, /*iicBus = */&Wire);

void setup()
{
  neoPixel_2.begin(2, 12); //Set RGB light pin to 2, the number of LED to 12 
  neoPixel_2.setBrightness(255);

  Serial.begin(115200);

  // Init sensor 
  while( NO_ERR != sensor_1.begin()&&NO_ERR != sensor_2.begin()&&NO_ERR != sensor_3.begin() ){
    Serial.println("Communication with device failed, please check connection");
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
   * Set encoder gain coefficient, accuracy value to rotate one detent 
   * Accuracy range: 1~51, the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * gainValue Range[1, 51], setting invalid when out of range.
   */
  sensor_1.setGainCoefficient(30);
  sensor_2.setGainCoefficient(30);
  sensor_3.setGainCoefficient(30);
  /**
   * Set encoder gain coefficient, accuracy value to rotate one detent 
   * Accuracy range: 1~51, the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * Return range: 1-51
   */
  uint8_t gainCoefficient_1 = sensor_1.getGainCoefficient();
  uint8_t gainCoefficient_2 = sensor_2.getGainCoefficient();
  uint8_t gainCoefficient_3 = sensor_3.getGainCoefficient();

  Serial.print("Encoder current gain coefficient: ");
  Serial.println(gainCoefficient_1);
  Serial.println(gainCoefficient_2);
  Serial.println(gainCoefficient_3);

  Serial.println();
  delay(1000);
}

void loop()
{
  /**
   * Detect if the button is pressed. 
   * Return true Button pressed, false, button unpressed 
   */
  if(sensor_1.detectButtonDown()){
    /**
     * Set the encoder count value
     * value Range[0, 1023], setting invalid when out of range
     * In this example, when the button is detected to be pressed, reset the encoder value to zero, then all the LEDs that light up before switch off.  
     */
    sensor_1.setEncoderValue(0);
  }

  if(sensor_2.detectButtonDown()){
    /**
     * Set the encoder count value
     * value Range[0, 1023], setting invalid when out of range
     * In this example, when the button is detected to be pressed, reset the encoder value to zero, then all the LEDs that light up before switch off.
     */
    sensor_2.setEncoderValue(0);
  }

  if(sensor_3.detectButtonDown()){
    /**
     * Set the encoder count value
     * value Range[0, 1023], setting invalid when out of range
     * In this example, when the button is detected to be pressed, reset the encoder value to zero, then all the LEDs that light up before switch off.
     */
    sensor_3.setEncoderValue(0);
  }

  /**
   * Get encoder current count value
   * Return value range: 0-1023
   */
  uint16_t encoderValue_1 = sensor_1.getEncoderValue();
  uint16_t encoderValue_2 = sensor_2.getEncoderValue();
  uint16_t encoderValue_3 = sensor_3.getEncoderValue();

  Serial.print("encoderValue_1: ");
  Serial.println(encoderValue_1);
   Serial.print("encoderValue_2: ");
  Serial.println(encoderValue_2);
   Serial.print("encoderValue_3: ");
  Serial.println(encoderValue_2);
  Serial.println();

  R = (map(encoderValue_1, 0, 1023, 0, 255));
  G = (map(encoderValue_2, 0, 1023, 0, 255));
  B = (map(encoderValue_3, 0, 1023, 0, 255));
  neoPixel_2.setRangeColor(0, 11, rgbToColor(round(R), round(G), round(B)));
  Serial.print("R: ");
  Serial.println(round(R));
  Serial.print("G: ");
  Serial.println(round(G));
  Serial.print("B: ");
  Serial.println(round(B));
  Serial.println();
  delay(1000);
}

// Static function 
uint32_t rgbToColor(uint8_t r, uint8_t g, uint8_t b)
{
  return (uint32_t)((((uint32_t)r<<16) | ((uint32_t)g<<8)) | (uint32_t)b);
}

Expected Results

Result 4

Data on serial monitor

Result 4-1

Example 5 Control servo angle

Function: control servo angle by rotating the rotary encoder.

/*!
 * @file        setSensor.ino
 * @brief       This demo shows tha thow to control servo angle by the encoder 
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author      [qsjhyy](yihuan.huang@dfrobot.com)
 * @version     V0.1
 * @date        2021-09-15
 * @get from    https://www.dfrobot.com
 * @url         https://github.com/DFRobot/DFRobot_VisualRotaryEncoder
 */
#include <DFRobot_VisualRotaryEncoder.h>

/*
Instantiate an object to drive our sensor;
Set address according to the encoder DIP:
| 1 | 2 | ADDR |
|---|---|------|
| 0 | 0 | 0x54 |
| 0 | 1 | 0x55 |
| 1 | 0 | 0x56 |
| 1 | 1 | 0x57 |
*/
DFRobot_VisualRotaryEncoder_I2C sensor(/*iicAddr = */0x54, /*iicBus = */&Wire);

#include <Servo.h>

Servo myservo;
int pos = 0;    // Init servo angle
void setup()
{
  myservo.attach(9);  // Set servo connection pin 

  Serial.begin(115200);

  // Init sensor 
  while( NO_ERR != sensor.begin() ){
    Serial.println("Communication with device failed, please check connection");
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
   * Set encoder gain coefficient, accuracy value to rotate one detent 
   * Accuracy range: 1~51, the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * Return range: 1-51
   */
  sensor.setGainCoefficient(51);

  /**
   * Get current encoder gain coefficient, accuracy value to rotate one detent 
   * Accuracy range: 1~51, the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * Return range: 1-51
   */
  uint8_t gainCoefficient = sensor.getGainCoefficient();
  Serial.print("Encoder current gain coefficient: ");
  Serial.println(gainCoefficient);

  Serial.println();
  delay(1000);
}

void loop()
{
  /**
   * Detect if the button is pressed 
   * Return true, button pressed. Return false: button unpressed 
   */
  if(sensor.detectButtonDown()){
    /**
     * Set the encoder count value
     * value Range[0, 1023], setting invalid when out of range
     * In this example, when the button is detected to be pressed, reset the encoder value to zero, then all the LEDs that light up before switch off.
     */
    sensor.setEncoderValue(0);
  }

  /**
   * Get encoder current count value
   * Return value range: 0-1023
   * Map the encoder value to servo angle 
   */
  uint16_t encoderValue = sensor.getEncoderValue();
  Serial.print("The encoder currently counts: ");
  Serial.println(encoderValue);
  pos = map(encoderValue, 0, 1023, 10, 170);
  myservo.write(pos);
  Serial.println();
  delay(1000);
}

Expected Results

Result 5

Example 6 Control LED light brightness

Function: control the LED light brightness by rotating the rotary encoder.

/*!
 * @file        setSensor.ino
 * @brief       This demo shows how to control LED light brightness by the encoder. 
 * @copyright   Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence     The MIT License (MIT)
 * @author      [qsjhyy](yihuan.huang@dfrobot.com)
 * @version     V0.1
 * @date        2021-09-15
 * @get from    https://www.dfrobot.com
 * @url         https://github.com/DFRobot/DFRobot_VisualRotaryEncoder
 */
#include <DFRobot_VisualRotaryEncoder.h>

/*
Instantiate an object to drive our sensor;
Set address according to encoder DIP: 
| 1 | 2 | ADDR |
|---|---|------|
| 0 | 0 | 0x54 |
| 0 | 1 | 0x55 |
| 1 | 0 | 0x56 |
| 1 | 1 | 0x57 |
*/
DFRobot_VisualRotaryEncoder_I2C sensor(/*iicAddr = */0x54, /*iicBus = */&Wire);

// #include <Servo.h>

// Servo myservo;
int LED = 0;    // Init LED brightness 
int ledPin = 10;  // Set LED light connection pin 
void setup()
{
  pinMode(ledPin, OUTPUT);

  Serial.begin(115200);

  // Init sensor 
  while( NO_ERR != sensor.begin() ){
    Serial.println("Communication with device failed, please check connection");
    delay(3000);
  }
  Serial.println("Begin ok!");

  /**
   * Set encoder gain coefficient, accuracy value to rotate a detent 
   * Accuracy range: 1~51, the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * gainValue Range[1, 51], setting invalid when out of range
   */
  sensor.setGainCoefficient(51);

  /**
   * Get current encoder coefficient, accuracy value to rotate one detect. 
   * Accuracy range: 1~51, the minimum is 1 (light up one LED about every 2.5 turns), the maximum is 51 (light up one LED every one detent rotation)
   * Return value range: 1-51
   */
  uint8_t gainCoefficient = sensor.getGainCoefficient();
  Serial.print("Encoder current gain coefficient: ");
  Serial.println(gainCoefficient);

  Serial.println();
  delay(1000);
}

void loop()
{
  /**
   * Detect if the button is pressed 
   * Return true, button pressed. Return false: button unpressed 
   */
  if(sensor.detectButtonDown()){
    /**
     * Set the encoder count value
     * value Range[0, 1023], setting invalid when out of range
     * In this example, when the button is detected to be pressed, reset the encoder value to zero, then all the LEDs that light up before switch off.
     */
    sensor.setEncoderValue(0);
  }

  /**
   * Get encoder current count value 
   * Return value: 0-1023
   * Map enocder value to LED brightness 
   */
  uint16_t encoderValue = sensor.getEncoderValue();
  Serial.print("The encoder currently counts: ");
  Serial.println(encoderValue);
  LED = map(encoderValue, 0, 1023, 0, 255);
  analogWrite(ledPin,LED);   //Write corresponding value to LED   
  Serial.println();
  delay(1000);
}

FAQ

For any questions, advice or cool ideas to share, please visit the DFRobot Forum.

More Documents