Sunday, December 11, 2011

Audio Delay

I've always wanted to build an audio delay box, something that would take an audio input (mono or stereo) and delay it by some variable amount (user determined). Why? Because when I've watched the Saturday afternoon game and the baseball playoffs for my home team (SF Giants), I realize just how lousy those national league announcers are. But, playing an out of sync radio broadcast with the TV broadcast is the stuff of nightmare. The radio is always ahead of the TV broadcast because the radio is transmitted locally and the TV broadcast goes around and around, up and down, cable, satellite, whatever.

So, I need an audio delay device. The Arduino family seems like a great place to start building such a device. Just before starting to build this project, I looked around to see if anyone had built one of these. There are plenty of options for products between $60 and $200 that delay between 1 second and 1 minute. I found one product that could delay up to 20 minutes.

I only need a delay of max 5 seconds, but I'm an engineer, so as big as I can make it will make me happy. Plus, I need to build it for less than $60 in parts, or I might as well buy it. Actually, that's not exactly true, any cost over $60 pays for my enjoyment in building the project, but you get what I mean.

If I use the Arduino (or the Mega) that's half or all of my budget, so this engineering process should get interesting.

I have a few ideas for designs and will make follow up posts detailing them with some pros and cons. In short, here's what I've thought through so far:

  1. ADC -> MEM -> DAC + CPLD/FPGA + Arduino
  2. ADC -> Flash Mem -> DAC + CPLD/FPGA/Arduino
  3. ADC -> MEM -> DAC + Arduino Mega (which has lots of address pins)
  4. Delta-Sigma Modulator + Delay Queue (implemented w/ Arduino + majolsurf mem expansion)
For MEM, I was thinking of an old DDR2 board.

