<?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[M5 Unit Scroll Arduino Example]]></title><description><![CDATA[<p dir="auto">Hi All, I can't find an Arduino example about Unit Scroll.. I would like to implement selection and click...<a href="https://github.com/m5stack/M5Unit-Scroll/tree/main/src" target="_blank" rel="noopener noreferrer nofollow ugc">M5Unit-Scroll<br />
</a></p>
<p dir="auto">best regards</p>
]]></description><link>https://community.m5stack.com/topic/7027/m5-unit-scroll-arduino-example</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Apr 2026 19:36:40 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/7027.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 28 Nov 2024 18:17:41 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Thu, 05 Dec 2024 20:53:21 GMT]]></title><description><![CDATA[<p dir="auto">EUREKA!!!!</p>
<p dir="auto">With this setup it works</p>
<pre><code>  Wire.begin(26, 32);  // (sda, sck)
  M5.begin(true, false, true);
  Serial.begin(115200);
</code></pre>
]]></description><link>https://community.m5stack.com/post/27345</link><guid isPermaLink="true">https://community.m5stack.com/post/27345</guid><dc:creator><![CDATA[cepics]]></dc:creator><pubDate>Thu, 05 Dec 2024 20:53:21 GMT</pubDate></item><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Mon, 02 Dec 2024 08:30:44 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/flypeek" aria-label="Profile: flypeek">@<bdi>flypeek</bdi></a> this code, Atom g21 and g25 connected to the scroll grove port and library original pin assigment, works!!!</p>
<pre><code>#include &lt;M5Atom.h&gt;
#include &lt;M5UnitScroll.h&gt;

M5UnitScroll unitScroll;

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

  if (!unitScroll.begin()) {
  // if (!unitScroll.begin(&amp;Wire, 0x40, 26, 32, 400000U)) {
  // if (!unitScroll.begin(&amp;Wire, 0x40, 32, 26, 400000U)) {
    Serial.println("Errore nell'inizializzazione del sensore");
    while (1);  // Ferma il programma in caso di errore
  }

  // LED
  unitScroll.setLEDColor(0x0000FF);
}

void loop() {
  int32_t encoderValue = unitScroll.getEncoderValue();
  Serial.print("Valore encoder: ");
  Serial.println(encoderValue);

  if (unitScroll.getButtonStatus()) {
    Serial.println("Pulsante premuto!");
    unitScroll.setLEDColor(0xFF0000);  // Rosso
    delay(500);
    unitScroll.setLEDColor(0x00FF00);  // Verde
    delay(500);
  }

  delay(100);
}
</code></pre>
<p dir="auto">but I need to connect the unit to the Atom grove port.... some tips??</p>
]]></description><link>https://community.m5stack.com/post/27294</link><guid isPermaLink="true">https://community.m5stack.com/post/27294</guid><dc:creator><![CDATA[cepics]]></dc:creator><pubDate>Mon, 02 Dec 2024 08:30:44 GMT</pubDate></item><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Sun, 01 Dec 2024 12:07:20 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/flypeek" aria-label="Profile: flypeek">@<bdi>flypeek</bdi></a> … means I can’t use atom grove port to connect to scroll unit?!?</p>
]]></description><link>https://community.m5stack.com/post/27271</link><guid isPermaLink="true">https://community.m5stack.com/post/27271</guid><dc:creator><![CDATA[cepics]]></dc:creator><pubDate>Sun, 01 Dec 2024 12:07:20 GMT</pubDate></item><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Sat, 30 Nov 2024 17:49:01 GMT]]></title><description><![CDATA[<p dir="auto">Connect the 4 wires on the back of g21 and g25, and modify the program code pin code<img src="/assets/uploads/files/1732988901378-snap6.jpg" alt="Snap6.jpg" class=" img-fluid img-markdown" /></p>
]]></description><link>https://community.m5stack.com/post/27253</link><guid isPermaLink="true">https://community.m5stack.com/post/27253</guid><dc:creator><![CDATA[flypeek]]></dc:creator><pubDate>Sat, 30 Nov 2024 17:49:01 GMT</pubDate></item><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Sat, 30 Nov 2024 13:15:46 GMT]]></title><description><![CDATA[<p dir="auto">I tried an i2c scanner (not the atom one that doesn't work):</p>
<pre><code>#include &lt;Wire.h&gt;

