Testing the Official 7" Touchscreen

Discussion and questions about programming with Ultibo.
User avatar
Ultibo
Site Admin
Posts: 2291
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Testing the Official 7" Touchscreen

Postby Ultibo » Tue Oct 04, 2016 4:52 am

Hi all,

As noted in yesterdays commit announcement (viewtopic.php?f=4&t=309) for Ultibo core 1.2.185 we now have a driver for the touchscreen on the Official Raspberry Pi 7" display but we need some testing to make sure it works.

It has been known for a while that the display part of the official 7" touchscreen works correctly with Ultibo and some have expressed an interest in getting the touch part of it working as well so we've gone ahead and looked at the Linux drivers (the only known source of any information about this device) to determine how to communicate with it. It turns out that (for whatever reason) the Raspberry Pi foundation decided to attach the whole device including the FocalTech FT5406 capacitive touchscreen controller directly to the GPU instead of making it available to the ARM CPU, the GPU then creates a memory based interface to read touch points from at regular intervals.

The Linux driver written by the Pi foundation uses a thread to poll the memory buffer about 60 times per second and check for touch points reported by the GPU, the actual location of the buffer itself is obtained by calling a mailbox function which returns the bus address which can be converted to a physical address for the CPU to access. The Ultibo driver follows pretty much this exact same model by creating a thread that obtains the buffer address during startup and polls for changes every 17ms (approx 60 times per second).

Below is a test project that includes the new RPiFT5406 driver and performs some startup checks to determine if the memory buffer is available and the driver is loaded, after that it goes into a loop waiting for either mouse or touch events to be available. Touch devices can report their data either as specific TTouchData events or as generic TMouseData events and this can be controlled by changing the value of TOUCH_MOUSE_DATA_DEFAULT in the GlobalConfig unit, by default this is set to True at the moment although that might change in future.

Touch devices also have settings to control rotation (since many touchscreen devices can be rotated through 360 degrees in software) and both screen width and height which will shortly be used for scaling and calibration of the data output.

This project was created for a Raspberry Pi 2B, to change it for 3B replace RaspberryPi2 in the uses clause with RaspberryPi3 and to make it suitable for A/B/A+/B+/Zero change RaspberryPi2 in the uses clause to RaspberryPi instead.

Code: Select all

program RPiTouchTest;

{$mode delphi}{$H+}

uses
  RaspberryPi2, {Include the RaspberryPi2 unit to give us network, filesystem etc}
  GlobalConfig,
  GlobalConst,
  GlobalTypes,
  Platform,
  Threads,
  Devices,
  Console,
  Logging,
  Touch,        {Include the Touch unit so we can receive touch data}
  Mouse,        {Include the Mouse unit so we can receive mouse data}
  RPiFT5406,    {Include the Raspberry Pi FT5406 touchscreen driver}
  HTTP,         {Include HTTP and WebStatus so we can see from a web browser what is happening}
  WebStatus,
  RemoteShell,     {Include RemoteShell and the ShellUpdate unit for remote updating}
  ShellFilesystem,
  ShellUpdate,
  SysUtils;
 
var
 LeftWindow:TWindowHandle;
 RightWindow:TWindowHandle;
 HTTPListener:THTTPListener;

 Address:LongWord;
 ResultCode:LongWord;
 TouchDevice:PTouchDevice;
 Properties:TTouchProperties;
 
 Count:LongWord;
 Buffer:String;
 MouseData:TMouseData;
 TouchData:TTouchData;
 
