<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[M5Unit-8Encoder only for ESP32?]]></title><description><![CDATA[<p dir="auto">Hi, I got a M5Unit-8Encoder and I am trying to get it to work with a Arduino Nano Every and a RB Pi Pico. I installed the library on <a href="https://github.com/m5stack/M5Unit-8Encoder" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/m5stack/M5Unit-8Encoder</a> and have tried the example. However it throws many compiler errors. Digging deeper, I found that the library calls  _wire-&gt;begin(_sda, _scl, _speed). So it passes three arguments, where the standard TwoWire class only has begin() functions with zero or one argument. However I am quite a beginner so am pretty much stuck.</p>
<p dir="auto">What am I missing here? Is the library only supposed to work for ESP32? There is little to no further documentation to be found.</p>
]]></description><link>https://community.m5stack.com/topic/6473/m5unit-8encoder-only-for-esp32</link><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Apr 2026 18:38:39 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/6473.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 14 May 2024 17:33:21 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to M5Unit-8Encoder only for ESP32? on Wed, 16 Apr 2025 23:46:52 GMT]]></title><description><![CDATA[<p dir="auto">Hi <a class="plugin-mentions-user plugin-mentions-a" href="/user/felmue" aria-label="Profile: felmue">@<bdi>felmue</bdi></a>, thanks for responding.<br />
The M5Stack Supplied github example is below.</p>
<pre><code>/*
    Description: Provide three LEGO motor drive modes。Press button B to switch
   the mode, button A and C control parameter value increase and decrease
*/

#include &lt;M5Stack.h&gt;
#include "UNIT_8ENCODER.h"
#include &lt;M5GFX.h&gt;

M5GFX display;
M5Canvas canvas(&amp;display);
UNIT_8ENCODER sensor;

long delay_time = 0;

void show_rgb_led(void) {
    sensor.setAllLEDColor(0xff0000);
    delay(1000);
    sensor.setAllLEDColor(0x00ff00);
    delay(1000);
    sensor.setAllLEDColor(0x0000ff);
    delay(1000);
    sensor.setAllLEDColor(0x000000);
}

void show_encoder_value(void) {
    int32_t encoder[8]    = {0};
    uint8_t btn_stauts[8] = {0};
    bool switch_status    = false;

    canvas.clear(BLACK);
    canvas.setCursor(80, 0);
    canvas.setTextSize(2);
    canvas.setTextColor(YELLOW);
    canvas.printf("8Encoder Demo");
    canvas.setColor(ORANGE);
    canvas.drawLine(0, 25, 320, 25);
    canvas.drawLine(0, 25 + 30, 320, 25 + 30);
    canvas.setCursor(0, 30);
    canvas.setTextSize(2);
    canvas.setTextColor(WHITE);
    canvas.printf("1-4");
    canvas.setColor(ORANGE);
    canvas.drawLine(60, 30, 60, 25 + 30);
    canvas.drawLine(125, 30, 125, 25 + 30);
    canvas.drawLine(190, 30, 190, 25 + 30);
    canvas.drawLine(255, 30, 255, 25 + 30);

    canvas.setColor(ORANGE);
    canvas.drawLine(0, 55 + 30, 320, 55 + 30);
    canvas.setCursor(0, 30 + 30);
    canvas.setTextSize(2);
    canvas.setTextColor(WHITE);
    canvas.printf("5-8");
    canvas.setColor(ORANGE);
    canvas.drawLine(60, 25 + 30, 60, 55 + 30);
    canvas.drawLine(125, 25 + 30, 125, 55 + 30);
    canvas.drawLine(190, 25 + 30, 190, 55 + 30);
    canvas.drawLine(255, 25 + 30, 255, 55 + 30);

    canvas.setTextColor(GREEN);
    for (int i = 0; i &lt; 8; i++) {
        encoder[i]    = sensor.getEncoderValue(i);
        btn_stauts[i] = sensor.getButtonStatus(i);
    }
    for (int i = 0; i &lt; 8; i++) {
        if (!btn_stauts[i]) {
            if (i &lt; 4)
                canvas.fillRect(60 + 65 * i, 30, 65, 25, GREEN);
            else
                canvas.fillRect(60 + 65 * (i - 4), 60, 65, 25, GREEN);
        }
    }
    canvas.drawString(String(encoder[0]), 60, 30);
    canvas.drawString(String(encoder[1]), 125, 30);
    canvas.drawString(String(encoder[2]), 190, 30);
    canvas.drawString(String(encoder[3]), 255, 30);
    canvas.drawString(String(encoder[4]), 60, 60);
    canvas.drawString(String(encoder[5]), 125, 60);
    canvas.drawString(String(encoder[6]), 190, 60);
    canvas.drawString(String(encoder[7]), 255, 60);

    switch_status = sensor.getSwitchStatus();
    canvas.setCursor(10, 120);
    canvas.setTextColor(WHITE);
    canvas.printf("switch:");
    if (switch_status) {
        canvas.fillRect(100, 110, 50, 30, GREEN);
    } else {
        canvas.fillRect(100, 110, 50, 30, RED);
    }

    canvas.setColor(ORANGE);
    canvas.drawLine(0, 185, 320, 185);
    canvas.drawLine(120, 185, 120, 320);
    canvas.drawLine(210, 185, 210, 320);
    canvas.setTextColor(YELLOW);
    canvas.drawString("RGB", 30, 190);
    canvas.drawString("Show", 30, 220);
    canvas.drawString("Encoder", 130, 190);
    canvas.drawString("Reset", 130, 220);

    canvas.pushSprite(0, 0);
}