void setup()
{
  Wire.begin(26, 32);  
  
  Serial.begin(115200);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address &lt; 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address&lt;16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address&lt;16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

</code></pre>
<p dir="auto">and I can see 0x40</p>
<p dir="auto">next I tried to put in two tab the modified library M5UnitScroll.h (for scl end sda atom pin) and M5UnitScroll.cpp..</p>
<p dir="auto">M5UnitScroll.h</p>
<pre><code>/*
 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
 *
 * SPDX-License-Identifier: MIT
 */
#ifndef _M5UNITSCROLL_H_
#define _M5UNITSCROLL_H_

#include "Arduino.h"
#include "Wire.h"
#include "pins_arduino.h"

#define SCROLL_ADDR            0x40
#define ENCODER_REG             0x10
#define BUTTON_REG             0x20
#define RGB_LED_REG            0x30
#define RESET_REG              0x40
#define INC_ENCODER_REG         0x50
#define BOOTLOADER_VERSION_REG 0xFC
#define JUMP_TO_BOOTLOADER_REG 0xFD
#define FIRMWARE_VERSION_REG   0xFE
#define I2C_ADDRESS_REG        0xFF

class M5UnitScroll {
   private:
    uint8_t _addr;
    TwoWire* _wire;
    uint8_t _scl;
    uint8_t _sda;
    uint32_t _speed;
    void writeBytes(uint8_t addr, uint8_t reg, uint8_t* buffer, uint8_t length);
    void readBytes(uint8_t addr, uint8_t reg, uint8_t* buffer, uint8_t length);

   public:
    bool begin(TwoWire* wire = &amp;Wire, uint8_t addr = SCROLL_ADDR, uint8_t sda = 26, uint8_t scl = 32, uint32_t speed = 400000U);
    int32_t getEncoderValue(void);
    int32_t getIncEncoderValue(void);
    bool getButtonStatus(void);
    void setLEDColor(uint32_t color, uint8_t index = 0);
    uint32_t getLEDColor(void);
    void setEncoderValue(int32_t encoder);
    void resetEncoder(void);
    bool getDevStatus(void);
    uint8_t getBootloaderVersion(void);
    uint8_t getFirmwareVersion(void);
    uint8_t setI2CAddress(uint8_t addr);
    uint8_t getI2CAddress(void);
    void jumpBootloader(void);
};

#endif
</code></pre>
<p dir="auto">and M5UnitScroll.cpp</p>
<pre><code>/*
 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
 *
 * SPDX-License-Identifier: MIT
 */
#include "M5UnitScroll.h"

/*! @brief Initialize the Encoder. */
bool M5UnitScroll::begin(TwoWire *wire, uint8_t addr, uint8_t sda, uint8_t scl, uint32_t speed) {
    _wire  = wire;
    _addr  = addr;
    _sda   = sda;
    _scl   = scl;
    _speed = speed;
    _wire-&gt;begin(_sda, _scl);
    _wire-&gt;setClock(_speed);
    delay(10);
    _wire-&gt;beginTransmission(_addr);
    uint8_t error = _wire-&gt;endTransmission();
    if (error == 0) {
        return true;
    } else {
        return false;
    }
}

/*! @brief Write a certain length of data to the specified register address. */
void M5UnitScroll::writeBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, uint8_t length) {
    _wire-&gt;beginTransmission(addr);
    _wire-&gt;write(reg);
    for (int i = 0; i &lt; length; i++) {
        _wire-&gt;write(*(buffer + i));
    }
    _wire-&gt;endTransmission();
}

/*! @brief Read a certain length of data to the specified register address. */
void M5UnitScroll::readBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, uint8_t length) {
    uint8_t index = 0;
    _wire-&gt;beginTransmission(addr);
    _wire-&gt;write(reg);
    _wire-&gt;endTransmission(false);
    _wire-&gt;requestFrom(addr, length);
    for (int i = 0; i &lt; length; i++) {
        buffer[index++] = _wire-&gt;read();
    }
}

/*! @brief Read the encoder value.
    @return The value of the encoder that was read */
int32_t M5UnitScroll::getEncoderValue(void) {
    int32_t value = 0;

    readBytes(_addr, ENCODER_REG, (uint8_t *)&amp;value, 4);
    return value;
}

/*! @brief Read the encoder inc value.
    @return The value of the encoder that was read */