begin
 {Wait a few seconds for all initialization to be done}
 Sleep(3000);

 {Create a console window to show what is happening}
 LeftWindow:=ConsoleWindowCreate(ConsoleDeviceGetDefault,CONSOLE_POSITION_TOPLEFT,True);
 
 {Display a startup message on the console}
 ConsoleWindowWriteLn(LeftWindow,'Starting Raspberry Pi touchscreen (FT5406) test');
 
 {And another window to show the touch/mouse data}
 RightWindow:=ConsoleWindowCreate(ConsoleDeviceGetDefault,CONSOLE_POSITION_RIGHT,False);
 
 {Open a logging window as well to record debug output from RPiFT5406}
 CONSOLE_REGISTER_LOGGING:=True;
 CONSOLE_LOGGING_POSITION:=CONSOLE_POSITION_BOTTOMLEFT;
 LoggingConsoleDeviceAdd(ConsoleDeviceGetDefault);
 LoggingDeviceSetDefault(LoggingDeviceFindByType(LOGGING_TYPE_CONSOLE));
 
 {Create and start the HTTP Listener for our web status page}
 HTTPListener:=THTTPListener.Create;
 HTTPListener.Active:=True;
 
 {Register the web status page to allow checking the rest of the system for responsiveness}
 WebStatusRegister(HTTPListener,'','',True);

 {Call the new TouchGetBuffer function from Platform}
 ResultCode:=TouchGetBuffer(Address);
 ConsoleWindowWriteLn(LeftWindow,'TouchGetBufer returned ' + ErrorToString(ResultCode));
 ConsoleWindowWriteLn(LeftWindow,' Address = ' + IntToHex(Address,8));
 if Address = 0 then
  begin
   ConsoleWindowWriteLn(LeftWindow,'WARNING: Touch buffer address is nil, test will probably not succeed');
  end;
 
 {Find the Touch device}
 TouchDevice:=TouchDeviceFindByDescription(RPIFT5406_TOUCH_DESCRIPTION);
 if TouchDevice = nil then
  begin
   ConsoleWindowWriteLn(LeftWindow,'WARNING: Touch device not found, test will probably not succeed');
  end
 else
  begin
   ConsoleWindowWriteLn(LeftWindow,'Touch device "' + DeviceGetDescription(@TouchDevice.Device) + '" with name "' + DeviceGetName(@TouchDevice.Device) + '" found');
   ConsoleWindowWriteLn(LeftWindow,' Thread handle = ' + IntToHex(PRPiFT5406Touch(TouchDevice).Thread,8));
   ConsoleWindowWriteLn(LeftWindow,' Thread name = ' + ThreadGetName(PRPiFT5406Touch(TouchDevice).Thread));
   ConsoleWindowWriteLn(LeftWindow,' Registers = ' + IntToHex(LongWord(PRPiFT5406Touch(TouchDevice).Registers),8));
  end; 
 
 {Output some information}
 if TouchDeviceProperties(TouchDevice,@Properties) = ERROR_SUCCESS then
  begin
   ConsoleWindowWriteLn(LeftWindow,'Touch device properties');
   ConsoleWindowWriteLn(LeftWindow,' Width = ' + IntToStr(Properties.Width));
   ConsoleWindowWriteLn(LeftWindow,' Height = ' + IntToStr(Properties.Height));
   ConsoleWindowWriteLn(LeftWindow,' Rotation = ' + IntToStr(Properties.Rotation));
   ConsoleWindowWriteLn(LeftWindow,' MaxX = ' + IntToStr(Properties.MaxX));
   ConsoleWindowWriteLn(LeftWindow,' MaxY = ' + IntToStr(Properties.MaxY));
   ConsoleWindowWriteLn(LeftWindow,' MaxZ = ' + IntToStr(Properties.MaxZ));
   ConsoleWindowWriteLn(LeftWindow,' MaxPoints = ' + IntToStr(Properties.MaxPoints));
  end;
 
 {Check Mouse data default}
 if TOUCH_MOUSE_DATA_DEFAULT then
  begin
   ConsoleWindowWriteLn(LeftWindow,'Variable TOUCH_MOUSE_DATA_DEFAULT is True, will read from Mouse data');
  end
 else
  begin
   ConsoleWindowWriteLn(LeftWindow,'Variable TOUCH_MOUSE_DATA_DEFAULT is False, will read from Touch data');
  end; 
 
 {Wait for data}
 ConsoleWindowWriteLn(LeftWindow,'Waiting for data, try touching the screen');
 while True do
  begin
   if TOUCH_MOUSE_DATA_DEFAULT then
    begin
     {Read from Mouse}
     if MouseRead(@MouseData,SizeOf(TMouseData),Count) = ERROR_SUCCESS then
      begin
       {Check Buttons field}
       if MouseData.Buttons = 0 then
        begin
         Buffer:='None';
        end
       else if (MouseData.Buttons and MOUSE_TOUCH_BUTTON) = MOUSE_TOUCH_BUTTON then
        begin
         Buffer:='Touch';
        end       
       else
        begin
         Buffer:='Other';
        end;
       
       if (MouseData.Buttons and MOUSE_ABSOLUTE_X) = MOUSE_ABSOLUTE_X then
        begin
         Buffer:=Buffer + ', Absolute X';
        end;

       if (MouseData.Buttons and MOUSE_ABSOLUTE_Y) = MOUSE_ABSOLUTE_Y then
        begin
         Buffer:=Buffer + ', Absolute Y';
        end;
       
       {Display Mouse Data}
       ConsoleWindowWriteLn(RightWindow,'Mouse OffsetX = ' + IntToStr(MouseData.OffsetX) + ' OffsetY = ' + IntToStr(MouseData.OffsetY) + ' Buttons = ' + Buffer);
      end
     else
      begin
       ConsoleWindowWriteLn(LeftWindow,'Error reading the mouse data');
      end;     
    end
   else
    begin
     {Read from Touch}
     if TouchDeviceRead(TouchDevice,@TouchData,SizeOf(TTouchData),TOUCH_FLAG_NONE,Count) = ERROR_SUCCESS then
      begin
       {Check Info field}
       if TouchData.Info = 0 then
        begin
         Buffer:='None';
        end
       else if (TouchData.Info and TOUCH_FINGER) = TOUCH_FINGER then
        begin
         Buffer:='Finger';
        end
       else
        begin
         Buffer:='Other';
        end;   
       
       {Display Touch Data}
       ConsoleWindowWriteLn(RightWindow,'Touch PointID = ' + IntToStr(TouchData.PointID) + ' PositionX = ' + IntToStr(TouchData.PositionX) + ' PositionY = ' + IntToStr(TouchData.PositionY) + ' PositionZ = ' + IntToStr(TouchData.PositionZ) + ' Info = ' + Buffer);
      end
     else
      begin
       ConsoleWindowWriteLn(LeftWindow,'Error reading the touch data');
      end;     
    end;   

   if TouchDevice = nil then Sleep(1000);
  end;
 
 {Halt this thread}
 ThreadHalt(0);
