-->

samedi 5 mars 2016

AC powered LED ( part 1 ) [ LED sur tension secteur ] : theory and my realisation


I - Disclaimer



ALL ELECTRIC CIRCUITS PRESENTED HERE HAVE ONLY A PEDAGOGIC PURPOSE. DON'T BUILD THEM. EXPERIMENTING WITH HIGH VOLTAGE CAN BE LETHAL.


II - Preamble


I was so surprised to see on this page that LEDs could be lit up from a house's main electrical supply only with a few electronical components - and especially with no electrical transformer. Lets see how it is possible.


II.1 - LED characteristic

Fig 01
A LED will let the current flow throuh it only if the voltage across its bounds is > the LED treshold voltage, that we will call \(u_{d0}\). Its v,i relation (R) can be taken as :
  • \( u_d<u_{d0} : i=0 \)

  • \( u_d<u_{d0} : i=K \times ( u_d-u_{d0} ) \)

  • \( K=0.03 ; u_{d0}=0.7V \)
For lighting up the LED without damaging it, voltage must be :
  • > LED treshold
  • not too high, else the current will burn it
Which is equivalent to say that current must be :
  •  positive
  • not too high, else it will burn the LED
We also remark that :
  • a small variation of V induce a big variation on i
which is equivalent to say that :
  • a big variation of i induces only a small variation on v

II.2 - Power characteristic

We will use the french 220 VAC, 50 Hz power supply :


Fig 02

 which equation will be taken as  \(A(t)=A_0 \times sin( \frac{2 pi}{T} \times t)\), with
  • A0=325 Volts 
  • T = \(\frac{1}{f}\) = 0.02 s




III - LED on AC


Consider this circuit :
Fig 03

What happens ?

Let be t=0.0005 s. We have A=50.82 V. Given the characteristic of the LED, you can see that the current will be very high - the LED is destroyed.

So we need a supplementary device on the circuit that maintains either the  tension or the current in the LED's safety operation area ( SOA ). A condensator will match that, and we will see why.


IV - Adding a condensator



Let's take the following circuit,
Fig 04
and see what happens.


IV.1 - Establish the interesting equation

Characteristic relation of a condensator is :
  • [R0] \( i_c(t)=C \times \frac{du_c(t)}{dt} \)
We have the two classical equations from the mesh & nodes laws :
  • [R1] \( i_c(t)=i_d(t) \)
  • [R2] \( u_c(t) + u_d(t)=a(t) \)
Combinating [R0] and [R2], we get : \( i_c(t)=\frac{d}{dt}( a(t) - u_d(t) ) \)
=>\( i_c(t)=C\left( \frac{d}{dt}( a(t) - u_d(t) ) \right) \)
=>\( i_c(t)=C( \frac{d}{dt}( A_0 \times sin(wt) ) - \frac{d}{dt}( u_d(t) ) ) \)
=>\( i_c(t)=C A_0 w \times cos(wt) - \frac{d}{dt}( u_d(t) ) \)
Combinating with [R1], we finally get :
\( i_d(t)=C A_0 w \times cos(wt) - \frac{d}{dt}( u_d(t) ) \qquad \mathbb(R3) \)
( Please note that since the LED characteristic is composed of 2 distincts regions, there is no global equation for describing it mathematically ; so it is kept "as is" )

IV.2 - Resolve

At t=0, a(t)=0 and start to increase.

* Lets suppose \(a(t)<u_{d0}\)
  • the LED is blocking current ( because a(t) is shared between the LED and the capacitor, so \(u_d(t)<u_{d0}\) too ).
  • Since the LED is blocking current, remembering [R0] means that \(u_c(t)\) is constant.
  • And since the voltage at terminals of a capacity is continuous, and that at t=0 the capacitor is discharged, \(u_c(t)\) is zero.
So if \(a(t)<u_{d0}\), \(u_c(t)=0\). The LED is carrying all the power source tension.


* Now suppose a(t) reaches \(u_{d0}\) : \(a(t)>=u_{d0}\) ; using [R3] :
\(i_d(t)=C A_0 w \times cos(wt) - \frac{d}{dt}( \frac{i}{K}+u_{d0})\)
\(i_d(t)=C A_0 w \times cos(wt) - \frac{1}{K} \qquad \mathbb(R4) \)
Since cosinus is limited by 1, If we choose C judiciously,
  • \(i_d(t)\) will stay in the SAO for the LED
  • we shall be able to neglect \(-\frac{1}{K}\)