void setup() {
    M5.begin(true, false, true);
    M5.Power.begin();
    display.begin();
    sensor.begin(&amp;Wire, ENCODER_ADDR, 21, 22, 100000UL);
    canvas.setColorDepth(8);  // mono color
    // canvas.setFont(&amp;fonts::efontCN_12);
    canvas.createSprite(display.width(), display.height());

    delay_time = millis() + 10;
}

void loop() {
    show_encoder_value();
    M5.update();
    if (M5.BtnA.wasPressed()) {
        show_rgb_led();
    } else if (M5.BtnB.wasPressed()) {
        for (int i = 0; i &lt; 8; i++) {
            sensor.resetCounter(i);
        }
    }
}
</code></pre>
<p dir="auto">My assumption  was just to change line 110 from (their default esp32  pin definition) for SDA / SCL</p>
<pre><code>sensor.begin(&amp;Wire, ENCODER_ADDR, 21, 22, 100000UL);
</code></pre>
<p dir="auto">To my pin definition for M5Dial Port A</p>
<pre><code>sensor.begin(&amp;Wire, ENCODER_ADDR, 13, 15, 100000UL);
</code></pre>
<p dir="auto">However that didn't work, After hours and hours of mucking about I found what works for me.</p>
<p dir="auto">ADD</p>
<pre><code>#define WIRE Wire

</code></pre>
<p dir="auto">In Setup ADD</p>
<pre><code>  WIRE.begin(13,15);
  sensor.begin(&amp;Wire, ENCODER_ADDR, 13, 15, 100000UL);
</code></pre>
<p dir="auto">Full Working Code Below</p>
<pre><code>#include "M5Dial.h"
#include &lt;Arduino.h&gt;
#include &lt;lvgl.h&gt;
//#include &lt;Wire.h&gt;
#include &lt;SPI.h&gt;
#include "ui.h"
#include "ui_helpers.h"
#include "UNIT_8ENCODER.h"

UNIT_8ENCODER sensor;

// init the tft espi
static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t disp_drv;  // Descriptor of a display driver
static lv_indev_drv_t indev_drv; // Descriptor of a touch driver

#define EXAMPLE_LCD_H_RES 240
#define EXAMPLE_LCD_V_RES 240
#define LV_VER_RES_MAX 240
#define LV_HOR_RES_MAX 240
M5GFX *tft;
#define WIRE Wire

void tft_lv_initialization() {
  lv_init();
  static lv_color_t buf1[(LV_HOR_RES_MAX * LV_VER_RES_MAX) / 10];  // Declare a buffer for 1/10 screen size
  static lv_color_t buf2[(LV_HOR_RES_MAX * LV_VER_RES_MAX) / 10];  // second buffer is optionnal
  // Initialize `disp_buf` display buffer with the buffer(s).
  lv_disp_draw_buf_init(&amp;draw_buf, buf1, buf2, (LV_HOR_RES_MAX * LV_VER_RES_MAX) / 10);
  tft=&amp;M5Dial.Lcd;
}