int32_t M5UnitScroll::getIncEncoderValue(void) {
    int32_t value = 0;

    readBytes(_addr, INC_ENCODER_REG, (uint8_t *)&amp;value, 4);
    return value;
}

/*! @brief Get the current status of the rotary encoder button.
    @return true if the button was pressed, otherwise false. */
bool M5UnitScroll::getButtonStatus(void) {
    uint8_t data;
    readBytes(_addr, BUTTON_REG, &amp;data, 1);
    return data == 0x00;
}

/*! @brief Set the color of the LED (HEX). */
void M5UnitScroll::setLEDColor(uint32_t color, uint8_t index) {
    uint8_t data[4];
    data[3] = color &amp; 0xff;
    data[2] = (color &gt;&gt; 8) &amp; 0xff;
    data[1] = (color &gt;&gt; 16) &amp; 0xff;
    data[0] = index;
    writeBytes(_addr, RGB_LED_REG, data, 4);
}

/*! @brief Get the color of the LED (HEX).
    @return The value of the led that was read */
uint32_t M5UnitScroll::getLEDColor(void) {
    uint8_t data[4];
    uint32_t value = 0;

    readBytes(_addr, RGB_LED_REG, data, 4);
    value = (data[3] | (data[2] &lt;&lt; 8) | (data[1] &lt;&lt; 16));
    return value;
}

void M5UnitScroll::setEncoderValue(int32_t encoder) {
    writeBytes(_addr, ENCODER_REG, (uint8_t *)&amp;encoder, 4);
}

void M5UnitScroll::resetEncoder(void) {
    uint8_t data = 1;
    writeBytes(_addr, 0x40, &amp;data, 1);
}

/*! @brief Get the dev status.
    @return 1 if the dev working, otherwise 0.. */
bool M5UnitScroll::getDevStatus(void) {
    _wire-&gt;beginTransmission(_addr);
    if (_wire-&gt;endTransmission() == 0)
        return true;
    else
        return false;
}

uint8_t M5UnitScroll::getBootloaderVersion(void) {
    _wire-&gt;beginTransmission(_addr);
    _wire-&gt;write(BOOTLOADER_VERSION_REG);
    _wire-&gt;endTransmission(false);

    uint8_t RegValue;

    _wire-&gt;requestFrom(_addr, 1);
    RegValue = _wire-&gt;read();
    return RegValue;
}

uint8_t M5UnitScroll::getFirmwareVersion(void) {
    _wire-&gt;beginTransmission(_addr);
    _wire-&gt;write(FIRMWARE_VERSION_REG);
    _wire-&gt;endTransmission(false);

    uint8_t RegValue;

    _wire-&gt;requestFrom(_addr, 1);
    RegValue = _wire-&gt;read();
    return RegValue;
}

uint8_t M5UnitScroll::setI2CAddress(uint8_t addr) {
    uint8_t temp[2] = {0};

    temp[0] = I2C_ADDRESS_REG;

    _wire-&gt;beginTransmission(_addr);
    _wire-&gt;write(temp[0]);
    _wire-&gt;write(addr);
    _wire-&gt;endTransmission();
    _addr = addr;
    return _addr;
}

uint8_t M5UnitScroll::getI2CAddress(void) {
    uint8_t temp[2] = {0};

    temp[0] = I2C_ADDRESS_REG;

    _wire-&gt;beginTransmission(_addr);
    _wire-&gt;write(temp[0]);
    _wire-&gt;endTransmission(false);

    uint8_t RegValue;

    _wire-&gt;requestFrom(_addr, 1);
    RegValue = _wire-&gt;read();
    return RegValue;
}

void M5UnitScroll::jumpBootloader(void) {
    uint8_t value = 1;

    writeBytes(_addr, JUMP_TO_BOOTLOADER_REG, (uint8_t *)&amp;value, 1);
}
</code></pre>
<p dir="auto">but this code outputs  "error"</p>
<pre><code>#include &lt;M5Atom.h&gt;
#include &lt;Wire.h&gt;
#include "M5UnitScroll.h"
// #include &lt;M5UnitScroll.h&gt;

M5UnitScroll unitScroll;

void setup() {
  M5.begin();

  Serial.begin(115200);
  Wire.begin(26, 32);  

  if (!unitScroll.begin()) {
    Serial.println("Error");
    while (1);
  }

  unitScroll.setLEDColor(0x0000FF);
}

