Monday, July 8, 2013

Voltage Divider, Charge Divider, Current Divider?

The Voltage Divider is a very simple circuit, accompanied by a simple equation. But, did you know this equation isn't limited to just a couple of resistors in series?

The picture can do all the talking:

I noticed this while studying for my AP Physics exam (which I got a 5 on, I happily note). I figured, V = I*R and Q = V*F are such similar equations--why can't the voltage divider equation apply to capacitors?

Resistors in series are analogous to capacitors in parallel (both properties, resistance and capacitance, respectively, add in these configurations), and vice versa (both are the inverses of the sums of the inverses of the respective properties in those configurations).

And I wondered if somehow I could use a ratio for resistors in parallel, and capacitors in series. I can.

Saturday, June 8, 2013

[Python] Livestream and -- Check if Live

I recently switched from iOS to Android, and one of the apps I had used on iOS was the mobile Livestream app. One feature was the ability to follow channels, and I liked to follow channels to see how some of my favorite artists draw--techniques and whatnot. (Also some other random channels whose content I might enjoy).

So anyway, I lost the ability to do this, since I couldn't find an equivalent app on Android. Apparently on the PC, one could make a "New Livestream" account to follow, but I don't wanna.

Solution? Make some code!

My computer-science-major friend had once told me about Python, a pretty (really) versatile scripting language. What better way to learn about this awesome language?

My code follows:
#Henry Choi
#checks if livestream is live

import json
import urllib2
import webbrowser

#read some files
read = open('livestream channels.txt','r')
str1 =

read = open('justin-twitch channels.txt','r')
str2 =

#create a 2D array| columns:3, rows:number of streams
info = [['' for j in range(3)] for i in range(len(str1+str2))]
#info = [['']*3]*len(str1)    |doesnt work|

#get the channel information

for i in range(len(str1)):
    #get and parse json
    url3 = urllib2.urlopen('' % str1[i]).read()
    asd = json.loads(url3)
    info[i][0] = str1[i]    #save stream name
    info[i][2] = asd['channel']['currentViewerCount']    #save stream viewer count
    if asd['channel']['isLive']:    #if live
        #mark as live
        info[i][1] = 1
        info[i][1] = 0
for i in range(len(str2)):
    url3 = urllib2.urlopen('' % str2[i]).read()
    asd = json.loads(url3)
    info[i+len(str1)][0] = str2[i]    #save stream name
    if asd:        #if live
        info[i+len(str1)][1] = 1    #mark as live
        info[i+len(str1)][2] = asd[0]['channel_count']    #save stream viewer count
        info[i+len(str1)][2] = 0

