помогите с TFT дисплеем RA8875
- Войдите на сайт для отправки комментариев
пытаюсь сделать беспроводной MIDI-контроллер на ESP32-minikit и китайском дисплее RA8875 4.3"
тач стандартный из библиотеки Adafruit_RA8875.h, резистивный
Удалось подключить дисплей запустить и запустить его, нарисовал прямоугольники в виде пианино, создал сервисы и характеристики BLE midi, запускается, компьютер видит, подключается, и работает, но при нажатии на клавиши на моем контроллере, воспроизводится нота с постоянными прерываниями, то есть вибрирует, не звучит ровно, как будто я очень быстро нажимаю ее и отпускаю, хотя я не отпускаю клавишу. может кто знает как исправить? я так понимаю что tft.touchRead(&tx, &ty); постоянно опрашивает тач модуль на нажатия, и данные идут постоянно, а мне полагаю нужно после нажатия получить координаты касания только один раз.
код
#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_RA8875.h"
#include <MIDI.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
#define SERVICE_UUID "03b80e5a-ede8-4b33-a751-6ce34ec4c700"
#define CHARACTERISTIC_UUID "7772e5db-3868-4112-a1a9-f2669d106bf3"
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
int CurrentNote = 0;
int PreviousNote = 0;
uint8_t midiPacket[] = {
0x80, // header
0x80, // timestamp, not implemented
0x00, // status
0x3c, // 0x3c == 60 == middle c
0x00 // velocity
};
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
MIDI_CREATE_DEFAULT_INSTANCE();
//MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI);
#define RA8875_INT 26
#define RA8875_CS 5 //SPI CS GPIO5
#define RA8875_RESET 25
Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET);
uint16_t tx, ty;
void setup()
{
Serial.begin(115200);
Serial.println("RA8875 start");
MIDI.begin(1);//MIDI.begin(channel); need software serial port on GPIO 17 and on slave gpio10!!!!!!
Serial.println(F("looping"));
if (!tft.begin(RA8875_480x272)) {
Serial.println("RA8875 Not Found!");
while (1);
}
Serial.println("Found RA8875");
delay(100);
tft.displayOn(true);
tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX
tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
tft.PWM1out(255);
pinMode(RA8875_INT, INPUT);
digitalWrite(RA8875_INT, HIGH);
tft.touchEnable(true);
Serial.print("Status: "); Serial.println(tft.readStatus(), HEX);
Serial.println("Waiting for touch events ...");
BLEDevice::init("Blecoder");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID));
pCharacteristic = pService->createCharacteristic(
BLEUUID(CHARACTERISTIC_UUID),
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_WRITE_NR
);
pCharacteristic->addDescriptor(new BLE2902());
pService->start();
pServer->getAdvertising()->addServiceUUID(SERVICE_UUID);
pServer->getAdvertising()->start();
}
void loop()
{
float xScale = 1024.0F/tft.width();
float yScale = 1024.0F/tft.height();
/* Wait around for touch events */
if (! digitalRead(RA8875_INT))
{
if (tft.touched())
{
Serial.print("Touch: ");
tft.touchRead(&tx, &ty);
Serial.print(tx); Serial.print(", "); Serial.println(ty);
}
}
PianoListener();
Piano();
//MIDI.read();
//MIDI.sendNoteOn(52 , 127, 1);
}
void Piano(){
tft.fillRect(0, 150, 50, 270, RA8875_WHITE);
tft.fillRect(55, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(110, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(165, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(220, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(275, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(330, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(385, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(440, 150 , 50 , 270, RA8875_WHITE);
tft.fillRect(0, 0, 30, 150, RA8875_WHITE);
tft.fillRect(75, 0, 10, 150, RA8875_WHITE);
tft.fillRect(130, 0, 30, 150, RA8875_WHITE);
tft.fillRect(165, 0, 30, 150, RA8875_WHITE);
tft.fillRect(240, 0, 10, 150, RA8875_WHITE);
tft.fillRect(295, 0, 10, 150, RA8875_WHITE);
tft.fillRect(350, 0, 30, 150, RA8875_WHITE);
tft.fillRect(385, 0, 30, 150, RA8875_WHITE);
tft.fillRect(465, 0, 15, 150, RA8875_WHITE);
}
void PianoListener(){
//key1
if ( tft.touched()) { //if the touch screen was touched this loop
tft.touchRead(&tx, &ty); //get the point of the touch
if ((tx>=50) && (tx<=150) && (ty>=120) && (ty<=450)) {
tft.fillRect(0, 150, 50, 270, RA8875_RED);
MIDI.sendNoteOn(48 , 127, 1);
midiPacket[2] = 0x90; // note down, channel 0
midiPacket[3] = 48;
midiPacket[4] = 127; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes
pCharacteristic->notify();
Serial.println("note1");
}
else{
MIDI.sendNoteOff(48 , 127, 1);
//MIDI.sendNoteOff(50 , 127, 1);
midiPacket[2] = 0x80; // note up, channel 0
midiPacket[4] = 0; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes)
pCharacteristic->notify();
//tft.fillRect(0, 150, 50, 270, RA8875_WHITE);
}
}
else{
MIDI.sendNoteOff(48 , 127, 1);
//MIDI.sendNoteOff(50 , 127, 1);
midiPacket[2] = 0x80; // note up, channel 0
midiPacket[4] = 0; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes)
pCharacteristic->notify();
//tft.fillRect(0, 150, 50, 270, RA8875_WHITE);
}
//key2
if ( tft.touched()) { //if the touch screen was touched this loop
tft.touchRead(&tx, &ty); //get the point of the touch
if ((tx>=160) && (tx<=250) && (ty>=120) && (ty<=450)) {
tft.fillRect(55, 150, 50, 270, RA8875_RED);
MIDI.sendNoteOn(50 , 127, 1);
midiPacket[2] = 0x90; // note down, channel 0
midiPacket[3] = 50;
midiPacket[4] = 127; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes
pCharacteristic->notify();
Serial.println("note2");
}
}
else{
//MIDI.sendNoteOff(50 , 127, 1);
midiPacket[2] = 0x80; // note up, channel 0
midiPacket[4] = 0; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes)
pCharacteristic->notify();
tft.fillRect(55, 150, 50, 270, RA8875_WHITE);
}
//key3
//if the touch screen was touched this loop
if ( tft.touched()) { //if the touch screen was touched this loop
tft.touchRead(&tx, &ty); //get the point of the touch
if ((tx>=260) && (tx<=350) && (ty>=120) && (ty<=450)) {
tft.fillRect(110, 150, 50, 270, RA8875_RED);
MIDI.sendNoteOn(52 , 127, 1);
midiPacket[2] = 0x90; // note down, channel 0
midiPacket[3] = 52;
midiPacket[4] = 127; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes
pCharacteristic->notify();
Serial.println("note3");
}
}
else{
//MIDI.sendNoteOff(52 , 127, 1);
midiPacket[2] = 0x80; // note up, channel 0
midiPacket[4] = 0; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes)
pCharacteristic->notify();
tft.fillRect(110, 150, 50, 270, RA8875_WHITE);
}
}
можно посоветовать запоминать, какая именно тач-"клавиша" нажата (причем не координаты. а именно какая клавиша) - и если при следующем опросе тача опять будет нажата та же клавиша - игнорировать ее
я пробовал что то подобное из примеров, но результат такой же. как я понял tft.touched() постоянно обновляется, не передает какое то значение один раз и при его изменении другое. нажал на экран и в терминале сыпется куча строк о том что я нажимаю на экран , хотя может оно так и должно и я смотрю совсем в другую сторону
tft.touched() постоянно обновляется, не передает какое то значение один раз и при его изменении другое. нажал на экран и в терминале сыпется куча строк о том что я нажимаю на экран , хотя может оно так и должно
да, тач именно так и работает - и это нормально.
Попробуйте вдуматься в мой совет выше, и вы поймете, что подобное поведение тача - не помеха.
Вам будет нужна еще одна переменная (например логическая) на каждую клавишу. И нота включается или выключается при ИЗМЕНЕНИИ этой переменной. Соответственно, возникает еще одна переменная - предыдущее состояние клавиши.
попробовал изменить, добавил состояния, теперь обратный эффект, при нажатии на первую клавишу - нота включается и не откючается, при повторном нажатии на эту же клавишу ничего не происходит, при нажатии на другую клавишу включается другая нота
#include <SPI.h> #include "Adafruit_GFX.h" #include "Adafruit_RA8875.h" #include <MIDI.h> #include <BLEDevice.h> #include <BLEUtils.h> #include <BLEServer.h> #include <BLE2902.h> #define SERVICE_UUID "03b80e5a-ede8-4b33-a751-6ce34ec4c700" #define CHARACTERISTIC_UUID "7772e5db-3868-4112-a1a9-f2669d106bf3" BLECharacteristic *pCharacteristic; bool deviceConnected = false; int CurrentNote = 0; int PreviousNote = 0; uint8_t midiPacket[] = { 0x80, // header 0x80, // timestamp, not implemented 0x00, // status 0x3c, // 0x3c == 60 == middle c 0x00 // velocity }; class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } }; MIDI_CREATE_DEFAULT_INSTANCE(); //MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI); #define RA8875_INT 26 #define RA8875_CS 5 //SPI CS GPIO5 #define RA8875_RESET 25 Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET); uint16_t tx, ty; void setup() { Serial.begin(115200); Serial.println("RA8875 start"); //MIDI.begin(); Serial.println(F("looping")); if (!tft.begin(RA8875_480x272)) { Serial.println("RA8875 Not Found!"); while (1); } Serial.println("Found RA8875"); delay(100); tft.displayOn(true); tft.GPIOX(true); // Enable TFT - display enable tied to GPIOX tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight tft.PWM1out(255); pinMode(RA8875_INT, INPUT); digitalWrite(RA8875_INT, HIGH); tft.touchEnable(true); Serial.print("Status: "); Serial.println(tft.readStatus(), HEX); Serial.println("Waiting for touch events ..."); BLEDevice::init("Blecoder"); BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID)); pCharacteristic = pService->createCharacteristic( BLEUUID(CHARACTERISTIC_UUID), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_WRITE_NR ); pCharacteristic->addDescriptor(new BLE2902()); pService->start(); pServer->getAdvertising()->addServiceUUID(SERVICE_UUID); pServer->getAdvertising()->start(); Piano(); } void loop() { float xScale = 1024.0F/tft.width(); float yScale = 1024.0F/tft.height(); if (! digitalRead(RA8875_INT)) { // PianoListener if (tft.touched()) { tft.touchRead(&tx, &ty); if ((tx>=80) && (tx<=150) && (ty>=120) && (ty<=450)) { //tft.fillRect(0, 150, 50, 270, RA8875_RED); CurrentNote = 48; } if ((tx>=160) && (tx<=220) && (ty>=120) && (ty<=450)) { //tft.fillRect(0, 150, 50, 270, RA8875_RED); CurrentNote = 50; } if ((tx>=230) && (tx<=300) && (ty>=120) && (ty<=450)) { //tft.fillRect(0, 150, 50, 270, RA8875_RED); CurrentNote = 52; } if(CurrentNote != PreviousNote){ //MIDI.sendNoteOff(PreviousNote, 127, 1); midiPacket[2] = 0x80; // note up, channel 0 midiPacket[3] = PreviousNote; midiPacket[4] = 0; // velocity pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes) pCharacteristic->notify(); //MIDI.sendNoteOn(CurrentNote, 127, 1); midiPacket[2] = 0x90; // note down, channel 0 midiPacket[3] = CurrentNote; midiPacket[4] = 127; // velocity pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes pCharacteristic->notify(); Serial.println(CurrentNote); } PreviousNote = CurrentNote; } else{ //MIDI.sendNoteOff(PreviousNote , 127, 1); midiPacket[2] = 0x80; // note up, channel 0 midiPacket[3] = PreviousNote; midiPacket[4] = 0; // velocity pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes pCharacteristic->notify(); Serial.println(PreviousNote+"off"); } } } void Piano(){ tft.fillRect(0, 150, 50, 270, RA8875_WHITE); tft.fillRect(55, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(110, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(165, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(220, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(275, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(330, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(385, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(440, 150 , 50 , 270, RA8875_WHITE); tft.fillRect(0, 0, 30, 150, RA8875_WHITE); tft.fillRect(75, 0, 10, 150, RA8875_WHITE); tft.fillRect(130, 0, 30, 150, RA8875_WHITE); tft.fillRect(165, 0, 30, 150, RA8875_WHITE); tft.fillRect(240, 0, 10, 150, RA8875_WHITE); tft.fillRect(295, 0, 10, 150, RA8875_WHITE); tft.fillRect(350, 0, 30, 150, RA8875_WHITE); tft.fillRect(385, 0, 30, 150, RA8875_WHITE); tft.fillRect(465, 0, 15, 150, RA8875_WHITE); }А где в Вашей программе прописано отпускание ноты? Я предполагаю, что это должно быть где-то в 159 строке.
отпускание ноты должно происходить после
157 строки
pCharacteristic->notify();но не работает частьelse{151152//MIDI.sendNoteOff(PreviousNote , 127, 1);153midiPacket[2] = 0x80;// note up, channel 0154midiPacket[3] = PreviousNote;155midiPacket[4] = 0;// velocity156pCharacteristic->setValue(midiPacket, 5);// packet, length in bytes157pCharacteristic->notify();158Serial.println(PreviousNote+"off");159160}после отпускания тач экрана на терминал ничего не выводит