Basically, the designs come down to some combination of the following elements:
  • An Analog to Digital Converter that outputs one or two channel (mono v. stereo) and 1 bit or N bit (generally, 16 bits). However, even the N-bit ADCs really stack up 1 bit outputs and then release them as N bits, but on a serial line! Therefore, the N-bit ADCs are simply bursty one bit ADCs. None of them have 8 or 16 parallel output, so their output needs to be thrown into a shift register if to be used in parallel.
  • A Digital to Analog Converter (1 bit or N bit). If data held in parallel, then it needs to be placed in an SR and sent to DAC, serially. N-bit DACs don't accept input in parallel.
  • Memory
    • Flash memory accepts input as a bit stream and it should be in page chunks, that is, written or read sequentially. Flash memory really isn't meant to be Random Access, or least NAND based flash isn't.
    • DDR2 has some interesting requirements (a section of low addressed memory that is off limits for storage) and 200 PINs to drive or read. The Arduino Mega could run a DDR2 board.
  • Data Transfer Protocols
    • I2C or SPI or Parallel or NIH (Not Invented Here or Roll My Own).
    • The challenge of the first two are lack of familiarity and/or speed limitations.
    • The challenge of the second is a heck of a lot of wiring - ugh!
    • The challenge of the third is inventing a stable (serial) protocol better than I2C or SPI.
  • Delay Control - one or two knobs that allow the user to dial in a delay (coarse/fine grained delay). It would be great if the delay could be from sub microsecond up to limit of the system. Also, if the system delay maximum is large, the coarse grained control should be non-linear in response (smaller steps closer to zero).
  • Display Delay - it would be nice if the user could see how much of a delay the system was using.
    • Controller/Control Signaling - somehow, all of these elements need to communicate with each other and do the delay work.
    In the end, the system converts analog voltage levels into frequency bit streams that get delayed then returned back into a voltage signal. Everything else is just implementation.

    Sunday, December 4, 2011

    Hardware Hacking

    There are some fabulous hardware devices out there for hardware hacking - it warms my EE heart. Having been out of the field for decades (really, only played with this stuff in college and high school), I'm enjoying getting back into things.

    That said, folks who've never studied the material before can still play.

    First, get yourself and arduino or similar device.

    Then, learn some basic electronics - youtube is a great place to start.

    Then, build and enjoy...

    Tuesday, November 29, 2011

    Watch a Memory Bit Switch

    Want to watch a memory bit flip at the atomic scale?



    Friday, October 7, 2011

    Brown Fox and Lazy Dog

    I saw this video and it reminded me of my early computer days. My father owned a computer time share business; companies ran their business on software designed and built by my father's software team on computers maintained by the company. It was the first cloud. Of course, it wasn't called that then. It was called time share, which was invariably mistaken for vacation property.

    How could this video possible trigger that?

    The jump happens around 1:20 mark.

    I worked at my dad's office in the summer between high school. They had IBM key punch machines. You'd bang out something in numbers and letters on the machine and it would produce a card with the characters printed on top and machine readable holes printed on the body of the card. My father's company produced a piece of hardware that meshed with the key punch interface and caused the machine to read or write cards. You had to pop a plate off the back of the machine and wire the device in there. There were hundreds of pins sticking up, but only forty or so were relevant.

    The device converted card data back and forth into RS-232, which at the time was the new plug-in standard between computer devices. Now, we have USB, Parallel, Serial (RS-232 was serial), FireWire, Wireless, etc. To test each hand built device they manufactured, you'd have a stack of cards with the alphabet and numerals on them, each one shifted in a loop (A-Z0-9 then B-Z0-9A, etc.). Sometimes, if you wanted to do a quick check, you'd type in "The quick brown fox jumps over the lazy dog."

    I helped build some of those devices, soldering them together at a workbench. The main builder, Freida, taught me how to solder. Earlier in her career, she worked on space hardware and missile electronics. When the electronics were soldered into boards for a missile special care had to be taken because of the vibrations from the missile's engine. Little double bends were made into each resistor, capacitor and inductor leg, that became springs to dampen the vibration. She built every device that way and made sure I did, too. Between her hardware production talent and the software designer who wrote the code that ran the box, those things were bomb proof.

    Companies all over the world bought the device. The company saw the future of computers and realized that other companies would want to take all of their punch card data and convert it into some other electronic format (magnetic tape and disk drives). But, that's not exactly what happened. Many of their customers had processes that centered around punch cards. For a manufacturer, the cards represented a pick list and notes could be made on the cards by hand. They were a physical token that was also machine readable. Think of today's 1D and 2D bar codes.

    These devices were built in the early 1970s and 1980s. I think years later one of the companies called him to ask if it was year 2000 compliant. Ha.

    The smells in that office were stunning, not in a bad way. The company was located in the basement of an apartment building. They had three large HP computers, bays of disk drives that would be laughable today due to their very small storage capacity. There's more computer power and storage in an iPod nano than was in that whole basement. There were teletype machines, hardware workbenches, and free coca-cola, BBQ potato chips and pretzels. The place smelled of ozone and machine oil and solder flux and bbq. There was a constant churning and humming going on from the teletypes, disk drives and magnetic tape.

    It's amazing what that little basement operation had going on inside of it. It was at the forefront of so many of the technologies that we see around us, today. Cloud, data centers, business accounting and manufacturing software, free goodies for the staff. All of that was going on forty years ago.

    The quick brown fox jumps over the lazy dog, indeed.

    Wednesday, October 5, 2011

    RIP Steve

    Monday, September 5, 2011

    Sims Social Addiction


     "Hello, Andy."










    This is when things began to go off the rails.








    Then, it all changed. It’s last night:







    Wednesday, July 13, 2011

    Vodaphone Hack

    If you follow mobile phone security (or haven't been on vacation), you've read about THC's Vodaphone hack by now. Although I shouldn't be surprised, it continually astounds me how companies make such poor security design decisions. Of course, then I realize that this was not a design decision as no security expert could have been consulted on this design. Perhaps Vodaphone rushed the product to market.

    Having watched a Fortune 500 company, which believed in security, lift its internal process to begin to match the onslaught of outside hacking, I can tell from the outside that Vodaphone has little or no internal security process. Despite any rhetoric and PR, they do not care about security, their customers or quite frankly their shareholders.

    Security is complicated and it takes trained professionals to ensure a product's security and safety. However, this type of problem could have been prevented easily - who stores an administrator password inside their systems and distributes them to customers?!

    I can't believe we have to close our eyes, hold our noses, cross our legs and hope these companies know what their doing. I always had philosophical problem with the White and Grey hackers who published their attacks. However, very few folks have the talent or knowledge to understand the complete and utter lack of security inherent in their consumer devices. Someone has to watch out for us.



    THC's Wiki for tracking this project can be found here.

    Wednesday, February 2, 2011

    Basic Programming 101: Session IV

    For-Loop and Counting

    The for-loop construct allows us control specific execution of a programs actions. It says: "do this for this many times." The program can count up, count down, count by fractions, whole numbers or whichever scalar value we choose. Recursion, although powerful, may have resource limitations (every function call takes memory). If the algorithm doesn't require "state" or memory, a for-loop does nicely.
    We have two examples here, a very short program that shows the for-loop and a second program that graphs functions.
    10 REM Simple for-loop prints nums 1..10
    20 for i = 1 to 10
    30 print i
    40 next i
    Function Grapher
    In this next example, we build a function graphing program that steps through a range of values and plots each of the points. We could do this in whole number steps, but the plotted functions may not appear continuous; they'll look more like points than connected curves/lines. The finer the grain of step, the more likely the function appears continuous.
    Lines 10 & 100 set up some constants and open a graphics window of the appropriate size. In this case, we keep two constants which represent the center of our graphics screen.
    10 xc = 250 : yc = 200
    100 graphics window 25,25,xc*2,yc*2
    Next, Line 110 contains our for-loop. It has a range of [-250..250] and granularity (step) of 1/10. You might need to make this finer (smaller) depending upon the kind of function you have. In this case, it could be step 1, because the function is a simple line.
    110 for t = -250 to 250 step 0.1
    Lines 120 and 130 contain the function. We set variables x and y to t. This will graph the line y=x. You might wonder why we didn't just make x the for-loop variable ("for x = -250 to 250"). There's a good reason for this, I will explain below.
    120 x = t
    130 y = t
    Line 140 does our work: set a point at . Not really because we have xc and yc in the calculations. Remember, is the center of the graphics window (the size of the window is 2*xc, 2*yc). Also, note that we subtract y from yc instead of add. That's because graphics windows are upside-down when compared to Euclidean graphs, which have positive Y going up the page. Computer graphics windows have positive Y going down the page and the origin (0,0) in the upper-left corner, a natural consequence of the way information is displayed on a computer's screen.
    140 graphics pset xc+x,yc-y
    Finally, we close the for-loop in Line 150 and, as I like to be disciplined in my coding, Line 160 ends the program. This line is not strictly needed, but if we ever implement a subroutine, you would want the program to end here, so make it a habit.
    150 next t
    160 end
    Why is X not the loop variable?
    We could have made x the loop variable, but didn't. Why? Because, not every equation to be plotted has only one value of y for every x. What does that mean? Consider the equation y^2 = x. This is a parabola, but tilted on its side 90 degrees. In all but one case, there are two values of y that satisfy any particular x. If x = 4, y = 2 or -2. To plot this equation, use y = t and x = t^2.
    Making a circle would be a challenge, since the equation for a circle is x^2 + y^2 = r^2. Fortunately, BASIC, like all good programming languages, provides a math library to assist us. Some of you may not have had trigonometry, yet, but there are well known functions from trig that address this problem: sine and cosine. In BASIC, these are sin and cos. They take an angle and return the Y or X value appropriate for that angle. In fact, cos(t)^2 + sin(t)^2 = 1 for every angle t. The math library uses radians, instead of degrees.
    To plot a circle, use x = 100*cos(t) and y = 100*sin(t). This paints a circle with radius 100. If you want an oval, change the constant (100) in either or both of the equations.
    In fact, playing around with programs is a great way to understand how they work. Feel free to play with this code and see what types of shapes and patterns you can draw. I've included some of the interesting ones I've found below. Use the comments section to add your own and tell us what it makes.
    Infinity: [-250..250],1/10,x=110*cos(t),y=100*sin(t)*cos(t)
    Spiral: [0..250],1/1000,x=t^2*cos(t)/2,y=t^2*sin(t)/2

    Tuesday, February 1, 2011

    Basic Programming 101: Session III


    Recursion, one of the great and subtle features of mathematics and programming, means to define a function or procedure using itself. Classic examples include factorial and the fibonacci sequence. Fibonacci has real world parallels (with leaf and population growth) and even touches upon fundamental mathematical constants. All from one little self-defined function.

    In this program, we display levels of triangles and play sounds when each triangle is drawn. The program asks the user to input the number of triangle levels, then, using two recursion steps (one for each level, one within a level), it draws the triangles. At no time does it track how many triangles it needs to draw, it only checks to see if it reached the end of the levels and the end of a row. The frequency of the sound played scales linearly with the number of levels while the duration of the sound falls (shortens) with the square of the levels. That's because the area of a triangle is proportional to the square of its height (or side).

    First, we set up some variables. These determine the size of a border region on the graphics window (bd) and the height and width of the drawable region on that window (py, px).

    10 bd = 10
    20 py = 433
    30 px = 500

    Next, we ask the user for number of levels to display and compute the delta width and height, which becomes the width and height of the triangles (dx, dy). We also compute the sound frequency (frq) and the duration of the sound (dur). If the duration is less than 1/20 of a second, it won't play, so we make sure its at least that duration.

    100 input "How many levels of triangles would you like? ",levels
    110 dx = px/levels
    120 dy = py/levels
    130 frq = 110+110*levels
    140 dur = 1/levels/levels
    150 if (dur < .05) then dur = .05

    Open the graphics window and be sure to include a border around it. Call our draw_triangle recursion routine with the point at which it is to start displaying the triangles and pass the number of levels to draw and an indicator to draw multiple levels. The point we pass is the lower left corner of the triangles - the recursive routine computes its drawing from the bottom up.

    160 graphics window 25,25,px+2*bd,py+2*bd
    170 draw_triangle(bd,py+bd,levels,1)
    180 end

    Here we have the routine that does the heavy lifting. It takes the lower left point, the current level and a boolean variable indicating whether we should draw sub levels (levels above this level). If is_full is ZERO, we only draw this level of triangles. Line 1010 tells us to stop if we have fewer than ONE level to draw. Line 1020 tells us if is_level is not ZERO, to draw the next level of triangles (level-1), and make sure it's a half triangle width to the right and a full triangle higher on the screen.

    1000 sub draw_triangle(x,y,level,is_full)
    1010 if (level < 1) then return
    1020 if (is_full <> 0) then draw_triangle(x+dx/2,y-dy,level-1,is_full)

    Here we draw the actual triangle then play a sound. Note the points on the triangle are computed from dx and dy.

    1030 graphics triangle x,y,x+dx,y,x+dx/2,y-dy
    1035 sound frq,dur,10

    Finally, our second recursion step draws the remaining triangles for this row. Notice how is_full will be ZERO, so none of the triangles drawn from this call will hit the lower levels. That's OK, we already took care of that above. Also, note that we are drawing the row with this call, so the point we pass is one triangle to the right and on the same line. Remember to decrement level by one when we make the call.

    1040 draw_triangle(x+dx,y,level-1,0)
    1050 end sub

    Wednesday, January 19, 2011

    Basic Programming 101: Session II

    All About Looping

    Writing a computer program that calculates Factorial and prints the result tells you almost everything you'll ever need to know about programming computers. Factorial requires an if statement (should I stop at 0! or keep going and calculate N*(N-1)!), it requires an input statement (Factorial of what number) and an output statement (print the result).

    This example calculates Factorial two separate ways. It's the same calculation and produces the same result, although each method uses a different technique: (1) for loop and (2) recursion.

    For Loop

    In this first part, we use a "for loop", which iterates over the numbers from 1 to N, multiplying them all together to get the answer N! = N * (N-1) * ... * 3 * 2 * 1.

    10 input "Give me a number? ",a
    20 gosub 2000
    30 print "Looping: ";str$(a);"! = ";f
    50 end
    2000 f = 1
    2010 for i = 1 to a
    2020 f = f*i
    2030 next i
    2040 return

    Line 20 (gosub 2000), jumps to 2000, sets 'f' equal to 1, and then line 2010 runs through all the numbers from 1 to 'a', finding their product and storing the value in 'f'. Line 2040 returns from the subroutine (back to line 30). Notice line 30 prints the resulting product, which is stored in 'f'.

    The for loop is located on lines 2010, 2020 and 2030. Those lines do all of the work to compute Factorial.


    The second method to compute Factorial uses recursion. In this case, we take advantage of the fact that N! = N * (N-1)!. Rather than loop explicitly, we create a subroutine (in this case a special kind of subroutine known as a function) which calculates Factorial using itself.

    3000 sub factorial(n)
    3010 if (n < 1) then
    3020 factorial = 1
    3030 else
    3040 factorial = n*factorial(n-1)
    3050 endif
    3060 end sub

    Line 3000 starts the function by naming it ("factorial") and telling the computer it takes one variable ('n'). Line 3010 is the "if statement", it makes sure the recursion doesn't go on forever. In this case, we stop if 'n' is ever less than 1. If 'n' is not less than 1, line 3040 tells the computer to calculate the factorial of 'n' by multiplying n and the result of factorial(n-1); just like the mathematical definition. Line 3060 ends the subroutine. The value to be returned is stored in a variable 'factorial', the same name as the function.

    One last item, the subroutine needs to be called:

    40 print "Recursion: ";str$(a);"! = ";factorial(a)

    Run the program to get the following:

    Give me a number? 6
    Looping: 6! = 720
    Recursion: 6! = 720

    Same result, two different methods, one using a for-loop and the other using a subroutine and recursion.

    Wednesday, January 12, 2011

    Basic Programming 101: Session I

    Let's write two programs: sum two numbers and hello, world.

    Summing two numbers in BASIC

    10 input a
    20 input b
    30 print a+b

    Run that and the computer asks for two numbers and prints their sum. However, it's not very informative because the "? " doesn't really tell you what the computer wants. Try adding the following line then run it:

    5 print "Give me a number";

    That's better, but it still isn't quite there. Try one more change:

    20 input "Give me another number? ", b
    30 print "The sum of your two numbers is " (a+b)

    That's it. Two questions with explicit instructions and an informative answer. Here's the whole program (list):

    5 print "Give me a number";
    10 input a
    20 input "Give me another number? ",b

    Save that and clear out the old program (del 1-), so we can write hello world.

    Hello, world!

    Run the following:

    10 input "What is your name? ", name$
    20 print "Hello, " name$

    Notice how this program, like the other one, displays everything on the console.

    Now, add these lines and run again:

    30 greeting$ = "Hello, " + name$
    50 graphics window 100,100,400,200
    60 graphics 0
    70 graphics moveto 10,100
    80 graphics drawtext greeting$

    It took a little more work, but this displays your text in a graphics window.

    Finally, for the coup de grace, add this line and run it.

    90 say greeting$

    Remember to save your work!

    Basic Programming 101: Prelude

    A long time ago, more years than I care to remember, I learned to write my first program in BASIC, not Visual Basic, but real, honest to goodness, HP 3000 series BASIC. A few years later I graduated to a TRS-80 with 4K of memory and a lousy tape recorder for program storage that never worked. I had to write my programs from memory.

    What a great environment! Easy to use, all of the principles of good software development were possible (and sometimes necessary).

    Recently, I started teaching my son (13) how to program and figured I'd show him a more useful and modern language: Java. Ugh. He got it, but it takes forever. Try doing a proper coding for a program that takes in two numbers and prints their sum or the classic "hello, world!". Forget it. I started thinking about what might be the best programming language to start off kids (or perhaps anybody). C? Perl? Javasript? XHTML? Ruby (on rails)? Lisp?

    What would you want your first experience with programming to feel like? The language should be powerful enough to do interesting things, yet simple enough that it doesn't get in the way of a beginner. It should fail informatively and be forgiving. It doesn't need to support a server farm or the support of a server farm. It needn't be able to run 3D vector calculations on a graphics card.

    It ought to inspire confidence to go deeper.

    Anyone who has coded for fun or for a living, that truly loves programming and can make computers sing or fly or run, knows how amazing the rush of coding a really great project feels. How to inspire that rush in kids? Airline pilots use flight simulators, little kids play with squishy balls and bats, small bikes have training wheels.

    And beginning programmers use BASIC.

    Check out Ron Nicholson's Chipmunk BASIC for the Mac. Great stuff. I'm using it for a beginning programming class for 7th and 8th graders.

    Monday, January 3, 2011

    Some Maze Programs

    This one suggests how to generate on the screen and walk through it in real time:

    This one generates the maze in a really cool fashion with doubly linked lists:

    Can they be combined into one program to let the kiddies surf through a generated maze?

    C++ for Web Apps

    Great blog post by Steve Hanov explaining how to use C++ in your web application. He goes through a number of scenarios, refers to a small web server (Hibachi) that won a coding contest, and finally shows how he wrote his own web server to support the application.

    Nice stuff.