#print info
print ('''
Enter the number to view the stream.


for i in range(len(info)):
    print (str(i+1).rjust(5)+':  %s %s \t%s' % ('*' if info[i][1] else ' ', info[i][2], info[i][0]))
print ('')

option = 1
while option != 0:
    option = input('Enter the number: ')
    if option == 0:     #just exit
    elif option in range(len(str1)+1):    #livestream from 1 to n''+info[option-1][0])
    elif option in range(len(str1)+1, len(str1)+1+len(str2)): from n to last''+info[option-1][0])
('Invalid choice. Please choose a correct one.')

And there it is!

txt files named "livestream channels.txt" and "justin-twitch channels.txt" should have the channel names of the appropriate streaming service, separated by new lines. They exist in the same folder as the python script.

Monday, April 22, 2013

iPad Retina a Computer?

Well, it's a small world isn't it? Someone has already beat me to it :P

Anyway, this is my take on it

 This display is at 100% zoom. Look how tiny that Wikipedia logo is!

Upside-down. Nothing some good software can't handle though!

The full setup.
The logic voltage is 3V3, and I'm driving all of the LEDs in parallel (I know, it's bad practice) with 24 Volts and 16K Pot (measured to be around 100 Ohms) in serial.

Thanks to:
My dad for buying the parts, instilling my love for electronics in me, and supporting me all the way
OSH Park for supplying the PCBs (highly recommend them)
Apple for commissioning LG to make the panels
VESA for standardizing everything, making it super easy to do this

I must say, there is a point of vanishing returns for amount of screens attached to one computer o.o

Tuesday, January 29, 2013

Bit Angle Modulation using Arduino

So I always wanted to replace my fluorescent lighting with RGB LED strips for those friday night parties because that would make waking up a bit more pleasant. You can wake up to some light instead of jarring noise... (Right now I use my computer to play some Pandora Radio dubstep at 7:20 am, but I digress.)

Anyway, I want my lighting to follow f.lux's principles, too (f.lux. Highly recommend this): nice, cool blue in the morning/afternoon, and a warm white in the night.

So yeah, color temperatures to RGB. BUT HAO 2 GET VALUES?
Don't worry, hex codes here.

Now, all I need are the actual RGB strips, and some CODE to use with a MICROCONTROLLER.
And some MOSFETs... and a 12v power supply... 
Oh, and RF links, since I want to use multiple strips in my room.
And some way to connect the microcontroller to my router, since I want to be able to change my lighting through a website.
Don't steal mah idea D:< .. actually I encourage you to do it! Send me a link if you do!

But before I buy hundreds of dollars worth of RGB LED strips, I've decided to make the code.

I was planning to use some Attiny85s, and those only have 2 PWM outputs. HOW 2 GET 3?
Well that's where software comes in. But software PWM takes a toll on the microprocessor.

Solution? Use bit angle modulation.
This thread explains it very nicely.

Or this picture. Either works I suppose.

So yeah, pretty much like that.

Next, I'll try to figure out how to make a function for this that supports multiple outputs, making them ride on the same modulation.
Also maybe I could make the microcontroller calculate stuff during Bit 7 using millis(), reducing overhead.

I'm not 100% sure if the Attiny85 will work, but WHATEVER. I have a couple of Attiny44s. :D

No extra hardware needed if you're using Arduino Uno or something.

Henry Choi
BAM LED dimmin'

Moar Info:

const int R_pin = 13;
const int period = 10;    //in microseconds - 20 is a 195.3125Hz period

//***Starting Stuffs*** 

//unsigned long time;
byte R_brightness = 0;

void setup() {

  pinMode(R_pin, OUTPUT);


void loop() {

  R_brightness = (pow(2, cos(millis() / 500.) ) - 0.5) *  (255) / (2 - 0.5);

  //a cosine function for fading (shamelessly stolen from my PSU project)
  //exponential to compensate for LED logarithmic brightness

  for (int multiplier = 0; multiplier <= 7; multiplier++) {
    if (R_brightness & 1 << multiplier)

      // Here, I use '<<' so that the bitwise operator '&' can be used. I use '&' as a mask.
      digitalWrite(R_pin, HIGH);
    delayMicroseconds(period << multiplier);
    // '<<' simply means to multiply by 2^[whatever on the right side]
    digitalWrite(R_pin, LOW);

/* If you want to do that mirroring thing that's addressed in the forums linked above, uncomment this part. Although, I personally don't see the blinking...
  for (int multiplier = 7; multiplier >= 0; multiplier--) {
    if (R_brightness & 1 << multiplier)

      digitalWrite(R_pin, HIGH);
    delayMicroseconds(period << multiplier);
    digitalWrite(R_pin, LOW);

Oh internet you so smart.

Tuesday, June 12, 2012

Overriding PSU Safety Features

So I have one of those computer PSUs that I converted into a "bench power supply;" not really that elegant, but it does the job. However, when I pull too much amps from it, it shuts off. This is a good thing, but one annoying part of it is that I have to disconnect the green wire from ground to reset the safety feature. Especially annoying when both my hands are occupied, holding wires to a capacitor.

I did the only sensible thing and overrode that safety feature, with the help of a certain programmable chip.

(Courtesy of ~underitall from DeviantArt.

My very professional-looking schematic of the circuit.

Pin 1 - D/C
Pin 2 - Input - Button with pull-down resistor (1KΩ Brown Black Red)
Pin 3 - Input - Red Wire (+5 VDC from PSU)
Pin 4 - Ground
Pin 5 - D/C
Pin 6 - Output - Status LED
Pin 7 - Output - Green Wire (PSU Power control)
Pin 8 - Vcc - Purple Wire (It provides +5 VDC even if the PSU is "off")

Prototype stage

Perfboard stage

  • When I just press the button, the PSU turns on, no safety features overridden. (State 1)
  • When I press and hold the button while the unit is on, the safety features are overridden. In this stage, the LED continually fades in and out, notifying the user of the possible danger that could occur. (State 2)
  • When the button is pressed again, the unit reverts back to ON. (State 1)
  • When the button is pressed once again, the unit turns off. (State 0)
When the green wire is provided +5 VDC (current sourcing), the PSU views it as disconnected, as when it isn't connected to anything, the voltage on the green wire is +5 VDC.
When it is pulled down to ground (current sinking), the PSU turns on.

And finally, here is the code:
(Get the Bounce Library here:

#include <Bounce.h>

#define pinLED 1
#define pinCtrl 2
#define pinButton 3
#define pinPower 4
int brightness = 0;
int state = 0; //0 is off, 1 is on, 2 is power

long timecurr = 0;
long timelater = 0;
#define period 500
#define holddown 1000

Bounce button = Bounce(pinButton,5);

void setup(){
  pinMode(pinLED, OUTPUT);
  pinMode(pinCtrl, OUTPUT);
  pinMode(pinButton, INPUT);
  pinMode(pinPower, INPUT);

void loop(){

  timecurr = millis();

  if(state == 0){
    digitalWrite(pinCtrl, HIGH);
    digitalWrite(pinLED, LOW);
    while( == HIGH){
      if( == LOW){
        state = 1;
  else if(state == 1){
    digitalWrite(pinCtrl, LOW);
    digitalWrite(pinLED, HIGH);
    timelater = timecurr;
    while( == HIGH){
      timecurr = millis();
      if(timecurr - timelater > holddown){
        brightness = 128+127*cos((2*PI*millis())/period);
        analogWrite(pinLED, brightness);
        state = 2;
      if( == LOW && state == 1){
          state = 0;
    brightness = 128+127*cos((2*PI*timecurr)/period);
    analogWrite(pinLED, brightness);
    digitalWrite(pinCtrl, LOW);
    timelater = timecurr;
    while(digitalRead(pinPower) == LOW){
      digitalWrite(pinCtrl, HIGH);
      timecurr = millis();
        timelater = millis();
        brightness = 128+127*cos((2*PI*millis())/period);
        analogWrite(pinLED, brightness);
      while(timelater - timecurr < 500);
      digitalWrite(pinCtrl, LOW);
      timecurr = millis();
        timelater = millis();
        brightness = 128+127*cos((2*PI*millis())/period);
        analogWrite(pinLED, brightness);
      while(timelater - timecurr < 500);
    while( == HIGH){
      if( == LOW){
        state = 1;


Special Thanks to:

My computer science major friend for helping me debug the code

MIT's High Low Tech for their tutorial on putting Arduino on the Attiny.
My brother for buying me an Arduino for Christmas!
Hack-a-Day for featuring me! Click here.

Thursday, March 1, 2012

Mounting a Card Reader under the Desk

Reattaching the wires to the header

 Don't want to drill too far in!

Making sure that the drill bit isn't wider than the threads