void loop() {
  int32_t encoderValue = unitScroll.getEncoderValue();
  Serial.print("Valore encoder: ");
  Serial.println(encoderValue);

  if (unitScroll.getButtonStatus()) {
    Serial.println("Pulsante premuto!");
    unitScroll.setLEDColor(0xFF0000);  // Red
    delay(500);
    unitScroll.setLEDColor(0x00FF00);  // Green
    delay(500);
  }

  delay(100);  
}
</code></pre>
]]></description><link>https://community.m5stack.com/post/27244</link><guid isPermaLink="true">https://community.m5stack.com/post/27244</guid><dc:creator><![CDATA[cepics]]></dc:creator><pubDate>Sat, 30 Nov 2024 13:15:46 GMT</pubDate></item><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Sat, 30 Nov 2024 09:57:42 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/happyuser" aria-label="Profile: HappyUser">@<bdi>HappyUser</bdi></a> I'm not sure how to check  the begin function return value..<br />
I tried:</p>
<pre><code>#include &lt;M5Atom.h&gt;
#include "M5UnitScroll.h"

M5UnitScroll Scroll;

bool scrolla;

void setup() {
  M5.begin();
  Serial.begin(115200);
  Scroll.begin();
}

void loop() {
  scrolla = Scroll.begin();
  Serial.println(scrolla);
  delay(1000);
  scrolla = Scroll.begin(&amp;Wire, SCROLL_ADDR, 32, 26);
  Serial.println(scrolla);
  delay(1000);
  scrolla = Scroll.begin(&amp;Wire, SCROLL_ADDR, 26, 32);
  Serial.println(scrolla);
  delay(1000);
}
</code></pre>
<p dir="auto">and the output in the serial monitor is:</p>
<pre><code>10:56:20.024 -&gt; 0
10:56:21.044 -&gt; 0
10:56:22.062 -&gt; 0
10:56:23.084 -&gt; 0
10:56:24.071 -&gt; 0
10:56:25.092 -&gt; 0
10:56:26.081 -&gt; 0
10:56:27.102 -&gt; 0
10:56:28.129 -&gt; 0
</code></pre>
]]></description><link>https://community.m5stack.com/post/27241</link><guid isPermaLink="true">https://community.m5stack.com/post/27241</guid><dc:creator><![CDATA[cepics]]></dc:creator><pubDate>Sat, 30 Nov 2024 09:57:42 GMT</pubDate></item><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Fri, 29 Nov 2024 07:54:24 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/cepics" aria-label="Profile: cepics">@<bdi>cepics</bdi></a> Have you checked whether M5UnitScroll.begin returns true? Baybe that gives a clue.<br />
Regards</p>
]]></description><link>https://community.m5stack.com/post/27211</link><guid isPermaLink="true">https://community.m5stack.com/post/27211</guid><dc:creator><![CDATA[HappyUser]]></dc:creator><pubDate>Fri, 29 Nov 2024 07:54:24 GMT</pubDate></item><item><title><![CDATA[Reply to M5 Unit Scroll Arduino Example on Thu, 28 Nov 2024 19:20:47 GMT]]></title><description><![CDATA[<p dir="auto">this code doesn't work</p>
<pre><code>
#include &lt;M5Atom.h&gt;
#include &lt;M5UnitScroll.h&gt;

M5UnitScroll Scroll;

int myVariable = 0;
int previousEncoderValue = 0;
bool buttonPressed = false;

void setup() {
  M5.begin();
  Serial.begin(115200);
  Scroll.begin(&amp;Wire, 0x40, 26, 32);
}

void loop() {
  int currentEncoderValue = Scroll.getEncoderValue();
  int difference = currentEncoderValue - previousEncoderValue;
  myVariable += difference;
  previousEncoderValue = currentEncoderValue;

  if (Scroll.getButtonStatus()) {
    if (!buttonPressed) {
      myVariable = 0;
      buttonPressed = true;
    }
  } else {
    buttonPressed = false;
  }
  Serial.print("myVariable ");
  Serial.println(myVariable);
  Serial.print("buttonPressed ");
  Serial.println(buttonPressed);
}
</code></pre>
<p dir="auto">some tips?</p>
]]></description><link>https://community.m5stack.com/post/27203</link><guid isPermaLink="true">https://community.m5stack.com/post/27203</guid><dc:creator><![CDATA[cepics]]></dc:creator><pubDate>Thu, 28 Nov 2024 19:20:47 GMT</pubDate></item></channel></rss>