// Display flushing
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint32_t w = (area-&gt;x2 - area-&gt;x1 + 1);
  uint32_t h = (area-&gt;y2 - area-&gt;y1 + 1);
  tft-&gt;startWrite();
  tft-&gt;setAddrWindow(area-&gt;x1, area-&gt;y1, w, h);
  tft-&gt;pushColors((uint16_t *)&amp;color_p-&gt;full, w * h, true);
  tft-&gt;endWrite();
  lv_disp_flush_ready(disp);
}

void init_disp_driver() {
  lv_disp_drv_init(&amp;disp_drv);  // Basic initialization
  disp_drv.flush_cb = my_disp_flush;  // Set your driver function
  disp_drv.draw_buf = &amp;draw_buf;      // Assign the buffer to the display
  disp_drv.hor_res = LV_HOR_RES_MAX;  // Set the horizontal resolution of the display
  disp_drv.ver_res = LV_VER_RES_MAX;  // Set the vertical resolution of the display
  lv_disp_drv_register(&amp;disp_drv);                   // Finally register the driver
  lv_disp_set_bg_color(NULL, lv_color_hex3(0x000));  // Set default background color to black
}

void my_touchpad_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
  uint32_t currentTime = millis(); 
  M5.Touch.update(currentTime);

  if(M5.Touch.getCount() &gt; 0)
  {

 
  auto pos = M5.Touch.getDetail();
    data-&gt;state = LV_INDEV_STATE_PRESSED; 
    data-&gt;point.x = pos.x;
    data-&gt;point.y = pos.y;
  }
  else
  {
 data-&gt;state = LV_INDEV_STATE_RELEASED;
  }
}

