Go Down

Topic: MCUFRIEND_kbv Library for Uno 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend Shields (Read 457023 times) previous topic - next topic

Luis_Silva

David, I'm using a Mega 2560 Chinese.
 This is the code I am using with the DHT-11 sensor.
I would like to see the temperature and humidity information on the Mcufriend 3.5 "480 * 320 screen.


My code:
Code: [Select]

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN            2        
#define DHTTYPE           DHT11    

DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;

void setup() {
 Serial.begin(9600);
 dht.begin();
 Serial.println("DHTxx Unified Sensor Example");
 sensor_t sensor;
 dht.temperature().getSensor(&sensor);
 // Print temperature sensor details.
 Serial.println("------------------------------------");
 Serial.println("Temperature");
 Serial.print  ("Sensor:       "); Serial.println(sensor.name);
 Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
 Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
 Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" *C");
 Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" *C");
 Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" *C");  
 Serial.println("------------------------------------");
 // Print humidity sensor details.
 dht.humidity().getSensor(&sensor);
 Serial.println("------------------------------------");
 Serial.println("Humidity");
 Serial.print  ("Sensor:       "); Serial.println(sensor.name);
 Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
 Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
 Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println("%");
 Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println("%");
 Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println("%");  
 Serial.println("------------------------------------");
 // Set delay between sensor readings based on sensor details.
 delayMS = sensor.min_delay / 1000;
}

void loop() {
 // Delay between measurements.
 delay(delayMS);
 // Get temperature event and print its value.
 sensors_event_t event;  
 dht.temperature().getEvent(&event);
 if (isnan(event.temperature)) {
   Serial.println("Error reading temperature!");
 }
 else {
   Serial.print("Temperature: ");
   Serial.print(event.temperature);
   Serial.println(" *C");
 }
 // Get humidity event and print its value.
 dht.humidity().getEvent(&event);
 if (isnan(event.relative_humidity)) {
   Serial.println("Error reading humidity!");
 }
 else {
   Serial.print("Humidity: ");
   Serial.print(event.relative_humidity);
   Serial.println("%");
 }
}


:)





david_prentice

Please edit your message to put the code into a "code window".

You can adapt your program by:
1.  include header
2.  constructor
3.  calling tft.begin(ID) in setup()
4.  replacing every Serial.print(..) with tft.print(..)

Bear in mind that the screen is a fixed size.   So it is wise to tft.setCursor() to set your printing position.

Note that if you select text colour with tft.setTextColor(TFT_WHITE, TFT_BLACK) it will rub out previous characters.
Otherwise,   you can simply fillRect() to rub out a previous line.

David.

Luis_Silva

Sorry, but I did not understand, how do I put the temperature and humidity information on the screen?

Code: [Select]
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN            2        
#define DHTTYPE           DHT11    

DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;

void setup() {
  Serial.begin(9600);
  dht.begin();
  Serial.println("DHTxx Unified Sensor Example");
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  // Print temperature sensor details.
  Serial.println("------------------------------------");
  Serial.println("Temperature");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" *C");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" *C");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" *C");  
  Serial.println("------------------------------------");
  // Print humidity sensor details.
  dht.humidity().getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.println("Humidity");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println("%");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println("%");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println("%");  
  Serial.println("------------------------------------");
  // Set delay between sensor readings based on sensor details.
  delayMS = sensor.min_delay / 1000;
}

void loop() {
  // Delay between measurements.
  delay(delayMS);
  // Get temperature event and print its value.
  sensors_event_t event;  
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println("Error reading temperature!");
  }
  else {
    Serial.print("Temperature: ");
    Serial.print(event.temperature);
    Serial.println(" *C");
  }
  // Get humidity event and print its value.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println("Error reading humidity!");
  }
  else {
    Serial.print("Humidity: ");
    Serial.print(event.relative_humidity);
    Serial.println("%");
  }





david_prentice

Please read the Forum instructions on how to post code.
Then edit your mesage properly.

I have given you suggestions on how to adapt your Serial program.
Please make an effort.

Yes,   I could write it all for you.   I don't mind helping you with specific problems.

But it is your project and your hobby.

David.


Luis_Silva

