Работа с сенсорным экраном. Тормоза это нормально ?

Тема в разделе "Arduino & Shields", создана пользователем Mono-S, 31 июл 2016.

  1. Mono-S

    Mono-S Нуб

    Уважаемые форумчане, здравствуйте!
    Решил заказать с али сенсорный экран 2.4 mcufriend.com.
    http://ru.aliexpress.com/item/2-4-i...605222899.html?spm=2114.13010608.0.103.QQUJlw
    Полазал по форумам, запустил программу тестовую. Все вроде хорошо. Экран определился - все работает. Но при попытке сделать что то кнопочное - получаю дикое (около 1 секунды время срабатывания сенсора)
    Использовал библиотеки для работы экрана <Adafruit_GFX.h> <MCUFRIEND_kbv.h> и для сенсора <TouchScreen.h>. Попытки запустить библиотеку Utouch.h у меня провалились.
    Код (C++):
    #include <Adafruit_GFX.h>    // Core graphics library
    #include <MCUFRIEND_kbv.h>
    MCUFRIEND_kbv tft;       // hard-wired for UNO shields anyway.

    #include <TouchScreen.h>
    #if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
    #endif



    uint8_t YP = A1;  // must be an analog pin, use "An" notation!
    uint8_t XM = A2;  // must be an analog pin, use "An" notation!
    uint8_t YM = 7;   // can be a digital pin
    uint8_t XP = 6;   // can be a digital pin


    TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
    TSPoint tp;

    #define MINPRESSURE 20
    #define MAXPRESSURE 1000

    uint8_t Orientation = 1;    //PORTRAIT

    // Assign human-readable names to some common 16-bit color values:
    #define BLACK   0x0000
    #define BLUE    0x001F
    #define RED     0xF800
    #define GREEN   0x07E0
    #define CYAN    0x07FF
    #define MAGENTA 0xF81F
    #define YELLOW  0xFFE0
    #define WHITE   0xFFFF
       

    void setup()
    {
     
        Serial.begin(9600);
        tft.begin(9600);

        tft.reset();
        int    identifier = tft.readID();

       

        ts = TouchScreen(XP, YP, XM, YM, 300);     //call the constructor AGAIN with new values.
        tft.begin(identifier);

        tft.setRotation(Orientation);
        tft.fillScreen(BLACK);
    }


    void loop()
    {
       
     
    tp = ts.getPoint();   //tp.x, tp.y are ADC values
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        pinMode(XP, OUTPUT);
        pinMode(YM, OUTPUT);
        digitalWrite(XM, HIGH);
        digitalWrite(YP, HIGH);
     

          //  tft.setCursor(0, 80); //фунция улавливания и калибровки координат сенсора
         //    tft.print("tp.x=" + String(tp.x) + " tp.y=" + String(tp.y) + "   ");
       
             tft.drawRect(165,120,110,40, CYAN);
         tft.setCursor(175,125);
         tft.setTextSize(2);
         tft.setTextColor(CYAN,BLACK);
         tft.print("KNOPKA 1");
         
           
         
     
           //If Button flush pressed  
    if (tp.x > 320 && tp.x < 580  && tp.y > 600 && tp.y < 700  ){
         

          tft.setCursor(25,140);
         tft.setTextSize(2);
         tft.setTextColor(CYAN,BLACK);
         tft.print("KNOPKA URA!!!");
              }
       

    }
     
    В результате этой программы при попытке нажать на кнопку кнопка нажимается - но вот время через которое это срабатывает - 1 секунда это как бы очень и очень много. Почитал форумы и гугл - нашел вот такую статью :
    http://easyelectronics.ru/rabota-s-rezistivnym-sensornym-ekranom.html
    Тут автор описывает получение координат с сенсора посредством avr-studio и ассемблерного кода. Но вот беда в ассемблере я не силен - что то подобное перенести на IDE у меня пока не получилось.

    Вот собственно и вопрос - как получить адекватное время реакции сенсора, не используя при этом библиотек. Или как можно научить работать библиотеку быстрее ? Потому сенсор стоит реально дешевле и удобнее, нежели городить кнопки.
     
  2. ostrov

    ostrov Гуру

    Почему pinMode в loop?
     
  3. Mono-S

    Mono-S Нуб

    да это было в примере adafruita. Но если убрать это дело из loop и переместить в setup - сенсор почему-то не работает после нажатия кнопки. извиняюсь а что так нельзя ?
     
  4. Mono-S

    Mono-S Нуб

    Пример из библиотеки mcufriend_kbv. Там стоит pinMode в цикле while(1)
    Код (C++):
    // the regular Adafruit "TouchScreen.h" library only works on AVRs

    // different mcufriend shields have Touchscreen on different pins
    // and rotation.
    // Run the UTouch_calibr_kbv sketch for calibration of your shield

    #include <Adafruit_GFX.h>    // Core graphics library
    //#include <Adafruit_TFTLCD.h> // Hardware-specific library
    //Adafruit_TFTLCD tft(A3, A2, A1, A0, A4);
    #include <MCUFRIEND_kbv.h>
    MCUFRIEND_kbv tft;       // hard-wired for UNO shields anyway.
    #include <TouchScreen.h>

    #if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
    #endif

    // These are the pins for some typical shields!
    // S6D0154: YP=A1, XM=A2, YM=7, XP=6
    // ST7783 : YP=A2, XM=A1, YM=6, XP=7
    // ILI9320: YP=A2, XM=A3, YM=8, XP=9
    // ILI9325: YP=A1, XM=A2, YM=7, XP=6
    // ILI9325BG: YP=A2, XM=A1, YM=6, XP=7
    // ILI9341: YP=A2, XM=A1, YM=7, XP=6
    // ILI9488: YP=A1, XM=A2, YM=7, XP=6
    // R65109V: YP=A2, XM=A1, YM=6, XP=7

    // most mcufriend shields use these pins and Portrait mode:
    uint8_t YP = A1;  // must be an analog pin, use "An" notation!
    uint8_t XM = A2;  // must be an analog pin, use "An" notation!
    uint8_t YM = 7;   // can be a digital pin
    uint8_t XP = 6;   // can be a digital pin
    uint8_t SwapXY = 0;

    uint16_t TS_LEFT = 920;
    uint16_t TS_RT  = 150;
    uint16_t TS_TOP = 940;
    uint16_t TS_BOT = 120;
    char *name = "Unknown controller";

    // For better pressure precision, we need to know the resistance
    // between X+ and X- Use any multimeter to read it
    // For the one we're using, its 300 ohms across the X plate
    TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
    TSPoint tp;

    #define MINPRESSURE 20
    #define MAXPRESSURE 1000

    #define SWAP(a, b) {uint16_t tmp = a; a = b; b = tmp;}

    int16_t BOXSIZE;
    int16_t PENRADIUS = 3;
    uint16_t identifier, oldcolor, currentcolor;
    uint8_t Orientation = 0;    //PORTRAIT

    // Assign human-readable names to some common 16-bit color values:
    #define BLACK   0x0000
    #define BLUE    0x001F
    #define RED     0xF800
    #define GREEN   0x07E0
    #define CYAN    0x07FF
    #define MAGENTA 0xF81F
    #define YELLOW  0xFFE0
    #define WHITE   0xFFFF

    void show_Serial(void)
    {
        Serial.print(F("Found "));
        Serial.print(name);
        Serial.println(F(" LCD driver"));
        Serial.print(F("ID=0x"));
        Serial.println(identifier, HEX);
        Serial.println("Screen is " + String(tft.width()) + "x" + String(tft.height()));
        Serial.println("Calibration is: ");
        Serial.println("LEFT = " + String(TS_LEFT) + " RT  = " + String(TS_RT));
        Serial.println("TOP  = " + String(TS_TOP)  + " BOT = " + String(TS_BOT));
        Serial.print("Wiring is: ");
        Serial.println(SwapXY ? "SWAPXY" : "PORTRAIT");
        Serial.println("YP=" + String(YP)  + " XM=" + String(XM));
        Serial.println("YM=" + String(YM)  + " XP=" + String(XP));
    }

    void show_tft(void)
    {
        tft.setCursor(0, 0);
        tft.setTextSize(2);
        tft.print(F("Found "));
        tft.print(name);
        tft.println(F(" LCD"));
        tft.setTextSize(1);
        tft.print(F("ID=0x"));
        tft.println(identifier, HEX);
        tft.println("Screen is " + String(tft.width()) + "x" + String(tft.height()));
        tft.println("Calibration is: ");
        tft.println("LEFT = " + String(TS_LEFT) + " RT  = " + String(TS_RT));
        tft.println("TOP  = " + String(TS_TOP)  + " BOT = " + String(TS_BOT));
        tft.print("\nWiring is: ");
        if (SwapXY) {
            tft.setTextColor(CYAN);
            tft.setTextSize(2);
        }
        tft.println(SwapXY ? "SWAPXY" : "PORTRAIT");
        tft.println("YP=" + String(YP)  + " XM=" + String(XM));
        tft.println("YM=" + String(YM)  + " XP=" + String(XP));
        tft.setTextSize(2);
        tft.setTextColor(RED);
        tft.setCursor((tft.width() - 48) / 2, (tft.height() * 2) / 4);
        tft.print("EXIT");
        tft.setTextColor(YELLOW, BLACK);
        tft.setCursor(0, (tft.height() * 6) / 8);
        tft.print("Touch screen for loc");
        while (1) {
            tp = ts.getPoint();
            pinMode(XM, OUTPUT);
            pinMode(YP, OUTPUT);
            pinMode(XP, OUTPUT);
            pinMode(YM, OUTPUT);
            if (tp.z < MINPRESSURE || tp.z > MAXPRESSURE) continue;
            if (tp.x > 450 && tp.x < 570  && tp.y > 450 && tp.y < 570) break;
            tft.setCursor(0, (tft.height() * 3) / 4);
            tft.print("tp.x=" + String(tp.x) + " tp.y=" + String(tp.y) + "   ");
        }
    }


    void setup(void)
    {
        uint16_t tmp;
        tft.begin(9600);

        tft.reset();
        identifier = tft.readID();
     
        } else {
            name = "unknown";
        }
        switch (Orientation) {      // adjust for different aspects
            case 0:   break;        //no change,  calibrated for PORTRAIT
            case 1:   tmp = TS_LEFT, TS_LEFT = TS_BOT, TS_BOT = TS_RT, TS_RT = TS_TOP, TS_TOP = tmp;  break;
            case 2:   SWAP(TS_LEFT, TS_RT);  SWAP(TS_TOP, TS_BOT); break;
            case 3:   tmp = TS_LEFT, TS_LEFT = TS_TOP, TS_TOP = TS_RT, TS_RT = TS_BOT, TS_BOT = tmp;  break;
        }

        Serial.begin(9600);
        ts = TouchScreen(XP, YP, XM, YM, 300);     //call the constructor AGAIN with new values.
        tft.begin(identifier);
        show_Serial();
        tft.setRotation(Orientation);
        tft.fillScreen(BLACK);
        show_tft();

        BOXSIZE = tft.width() / 6;
        tft.fillScreen(BLACK);

        tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
        tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
        tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN);
        tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN);
        tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE);
        tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA);

        tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
        currentcolor = RED;
        delay(1000);
    }

    void loop()
    {
        uint16_t xpos, ypos;  //screen coordinates
        tp = ts.getPoint();   //tp.x, tp.y are ADC values

        // if sharing pins, you'll need to fix the directions of the touchscreen pins
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        pinMode(XP, OUTPUT);
        pinMode(YM, OUTPUT);
        //    digitalWrite(XM, HIGH);
        //    digitalWrite(YP, HIGH);
        // we have some minimum pressure we consider 'valid'
        // pressure of 0 means no pressing!

        if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE) {
            // is controller wired for Landscape ? or are we oriented in Landscape?
            if (SwapXY != (Orientation & 1)) SWAP(tp.x, tp.y);
            // scale from 0->1023 to tft.width  i.e. left = 0, rt = width
            // most mcufriend have touch (with icons) that extends below the TFT
            // screens without icons need to reserve a space for "erase"
            // scale the ADC values from ts.getPoint() to screen values e.g. 0-239
            xpos = map(tp.x, TS_LEFT, TS_RT, 0, tft.width());
            ypos = map(tp.y, TS_TOP, TS_BOT, 0, tft.height());

            // are we in top color box area ?
            if (ypos < BOXSIZE) {               //draw white border on selected color box
                oldcolor = currentcolor;

                if (xpos < BOXSIZE) {
                    currentcolor = RED;
                    tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
                } else if (xpos < BOXSIZE * 2) {
                    currentcolor = YELLOW;
                    tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
                } else if (xpos < BOXSIZE * 3) {
                    currentcolor = GREEN;
                    tft.drawRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, WHITE);
                } else if (xpos < BOXSIZE * 4) {
                    currentcolor = CYAN;
                    tft.drawRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, WHITE);
                } else if (xpos < BOXSIZE * 5) {
                    currentcolor = BLUE;
                    tft.drawRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, WHITE);
                } else if (xpos < BOXSIZE * 6) {
                    currentcolor = MAGENTA;
                    tft.drawRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, WHITE);
                }

                if (oldcolor != currentcolor) { //rub out the previous white border
                    if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
                    if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
                    if (oldcolor == GREEN) tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN);
                    if (oldcolor == CYAN) tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN);
                    if (oldcolor == BLUE) tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE);
                    if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA);
                }
            }
            // are we in drawing area ?
            if (((ypos - PENRADIUS) > BOXSIZE) && ((ypos + PENRADIUS) < tft.height())) {
                tft.fillCircle(xpos, ypos, PENRADIUS, currentcolor);
            }
            // are we in erase area ?
            if (ypos > tft.height() - 10) {
                // press the bottom of the screen to erase
                tft.fillRect(0, BOXSIZE, tft.width(), tft.height() - BOXSIZE, BLACK);
            }
        }
    }

     
     
  5. Mono-S

    Mono-S Нуб

    Тормоза это не нормально! Проблему решил.
    1. Почему то на отрисовку всего дисплея тратится аж 2 секунды!
    это не порядок - зачем отрисовывать дисплей каждый цикл - когда можно 1- по условию 2- по времени.
    Саму картинку набора я отрисовываю по условию - изменилось меню и т.д. - показания трех датчиков - раз 2 секунды. Отрисовывать достаточно. И все залетало! даже более чем.
    p.s. millis() решает)=