-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Open
Labels
Description
Hi, I am using an ESP32S3 N16R8 module, and the display is ST7789, I am finding it difficult to print the angle values obtained from the encoder, which uses SPI communication to the display. I am using Arduino IDE by the way, both the display and encoder use the same MOSI and SCK I tried defining different modes for the encoder. What i feel is that the display seems to hold the SPI communication all the time, (my display does not have a CS pin).
These were my pin configurations
// For ESP32 Dev board (only tested with ILI9341 display)
// The hardware SPI can be mapped to any pins
#define TFT_MISO 13
#define TFT_MOSI 11
#define TFT_SCLK 12
#define TFT_CS 9 // Chip select control pin
#define TFT_DC 16 // Data Command control pin
#define TFT_RST 17 // Reset pin (could connect to RST pin)
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
This was the code i used to display angle on to the display
#include <SPI.h>
#include <TFT_eSPI.h>
/* ---------------- TFT Setup ---------------- */
TFT_eSPI tft = TFT_eSPI();
#define SCREEN_W 240
#define SCREEN_H 240
/* ---------------- AS5048A Encoder Setup ---------------- */
#define PIN_CS 10
#define PIN_SCK 12
#define PIN_MOSI 11
#define PIN_MISO 13
#define AS5048_ANGLE_REG 0x3FFF
SPISettings as5048SPI(1000000, MSBFIRST, SPI_MODE1);
/* ---------------- Filter Parameters ---------------- */
const float ALPHA = 0.10;
const float DEAD_BAND = 0.05;
float filteredAngle = 0.0;
float stableAngle = 0.0;
bool firstSample = true;
/* ---------------- Utility: Even Parity ---------------- */
uint16_t addEvenParity(uint16_t v) {
uint8_t ones = 0;
for (int i = 0; i < 15; i++) {
if (v & (1 << i)) ones++;
}
if (ones % 2) v |= 0x8000;
return v;
}
/* ---------------- Read Raw Angle ---------------- */
uint16_t readRawAngle() {
uint16_t cmd = addEvenParity(0x4000 | AS5048_ANGLE_REG);
uint16_t resp;
SPI.beginTransaction(as5048SPI);
digitalWrite(PIN_CS, LOW);
SPI.transfer16(cmd);
digitalWrite(PIN_CS, HIGH);
delayMicroseconds(2);
digitalWrite(PIN_CS, LOW);
resp = SPI.transfer16(0x0000);
digitalWrite(PIN_CS, HIGH);
SPI.endTransaction();
return resp & 0x3FFF; // 14-bit angle
}
/* ---------------- Convert to Degrees ---------------- */
float readAngleDegrees() {
return (readRawAngle() * 360.0f) / 16384.0f;
}
/* ---------------- Filters ---------------- */
float lowPassFilter(float angle) {
if (firstSample) {
filteredAngle = angle;
firstSample = false;
} else {
filteredAngle = ALPHA * angle + (1.0f - ALPHA) * filteredAngle;
}
return filteredAngle;
}
float deadbandFilter(float angle) {
if (fabs(angle - stableAngle) < DEAD_BAND) return stableAngle;
stableAngle = angle;
return angle;
}
/* ---------------- Setup ---------------- */
void setup() {
Serial.begin(115200);
pinMode(PIN_CS, OUTPUT);
digitalWrite(PIN_CS, HIGH);
SPI.begin(PIN_SCK, PIN_MISO, PIN_MOSI, PIN_CS);
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
// Display logo/brand first
const char* brand = "LUSTREJ";
const char* tagline = "where craft meets precision";
int brandFont = 4;
int taglineFont = 2;
int brandWidth = tft.textWidth(brand, brandFont);
int taglineWidth = tft.textWidth(tagline, taglineFont);
int brandX = (tft.width() - brandWidth) / 2;
int brandY = (tft.height() / 2) - 18;
int taglineX = (tft.width() - taglineWidth) / 2;
int taglineY = brandY + 32;
tft.setCursor(brandX, brandY, brandFont);
tft.println(brand);
delay(200);
tft.setCursor(taglineX, taglineY, taglineFont);
tft.println(tagline);
delay(1500);
tft.fillScreen(TFT_BLACK); // Clear screen for angle display
tft.setTextSize(3);
tft.setCursor(20, SCREEN_H / 2 - 10);
tft.println("Angle:");
}
/* ---------------- Main Loop ---------------- */
void loop() {
float angle = readAngleDegrees();
// Wrap angle to 0-360
if (angle < 0.0f) angle += 360.0f;
if (angle >= 360.0f) angle -= 360.0f;
angle = lowPassFilter(angle);
angle = deadbandFilter(angle);
// Print to Serial
Serial.print("Angle: ");
Serial.println(angle, 2);
// Display on TFT
tft.fillRect(20, SCREEN_H / 2 + 20, 200, 40, TFT_BLACK); // Clear previous value
tft.setCursor(20, SCREEN_H / 2 + 20);
tft.printf("%.2f°", angle);
delay(50); // 20 Hz update rate
}
Can you please help me find out what went wrong
Reactions are currently unavailable