Hello David, I can not calibrate my 3.5 "480 * 320 TFT LCD, can you help me? :)


Code: [Select]
// the regular Adafruit "TouchScreen.h" library only works on AVRs

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

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;       // hard-wired for UNO shields anyway.
#include <TouchScreen.h>

char *name = "Please Calibrate.";  //edit name of shield
const int XP=7,XM=55,YP=56,YM=6; //ID=0x9341
const int TS_LEFT=907,TS_RT=136,TS_TOP=942,TS_BOT=139;

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

#define MINPRESSURE 200
#define MAXPRESSURE 1000
 

int16_t BOXSIZE;
int16_t PENRADIUS = 1;
uint16_t ID, 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.println(F("Most Touch Screens use pins 6, 7, A1, A2"));
    Serial.println(F("But they can be in ANY order"));
    Serial.println(F("e.g. right to left or bottom to top"));
    Serial.println(F("or wrong direction"));
    Serial.println(F("Edit name and calibration statements\n"));
    Serial.println(name);
    Serial.print(F("ID=0x"));
    Serial.println(ID, 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.println("Wiring is always 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(1);
    tft.print(F("ID=0x"));
    tft.println(ID, HEX);
    tft.println("Screen is " + String(tft.width()) + "x" + String(tft.height()));
    tft.println("");
    tft.setTextSize(2);
    tft.println(name);
    tft.setTextSize(1);
    tft.println("PORTRAIT Values:");
    tft.println("LEFT = " + String(TS_LEFT) + " RT  = " + String(TS_RT));
    tft.println("TOP  = " + String(TS_TOP)  + " BOT = " + String(TS_BOT));
    tft.println("\nWiring is: ");
    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);
        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.reset();
    ID = tft.readID();
    tft.begin(ID);
    Serial.begin(9600);
    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);
    // we have some minimum pressure we consider 'valid'
    // pressure of 0 means no pressing!

    if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE) {
        // 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
        //
        // Calibration is true for PORTRAIT. tp.y is always long dimension
        // map to your current pixel orientation
        switch (Orientation) {
            case 0:
                xpos = map(tp.x, TS_LEFT, TS_RT, 0, tft.width());
                ypos = map(tp.y, TS_TOP, TS_BOT, 0, tft.height());
                break;
            case 1:
                xpos = map(tp.y, TS_TOP, TS_BOT, 0, tft.width());
                ypos = map(tp.x, TS_RT, TS_LEFT, 0, tft.height());
                break;
            case 2:
                xpos = map(tp.x, TS_RT, TS_LEFT, 0, tft.width());
                ypos = map(tp.y, TS_BOT, TS_TOP, 0, tft.height());
                break;
            case 3:
                xpos = map(tp.y, TS_BOT, TS_TOP, 0, tft.width());
                ypos = map(tp.y, TS_LEFT, TS_RT, 0, tft.height());
                break;
        }

        // 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 ?
        // Plain Touch panels use bottom 10 pixels e.g. > h - 10
        // Touch panels with icon area e.g. > h - 0
        if (ypos > tft.height() - 10) {
            // press the bottom of the screen to erase
            tft.fillRect(0, BOXSIZE, tft.width(), tft.height() - BOXSIZE, BLACK);
        }
    }
}



 Link video: https://youtu.be/bM8-3V-WedM


david_prentice

You can see that the line follows the X direction.   It is just backwards.
You can see that the line follows the Y direction.   It is just backwards.

Run the example called:   TouchScreen_Calibr_native
Copy-paste the result from the Serial Terminal.

Compare it with the default values from the TouchShield_new example.
You will see that the TS_LEFT and TS_RIGHT values are different.

Replace with the calibration values.   The line will follow the stylus perfectly.


The Calibration sketch gives you the "best" results.

If you are lazy,  you can just observe the line from the TouchShield_new example.
1.  move the stylus horizontally.
2.  if the pen moves vertically,   it means the XP, XM, YP, YM pins should be swapped.
3.  if the pen moves backwards,  it means the LEFT and RT values should be swapped.
4.  move the stylus vertically.
5.  if the pen moves backwards,  it means the TOP and BOT values should be swapped.
6.  when you have done (1) .. (5) correctly,  you get a "good enough" result for big buttons.

