EUREKA!!!!
With this setup it works
Wire.begin(26, 32); // (sda, sck)
M5.begin(true, false, true);
Serial.begin(115200);
EUREKA!!!!
With this setup it works
Wire.begin(26, 32); // (sda, sck)
M5.begin(true, false, true);
Serial.begin(115200);
@flypeek this code, Atom g21 and g25 connected to the scroll grove port and library original pin assigment, works!!!
#include <M5Atom.h>
#include <M5UnitScroll.h>
M5UnitScroll unitScroll;
void setup() {
M5.begin();
Serial.begin(115200);
if (!unitScroll.begin()) {
// if (!unitScroll.begin(&Wire, 0x40, 26, 32, 400000U)) {
// if (!unitScroll.begin(&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);
}
but I need to connect the unit to the Atom grove port.... some tips??
@flypeek … means I can’t use atom grove port to connect to scroll unit?!?
I tried an i2c scanner (not the atom one that doesn't work):
#include <Wire.h>
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 < 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<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<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
}
and I can see 0x40
next I tried to put in two tab the modified library M5UnitScroll.h (for scl end sda atom pin) and M5UnitScroll.cpp..
M5UnitScroll.h
/*
* 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 = &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
and M5UnitScroll.cpp
/*
* 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->begin(_sda, _scl);
_wire->setClock(_speed);
delay(10);
_wire->beginTransmission(_addr);
uint8_t error = _wire->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->beginTransmission(addr);
_wire->write(reg);
for (int i = 0; i < length; i++) {
_wire->write(*(buffer + i));
}
_wire->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->beginTransmission(addr);
_wire->write(reg);
_wire->endTransmission(false);
_wire->requestFrom(addr, length);
for (int i = 0; i < length; i++) {
buffer[index++] = _wire->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 *)&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 *)&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, &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 & 0xff;
data[2] = (color >> 8) & 0xff;
data[1] = (color >> 16) & 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] << 8) | (data[1] << 16));
return value;
}
void M5UnitScroll::setEncoderValue(int32_t encoder) {
writeBytes(_addr, ENCODER_REG, (uint8_t *)&encoder, 4);
}
void M5UnitScroll::resetEncoder(void) {
uint8_t data = 1;
writeBytes(_addr, 0x40, &data, 1);
}
/*! @brief Get the dev status.
@return 1 if the dev working, otherwise 0.. */
bool M5UnitScroll::getDevStatus(void) {
_wire->beginTransmission(_addr);
if (_wire->endTransmission() == 0)
return true;
else
return false;
}
uint8_t M5UnitScroll::getBootloaderVersion(void) {
_wire->beginTransmission(_addr);
_wire->write(BOOTLOADER_VERSION_REG);
_wire->endTransmission(false);
uint8_t RegValue;
_wire->requestFrom(_addr, 1);
RegValue = _wire->read();
return RegValue;
}
uint8_t M5UnitScroll::getFirmwareVersion(void) {
_wire->beginTransmission(_addr);
_wire->write(FIRMWARE_VERSION_REG);
_wire->endTransmission(false);
uint8_t RegValue;
_wire->requestFrom(_addr, 1);
RegValue = _wire->read();
return RegValue;
}
uint8_t M5UnitScroll::setI2CAddress(uint8_t addr) {
uint8_t temp[2] = {0};
temp[0] = I2C_ADDRESS_REG;
_wire->beginTransmission(_addr);
_wire->write(temp[0]);
_wire->write(addr);
_wire->endTransmission();
_addr = addr;
return _addr;
}
uint8_t M5UnitScroll::getI2CAddress(void) {
uint8_t temp[2] = {0};
temp[0] = I2C_ADDRESS_REG;
_wire->beginTransmission(_addr);
_wire->write(temp[0]);
_wire->endTransmission(false);
uint8_t RegValue;
_wire->requestFrom(_addr, 1);
RegValue = _wire->read();
return RegValue;
}
void M5UnitScroll::jumpBootloader(void) {
uint8_t value = 1;
writeBytes(_addr, JUMP_TO_BOOTLOADER_REG, (uint8_t *)&value, 1);
}
but this code outputs "error"
#include <M5Atom.h>
#include <Wire.h>
#include "M5UnitScroll.h"
// #include <M5UnitScroll.h>
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);
}
@HappyUser I'm not sure how to check the begin function return value..
I tried:
#include <M5Atom.h>
#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(&Wire, SCROLL_ADDR, 32, 26);
Serial.println(scrolla);
delay(1000);
scrolla = Scroll.begin(&Wire, SCROLL_ADDR, 26, 32);
Serial.println(scrolla);
delay(1000);
}
and the output in the serial monitor is:
10:56:20.024 -> 0
10:56:21.044 -> 0
10:56:22.062 -> 0
10:56:23.084 -> 0
10:56:24.071 -> 0
10:56:25.092 -> 0
10:56:26.081 -> 0
10:56:27.102 -> 0
10:56:28.129 -> 0
this code doesn't work
#include <M5Atom.h>
#include <M5UnitScroll.h>
M5UnitScroll Scroll;
int myVariable = 0;
int previousEncoderValue = 0;
bool buttonPressed = false;
void setup() {
M5.begin();
Serial.begin(115200);
Scroll.begin(&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);
}
some tips?
Hi All, I can't find an Arduino example about Unit Scroll.. I would like to implement selection and click...M5Unit-Scroll
best regards
@AreaKode on GitHub I found only the .bin file....
is there an Arduino version of the code? I would like to add some functions..
@AreaKode .... also putting a small peace of paper in between joy and atom works to me!! maybe a more portable solution!!
@AreaKode While I'm waiting for new batteries and a battery charger, I'm charging the batteries by inserting them into the two slots of the joypad and connecting the joypad's USB-C port to a USB charger. When the two LEDs are green, I've noticed that as soon as I install the charged batteries, I get readings of over 65V on the joypad... after a few takeoff attempts, the value drops to around 4V and the system starts working as it should
I'm having several issues with my M5 Atom Fly and Joy.
Specifically, I'm having trouble selecting flight modes (Sport, Stable) and altitude (Auto, Manual) using the R and L buttons. These controls are very unreliable, and I can't figure out why they sometimes work and other times don't.
Furthermore, as soon as I turn on the drone and controller, and try to take off in Stable/Auto mode, the drone rises very little off the ground and starts moving backwards, ignoring my commands. It continues to fly backwards until it hits something and stops. After several attempts, sometimes the drone finally starts responding to commands, but by then the battery is almost empty and I have to stop flying.
Has anyone ever had similar problems? What could be causing this abnormal behavior? Thanks in advance for any suggestions.
I've tried updating the firmware on both the joy and fly using m5 burner, but it hasn't fixed the problems
best regards
Unfortunately, even with new cables, the problem persists ..
I tested my SmallHD 503U monitor with a RPI3 and it works
@macsbug what do you think?
best regards
Hi all,
two days ago, I wanted to try the Atom lite display and smallhd 503U again and, after loading the test sketch (https://docs.m5stack.com/en/atom/atom_display),
#include <Arduino.h>
#include <vector>
#include <M5AtomDisplay.h>
M5AtomDisplay display;
void setup(void)
{
display.begin();
}
void loop(void)
{
display.fillScreen(RED);
delay(1000);
display.fillScreen(GREEN);
delay(1000);
display.fillScreen(BLUE);
delay(1000);
}
the SmallHD 503U monitor began to color.
I then created my code and worked on it for two days, visualizing the data coming from another atom through the ESPNOW protocol without problems..
while I was working on the TX code (ATOM LITE), suddenly the smallhd 503U stopped displaying the HDMI output of the ATOM lite Display RX
then the ritual tests began:
atom and cables, on a TV, work perfectly
503U and cables connected to the PC work perfectly
I switched from battery to an AC adapter for the monitor (20v 11,5 A)
I updated the 503U firmware to the latest available, 5.5.6. ( was 4.7.2 than 4.8.7)
I tried all 5 cables present at home and they all work between AtomDisplay and TV and between PC and 503U and they don't work between AtomDisplay and 503U
I tried various settings of M5AtomDisplay display() and display.setColorDepth()
M5AtomDisplay display(1920,1080,24);
M5AtomDisplay display(1080,720,24);
M5AtomDisplay display(1080,720,50);
M5AtomDisplay display(1080,720,60);
M5AtomDisplay display ( 640, 360, 60, 1980, 1080, 2, 2, 74250000 );
display.setColorDepth(8);
display.setColorDepth(24);
display.setColorDepth(10);
I couldn't figure out if the 503U is capable of"adaptive resolution scaling" and the green led on the monitor for input sensing it went back off like at the beginning of this long story
I can't figure out what's happening and I ordered some new hdmi cables..
ideas?
best regards
Mauro
I've bought the PICO DIY Kit, that contained the ESP32 Downloader. I'm securely connected the 5 pins of the Downloader to the appropriate pins on the Stamp Pico. Then I connect the USB-C cable (sync+charge) to the Thunderbolt 3 computer port. All drivers are installed. Also, no LED is lighting up on the Downloader.
osx version 14.3.1
some tips?
best regards
Hi all,
I don't know how to use Arduino serial monitor, for debugging purpose , with M5Dial ...
some tips?
no, still don't work!!
yes 5 inches.......
in SD.h I changed:
bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=4000000, const char * mountpoint="/sd", uint8_t max_files=5, bool format_if_empty=false);
to
bool begin(uint8_t ssPin=SS, SPIClass &spi=SPI, uint32_t frequency=1000000, const char * mountpoint="/sd", uint8_t max_files=5, bool format_if_empty=false);
and in sd_diskio.cpp:
if (card->frequency > 25000000) {
card->frequency = 25000000;
}
to
if (card->frequency > 10000000) {
card->frequency = 10000000;
}
.... and now seems to work!!