void init_touch_driver() {
  lv_disp_drv_register(&amp;disp_drv);
  lv_indev_drv_init(&amp;indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_t * my_indev = lv_indev_drv_register(&amp;indev_drv);  // register
}

void setup()
{
  auto cfg = M5.config();
  M5Dial.begin(cfg, true, false);
  M5Dial.Display.setBrightness(80);
  Serial.begin(115200);
  tft_lv_initialization();
  init_disp_driver();
  init_touch_driver();
  ui_init();

  WIRE.begin(13,15);
  sensor.begin(&amp;Wire, ENCODER_ADDR, 13, 15, 100000UL);
}


void loop()
{
    uint32_t wait_ms = lv_timer_handler();
    M5.delay(wait_ms);
    M5Dial.update();
}


void SLS_Function_1(lv_event_t *e) {            // Squareline Studio Function 1 Code Runs Here

bool switch_status = false;  
sensor.setAllLEDColor(0x00ff00);  // GREEN
switch_status = sensor.getSwitchStatus();
Serial.println("function-1 Set All Leds Green - Switch Status is:  " + String(switch_status));    
}

void SLS_Function_2(lv_event_t *e) {            // Squareline Studio Function 2 Code Runs Here           

bool switch_status = false;
sensor.setAllLEDColor(0x0000ff);  // BLUE
switch_status = sensor.getSwitchStatus();
Serial.println("function-2 Set All Leds Blue - Switch Status is:  " + String(switch_status));   
}
</code></pre>
<p dir="auto">So, I got there in the end, and a pretty easy fix, once you know. Isn't that half the fun??</p>
<p dir="auto">I just think that their documentation is a little lacking unless you want to use the "Exact same HW setup" as provided in the limited examples. For example you have to dig into the github repo for this module to find all the functions available for this unit, especially if they are targeting a potentially large STEM  customer base? Unless of course you just want to use UIFlow.</p>
<p dir="auto">Anyway, once again thanks for responding and hopefully the above may help anyone else using the Encoder.</p>
]]></description><link>https://community.m5stack.com/post/28917</link><guid isPermaLink="true">https://community.m5stack.com/post/28917</guid><dc:creator><![CDATA[iainmac]]></dc:creator><pubDate>Wed, 16 Apr 2025 23:46:52 GMT</pubDate></item><item><title><![CDATA[Reply to M5Unit-8Encoder only for ESP32? on Wed, 16 Apr 2025 05:27:38 GMT]]></title><description><![CDATA[<p dir="auto">Hello <a class="plugin-mentions-user plugin-mentions-a" href="/user/iainmac" aria-label="Profile: iainmac">@<bdi>iainmac</bdi></a></p>
<p dir="auto">you probably need to adjust the GPIOs used for I2C. You can find the GPIOs M5Dial uses for port A <a href="https://docs.m5stack.com/en/core/M5Dial?id=pinmap" target="_blank" rel="noopener noreferrer nofollow ugc">here</a>. (Section HY2.0-4P)</p>
<p dir="auto">Thanks<br />
Felix</p>
]]></description><link>https://community.m5stack.com/post/28899</link><guid isPermaLink="true">https://community.m5stack.com/post/28899</guid><dc:creator><![CDATA[felmue]]></dc:creator><pubDate>Wed, 16 Apr 2025 05:27:38 GMT</pubDate></item><item><title><![CDATA[Reply to M5Unit-8Encoder only for ESP32? on Mon, 14 Apr 2025 12:27:45 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jmcdeg" aria-label="Profile: jmcdeg">@<bdi>jmcdeg</bdi></a><br />
Did you ever progress with this issue. I am trying to pair the 8Ch Encoder unit with an M5Dial and am getting no-where. Fairly sure like you its an I2C issue.</p>
<p dir="auto">Strangely I had no problem getting it to work on a bare bones ESP32 Dev Module on the default I2C pins. <a href="https://www.az-delivery.de/en/products/esp32-developmentboard" target="_blank" rel="noopener noreferrer nofollow ugc">https://www.az-delivery.de/en/products/esp32-developmentboard</a></p>
<p dir="auto">See Code Below for that working example.<br />
Somewhat Ironic that when trying to pair it with one of their own Boards (M5Dial) it doesn't work out of the box. UIFlow2 works fine. I just cant for the life of me get the Arduino framework example they provide to work.</p>
<pre><code>// ========== SETUP &amp; LOOP ========== //
void setup() {
    Serial.begin(115200);
    sensor.begin(&amp;Wire, ENCODER_ADDR, 21, 22, 100000UL);
    
    while (!Serial); // Wait for serial
    
    Serial.println("System Ready - Send 'enc all set zero' to reset encoders");
    
    // Initialize to first state
    sensor.setAllLEDColor(0xff0000); // Start main LEDs RED
}
</code></pre>
<pre><code>/*
 * Sequential Non-Blocking LED Control for UNIT_8ENCODER
 * - Main LEDs complete full cycle first
 * - Then Channel 0 LED runs its cycle
 * - Continues in this sequential pattern
 */

#include "UNIT_8ENCODER.h"

UNIT_8ENCODER sensor;

// ========== TIMING CONTROL ========== //
unsigned long prevLedUpdate = 0;
unsigned long prevEncoderReport = 0;

const long LED_UPDATE_INTERVAL = 1000;      // 1 second per color for main LEDs
const long CH0_LED_INTERVAL = 250;         // 250ms per color for channel 0
const long ENCODER_REPORT_INTERVAL = 2000; // Report every 2 seconds

// ========== SYSTEM STATE ========== //
enum SystemMode { RUNNING_MAIN_LEDS, RUNNING_CH0_LED };
SystemMode currentMode = RUNNING_MAIN_LEDS;

// ========== LED STATE MACHINES ========== //
enum MainLedState { MAIN_RED, MAIN_GREEN, MAIN_BLUE, MAIN_OFF, MAIN_COMPLETE };
MainLedState mainLedState = MAIN_RED;

enum Ch0LedState { CH0_RED, CH0_GREEN, CH0_BLUE, CH0_OFF, CH0_COMPLETE };
Ch0LedState ch0LedState = CH0_RED;

// ========== ENCODER FUNCTIONS ========== //
void show_encoder_values() {
    Serial.println("\n----- Encoder Report -----");
    for (int i = 0; i &lt; 8; i++) {
        Serial.printf("Encoder CH-%d: %ld\n", i, sensor.getEncoderValue(i));
        Serial.printf("Button CH-%d: %d\n", i, sensor.getButtonStatus(i));
    }
    Serial.printf("Switch: %s\n", sensor.getSwitchStatus() ? "ON" : "OFF");
}