Quite honestly,   I use the calibration sketch.    It detects the correct pins and the correct values.

Following the "lazy" method makes my brain hurt.

David.

Luis_Silva

David, I already changed all the values and it does not work, I do not understand.

https://uploaddeimagens.com.br/imagens/20181211_143805_1_-jpg-b0dc1a83-00df-4dd1-bca4-5178dfbd691e

No Touch_shield_new tenho os seguintes valores:

ID=0*6814
PORTRAIT Valves:
LEFT=907  RT=136
TOP=942  BOT=139

david_prentice

I have a RM68140 Shield.  This is my calibration:

Code: [Select]

const int XP=7,XM=A1,YP=A2,YM=6; //320x480 ID=0x6814
const int TS_LEFT=134,TS_RT=906,TS_TOP=114,TS_BOT=924;


Copy-paste my values into your sketch.

David.

Luis_Silva

Thanks for the help David.

https://uploaddeimagens.com.br/imagens/20181211_163318_1_-jpg


Code: [Select]
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;       // hard-wired for UNO shields anyway.
#include <TouchScreen.h>

char *name = "Please Calibrate.";  //edit name of shield
const int XP=7,XM=A1,YP=A2,YM=6; //ID=0x9341
const int TS_LEFT=139,TS_RT=942,TS_TOP=136,TS_BOT=907;


Luis Silva  :)

wolfrose

Guys I want to start learning how to program these displays.

I tested my shield with the library.

But I want to do my own library.

I've looked into the Mcufriend_kbv library and it's quite difficult to find the hardware interface with the shield.

So, the shield is basically as follows:



First of all which datasheet should I read? Is it the ILI9335 or the ILI 9328?

Second, how to define the pins of data transmit and receive?

1. The pins on the left side:
LCD_RST, LCD_CS, LCD_RS, LCD_WR, LCD_RD,

2. The pins on the right side:
LCD_SS, LCD_DI, LCD_DO, LCD_SCK

Which one of these groups should I use for SPI communication?



Third, what's the best way to mask the data pin, since they are located on different ports?



Thanks,

MAS3

Hi wolfrose.

david_prentice does a wonderful job on supporting these boards.

I can understand why someone would want to try to do their own library, they will learn a great deal doing that.
But there really is no other need to do this.

If you still want to do this to learn, first advice i can give is learn to use the tools you already have.
All of your questions can be answered by using david_prentice's library and tools (i'm not sure about your last question, because i don't understand that one).
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

wolfrose

Hi wolfrose.

david_prentice does a wonderful job on supporting these boards.

I can understand why someone would want to try to do their own library, they will learn a great deal doing that.
But there really is no other need to do this.

If you still want to do this to learn, first advice i can give is learn to use the tools you already have.
All of your questions can be answered by using david_prentice's library and tools (i'm not sure about your last question, because i don't understand that one).
Of course my whole goal is to learn how to control displays and run them the way I want.


My last question is about the data pins which are D0,D1,D2 ... etc. What are they used for? Do I have to use them or they are for something else?

What I know is that to communicate with the display I only need the SPI pins which are 3 pins.

RajanBS

David Prentice Sir, thanks for great library MCUfriend_kbv for TFT pins change. I did it successfully for analogue pins. However, I am not able to change data (digital) pins like LCD_D0 to LCD_D7. Please help.

I am going to mount CNC shield on Uno pins of Mega hence I need different pins for TFT LCD 3.5" to be able to connect to same Arduino Mega.

Regards,
Rajan.

Mixius

Have a nice day! You can help me with setting up the display connection. How to change the code to get the next connection. I used this connection to recognize the display chip, there is a device, and such a connection was used there but another display

ATMEGA1284 MightyCore

#define LCD_RST  15   // PD7
#define LCD_CS    A2     // PA2
#define LCD_RS    A0     // PA0
#define LCD_WR   A1    // PA1
#define LCD_RD   14     // PD6

#define LCD_D0    0      //PB0...7
#define LCD_D1    1
#define LCD_D2    2
#define LCD_D3    3
#define LCD_D4    4
#define LCD_D5    5
#define LCD_D6    6
#define LCD_D7    7

Go Up