Menu

ili9341 read gram

Help
2017-11-04
2017-11-09
  • stan cartwright

    stan cartwright - 2017-11-04

    Hi. For too long I've tried to read a pixel colour on ili9341. I've connected a line from miso via logic level conveter to portb.4 miso on a uno so I can read from glcd.
    There's examples in c and welsh but do they use words or bytes? I've not read from a device I think. Not too clever on serial stuff. I haven't even tried my basic code below yet. Am I on the right track? Just reading pixel value as rgb would be ok. There's code I'm trying to mod below from sites where other people can't get it to work.Does the same,reads pixel.

    Sub read_pixel (In GLCDX as word, In GLCDY as word)
      SetAddressWindow_ILI9341 ( GLCDX, GLCDY, GLCDX, GLCDY )
      SendCommand_ILI9341(0x2e)
      pcolour = GLCDReadByte ;dummy read
      pcolour_h  = GLCDReadByte ;2 reads-hi low bytes
      pcolour = GLCDReadByte
      pcolour = (pcolour & 0xF800) | (pcolour & 0x00FC)
      pcolour = FnLSL(pcolour, 3)
      pcolour = pcolour or GLCDReadByte
      pcolour = FnLSR(pcolour, 11)
    end sub
    

    LCD.getPixel = function(x,y) {
    ce.reset(); // chip enable
    spi.write(0x2A,dc); // cmd 0x2A - x/col addr - w/ dc for cmd (0)
    spi.write(x>>8,x,x>>8,x); // x [Start Point MSByte, LSByte, then End Point)
    spi.write(0x2B,dc); // cmd 0x2B - y/row/page addr - w/ dc for cmd (0)
    spi.write(y>>8,y,y>>8,y); // x [Start Point MSByte, LSByte, then End Point)
    spi.write(0x2E,dc); // cmd 0x2E - memory read - w/ dc for cmd (0)
    spi.write(0x00,0x00,0x00);
    var p = spi.send([0x00,0x00,0x00]
    );
    ce.set();
    return p;

            uint16_t readPixel(int16_t x, int16_t y) {
            uint8_t r, g, b;
            setAddrWindow(x, y, x, y);
            r = readcommand8(0x2E);
            r = readdata();              //dummy
            r = readdata();
            g = readdata();
            b = readdata();
            return color565(r, g, b);    //.kbv
        }
    

    Set_Index(0x2A);
    Write_Command(x>>8);
    Write_Command(x);
    Set_Index(0x2B);
    Write_Command(y>>8);
    Write_Command(y);

    Set_Index( 0x2E ); // ILI9341_CMD_MEMORY_READ
    Read_Data(); // Dummy read (PMDIN = 0x002E)
    Read_Data(); // Dummy read (PMDIN = 0x0000)
    color = Read_Data(); // 1st 16 bits (red and green)
    color = (color & 0xF800) | (color & 0x00FC) << 3;
    color |= Read_Data() >> 11; // 2nd 16 bits (blue and red)

    TFT_CS = 1;
    return color;

     
  • stan cartwright

    stan cartwright - 2017-11-05

    Not a popular subject. It should be easy as the rest of the glcb ili9341 include but not explined..well not in gcb format. Supposed to be dummy read then 3 reads then the result is r,g,b in 3 bytes and shifted to be 5,6,5 or summat?*! vague info sorry but using c for inpiration.

     
    • Anobium

      Anobium - 2017-11-05

      When i get a free moment,. I will have a look at this.

       
  • stan cartwright

    stan cartwright - 2017-11-05

    glcd read is for a kxxxxdevice it seems from error messages.
    trying http://gcbasic.sourceforge.net/help/_spi_overview.html
    been down this road a few times and lost code....as you do...not
    Anobium...when do you get a free moment?
    I want to figure this myself but only c stuff to go by. Been on back boiler a while. Happy days using the touch screen or sd card slot in my dreams.

     
  • stan cartwright

    stan cartwright - 2017-11-08

    From google it seems sending the read command after setting window x,y,x,y then you read a dummy byte then 3 bytes that are r,g,b
    I am new to reading/sending Hw spi . After send 0x2e which is supposed to be pixel read,how do I read 4 bytes back assuming the read pointer is incremented by the display?

    Sub read_pixel (px,py)
      SetAddressWindow_ILI9341 (px,py,px,py )
      SendCommand_ILI9341(0x2e)
    ;now read
      readbyte
    
    '  pcolour = GLCDReadByte ;dummy read
    '  pcolour_h  = GLCDReadByte
    '  pcolour = GLCDReadByte
    '  pcolour = (pcolour & 0xF800) | (pcolour & 0x00FC)
    '  pcolour = FnLSL(pcolour, 3)
    '  pcolour = pcolour or GLCDReadByte
    '  pcolour = FnLSR(pcolour, 11)
    end sub
    Sub readbyte
      set glcd_CS OFF;
      set glcd_DC ON;
      SPITransfer what?, where?
      set ILI9341_CS ON;
    end sub
    
     
  • mmotte

    mmotte - 2017-11-09

    Stan,
    Look for example in what you already are using.
    The glcd_ILI9341.h file

    Function ILI9341_ReadID as long
    
            SendCommand_ILI9341( 0xd9 )
            'write data
            SendData_ILI9341( 0x11 )
            set ILI9341_CS OFF
            set ILI9341_DC OFF
            SPITransfer  0xd3,  ILI9341TempOut
            set ILI9341_DC ON
            SPITransfer  0x00,  SysCalcTempA
            set ILI9341_CS ON
    

    No this isn't the code for your task but it is how to get there.

    GL
    M

     
  • stan cartwright

    stan cartwright - 2017-11-09

    Thanks Mike, Anobium hinted the glcd with many pins held the answer but serial, although fundamental for ucntrls, isn't "basic" :)
    hwspi, the chip does something inside...it just works...like a car engine. doh
    All I want is to read a pixel. GCB space invaders on hold 'til then

     
    • Anobium

      Anobium - 2017-11-09

      Reading the GLCD may not be the way to go.... any read to the GLCD is slow compared to RAM. I mean really slow.

      Consider this. Create an array of invader positions and the bxmbs, read the array..... paint.

       
  • stan cartwright

    stan cartwright - 2017-11-09

    Evan. Think checking missile x,y within each invader x,y x+width,y+height...too slow if the pixel ahead of missile is blank- if lit then check which invader collision. Other stuff in games need pixel read as well.
    I can't think of an original project...everything's been done before..well not in GCB ..but arduino youtube it seems...all in c :( ha.
    sort of,- gcb can do this to, not in c
    I could do invaders on a ssd1306...but what's the point? I can't see letters without glasses.
    ps there's a touch spi that needs to be read on the ili9341 boards I have and sd card slot doing nothing.
    which is sorted in arduino c somewhere.

     

    Last edit: stan cartwright 2017-11-09
  • stan cartwright

    stan cartwright - 2017-11-09

    All this gives is 255 for any pixel colour. So many things could be wrong. Should I scope miso line to uno?

    #chip mega328p, 16
    #option explicit
    #include <glcd.h>
    
    #define GLCD_DI portb.4 ;miso sdo
    
    #define GLCD_TYPE GLCD_TYPE_ILI9341
    #define GLCD_DC   portb.2
    #define GLCD_CS   portd.7
    #define GLCD_RESET   portd.4
    #define GLCD_DO   portb.3 ;  MOSI SDI
    #define GLCD_SCK   portb.5 ;    SCK
    #define ILI9341_HardwareSPI    ' remove/comment out if you want to use software SPI.
    #define GLCD_EXTENDEDFONTSET1
    GLCDfntDefaultsize = 2
    #define SPI_HardwareSPI
    dir glcd_DC    out
    dir glcd_CS    out
    dir glcd_RESET out
    dir glcd_DO    Out
    dir glcd_DI    In
    dir glcd_SCK   Out
    
    GLCDRotate LANDSCAPE_REV
    dim pcolour as word
    dim px,py as word
    dim bytesent,c1,c2,c3 as byte
    px=200:py=100
    GLCDCLS
    Pset (px,py,ILI9341_black)
    read_pixel (px,py)
    ;GLCDPrint (0,0,pcolour)
    GLCDPrint (0,24,c1)
    GLCDPrint (0,48,c2)
    GLCDPrint (0,72,c3)
    do
    loop
    ;
    Sub read_pixel (px,py)
      SetAddressWindow_ILI9341 (px,py,px,py )
      SendCommand_ILI9341(0x2e) ; cmd 0x2E - memory read - w/ dc for cmd (0)
    ;now read
      readbyte ;dummy read
      readbyte
      c1=bytesent
      readbyte
      c2=bytesent
      readbyte
      c3=bytesent
    end sub
    Sub readbyte
      set glcd_CS OFF;
      set glcd_DC ON;
      SPITransfer 0, bytesent
      set glcd_CS ON
      set GLCD_DC ON
      wait 10 ms
    end sub
    
     
  • Anobium

    Anobium - 2017-11-09

    Does the device read operations? Is it a write only device? Put a protocol analyser on the line to decode the communications.

     
  • stan cartwright

    stan cartwright - 2017-11-09

    on a chinese budget pins must do something so miso should work and but how to send to display to make it send back I've never done, still looking at spi help and no mental picure of it how it works with the cs,rs stuff on off time,just can't picture it cos it's new.
    Since it's 3.3V in I assume it's the same out and di/miso is buffered to 5V logic to uno.
    So first a simple di read test routine anyone please incase the display doesn't have read.
    Is there a protocol analyser in demos?
    should I use C:\GCB@Syn98.01\GreatCowBasic\Demos\SPI Solutions\AVR SPI Examples for reading?

     

    Last edit: stan cartwright 2017-11-09
    • Anobium

      Anobium - 2017-11-11

      Page 37 of the datasheet is the secret. The diagram on the page shows the protocol to read the pixel value.

      The piece of code returns the correct 24bit color value for the Red, White and Red and then to check.... I read the background which is Black.

      Returned value is below. I set pixel to Red, White, and Red.

          0xFC0000
          0xFCFCFC
          0xFC0000
          0x000000
      

      Code I used, with modifications to get it working.

            Pset 0,0, ILI9341_RED
            Pset 1,1, ILI9341_WHITE
            Pset 2,2, ILI9341_RED
      
            pixcol = ReadPixel_ILI9341( 0,0 )
            GLCDPrint 10, 10, hex( pixcol_U )
            GLCDPrint 26, 10, hex( pixcol_H )
            GLCDPrint 42, 10, hex( pixcol )
      
            pixcol = ReadPixel_ILI9341( 1,1 )
            GLCDPrint 10, 20, hex( pixcol_U )
            GLCDPrint 26, 20, hex( pixcol_H )
            GLCDPrint 42, 20, hex( pixcol )
      
            pixcol = ReadPixel_ILI9341( 2,2 )
            GLCDPrint 10, 30, hex( pixcol_U )
            GLCDPrint 26, 30, hex( pixcol_H )
            GLCDPrint 42, 30, hex( pixcol )
      
            pixcol = ReadPixel_ILI9341( 3,3 )
            GLCDPrint 10, 40, hex( pixcol_U )
            GLCDPrint 26, 40, hex( pixcol_H )
            GLCDPrint 42, 40, hex( pixcol )
      

      Secret is on page 37 of https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf

       
  • stan cartwright

    stan cartwright - 2017-11-11

    Works ok Evan. I did try to get it working myself but got nowhere. I copied glcd SendCommand_ILI9341(ILI9341_CASET--PASET) but used SetAddressWindow_ILI9341 (px,py,px,py ) instead and other errors. Thanks for sorting the function for display.
    Fine as is. Not sure really about 24 biit colour and gcb 16 bit colour conversion and worth doing.
    ' color = Read_Data(); // 1st 16 bits (red and green)
    ' color = (color & 0xF800) | (color & 0x00FC) << 3;
    ' color |= Read_Data() >> 11; // 2nd 16 bits (blue and red)

     
  • stan cartwright

    stan cartwright - 2017-11-13

    Can't get white which is fc fc fc to be ili9341 ffff, yet.
    Not that many glcd colours, maybe a lookup table with primary colours first would be easier/faster to do.
    Just been thinking pixcol can't be 565 format as 0xfc is 6 bit and only green is 6 bit so forget that route.

    ;colour=fnlsl((pixcol and 0xF800) or (colour_h and 0x00FC),3)
    ;colour=(fnlsl((pixcol and 0xf8),11)) or (fnlsl ((pixcol and 0x7e0),5)) or (pixcol and 0x1f)
    x1=(pixcol_u and 0xf8) or (fnlsr(pixcol_h,5))
    ;x1 = (r & 0xF8) | (g >> 5); // Take 5 bits of Red component and 3 bits of G component
    x2=(fnlsl((pixcol_h and 0x1c),3)) or (fnlsr(pixcol,3))
    ;x2 = ((g & 0x1C) << 3) | (b  >> 3); // Take remaining 3 Bits of G component and 5 bits of Blue component
    ;colour=x1+(256*x2)
    GLCDPrint 0,48,x1
    GLCDPrint 200,48,x2
    
     

    Last edit: stan cartwright 2017-11-13
  • stan cartwright

    stan cartwright - 2017-11-13

    I think there's a problem. I tested colour pixcol values and cyan and aqua are the same
    black----00-00-00
    white----fc-fc-fc
    red------00-00-fc
    green----00-fc-00
    blue-----fc-00-00
    cyan-----fc-fc-00
    yellow---00-fc-fc
    aqua-----fc-fc-00
    purple---fc-20-f4
    D_grey---50-50-50

    dim pixcol as long
    dim setpixcol,px,py as word
    GLCDRotate ( Landscape_rev )     ' optionally you can rotate the screen.
    GLCDCLS ILI9341_BLACK
    px=300:py=100
    Pset (px,py, ILI9341_aqua)
    dim x1,x2 as byte
    dim colour as word
    pixcol = ReadPixel_ILI9341( px,py )
    GLCDPrint 0,0,pixcol
    GLCDPrint (0,24,hex( pixcol ))
    GLCDPrint (100,24,hex( pixcol_h ))
    GLCDPrint (200,24,hex( pixcol_u ))
    
     

    Last edit: stan cartwright 2017-11-13
  • stan cartwright

    stan cartwright - 2017-11-14

    Fine for me as is. Doing my head.
    itmt, I tried your advice Anobium for sprite and is fast and simpler than checking pixels.
    16 x 16 sprite

    sub sprite (spritedata_ptr,sprite_x,sprite_y)
      SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x +15,sprite_y +15 )
      for ptr=spritedata_ptr to spritedata_ptr+255
        ReadTable spritedata,ptr,pixel
        SendWord_ILI9341 pixel
      next ptr
    end sub
    ;
    sub erase_sprite (sprite_x,sprite_y)
      SetAddressWindow_ILI9341 ( sprite_x,sprite_y,sprite_x +15,sprite_y +15 )
      repeat 256
        SendWord_ILI9341 0
      end repeat
    end sub
    

    https://youtu.be/TvvLzQhLIMg

     

    Last edit: stan cartwright 2017-11-14
    • Anobium

      Anobium - 2017-11-14

      Post the complete project and I will put up on Twitter etc.

       
  • stan cartwright

    stan cartwright - 2017-11-14

    Er,,it's not complete. Pixel read is fine as is. Pity I had to go through the lib for the above sprite code which now looks so simple. I think it could be improved tough. Lots of effort gone into fonts and redefining and line graphics but no mention of multicoloured sprites.
    I'll post the sprite code in demos as it's simple and saves someone else figuring it.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.