помогите с 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() постоянно обновляется, не передает какое то значение один раз и при его изменении другое. нажал на экран и в терминале сыпется куча строк о том что я нажимаю на экран , хотя может оно так и должно
да, тач именно так и работает - и это нормально.
Попробуйте вдуматься в мой совет выше, и вы поймете, что подобное поведение тача - не помеха.
Вам будет нужна еще одна переменная (например логическая) на каждую клавишу. И нота включается или выключается при ИЗМЕНЕНИИ этой переменной. Соответственно, возникает еще одна переменная - предыдущее состояние клавиши.
попробовал изменить, добавил состояния, теперь обратный эффект, при нажатии на первую клавишу - нота включается и не откючается, при повторном нажатии на эту же клавишу ничего не происходит, при нажатии на другую клавишу включается другая нота
А где в Вашей программе прописано отпускание ноты? Я предполагаю, что это должно быть где-то в 159 строке.
отпускание ноты должно происходить после
157 строки
pCharacteristic->notify();
но не работает часть
else
{
151
152
//MIDI.sendNoteOff(PreviousNote , 127, 1);
153
midiPacket[2] = 0x80;
// note up, channel 0
154
midiPacket[3] = PreviousNote;
155
midiPacket[4] = 0;
// velocity
156
pCharacteristic->setValue(midiPacket, 5);
// packet, length in bytes
157
pCharacteristic->notify();
158
Serial
.println(PreviousNote+
"off"
);
159
160
}
после отпускания тач экрана на терминал ничего не выводит