Hi All, I would like to play with COMX LTE and Core1 to control my stove with SMS..
all the sketches I found use Adafruit_FONA.h, but I don't know which pin I have to assign for RST...
some tips?
best regards
Hi All, I would like to play with COMX LTE and Core1 to control my stove with SMS..
all the sketches I found use Adafruit_FONA.h, but I don't know which pin I have to assign for RST...
some tips?
best regards
Hi all
I would like to play with Unit_Roller and SimpleFOC.h but I don't know how to setup the Motor configuration..
is there an Arduino example for unit_roller using SimpleFOC.h?
I'm using M5Nanoc6 as controller
this code compile but doesn't produce any motor movement.
#include "SimpleFOC.h"
#include "unit_rolleri2c.hpp"
#include <M5Unified.h>
// Create a Unit Roller object
UnitRollerI2C RollerI2C;
// Motor configuration for SimpleFOC
BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11, 8);
void setup() {
M5.begin();
// Initialize the Unit Roller
if (RollerI2C.begin(&Wire, 0x64, 2, 1, 400000)) {
M5.Lcd.println("Roller initialized");
}
// Initialize the SimpleFOC driver
driver.voltage_power_supply = 12;
driver.init();
motor.linkDriver(&driver);
// Motor control mode
motor.controller = MotionControlType::velocity;
// Initialize the motor
motor.init();
motor.initFOC();
}
void loop() {
// Motor control using SimpleFOC
motor.loopFOC();
motor.move(2);
}
any tips
best regards
@kuriko thanks for the reply, as I wrote on post n. 1,
@cepics said in AtomS3R Camera & esp_camera.h example:
I can upload and run the camera.ino
for my project I need to take picture and display it in a web page....
Hi all, I can upload and run the camera.ino Arduino sketch on GitHub setting OPI PSRAM in tools menu in Arduino IDE 2.3.4.
I wolud like now to try this project ESP32-CAM Take Photo and Display in Web Server but without any joy!!
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-cam-take-photo-display-web-server/
IMPORTANT!!!
- Select Board "AI Thinker ESP32-CAM"
- GPIO 0 must be connected to GND to upload a sketch
- After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
*********/
#include "WiFi.h"
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour problems
#include "driver/rtc_io.h"
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <FS.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
boolean takeNewPhoto = false;
// Photo File Name to save in SPIFFS
#define FILE_PHOTO "/photo.jpg"
// OV2640 camera module pins (CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#define SIOD_GPIO_NUM 12
#define SIOC_GPIO_NUM 9
#define Y9_GPIO_NUM 13
#define Y8_GPIO_NUM 11
#define Y7_GPIO_NUM 17
#define Y6_GPIO_NUM 4
#define Y5_GPIO_NUM 48
#define Y4_GPIO_NUM 46
#define Y3_GPIO_NUM 42
#define Y2_GPIO_NUM 3
#define VSYNC_GPIO_NUM 10
#define HREF_GPIO_NUM 14
#define PCLK_GPIO_NUM 40
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { text-align:center; }
.vert { margin-bottom: 10%; }
.hori{ margin-bottom: 0%; }
</style>
</head>
<body>
<div id="container">
<h2>ESP32-CAM Last Photo</h2>
<p>It might take more than 5 seconds to capture a photo.</p>
<p>
<button onclick="rotatePhoto();">ROTATE</button>
<button onclick="capturePhoto()">CAPTURE PHOTO</button>
<button onclick="location.reload();">REFRESH PAGE</button>
</p>
</div>
<div><img src="saved-photo" id="photo" width="70%"></div>
</body>
<script>
var deg = 0;
function capturePhoto() {
var xhr = new XMLHttpRequest();
xhr.open('GET', "/capture", true);
xhr.send();
}
function rotatePhoto() {
var img = document.getElementById("photo");
deg += 90;
if(isOdd(deg/90)){ document.getElementById("container").className = "vert"; }
else{ document.getElementById("container").className = "hori"; }
img.style.transform = "rotate(" + deg + "deg)";
}
function isOdd(n) { return Math.abs(n % 2) == 1; }
</script>
</html>)rawliteral";
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
ESP.restart();
}
else {
delay(500);
Serial.println("SPIFFS mounted successfully");
}
// Print ESP32 Local IP Address
Serial.print("IP Address: http://");
Serial.println(WiFi.localIP());
// Turn-off the 'brownout detector'
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// OV2640 camera module
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if (psramFound()) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
ESP.restart();
}
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(200, "text/html", index_html);
});
server.on("/capture", HTTP_GET, [](AsyncWebServerRequest * request) {
takeNewPhoto = true;
request->send(200, "text/plain", "Taking Photo");
});
server.on("/saved-photo", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, FILE_PHOTO, "image/jpg", false);
});
// Start server
server.begin();
}
void loop() {
if (takeNewPhoto) {
capturePhotoSaveSpiffs();
takeNewPhoto = false;
}
delay(1);
}
// Check if photo capture was successful
bool checkPhoto( fs::FS &fs ) {
File f_pic = fs.open( FILE_PHOTO );
unsigned int pic_sz = f_pic.size();
return ( pic_sz > 100 );
}
// Capture Photo and Save it to SPIFFS
void capturePhotoSaveSpiffs( void ) {
camera_fb_t * fb = NULL; // pointer
bool ok = 0; // Boolean indicating if the picture has been taken correctly
do {
// Take a photo with the camera
Serial.println("Taking a photo...");
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return;
}
// Photo file name
Serial.printf("Picture file name: %s\n", FILE_PHOTO);
File file = SPIFFS.open(FILE_PHOTO, FILE_WRITE);
// Insert the data in the photo file
if (!file) {
Serial.println("Failed to open file in writing mode");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.print("The picture has been saved in ");
Serial.print(FILE_PHOTO);
Serial.print(" - Size: ");
Serial.print(file.size());
Serial.println(" bytes");
}
// Close the file
file.close();
esp_camera_fb_return(fb);
// check if file has been correctly saved in SPIFFS
ok = checkPhoto(SPIFFS);
} while ( !ok );
}
I copied and pasted settings from the camera_pins.h tab but atom cam crash..
load:0x403cb700,len:0x30e4
entry 0x403c88ac
Connecting to WiFi...
SPIFFS mounted successfully
IP Address: http://192.168.1.97ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40376b24
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2820,len:0x1188
load:0x403c8700,len:0x4
load:0x403c8704,len:0xbf0
load:0x403cb700,len:0x30e4
entry 0x403c88ac
Connecting to WiFi...
SPIFFS mounted successfully
IP Address: http://192.168.1.97
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40376b24
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2820,len:0x1188
load:0x403c8700,len:0x4
load:0x403c8704,len:0xbf0
load:0x403cb700,len:0x30e4
entry 0x403c88ac
Connecting to WiFi...
SPIFFS mounted successfully
IP Address: http://192.168.1.97
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40376b24
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2820,len:0x1188
load:0x403c8700,len:0x4
load:0x403c8704,len:0xbf0
load:0x403cb700,len:0x30e4
entry 0x403c88ac
I know this example is made for AI Thinker ESP32-CAM but changing camera_pins is not enough...
some tips?
best regards
@wschnell Hi, sorry for the late response...;-)
I'm trying your code but Arduino doesn't compile with this error:
Compilation error: 's' was not declared in this scope
about this line:
Serial2.printf("AT+CSTT="%s","%s","%s"\r\n", apn, user, pass);
no way to work with SIM800L MODULE!!
tips??
@felmue You are right!!!
I thought that calling M5.begin() without any parameters would set all parameters to true..
thanks a lot
Hi All,
I'm working on a espnow communication between two M5Atom
the communication works well but when I try to use the built in led, the tx atom crash...
this is the working sender sketch (without led):
#include "M5Atom.h"
#include <Preferences.h>
Preferences preferences;
#include "Leddar.h"
#include <Arduino.h>
#include <esp_now.h>
#include <esp_wifi.h>
byte FilmPlate = 20;
short ToRs232;
short cm1;
short cm2;
short cm3;
short cm4;
short cm5;
short cm6;
short cm7;
short cm8;
float Amp1;
float Amp2;
float Amp3;
float Amp4;
float Amp5;
float Amp6;
float Amp7;
float Amp8;
///////////////// OTA /////////////////////
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
const char *host = "xx";
const char *ssid = "xxx";
const char *password = "xxxxx";
WebServer server(80);
///////////////// fine OTA /////////////////////
bool StatoRX;
bool StatoPAIR = 0;
// //////////////////// ESPNOW /////////////////////////
// Set your Board and Server ID
#define BOARD_ID 1
#define MAX_CHANNEL 13 // for North America // 13 in Europe
uint8_t serverAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
typedef struct struct_message2 {
uint8_t msgType;
uint8_t id;
uint8_t macAddr[6];
short ToRs232;
bool unit;
} struct_message2;
typedef struct struct_message {
uint8_t msgType;
uint8_t id;
// uint8_t macAddr[6];
byte FilmPlate;
short ToRs232;
short cm1;
short cm2;
short cm3;
short cm4;
short cm5;
short cm6;
short cm7;
short cm8;
float Amp1;
float Amp2;
float Amp3;
float Amp4;
float Amp5;
float Amp6;
float Amp7;
float Amp8;
} struct_message;
typedef struct struct_pairing { // new structure for pairing
uint8_t msgType;
uint8_t id;
uint8_t macAddr[6];
uint8_t channel;
} struct_pairing;
//Create 2 struct_message
struct_message myData; // data to send
struct_message2 inData; // data received
struct_pairing pairingData;
enum PairingStatus { NOT_PAIRED,
PAIR_REQUEST,
PAIR_REQUESTED,
PAIR_PAIRED,
};
PairingStatus pairingStatus = NOT_PAIRED;
enum MessageType { PAIRING,
DATA,
};
MessageType messageType;
#ifdef SAVE_CHANNEL
int lastChannel;
#endif
int channel = 1;
unsigned long currentMillis = millis();
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
unsigned long start; // used to measure Pairing time
unsigned int readingId = 0;
void addPeer(const uint8_t *mac_addr, uint8_t chan) {
esp_now_peer_info_t peer;
ESP_ERROR_CHECK(esp_wifi_set_channel(chan, WIFI_SECOND_CHAN_NONE));
esp_now_del_peer(mac_addr);
memset(&peer, 0, sizeof(esp_now_peer_info_t));
peer.channel = chan;
peer.encrypt = false;
memcpy(peer.peer_addr, mac_addr, sizeof(uint8_t[6]));
if (esp_now_add_peer(&peer) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
memcpy(serverAddress, mac_addr, sizeof(uint8_t[6]));
}
void printMAC(const uint8_t *mac_addr) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.print(macStr);
}
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
// Serial.print("\r\nLast Packet Send Status:\t");
// Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status == ESP_NOW_SEND_SUCCESS) {
// M5.dis.drawpix(0, 0x00ff00); // GREEN 绿色
StatoRX = 1;
} else {
// M5.dis.drawpix(0, 0xff0000); // RED 红色
StatoRX = 0;
}
}
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *incomingData, int len) {
// Serial.print("Packet received from: ");
// printMAC(mac_addr);
// Serial.println();
// Serial.print("data size = ");
// Serial.println(sizeof(incomingData));
uint8_t type = incomingData[0];
switch (type) {
case DATA: // we received data from server
memcpy(&inData, incomingData, sizeof(inData));
ToRs232 = inData.ToRs232;
break;
case PAIRING: // we received pairing data from server
memcpy(&pairingData, incomingData, sizeof(pairingData));
if (pairingData.id == 0) { // the message comes from server
printMAC(mac_addr);
Serial.print("Pairing done for ");
printMAC(pairingData.macAddr);
Serial.print(" on channel ");
Serial.print(pairingData.channel); // channel used by the server
Serial.print(" in ");
Serial.print(millis() - start);
Serial.println("ms");
addPeer(pairingData.macAddr, pairingData.channel); // add the server to the peer list
#ifdef SAVE_CHANNEL
preferences.begin("C-Wheels", false);
preferences.putUInt("lastChannel", lastChannel); // Store to the Preferences
preferences.end(); // Close the Preferences
#endif
pairingStatus = PAIR_PAIRED; // set the pairing status
}
break;
}
}
PairingStatus autoPairing() {
switch (pairingStatus) {
case PAIR_REQUEST:
Serial.print("Pairing request on channel ");
Serial.println(channel);
StatoPAIR = 1; // probabilmente si puo togliere
// set WiFi channel
ESP_ERROR_CHECK(esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE));
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
}
// set callback routines
esp_now_register_send_cb(OnDataSent);
esp_now_register_recv_cb(OnDataRecv);
// set pairing data to send to the server
pairingData.msgType = PAIRING;
pairingData.id = BOARD_ID;
pairingData.channel = channel;
// add peer and send request
addPeer(serverAddress, channel);
esp_now_send(serverAddress, (uint8_t *)&pairingData, sizeof(pairingData));
previousMillis = millis();
pairingStatus = PAIR_REQUESTED;
break;
case PAIR_REQUESTED:
// time out to allow receiving response from server
currentMillis = millis();
if (currentMillis - previousMillis > 250) {
previousMillis = currentMillis;
// time out expired, try next channel
channel++;
if (channel > MAX_CHANNEL) {
channel = 1;
}
pairingStatus = PAIR_REQUEST;
}
break;
case PAIR_PAIRED:
StatoPAIR = 0;
// nothing to do here
break;
}
return pairingStatus;
}
///////////////////////////FINE ESPNOW///////////////
byte CH;
byte CHold;
bool aggiornaCH;
LeddarVu8 Leddar(115200, 1); //Baudrate = 115200 Modbus slave ID = 01
void setup() {
M5.begin();
// M5.begin(false, false, true);
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, 22, 19); // atom RS232 MOD
delay(1000);
M5.update();
Serial.println();
Serial.print("Client Board MAC Address: ");
Serial.println(WiFi.macAddress());
WiFi.mode(WIFI_STA);
WiFi.disconnect();
start = millis();
#ifdef SAVE_CHANNEL
preferences.begin("xxxx", false);
lastChannel = preferences.getUInt("lastChannel", 0);
preferences.end();
Serial.println(lastChannel);
if (lastChannel >= 1 && lastChannel <= MAX_CHANNEL) {
channel = lastChannel;
}
Serial.println(channel);
#endif
pairingStatus = PAIR_REQUEST;
Serial1.begin(9600, SERIAL_8N1, 23, 19); //ATOM_RS232
Leddar.init();
// M5.dis.drawpix(0, 0xfff000); // YELLOW 黄色
M5.update();
}
void loop() {
char result = Leddar.getDetections();
if (result >= 0) {
for (int i = 0; i < Leddar.NbDet; i++) {
if (Leddar.Detections[i].Segment + 1 == 1) {
myData.cm1 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp1 = Leddar.Detections[i].Amplitude;
}
if (Leddar.Detections[i].Segment + 1 == 2) {
myData.cm2 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp2 = Leddar.Detections[i].Amplitude;
}
if (Leddar.Detections[i].Segment + 1 == 3) {
myData.cm3 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp3 = Leddar.Detections[i].Amplitude;
}
if (Leddar.Detections[i].Segment + 1 == 4) {
myData.cm4 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp4 = Leddar.Detections[i].Amplitude;
if (M5.Btn.isPressed()) { //ATOM
FilmPlate = 100 - Leddar.Detections[i].Distance;
}
}
if (Leddar.Detections[i].Segment + 1 == 5) {
myData.cm5 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp5 = Leddar.Detections[i].Amplitude;
}
if (Leddar.Detections[i].Segment + 1 == 6) {
myData.cm6 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp6 = Leddar.Detections[i].Amplitude;
}
if (Leddar.Detections[i].Segment + 1 == 7) {
myData.cm7 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp7 = Leddar.Detections[i].Amplitude;
}
if (Leddar.Detections[i].Segment + 1 == 8) {
myData.cm8 = Leddar.Detections[i].Distance + FilmPlate;
myData.Amp8 = Leddar.Detections[i].Amplitude;
}
myData.FilmPlate = FilmPlate;
}
} else {
Serial.print("Vu8 Error: ");
Serial.print((int)result);
Serial.print("\n");
}
sendData();
// if (pairingStatus == PAIR_PAIRED) {
// M5.dis.drawpix(0, 0x00ff00);
// }
// M5.dis.drawpix(0, 0x00ff00);
M5.update();
delay(20); //crasha se la tolgo
}
void sendData() {
if (autoPairing() == PAIR_PAIRED) {
myData.msgType = DATA;
myData.id = BOARD_ID;
esp_err_t result = esp_now_send(serverAddress, (uint8_t *)&myData, sizeof(myData));
}
}
when I add M5.dis.drawpix(0, 0x00ff00);
the Atom crash..
this is the serial monitor output:
M5At
Client Board MAC Address: D8:A0:1D:5C:95:0C
Pairing request on channel 1
assert failed: xQueueSemaphoreTake queue.c:1545 (( pxQueue ))
Backtrace: 0x400843b1:0x3ffb2060 0x4008cb85:0x3ffb2080 0x400921c5:0x3ffb20a0 0x4008db95:0x3ffb21d0 0x400d4430:0x3ffb2210 0x400d311f:0x3ffb2240 0x400d3459:0x3ffb2270 0x400dc9ed:0x3ffb2290
ELF file SHA256: 75047b7540bb511b
Rebooting...
any idea??
Hi All,
I would like to "talk" to a pellet stove through its TTL serial port.. among the various M5 accessories in my drawer, I have THE COMMU module and I was wondering if it was possible to connect a TTL 5v to it...
best regards
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