помогите с TFT дисплеем RA8875

djsasha777
Offline
Зарегистрирован: 21.02.2019

пытаюсь сделать беспроводной 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);
  }


}

 

b707
Offline
Зарегистрирован: 26.05.2017

можно посоветовать запоминать, какая именно тач-"клавиша" нажата (причем не координаты. а именно какая клавиша) - и если при следующем опросе тача опять будет нажата та же клавиша - игнорировать ее

djsasha777
Offline
Зарегистрирован: 21.02.2019

я пробовал что то подобное из примеров, но результат такой же. как я понял  tft.touched() постоянно обновляется, не передает какое то значение один раз и при его изменении другое. нажал на экран и в терминале сыпется куча строк о том что я нажимаю на экран , хотя может оно так и должно и я смотрю совсем в другую сторону

b707
Offline
Зарегистрирован: 26.05.2017

djsasha777 пишет:

 tft.touched() постоянно обновляется, не передает какое то значение один раз и при его изменении другое. нажал на экран и в терминале сыпется куча строк о том что я нажимаю на экран , хотя может оно так и должно

да, тач именно так и работает - и это нормально.

Попробуйте вдуматься в мой совет выше, и вы поймете, что подобное поведение тача - не помеха.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Вам будет нужна еще одна переменная (например логическая) на каждую клавишу. И нота включается или выключается при ИЗМЕНЕНИИ этой переменной. Соответственно, возникает еще одна переменная - предыдущее состояние клавиши.

djsasha777
Offline
Зарегистрирован: 21.02.2019

попробовал изменить, добавил состояния, теперь обратный эффект, при нажатии на первую клавишу - нота включается и не откючается, при повторном нажатии на эту же клавишу ничего не происходит, при нажатии на другую клавишу включается другая нота

#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);   
}

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А где в Вашей программе прописано отпускание ноты? Я  предполагаю, что это должно быть где-то в 159 строке.

djsasha777
Offline
Зарегистрирован: 21.02.2019
 

отпускание ноты должно происходить после 

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   }

после отпускания тач экрана на терминал ничего не выводит