Turn Off LCD while keeping touch sensor active

Discussion in 'Accessories' started by objectr, Jun 23, 2014.

  1. objectr

    objectr Member

    Joined:
    May 28, 2014
    Messages:
    36
    Likes Received:
    1
    The title pretty much says it all...
    I want to turn the 7" touch lcd off (using a relay connected to the sam3x) while keeping the touch input active (so i can wake it up on touch again)
    If anyone has ever done that, or has any input on that topic I would really appreciate it.
    Thanks
     
  2. fetcher

    fetcher Member

    Joined:
    Mar 9, 2014
    Messages:
    166
    Likes Received:
    20
    Relays tend to be power-hungry -- just keeping the coil energized could easily draw more current than what your display draws.

    Anyway, the UDOO already has MOSFETs on board for switching +5V and +3.3V power to the LCD on and off, as well as a separate, unswitched +3.3V line on the LCD connector that can keep your touch sensor powered. Take a look at CN13 and surrounding circuitry on page 11 of the schematic ("LVDS Interface"). Pins 15 and 16 are switched +5V power, 17 is switched +3.3V, and 18 unswitched +3.3V for the sensor.

    The LCD power switching control is connected to GPIO #2 on the i.MX6 chip (not the SAM3x). You'd need to use the "export" facility to get usermode access to to this GPIO signal, or add it to the "set_in_outputmode_high" list in board-mx6qd_seco_UDOO.h (or board-mx6sdl_seco_UDOO.h for a dual board). There's also a separate backlight on/off signal (pin 20) on GPIO #4, intended to switch an external backlight driver that has an enable input.
     
  3. dantavious

    dantavious New Member

    Joined:
    Nov 29, 2013
    Messages:
    32
    Likes Received:
    0
    Thanks for all the good info. I was looking to accomplish the same affect however, I was attempting to do it via XORG with the Option "DPMS in the Monitor section. "xset dpms force off" only blanks the screen instead of totally cutting power though. I will be interested to see what you guys come up with.
     
  4. hillcz

    hillcz Member

    Joined:
    Oct 3, 2013
    Messages:
    72
    Likes Received:
    1
    Hi fetcher
    Can you please tell me how to turn off the backlight with GPIO 4?
    Ideally with DPMS. THX
     
  5. fetcher

    fetcher Member

    Joined:
    Mar 9, 2014
    Messages:
    166
    Likes Received:
    20
    For controlling it manually from the command-line, try this as root;

    # cd /sys/class/gpio
    # echo 4 >/sys/class/gpio/export
    # echo out > /sys/class/gpio/gpio4/direction
    # echo 1 >/sys/class/gpio/gpio4/value
    # echo 0 >/sys/class/gpio/gpio4/value

    (cursor up, up, enter to turn backlight back on if your screen is now blank ;)

    That will only work if your panel uses the BL_ON signal provided on CN13 pin 20.
    Doing the same with gpio2, rather than 4 should work to toggle +5V and +3.3V power to the LCD itself, rather than its backlight driver.

    I would like to get this working automatically via DPMS also, but haven't yet figured out a good way. It may require patching the X server, though a custom, stripped-down Xscreensaver module that just toggles those GPIO's rather than drawing anything might be enough.
     
  6. fabio978

    fabio978 Member

    Joined:
    Jul 2, 2014
    Messages:
    51
    Likes Received:
    5
    Thank you very much!
    I created a shell script to turn on and off LCD backlight, then i used Tasker to associate it with "display state change", so when DayDream starts, my LCD backlight goes off and when you touch the screen (or move your mouse) it will turn on again :cool:
     
  7. hillcz

    hillcz Member

    Joined:
    Oct 3, 2013
    Messages:
    72
    Likes Received:
    1
    If I try as root : echo 4 >/sys/class/gpio/export
    A have response -bash: echo: write error: Device or resource busy
     
  8. fetcher

    fetcher Member

    Joined:
    Mar 9, 2014
    Messages:
    166
    Likes Received:
    20
    Hmm, what Linux distro are you running? I'm on Debian 1.1 here. The error suggests something else has already taken control of that GPIO pin. You could edit kernel file arch/arm/mach-mx6/board-mx6qd_seco_UDOO.h (assuming a quad board) and add GPIO 2 and 4 to the set_in_outputmode_high list, so that they're automatically exported at startup time (and turned on by default)--
    Code:
    static unsigned int mx6q_set_in_outputmode_high[] = {
            MX6Q_PAD_GPIO_0__GPIO_MODE,
            MX6Q_PAD_NANDF_D5__GPIO_MODE,
            MX6Q_PAD_EIM_EB3__GPIO_MODE,
            MX6Q_PAD_NANDF_CS0__GPIO_MODE,
            MX6Q_PAD_GPIO_2__GPIO_MODE,      // add this
            MX6Q_PAD_GPIO_4__GPIO_MODE,      // and this...
    };
    
     
  9. fabio978

    fabio978 Member

    Joined:
    Jul 2, 2014
    Messages:
    51
    Likes Received:
    5
    I forgot to mention i was talking about Android, so in that case the path is /sys/devices/virtual/gpio/gpio4 (at least that worked for me)

    echo 0 > /sys/devices/virtual/gpio/gpio4/value - to turn off
    echo 1 > /sys/devices/virtual/gpio/gpio4/value - to turn on
     
  10. hillcz

    hillcz Member

    Joined:
    Oct 3, 2013
    Messages:
    72
    Likes Received:
    1
    I tried with debian but same result. I have UDOO Dual not the quad.

    OK i compile my kernel and now it is ok.

    Any idea how turn off display after 30s without touch ane turn on after touch intterupt signal ?

    THX

    ANY WAY TO DO THIS:

    Code:
    #!/bin/sh
    while true
    do
    if [cat /dev/input/event0]
    then echo 0 >/sys/class/gpio4/value; fi
    done
    
     
  11. hillcz

    hillcz Member

    Joined:
    Oct 3, 2013
    Messages:
    72
    Likes Received:
    1
    Code:
    #!/bin/sh
    export DISPLAY=0:0
    while true
    do
    if  /usr/bin/xset q | grep "Monitor is Off"
    then echo 0 >/sys/class/gpio/gpio4/value; else echo 1 >/sys/class/gpio/gpio4/va$
    sleep 1
    done
    
    It's not pretty but functional :-D
     
  12. fetcher

    fetcher Member

    Joined:
    Mar 9, 2014
    Messages:
    166
    Likes Received:
    20
    Here's a simple X11 screensaver I wrote, basically a hacked-up version of an old and simple one called "Beforelight" from early 90s. Rather than drawing anything on the screen, it just turns the backlight off instead, then back on when there's input activity. It also suspends the Udoo's video output via DPMS for a small additional power savings. Turning off gpio2 (LCD power) as well as gpio4 (backlight) to scavenge a few more mW may be worthwhile too, and would be a simple enough addition, but for now it doesn't try -- not having one of these touchscreen LCD's on hand to test, I was afraid they could be operating the touch sensors from these same LCD power rails. The connector has pins for switched +5V, switched +3.3V (both toggled simultaneously by gpio2) as well as an unswitched +3.3V, unswitched +12V, and the separate backlight control line.

    Anyway, use 'xset s' to control the timeout period, or to force an immediate off-state via window-manager hotkey (xset s activate... do a sleep 0.2 first so the key-release won't wake it back up). I thought about making a module for xscreensaver, but this is much lighter-weight: the compiled & stripped binary is only 6K. It hooks into the X server's XSS (X Screen Saver) extension, and should consume no CPU cycles at all until awakened by an idle timeout event.

    I think the XSS spec allows for only one registered screensaver at a time, so be sure 'xscreensaver' isn't running also.

    See comments at the top of the C file for dependencies, and how to compile & use. I run this on Debian, but Ubuntu shouldn't be much different.

    (attached .c file is the same as the inline code below.... ooops, I forgot that this silly forum won't allow a .c file, for some inexplicable reason! Guess I'll have to ZIP it first...)

    Code:
    /*
     * udooblkt.c
     *
     * (based on:)
     * $XConsortium: b4light.c,v 1.3 94/04/17 20:59:38 rws Exp $
     *
     * Copyright (c) 1992  X Consortium
     * ...
     * (original) Author:  Keith Packard, MIT X Consortium
     * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     *  -jnh- (fetcher) 2014-07-28
     *  gutted version of "Beforelight", patched to trigger
     *  GPIO-controlled backlight toggle on UDOO board;
     *  All screen-drawing code removed
     *
     * Install these first:
     *  apt-get install xutils-dev libxss-dev libxmuu-dev
     *
     * Compile:
     *  gcc -s -O2 -o udoobklt udoobklt.c -lXss -lXext -lXt -lX11
     * 
     * Use:
     *  ./udoobklt &   # <- add to Xsession, .xinitrc, etc.
     *  xset s 60      # <- e.g. 60 second timeout
     * 
     */
    
    #define GPIODIR "/sys/class/gpio/gpio4/direction"
    #define GPIOVAL "/sys/class/gpio/gpio4/value"
    
    #include <X11/Xatom.h>
    #include <X11/Intrinsic.h>
    #include <X11/StringDefs.h>
    #include <X11/Shell.h>
    #include <X11/extensions/scrnsaver.h>
    #include <X11/Xcms.h>
    
    #include <X11/extensions/dpms.h>
    
    #include <stdlib.h>
    #include <time.h>
    
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
     int DIR,VAL;
    
    #ifndef ZERO
    # define ZERO ((Cardinal)0)
    #endif
    
    static int  ss_event, ss_error;
    
    static Display *display;
    static Window  root, saver;
    static int screen;
    static int  scr_wid, scr_hei;
    static int  screen_saved;
    static XtAppContext app_con;
    
    static unsigned long    black_pixel;
    
    static void 
    StartSaver (void)
    {
        if (screen_saved)
            return;
        screen_saved = True;
    
      if  ( ( DIR=open(GPIODIR,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio_dir_setup"); exit(1); }
      write(DIR,"out\n",4);
      close(DIR);
    
      if  ( ( VAL=open(GPIOVAL,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio_val_setup"); exit(1); }
      write(VAL, "0",1);
      close(VAL);
    
      /* this should stop i.MX6 rasterizer & save a few more milliwatts... */
      DPMSForceLevel(display, DPMSModeOff);
    
    }
    
    static void
    StopSaver (void)
    {
        if (!screen_saved)
            return;
        screen_saved = False;
    
    /* no need to repeat this
      if  ( ( DIR=open(GPIODIR,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio_dir_setup"); exit(1); }
      write(DIR,"out\n",4);
      close(DIR);
    */
    
      if  ( ( VAL=open(GPIOVAL,O_WRONLY|O_SYNC) ) <= 0 ) { perror("gpio_val_setup"); exit(1); }
      write(VAL, "1",1);
      close(VAL);
    }
    
    static int 
    ignoreError (Display *display, XErrorEvent *error)
    {
        return 0;
    }
    
    int 
    main(int argc, char *argv[])
    {
        Widget toplevel;
        XEvent  event;
        XScreenSaverNotifyEvent *sevent;
        XSetWindowAttributes    attr;
        XScreenSaverInfo        *info;
        unsigned long           mask;
        Pixmap                  blank_pix;
        XColor                  dummyColor;
        XID                     kill_id;
        Atom                    kill_type;
        int                     (*oldHandler)(Display*, XErrorEvent*);
        Window                  r;
        int                     x, y;
        unsigned int            w, h, b, d;
        Status                  s;
    
    #if !defined(X_NOT_POSIX)
        srand((int)time((time_t *)NULL));
    #else
        srand((int)time((int *)NULL));
    #endif
    
        toplevel = XtAppInitialize (&app_con, "udooGPIOblanker", NULL, ZERO,
                                    &argc, argv, NULL, NULL, ZERO);
        display = XtDisplay (toplevel);
        root = DefaultRootWindow (display);
        screen = DefaultScreen (display);
        scr_wid = DisplayWidth (display, screen);
        scr_hei = DisplayHeight (display, screen);
        if (!XScreenSaverQueryExtension (display, &ss_event, &ss_error))
            exit (1);
    
        oldHandler = XSetErrorHandler (ignoreError);
        if (XScreenSaverGetRegistered (display, screen, &kill_id, &kill_type)) {
            s = XGetGeometry(display, kill_id, &r, &x, &y, &w, &h, &b, &d);
            if (s == True && r == root && w == 1 && h == 1 && d == 1) {
                /* Try to clean up existing saver & resources */
                XKillClient (display, kill_id);
                XScreenSaverUnregister(display, screen);
            }
        }
        XSync(display, FALSE);
        XSetErrorHandler(oldHandler);
        XScreenSaverSelectInput (display, root, ScreenSaverNotifyMask);
    
        blank_pix = XCreatePixmap (display, root, 1, 1, 1);
        XScreenSaverRegister (display, screen, (XID) blank_pix, XA_PIXMAP);
    
        info = XScreenSaverAllocInfo ();
        XScreenSaverQueryInfo (display, root, info);
        mask = 0;
        attr.background_pixel = black_pixel;
        mask |= CWBackPixel;
        attr.cursor = XCreatePixmapCursor (display, blank_pix, blank_pix, &dummyColor, &dummyColor, 0, 0);
        mask |= CWCursor;
    
        XScreenSaverSetAttributes (display, root, 0, 0,
            DisplayWidth (display, screen), DisplayHeight(display, screen), 0,
            CopyFromParent, CopyFromParent, (Visual *)CopyFromParent, mask, &attr);
    
        XSync (display, False);
    
        XSetErrorHandler (ignoreError);
    
        DPMSEnable(display);
    
        saver = info->window;
        if (info->state == ScreenSaverOn)
        {
            if (info->kind != ScreenSaverExternal) 
            {
                XResetScreenSaver (display);
                XActivateScreenSaver (display);
            }
            StartSaver ();
        }
        for (;;) 
        {
            XtAppNextEvent (app_con, &event);
            if (event.type == ss_event) {
                sevent = (XScreenSaverNotifyEvent *) &event;
                if (sevent->state == ScreenSaverOn) {
                    if (sevent->kind != ScreenSaverExternal) {
                        XResetScreenSaver (display);
                        XActivateScreenSaver (display);
                    } else {
                        StartSaver ();
                    }
                } else if (sevent->state == ScreenSaverOff) {
                    StopSaver ();
                }
            } else {
                XtDispatchEvent(&event);
            }
        }
    }
    
     

    Attached Files:

  13. hillcz

    hillcz Member

    Joined:
    Oct 3, 2013
    Messages:
    72
    Likes Received:
    1
    thx
    perfect!!!
    note : in ubuntu add libxt-dev
     
  14. hillcz

    hillcz Member

    Joined:
    Oct 3, 2013
    Messages:
    72
    Likes Received:
    1
    note:
    for 15.6 inch set GPIO to 2
     

Share This Page