Here is all the magic :



  • in sinusoidal mode, the sin and cos functions are limited
  • the LED has a quasi-NULL resistance \( \frac{1}{K} \) ( rotate the LED characteristic by 90° to see that )
  • ( Physically talking, the LED oppose no resistance to the current, so the current is determined by the capacitor. Since sin / cos function are limited, we only need to choose a good C value to keep the current in the LED's SOA ).

    * So,the capacitor gets charged through the LED. As soon as a(t) starts to decrease, the capacitor should discharge ; but the doesn't allow a reverse current ; so the capacitor stay charged, and the LED blocks.

    * When a(t) starts to grow again, nothing happens, because the capacitor is already charged.

    IV.3 - Values

    Using (R4), we get : \(C=\frac{0.020}{325*2*3.14*50}  =1.96e-7 \approx 2e-7 = 0.2uF = 200nF\)
    So we are gonna use the normalized value 220nF for C.

    IV.4 - Simulation


     Here is a simulation done with the excellent gEDA and ngspice softwares :
    
    
    Fig 05 Fig 06

    We can zoom the first 20 microseconds to see the LED becoming non-blocking at nearly 0.7V, and the capacitor starting charging:
    Fig 07

    Now focus on the current, its maximum is about 22mA, which is good for a LED ( it is negative because I think ngspice takes the generator convention, I begin with gEDA and ngspice ):
    Fig 08

    IV.5 - Remarks


    IV.5.1 - Focus on a \(u_d(t) \approx u_{d0} \)

    When \( a(t) < u_{d0} \), i is zero.

    When \( a(t) > u_{d0} \), i is not zero. But what about  \( a(t) = u_{d0} \) ? \( i=CA_0w \times cos(wt) \) with \( t \approx 0 \) ; so \( i \approx CA_0w \), which is far from zero. In fact \( u_c(t) \) is not mathematically derivable for \(u_d(t)=u_{d0} \), so i(t) is not continuous at this point.

    That's why you see on Fig 08 i growing quasi-instantaneously from 0mA to 23mA, then growing down to stabilize to 22mA. On the LED characteristic below ( Fig 09), phase 1 is the growing a(t) before it reaches \(u_{d0}\), the current discontinuity is the discrete jump from phase 1 to phase 2, and the stabilization is phase 2.
    Fig 09
    In reality, the capacitor has a small resistance, the wires of the circuit have a resistance, so current is not discontinuous, but have the form of a line with a huge slope.

    IV.5.2 - Reverse tension problem at LED's terminations

    As said above, you can see the voltage at LED terminations growing down up to -600 Volts. Thats a problem because LEDs only accept a reverse tension up to -5, -10, -15 Volts.


    V - Resolving the huge reverse tension problem at LED's terminations


    The problem is that the capacity is not discharging. Ideally, when a(t) goes negative, the capacitor should act as a generator, discharging itself and compensing the negative values of a(t).

    Resolving this is as simple as putting a second LED in parallel with the first one that allow the current flowing in both directions.
    Fig 10 Fig 11

    As you see, the tension across LEDs terminals are now clamped.


    VI - Finally - adding resistors

    We have to add resistors for three reasons :
    1. Your AC input may vary, due to electric network fluctuations
    2. Handling the so-called "inrush currents" ( see IV.5.1  for example )
    3. Allow capacitor to discharge when circuit is powered off
       
    For 1. and 2., the resistor will be serial with the 2 diodes and have a value of 2kOhms ( so that they dont have a too high tension at their terminals, for low power dissipation )

    For 3., the resistor will be parallel with the capacitor and have a value of 1MegaOhm ( for not disturbing the running of the circuit ; the current flowing through it will be neglectable in regard of that flow through the LEDs )

    So you get the final circuit :
    Fig 12 Fig 13


    Does it work ? Yep, here is a quick & dirty realisation :

    2 capacitors of 100nF,250VAC ( 200nF instead of 220nF ), 7 resistors of 100ko each ( 700ko instead of 1Mo ), 2 cheap blue LEDs, 1 resistor of 2ko ; all the stuff plugged on the french 230VAC. ( the burned marks are from other circuits, some TIP142s died there )

















    dimanche 20 juillet 2014

    vendredi 11 juillet 2014

    Linux Hybrid Graphics : INTEL HDGraphics Display and AMD Radeon Headless OpenCL

    My goal is to run xorg on my integrated INTEL HD200 card, wired to a monitor, while running OpenCL applications on my PCIe AMD Radeon HD6670, whith no monitor attached.
    I am writing this post while I am testing.

    Setup:


    Debian wheezy amd64

    Kernel : 3.15.5

    Card0: Intel HDGraphics 2000
    Driver : from Wheezy

    Card1 : Radeon HD 6770
    Driver : Catalyst 14.4

    I use Lightdm as my DisplayManager

    AMD APP SDK not installed, Catalyst provides libOpenCL, clinfo, libamdocl64, ...

    Preambule :


    Ensure my software installation is OK :
    • ensure I can have xorg running on Card0
    • ensure I can have xorg running on Card1
    For this, I need to have 2 xorg.conf files, one per card. 

    From this point I have interesting results :
    • xorg on Card0 : from an xterm, clinfo sees only one cl device : INTEL corei3
    • xorg on Card1 : from an xterm, clinfo sees two devices : INTEL corei3 and AMD GPU

    1 : one xserver and two drivers simultaneaously


    This leads to the proprietary libs problem :
    • Intel driver uses opensource libs ( libGL, etc )
    • AMD driver uses its own libs ( libGL, libglx, libGLEW )
    So the 2 drivers loaded in the same xorg server is impossible ( leads to segfaults )

    2 : An interesting thing

      

    2.1 by accident

    As I was testing, I was lead to boot on recovery mode ; and this is what I've found :
    As root on recovery console , I run clinfo ; and magically clinfo sees two devices : INTEL corei3 and AMD GPU. Xorg is not started at this point.And fglrx throw me some logs directly in the console :

    FireGL : Kernel Thread PID ...
    IRQ 47 enabled
    Reserved FB Block : shared ...
    Reserve FB Block : unshared ...
     
    After closing the recovery console, boot process continues, I log in and  :
    • clinfo still sees my two cl devices in a tty ( Ctrl + Alt + F1 )
    • clinfo segfault in an xterm

    I run :
    in tty1 : strace clinfo > clinfo.tty.txt 2>&1
    in xterm : strace clinfo > clinfo.xterm.txt 2>&1

    And use meld on the log files  ; basically the main difference is that at one point :
    • in tty1 clinfo open /dev/ati/card0
    • in xterm clinfo try to connect to the xserver, then segfaults.

    Edit : this is because the environment variable COMPUTE is not defined. 
    export COMPUTE=:i 
    ( where i is the number of your xorg server ) resolves this issue ; but only the CPU device is seen.

    At this point, am I able to run a true OpenCl application on virtual tty1 whereas xorg runs ?
    The response is : YES :)

    I take a simple "hello world" OpenCL program, modify it to ensure it will select a CL_DEVICE_TYPE_GPU, and its OK. BUT...

    2.2 root / non-root

    ...I have to execute it as root ; as a normal user, it sees no devices at all.

    So lets investigate that ; I do

        #./helloworld > sample.root.log 2>&1 
        $./helloworld > sample.root.log 2>&1
    

    Then a meld on the log files shows two ioctl() problems :
        ioctl(5, 0xc0586450, 0x7fffae16dba0)    = -1 EACCES (Permission denied)
        ioctl(6, 0x80146454, 0x7fffae16dc90)    = -1 EACCES (Permission denied) 
     After googling ioctl(), I found that the interesting part of the command is the lower 16-bits word of the 2nd parameter, so I googled ioctl 0x6450 and got this :
        {"drm/radeon_drm.h",    "DRM_IOCTL_RADEON_CMDBUF",      0x6450},
        {"drm/radeon_drm.h",    "DRM_IOCTL_RADEON_FREE",        0x6454},
    
    Further investigations leads to this:
    DRM_IOCTL_DEF_DRV(ioctl, func, flags)
    ... 
    flags is a bitmask combination of the following values. It restricts how the ioctl is allowed to be called.
          DRM_AUTH - Only authenticated callers allowed
          DRM_MASTER - The ioctl can only be called on the master file handle
          DRM_ROOT_ONLY - Only callers with the SYSADMIN capability allowed
          DRM_CONTROL_ALLOW - The ioctl can only be called on a control device
          DRM_UNLOCKED - The ioctl handler will be called without locking the DRM global mutex
    
    Due to the possibility of DRM_ROOT_ONLY call, I get aroud the problem for the moment by setting setuid bit :
        #chown root:root helloworld
        #chmod o=rwx helloworld
        #chmod u+s helloworld
    

    this lead me to try this :

    2.3 normal user on AMD only xserver( which is not the goal )

    It works perfectly !

    3 : Back to main goal


    • Section 2 seems to indicate that an OpenCL app has to connect to Xserver to run, and not connect directly ( i.e. via OpenCL SKD ) to drm devices
    • Section 1 proove that one xserver can not achieve this
    So lets try two xservers ?

    OK, but instead of having one xserver needing access to two different versions of some libraries ( libGL.so for exmaple ), I shall have two xservers needing access to two different versions of some libraries ! Solution ?

    • using LD_PRELOAD or LD_LIBRARY_PATH  : for instant it does not work, and I'm afraid of some hard-coded file loadings in the graphical stack.
    • using a chroot ( more later... )
    I finally succeeded in running simultaneously :
    • one xorg with Card0 on a monitor, in my standard environment, with OpenGL enabled, and even Compiz. I name this display :0
    • one xorg with Card1 without monitor ( VGA & HDMI connectors empty ) , in a chrooted environment. I name this display :1 



    But for instant doing 
    #export COMPUTE=:1
    #clinfo
    
    in the chrooted environment just stucks, either on a tty console or a xterm on display :0 ( more later... )

    4 : Finally


    The only way I found to run OpenCL apps on my Radeon HD6670 while displaying my usual stuff on my HDGraphics 2000 is to run the app as root on a tty, as mentionned in 2.1.

    n.b. : One last thing, if I run the OpenCl app in a tty, while no xorg server is running ( /etc/init.d/your-display-manager stop ), my 2 devices are seen.

    Hope this can help others in hybrid graphics configs.