end.

To save us from chasing our tails looking for bugs it would be good if you could prove that your touchscreen works with the official Raspbian release before testing with this project, if you are confident that it works correctly under Raspbian and you have any necessary settings included in your config.txt file then go ahead and try the test with Ultibo and report your results back here.

Thanks!
Ultibo.org | Make something amazing
https://ultibo.org
Gavinmc42
Posts: 1662
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Testing the Official 7" Touchscreen

Postby Gavinmc42 » Tue Oct 04, 2016 8:29 am

Thanks, was waiting for this code so I can test it.
Let you know tmr.
Gavinmc42
Posts: 1662
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Testing the Official 7" Touchscreen

Postby Gavinmc42 » Wed Oct 05, 2016 4:05 am

Spits out lots of data fast even with a PiB+.
Does not seem to need calibration, can detect x=0, y=0 to x=799, y=479 :o
Also seems to detect multiple touches fine too.

Might have to slow it down or get a drawing program working.
More than good enough for UI button pushing.

Every time I use Ultibo I have a hard time getting used to how usable it is, just keeps getting better.
User avatar
Ultibo
Site Admin
Posts: 2291
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: Testing the Official 7" Touchscreen

Postby Ultibo » Wed Oct 05, 2016 4:17 am

Awesome, thanks Gavin!