void Zero_All_Encoders() {
    for (int i = 0; i &lt; 8; i++) {
        sensor.resetCounter(i);
    }
    Serial.println("All encoders zeroed!");
}

// ========== SEQUENTIAL LED CONTROL ========== //
void update_leds_sequentially() {
    unsigned long currentMillis = millis();
    
    switch(currentMode) {
        case RUNNING_MAIN_LEDS:
            if (currentMillis - prevLedUpdate &gt;= LED_UPDATE_INTERVAL) {
                prevLedUpdate = currentMillis;
                
                switch(mainLedState) {
                    case MAIN_RED:
                        sensor.setAllLEDColor(0xff0000); // RED
                        mainLedState = MAIN_GREEN;
                        break;
                    case MAIN_GREEN:
                        sensor.setAllLEDColor(0x00ff00); // GREEN
                        mainLedState = MAIN_BLUE;
                        break;
                    case MAIN_BLUE:
                        sensor.setAllLEDColor(0x0000ff); // BLUE
                        mainLedState = MAIN_OFF;
                        break;
                    case MAIN_OFF:
                        sensor.setAllLEDColor(0x000000); // OFF
                        mainLedState = MAIN_COMPLETE;
                        break;
                    case MAIN_COMPLETE:
                        // Main cycle complete, switch to channel 0
                        currentMode = RUNNING_CH0_LED;
                        ch0LedState = CH0_RED; // Reset channel 0 state
                        prevLedUpdate = currentMillis; // Reset timer for channel 0
                        break;
                }
            }
            break;
            
        case RUNNING_CH0_LED:
            if (currentMillis - prevLedUpdate &gt;= CH0_LED_INTERVAL) {
                prevLedUpdate = currentMillis;
                
                switch(ch0LedState) {
                    case CH0_RED:
                        sensor.setLEDColor(0, 0xff0000); // RED
                        ch0LedState = CH0_GREEN;
                        break;
                    case CH0_GREEN:
                        sensor.setLEDColor(0, 0x00ff00); // GREEN
                        ch0LedState = CH0_BLUE;
                        break;
                    case CH0_BLUE:
                        sensor.setLEDColor(0, 0x0000ff); // BLUE
                        ch0LedState = CH0_OFF;
                        break;
                    case CH0_OFF:
                        sensor.setLEDColor(0, 0x000000); // OFF
                        ch0LedState = CH0_COMPLETE;
                        break;
                    case CH0_COMPLETE:
                        // Channel 0 cycle complete, switch back to main LEDs
                        currentMode = RUNNING_MAIN_LEDS;
                        mainLedState = MAIN_RED; // Reset main LED state
                        prevLedUpdate = currentMillis; // Reset timer for main LEDs
                        break;
                }
            }
            break;
    }
}

// ========== SETUP &amp; LOOP ========== //
void setup() {
    Serial.begin(115200);
    sensor.begin(&amp;Wire, ENCODER_ADDR, 21, 22, 100000UL);
    
    while (!Serial); // Wait for serial
    
    Serial.println("System Ready - Send 'enc all set zero' to reset encoders");
    
    // Initialize to first state
    sensor.setAllLEDColor(0xff0000); // Start main LEDs RED
}

void loop() {
    // Handle serial commands
    if (Serial.available() &gt; 0) {
        String input = Serial.readStringUntil('\n');
        input.trim();
        input.toLowerCase();

        if (input == "enc all set zero") {
            Zero_All_Encoders();
        } else {
            Serial.println("Unknown command. Try: 'enc all set zero'");
        }
    }

    // Update LEDs sequentially
    update_leds_sequentially();

    // Periodic encoder reports
    if (millis() - prevEncoderReport &gt;= ENCODER_REPORT_INTERVAL) {
        prevEncoderReport = millis();
        show_encoder_values();
    }
}
</code></pre>
]]></description><link>https://community.m5stack.com/post/28882</link><guid isPermaLink="true">https://community.m5stack.com/post/28882</guid><dc:creator><![CDATA[iainmac]]></dc:creator><pubDate>Mon, 14 Apr 2025 12:27:45 GMT</pubDate></item></channel></rss>