segunda-feira, 9 de fevereiro de 2009

Joule Thief


Havia visto esse circuito há um tempo no instructables.org e fiquei curioso em entender como ele funcionava. Esse final de semana acabei montando e testando.

Há muita controvérsia na Internet sobre o seu funcionamento. Uns dizem que ele é um oscilador de relaxação, enquanto outros dizem que se trata de um oscilador de bloqueio ou oscilador Hartley. Muita especulação inclusive sobre o valor da indutância do transformador (ou seria uma bobina com tap central?).

O circuito, em carga, é, na verdade, um oscilador astável, controlado por um transformador de pulso entre o coletor e a base. O lado do coletor opera como um conversor boost em modo fly-back de corrente descontínua.

Sabendo disso, fiz algumas melhorias no circuito básico:

  1. Coloquei um retificador, feito com diodo schottky e um capacitor, para melhorar o ripple.
  2. Coloquei um capacitor de 1n em paralelo com o resistor da base, para melhorar o tempo de transição do transistor.

O resultado pode ser visto abaixo, com 4 LEDs em série sendo iluminados por uma única pilha NiMH (que estava descarregada!). Muito legal!!

Posted by Picasa


Posted by Picasa

Decomposição LU funcional

Semana passada escrevi um código para a decomposição LU puramente funcional.



{-
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
.

-}

import Data.Array.IArray

type Dim=(Int,Int)

lu::Array Dim Double -> (Array Dim Double,Array Dim Double)
lu a =(aa l,aa u)
where
(l,u)=lu' a [] []
aa = accumArray (+) 0 (bounds a)
lu'::(Floating e) => Array Dim e
-> [(Dim,e)]
-> [(Dim,e)]
-> ([(Dim,e)],[(Dim,e)])
lu' a l u=if (ui==li)
then ( ((ui,uj),1.0):l,((ui,uj),a!(ui,uj)):u)
else (lu' an (l++ln) (u++un))
where
k=li
((li,lj),(ui,uj))=bounds a
lik i=(a!(i,k)/a!(k,k))
un=[((k,j),a!(k,j)) | j<-[lj..uj]]
ln=((lj,lj),1.0):[((i,k),lik i) | i <- [li+1..ui] ]
an=array ((li+1,lj+1),(ui,uj))
[((i,j),e_an i j) | i <- [li+1..ui] , j <- [lj+1..uj] ]
e_an i j=a!(i,j)-(lik i)*a!(k,j)



Esse código usa a forma KIJ (ver Matrix Computations, de Gene Golub), que atualiza todos os valores de forma imediata. Essa forma permite a implemntação recursiva que eu usei, e permite que seja implementado o pivotamento parcial.

Um cara chamando Matt implementou algo semelhante em uma biblioteca de DSP (Matt's Haskell DSP Library), mas ele usou uma versão de produtos internos (IJK) que torna o pivotamento mais complicado. De qualquer forma, vale a pena dar uma olhada, pois é um dos códigos mais elegantes que já vi em Haskell...



lu a = a'
where
a' = array bnds [ ((i,j), luij i j) | (i,j) <- range bnds ]
luij i j | i>j = (a!(i,j) - sum [ a'!(i,k) * a'!(k,j) | k <- [1 ..(j-1)] ]) / a'!(j,j)
| i<=j = a!(i,j) - sum [ a'!(i,k) * a'!(k,j) | k <- [1 ..(i-1)]]
bnds = bounds a

Postagens populares