Now, who can think of something to do with a 7" touchscreen?

Just 2 quick questions,

Does it seem to be the correct orientation? (eg is Top/Left the minimum and Bottom/Right the maximum)
Does it give a final X=0, Y=0, Buttons=None when you release any/all fingers?

Thanks again!

PS. If anyone else has one of these to test and confirm the results that would be cool.
Ultibo.org | Make something amazing
https://ultibo.org
Gavinmc42
Posts: 1662
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Testing the Official 7" Touchscreen

Postby Gavinmc42 » Wed Oct 05, 2016 6:39 am

Answer to both is yes
top left is 0,0, bottom right 799,479
fingers off = 0

Might try some drawing stuff, play with my plotting software.
See if difference fingers can track at the same time?
10 finger paint program ;)
hansotten
Posts: 64
Joined: Thu Feb 04, 2016 7:07 am

Re: Testing the Official 7" Touchscreen

Postby hansotten » Wed Oct 05, 2016 8:50 am

Most Official 7 inch Touchscreen cases demand the touchscreen to be mounted upside down.

On Raspbian a simple config.txt entry makes the display turn alo 90/180/270 degrees.

Is this also possible with Ultibo somehow?
User avatar
Ultibo
Site Admin
Posts: 2291
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: Testing the Official 7" Touchscreen

Postby Ultibo » Wed Oct 05, 2016 10:13 am

hansotten wrote:Is this also possible with Ultibo somehow?

Yes, the same config.txt entries that rotate the display in Raspbian also work in Ultibo, so adding display_rotate=2 turns the display around 180 degrees.

What we don't know is if the touchscreen coordinates also change with these settings, of course the touch device in Ultibo has a rotation parameter that allows controlling this but in the case of the Raspberry Pi the touchscreen is attached to the GPU directly which may be translating the coordinates already.

If anyone has a chance to test this it would be very useful to know.
Ultibo.org | Make something amazing
https://ultibo.org
Gavinmc42
Posts: 1662
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Testing the Official 7" Touchscreen

Postby Gavinmc42 » Thu Oct 06, 2016 6:51 am

Display rotates but touch x,y coordinates stay the same.
Bottom right is now 0,0 etc.

Can you change the touch screen rotation in config.txt too?
Gavinmc42
Posts: 1662
Joined: Sun Jun 05, 2016 12:38 pm
Location: Brisbane, Australia

Re: Testing the Official 7" Touchscreen

Postby Gavinmc42 » Thu Oct 06, 2016 7:32 am

display_rotate=1 rotates display 90 degrees but touch stays the same.
display_rotate=3 will probably do 270 degrees. Yep.
User avatar
Ultibo
Site Admin
Posts: 2291
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: Testing the Official 7" Touchscreen

Postby Ultibo » Thu Oct 06, 2016 10:28 am

Gavinmc42 wrote:Can you change the touch screen rotation in config.txt too?

I got the display_rotate setting from the official config.txt documentation here https://www.raspberrypi.org/documentati ... fig-txt.md and it obviously does rotate the screen but not the touch coordinates.

Looking around a bit further there is this document https://www.raspberrypi.org/documentati ... hooting.md which says you can use the setting lcd_rotate instead so I wonder if that one changes the touch coordinates. Otherwise the question remains as to how Raspbian adjusts the touch coordinates when the GPU changes the rotation, unless it also reads config.txt file.

The official way to do it on Ultibo will be via a call to TouchDeviceControl() to set the rotation parameter, obviously for non Raspberry Pi touchscreens that will be required, just trying figure if it is also needed for the official 7" screen.

If anyone can test that would be great.
Ultibo.org | Make something amazing
https://ultibo.org

Return to “General”

Who is online

Users browsing this forum: No registered users and 2 guests