It seems you're using an old browser...
We're sorry, but your browser is out of date. In order to view this site correctly, you may want to:
- Upgrade your browser to a newer version of IE.
- Try Mozilla Firefox, is fast, secure, and free!
tess's Blog
Goodbye, Kimiko
Submitted by tess on Mon, 2012-05-07 11:47The weekend before we put her asleep was very rough. She couldn't keep anything inside of her for long. Her fur was covered in nasty stuff this morning. She didn't have the energy to get to the catbox less than a meter away, or clean herself afterward.
The appointment was late in the morning. I took advantage of my working-at-home status, at pulled my laptop down to the floor so I could get in some scritching.
We decided to go to the local animal hospital instead of our standard vet to put Kimiko to sleep. The vet was surprisingly skillful -- and fast. He gently introduced himself to her. He was advised that it'd be best to give her an anesthetic first as she was likely to fight tooth and nail. We petted and talked to Kimi and one hissing thrash later, it was done.
We were left alone with her for a few minutes, petting, talking, and crying. I snapped a final picture. Kimi has been having problems maintaining her balance for months now. Even when sitting on all four paws, she wavered back and forth slightly. As the drugs took hold, she suddenly toppled over nearly falling off the exam table. It was only then I realized that she had been using all her strength just to sit. Sleeping had been incredibly difficult for her for months as well. No wonder why she held any spot she took so fiercely.
Within minutes, her eyes dilated, and her breathing became short and shallow. We checked and she was indeed, quite malleable. The vet came in. Gently he positioned her, wetted a thigh, and gave her a final injection. It was a light, garish pink, the color of watered down cinnamon mouthwash. 10cc's went in, and we were left alone once more.
We said our tearful goodbyes to the tiny, emaciated little white cat I had known and loved for over three years. We kissed her on the head. A small puff came from the body and her breathing stopped. I petted her one last time, gently pressing the tiny pink pads on her paws -- something she rarely allowed in life.
Goodbye, by all your names:
Hecate,
Little Miss Pinky Paws, and
Kimiko,
You will be deeply missed.
- tess's blog
- Login to post comments
The Stylus isn't an Inert Element
Submitted by tess on Sat, 2012-04-07 11:12This morning an article came across my feed that crystallized to me how wrong-headed the tech blogosphere is about the stylus. In this Read-write-web article, the author argues that the iPad isn't a proper drawing surface. I am in complete agreement with this point. A touchable interface is the cornerstone of the Tablet experience. Unfortunately, the Tablet fails when it comes to the production of artistic works. The author argues that the fault is the lack of physical feedback of the touchscreen. Instead, the software uses other kinds of feedback such as sound, graphics, or vibration.
Which doesn't make any sense.
Most artists, particularly those that create 2D work such as drawings or illustrations, start with physical media. It's cheap, versatile, and yes, it's physical feedback is simply unmatched. Many webcomic artists start with physical media, and scan in their drawings to publish their stories. While this works, it has a number of drawbacks in the digitial world. Scans can be blurry or messy. Cleanup can take a large amount of time, and scanners can be fussy, broken, or unavailable.
Enter the Wacom graphics tablet. I bought my Graphire 2 while I was in college early in the millennium. The $99 USB device still works and is still in service today. What's interesting about this bare-bones device is what it lacks. It has no display. No vibration. It doesn't even have buttons! Yet, I and many other artists can produce and continue to produce wonder pieces of art thanks to it and it's descendants. You'd think that the iPad and other tablets would be the ultimate "artist's digital sketchbook".
But tablets suck at artwork. They are flatly unacceptable. The problem isn't haptics, or display resolution, or any of that nonsense. It all comes down to one simple thing:
Precision.
Tablet touchscreens lack precision due to the nature of the technology. If you've ever held up a touchscreen and reflected light off of it at just the right angle, you'll notice a grid of "dots" cover the screen. Each dot is a tiny capacitor that can register a scale of contact. Clever (and highly patentable) mathematics are used to "guess" where you actually tapped on the screen. The problem is that capacitive touchscreens aren't manufactured to have the resolution required by artists. They are simply too expensive for the average consumer.
Compare this with the technology behind a Wacom tablet. This device uses not capacitors, but a magnetic field using wires (circuit tracings) and a coil inside the stylus. The nature of this technology allows much greater densities of tap registration. With a little clever circuity in the stylus, pressure sensitivity can be measured with a minimum of additional components. This formula has worked well for Wacom, and digital artists for years and years. While it takes effort to get used to the lack of physical feedback provided by traditional media, a skilled artist can overcome that problem within hours. The result is clean digital lines without any scanning artifacts.
But it has one critical problem. You need a stylus.
The inductive system Wacom uses does not work with fingers. You can touch a Wacom tablet (with the exception of the Bamboo line) all day and not get a single click. Capacitive touchscreens take advantage of the conductive nature of fingers, and use that as a means to register taps. This is also why sausages work with touchscreens. In a mobile device world, this can be an advantage as only conductive objects register as taps, and it's unlikely you'll be carrying pieces of metal or meat in your book bag or pocket. Styli that work with touchscreens actually have a piece of rubber or plastic with a conductive coating. That's why they work. You can actually create a touchscreen stylus yourself with an old pen and some conductive foam commonly used to transport integrated circuits.
The stylus has gained a bad reputation since the iPhone became the darling of the tech blogger world. This reputation is entirely undeserved, as the fault isn't the stylus, but the screens used at the time. In addition to Capacitive and Inductive, there's an older touchscreen tech -- resistive. The Palm series of PDAs heavily relied on resistive touchscreens. The physical configuration is similar to capacitive touchscreens, but relies on a different electronic property. When Palm was king, resistive screens were readily available and inexpensive. With a simple pointing device and again, clever mathematics, a tap could be registered and narrowed to a small region.
The problem is that resistive screens registered any and all physical taps. Furthermore, they had to be built using flexible material that deflected on contact. Capacitive touchscreens do not need physical deflection. As the size of the screens were often small in this age of mobile devices, a stylus was required to register taps accurately. Fingers were simply too mooshy. When Apple came along with the right combination of existing technologies, the stylus became the whipping child of an earlier era of technology.
The stylus is not the enemy. Bad touchscreen tech is.
As of late, the Internet seems to be reconsidering the stylus. Thinkgeek popularized the idea of a capacitive touchscreen stylus to avoid the greasiness inherent to a finger controlled interface. Wacom has recently began producing a "premium" capacitive stylus under it's Bamboo brand. Yet, there hasn't been one article that doesn't repeat the words of Steve Jobs: "If you see a stylus, you blew it." The author of the article expands on this point:
Apple's second mobile operating system nearly eliminated the friction between the software and the physical human interacting with it. It felt like touching and manipulating the actual pixels. A stylus would just be an inert barrier in between.
And that is completely wrong when it comes to artwork.
For centuries, if not millennia, artists have used sticks of charcoal, quills, brushes, pens, and pencils in order to produce drawings and illustrations. These devices are long, usually cylindrical, and are often controlled by pinching them between the pointer finger and the thumb. Sound familiar? The stylus inherits this form factor. In addition to sheer familiarity, this form factor has been sucessful for one reason:
The stylus is not an inert element. It is an active, mechanical element that acts as a movement reduction device.
Leonardo da Vinci did not use finger paints, he used a brush. The stylus, pen, brush, and so on translates the relatively large mechanical movements of the hand into smaller more precise movements necessary for the production of detailed artwork. This was, coincidentally, why the stylus was necessary on Palm and Windows Mobile devices. The screens were smaller as they were more expensive to produce. The stylus allowed more precise input on the smaller surface.
Today, this remains a problem even on the relatively larger size of the tablet computer. Using a finger to produce artwork is akin to using finger paints. It's messy, clumsy, and the results tend to be prized the most by the parents of diminutive artists. A stylus is required to make artwork more detailed as fingers are too large to do it accurately. The problem is that current capacitive styli replicate not pens, but fingers. The tips are large and squishy, making it seems like finger painting with a cleaner, straighter finger. Pen-precise styli could easily be created, but the touch resolution of the average touchscreen is not yet up to the task. There are too few capacitiors, and they are too far apart.
The problem is not the stylus, dear tech bloggers. The problem is the screen.
- tess's blog
- Login to post comments
Extra
Submitted by tess on Sun, 2012-04-01 10:39Yesterday I passed the Extra Class Amateur Radio exam. When I first got back into this hobby, I had only expected to pass the Technician class test and leave it at that for some months or years. When I passed, the VEs (Volunteer Examiners) vocally suggested I should take my chances with the General-class exam. After all, I only needed to pay them $15 once no matter how many tests I took that day. So, I sat down and muddled my way through. To my surprised, I passed the General class with a margin of one question. The VEs then suggested I take the Extra, but I knew I wouldn't pass that one, not without studying.
Today, there are three classes of Ham Radio licenses -- Technician, General, and Extra. The material is cumulative, in order to take one exam, you must pass each one that precedes it. The questions from all exam classes are multiple-choice, and each derive from a nation-wide question pool. Other countries may have similar processes, and even borrow heavily from one another as many questions only concern physics that know no nationality. While the Tech and General class exams are 30 questions each, the Extra-class exam in 50 questions. No only is the exam longer, the question pool is bigger and the questions much, much more difficult. Techs need only know the two most basic Ohm's Law equations: Resistance (R) = Voltage (E) / Amperage (I), and Watts (P) = Amperage * Voltage. (This leads my personal mnemonic "Ohm's law for Evangelion Fans", R=E/I likes P=I*E, or "Rei likes Pie".) Generals need to know the expansions of the basic Ohm's Law equations such as P=i2*R as well as how to calculate series and parallel resistances and capacitances. Extras need to know much more complex things like Impedance, bandwidth calculations, and Resonance. There has been a suggestion that the huge jump in complexity is due to the fact that the much newer Tech and General question pools were made easier in the last review. The Extra question pool is older, and reflects the much more technical bent of earlier tests.
The Extra Class exam pool is due to be revised on July 1st, 2012. As a consequence, all the books and materials you may find months before that date reflect the older question pool. This means that you either study now before the new pool comes into effect, or you wait until new books can be published to help you study. You either study now and take the test before July, or you may have to wait until late this year just to get started. Last fall, I had checked out the ARRL's study guide for the Extra Class exam, but found it meandering and poorly written. Eventually, I gave up trying to make sense of the incomprehensible mess it presented to me. Switching to a question-centric approach, I had purchased the ARRL's Extra Class Q+A as an eBook early last winter. I slowly slogged through half of it, but I found the explanations terse and laid out in numerical order of the question pool. This was a horrible way to study.
Some months ago, a friend bought Gordon West's General Class study guide. The writing in these books is surprisingly good. The questions have been reorganized so that similar questions are grouped together. The explanation text is much more helpful than the ARRL's Q+A books. After sitting on the idea for a few weeks, I drove up to my local ham store and bought the Extra Class book. I tore through it in a week, surprising even myself. Afterward, I planned to drill using Eham.net's online exam generator. This turned out to be the best way, as the question pool is some 700 questions. Each question pool, including the mammoth Extra, is broken up into topic-related portions called "Elements". You only get a few questions from each element. By using the generator, you get a random sampling from each element put together like a real test. Typically I'd take one or two practice exams each night. If I couldn't remember an equation, or couldn't guess an answer with any confidence, I'd open the book for help.
Throughout this process, I did not give much consideration as to why I was doing this. Each license class gives you additional operative privileges. Mostly, this comes down to how much radio spectrum in which you can play. Techs are granted most of the Ham bands above 30Mhz. This includes the two most popular VHF bands, 6 meters (50-54Mhz) and 2 meters (144-148Mhz), and the 70cm (420-450Mhz) UHF band. General Class gives you access to much of the HF bands. These are great for long-distance communication. Extras are allowed key segments of the HF bands that are the best for long-distance, or "DX", contacts. One might think I'd be excited to dive into these most-privileged portions of the ham radio spectrum, but that isn't really the case.
People who chase long-distance contacts, "DXers", dream of being Extras. Those dreams also include kilowatt transmitters and "antenna farms" sprouting from rooftops and the tippy-top of metal tower from their backyard. While it may be fun to someday have those things, that's simply impossible given my current living situation. I live in a second story apartment in Minneapolis. My antenna -- intended for service on the roof of a car -- is magnet-mounted to the metal railing of my balcony. And while I have a transmitter capable of 100 watts of output, I love my tiny QRP rig with a miniscule output of 5 watts. Any contact I make with this setup astounds me. The new spectrum allotted to Extras is typically reserved for Morse Code enthusiasts. Something I have a passing interest in, but I'm much more sanguine about digital modes such as PSK31.
So why? Why even bother with Extra?
There's several reasons I pursued this. In my day job, I build education material for enterprise software. While it's a challenge in it's own right, it isn't per se a technical challenge. Ham Radio presents this challenge, and the Extra Class exam presented a neat goal and a short and satisfying time-line of several weeks. I wanted to prove to myself that I could pass this test, learning all the necessary electrical and operating theory to back it up. And, for lack of better words, it was in front of me. Passing the Extra means I've arrived at an endpoint, and now I can enjoy the craft without seeing something above me. I can move on to other challenges such as catching better contacts, newer modes, and someday building my own radio from scratch.
But that'll be another day.
P.S.: In case you're wondering, I decided not to change my call sign at this time. My current one is ridiculous, unpronounceable, and I've grown quite fond of it.
- tess's blog
- Login to post comments
The Coming Tablet World
Submitted by tess on Mon, 2012-02-20 23:47Earlier this evening a friend sent out a request on Twitter:
@[redacted] needs a new laptop. Any recommendations? She needs win7 and not too expensive.
I found something that met the criteria and quickly sent off a reply. There wasn't much too the request. Desktop Computers (including laptops) haven't changed much for the last few years. Even the specs have for the most part stabilized: 2 to 4 cores, 1.5-2.1 GHz, 4 - 8GB of memory, Hard Drives up to 750GB... Getting a new computer is simply no longer exciting.
Contrast this with mobile devices. Smartphones and tablets have come to such an amazing prominence that they now consist of the majority of Internet traffic today. Most people in the US consume content on websites, blogs, and social media on these devices from the sofa while watching television. I too, have succumbed to this madness last summer and bought one myself. Yet, they are rarely considered machines on which you "can get work done". Just try to develop a web site on an iPad.
And that's the shameful part of it: you should be able to develop a website on a tablet. Hell, you should be able to write and compile software on it. My HP TouchPad has more CPU and memory power than the computer I used in college to write my assignments and compile my C++ code. Spec-wise, there should be no reason why a tablet of today could not supplant a desktop-class machine. The problem is the industrial complex including both the hardware manufacturers and the OS developers.
Apple championed the ideal of "owning the entire stack". They build the hardware, they code the software. This allowed Apple to integrate the two with spectacular refinement since the late Steve Job's return. There's also the opposing edge to that sword: You are at their mercy. If they decide to no longer support your model -- as Apple has with their recently announced Mountain Lion -- you're out of luck. Fork over another $1500 and you'll be reinstated into grace.
It's with distaste that other manufacturers have taken up the same methods, hoping to swell their coffers in the same manner as Cupertino. Since the original Droid, we've been fighting locked bootloaders on Android phones and tablets. The strategy hasn't worked. Samsung, Motorola, HTC; you're not Apple. You don't have the same fanatics or the legacy of a charismatic figure promising us a skeuomorphic Rapture of the Hipsters. What you can do sounds simple, but requires more thought and much more risk.
HTC is a prime example of Doing It Wrong. They seemingly put out a new smartphone model every month. None of them are distinct, and the modifications to stock Android, HTC Sense, provides only a minimal visual flare at the cost of increased pace of obsolescence. More than once, a firmware update has been held up because Sense couldn't be shoehorned into a popular device. At least once, a device that had an announced upgrade was canceled because Sense wouldn't fit. The subsequent outcry called for a a Sense-less upgrade, but HTC's response was lukewarm.
Apple did have it right with part of their formula: The number of models should not exceed the fingers on one hand. The times those models are replaced with a newer version should not exceed once a year. Customers like it simple. Do it right; don't rush anything out the door and make sure it's solid.
This is why I've watched developments in Windows 8 with great interest. Microsoft is trying to create a tablet experience in which you Can Get Work Done. While the hybrid Metro/Aero environment is abominable, their aim really does seem well thought out, if unsettlingly different. For the first time, ARM will be supported as a major Windows platform. Furthermore, the experience is "touch first". Microsoft hopes the touchscreen will be standard computer equipment going forward.
What is possibly more interesting to me is what open source developers will do. With Microsoft pushing touch interfaces, the tablet form factor will become the de facto standard. The two most popular desktop environments are already gearing up for this change. GNOME3 is taking a radical unified approach, casting off old mouse-centric WIMP interfaces and aiming for a blend not unlike Windows 8. KDE is remixing their astonishingly flexible DE into Plasma Active. For the moment, it is difficult to find a touch device on which either of these open source stacks will run. I hope that with the release of Windows 8, this will change.
That is, if Microsoft doesn't screw it up.
They already are, sadly. As part of the Windows 8 operating system, Microsoft is pushing "secure boot". If this sounds like the return of the Android locked bootloader controversy, you're right. This time it's bigger and meaner. While x86 based tablets will have no requirement to use secure boot, any ARM based tablets will. Furthermore, Microsoft will deny manufacturers the right to apply the Certified for Windows 8 sticker if an ARM tablet allows the user to disable the secure boot feature. One may think the solution would be to stick with x86, but the venerable CISC architecture was never designed for low power operation -- something critical for a mobile device. ARM, on the other hand, is specifically geared to function in an embedded context.
There are several technical discussions elsewhere on the 'net highlighting why "secure boot" is little more than DRM in disguise. Microsoft intends to create a technical vendor lock, preventing the upstart Linuxes from whittling away their overwhelming marketshare. It's petty. It'd devious. And they probably can get away with it. Universe knows Apple has for years.
Is there no hope for those of us that wish to run on an open source stack? If the open source community has shown anything, it's determination. Despite smartphone manufacturers best efforts, bootloaders have been cracked and hardware wrested from their control.
A famous hacker once put it thus: If a thing can be decrypted, it can be stolen reclaimed.
- tess's blog
- Login to post comments
Getting Forked
Submitted by tess on Sun, 2012-01-29 17:11Since last weekend, I spent my evenings manually moving content on deninet. It many ways, it was an exhausting process, but it gave me something to do while I suffer through the last two seasons of Star Trek: Voyager. Let me chart how I arrived at this point.
Over vacation time in December, I decided to conduct a little experiment. I would attempt to upgrade the current deninet website from Drupal 6 to Drupal 7. When I had attempted this a year ago, it did not go well. The upgrade process crashed spectactually, leaving me with a lump of a database. Thankfully I was doing this on a local copy, and not the live site. I had speculated that in the interviening year, Drupal would have ironed out a lot of the edge cases I originally ran into. So, I copied off the site and tried again. To my astonishment, it worked.
This created a dilemma. The previous year I had created a new deninet website by manually copying content from the version based on Drupal 6 to the new one based on Drupal 7. When all the features I needed to run the site were available, I'd switch to the new site. I had maintained the D7 fork from time to time, manually importing nodes and to make sure the two sites where in sync. At the time, this seemed the best way to go. I would lose things like comments and break all the URLs, but the end would be a good move.
Except that the new site never seemed to get anywhere.
I had reservations about the URLs and the comments. While I could bury my feelings, claming it was for "the greater good", it still bothered me. There was the bigger issue that I really wasn't getting anywhere with the D7 site. It sat and languished, while I couldn't resolve the issue.
After successfully upgrading the site, I began to wonder if I could take a more fluid approach. I used Pathauto to create URLs that would be the same for both the current D6 site, as well as a D7 site -- upgraded or new. The biggest problem was images.
- tess's blog
- Login to post comments
Low Power Ham Radio, PSK31, and Making your Watts Count
Submitted by tess on Sat, 2011-12-31 12:09Yesterday I had a wonderful contact of firsts. It was:
- My first contact outside the US
- My first contact with Canada
- My first contact on 20 meters
- My first contact on PSK31
Until later that day, my only radio is my beloved Yaesu FT-817ND. It's a low power rig that is intended for backpacking purposes, featuring a maximum output of 5 watts and an internal battery. It's an adorable little rig, but the total output wattage is tiny compared to typical Ham Radio rigs.
Let's compare my FT-817 to my newest rig that arrived only hours later -- an Icom 707. This older rig was originally released in 1993, 11 years before the 817ND! Nevertheless, the power output for the 707 is common to many rigs manufactured today, 100 watts.Even with a modest antenna, you can go across the country easily on 100 watts. With luck and the Ionosphere on your side, you can go around the world! With only 5 watts, however, things become much more tricky. You need to consider your mode carefully.
A mode is the method of encoding information in a radio signal. The most basic one you're probably familiar with through movies, Morse Code. This method turns the transmitter (or more specifically, the power amplifier connected to the antenna) on and off. Like binary, it has two "digits", a short "dit" and a long "dah". By encoding each letter of the alphabet as a series of dits and dahs, you can exchange information. Since the signal is either fully on, or fully off, and the frequency is constant, Hams like calling this mode CW, or Continuous Wave. CW is the mode proper, while Morse is merely a method of encoding the information.
Other modes you're already familiar with, AM and FM. These are voice modes. Explaining these requires a bit more imagination. Think of your voice as a sine wave. Radio waves can also be thought of as a sine wave. For your voice, the length between the peaks of wave is much, much bigger than the radio wave. So much so, you can superimpose your voice wave by varying the power output of the transmitter. This is how AM, or Amplitude Modulation works. FM, or Frequency Modulation works by varying the frequency of the radio signal proportionally with your voice sine wave. FM was created to avoid noise generated by the atmosphere, most of which causes spikes in amplitude.
While voice modes are easily approachable, they are rarely used in QRP work. Voice modes have a hidden cost, Sidebands. The original, unmodulated radio signal produced by the transmitter still makes it to the antenna even when you're talking! This bit of the signal, the Carrier Wave, doesn't contain any information. Instead, by a quirk of combining waveforms, the signal spreads out below and above the carrier wave proportional to the spoken frequency. These are Sidebands. FM has huge sidebands, since it's frequency changes slightly. While AM's are smaller, the two sidebands are mirrors, containing the same vocal information. A more efficient modification of AM is called Single Side Band. This mode cuts out one of the sidebands and the carrier wave. This means that what is transmitted has much more punch and travels further than it would otherwise. This makes SSB a good mode for low power work.
The ultimate mode for QRP work is still CW. Since there is no superimposed audio wave, the sidebands are tiny. All the punch is put into a very narrow range of frequencies, meaning each watt carries the signal that much further. The problem is that CW is a dying art. It's no longer a required skill to get an Amateur Radio license. While this was done to lower the barrier to entry for prospective Hams, the ubiquity of computers has popularized Morse Code Decoders -- software that can listen to a CW signal and print out the text. Likewise, Morse Encoders allow you to use a keyboard to type letters, making the computer translate them into dits and dahs for you.
The problem is, that feels like cheating to me. If you're going to do CW, you should break out a straight key, or an iambic paddle and cut out the silicon middleman. And while that is my plan, after I practice thoroughly, I'm still facing the problem of a poor antenna and a low power rig. Enter PSK31.
PSK31 stands for Phased Shift Keying, 31 Baud. In many ways, it's like Morse Code. It encodes letters in an equivalent of dits and dahs, but by shifting the phase of the signal. Going back to our imagined sine wave, if you're at a peak, PSK31 will suddenly shift to a valley, with no transition in between. By doing this rapidly, we can encode letters in a series of timed phase reversals. The nifty thing is that this is not done with the radio signal! Instead, PSK31 is encoded as an audio tone! Why do this? PSK31 was designed to be simple, and bare bones. Requiring new transmitters to be build just to support it would hamper adoption. Instead, PSK31 is produced (and received) by a computer, and sent to a standard SSB transceiver. Unlike transmitting a full human voice on SSB, PSK31 only results in a very narrow range of audio, this means the sidebands are very narrow. As narrow or more narrow than CW! This means all the power is packed into a tiny bit of frequency, making each watt count.
Now here comes the really nifty part: PSK31 conversations are often all sent and received with the transceiver tuned to the same frequency. Multiple people, having multiple conversations, at the same time, on the same frequency. How? Recall that PSK31 is encoded as audio first. By telling the PSK31 software to produce audio at one tone or another, multiple people can occupy the same frequency. It's like a room full of people each with a whistle. Only two people in the room have the same kind of whistle that produces the same tone. Since they're only listening for the same tone they themselves are producing, they can ignore everyone else.
Want to try it yourself? Really! No radio required! Download and install Digipan on your computer. If you're on Linux, it runs just fine in Wine! Now, plug in a microphone and start up the software. Go to Configure -> Sound Card and set things appropriately. Then put on this Youtube video while having the mic pointed at your computer speakers. Nifty!
In a typical Ham setup, however, a special interface is required to interconnect the computer in the transceiver in a safe way. Too much audio power from the receiver can damage your computer's sound card. Too much from the computer, can damage the transmitter. I recently purchased a SignaLink USB. The nice thing about this unit is it's only a USB sound card to the computer. It works in Linux just fine.
While I made my 560 mile contact fairly easily, there's a lot more I can do. My antenna was not properly tuned, resulting in poor efficiency. Not all of my 5 watts ended up "in the air". I think with some additional work and tuning, I can make it much, much further.
- tess's blog
- Login to post comments
How does Drupal 7 Work? Part 4: Modules and Menus
Submitted by tess on Wed, 2011-12-21 23:24Understanding how Drupal gets from a page URL to page content is a complex topic involving many moving parts. In previous parts we've covered how Drupal initializes itself, we haven't discussed how a requested URL is routed within the CMS to the code that produces the web page. Handling this is the beating heart of Drupal -- the Menu System. Before we get to that, however, we need discussed modules. We glossed over them in the last part, but here we dive into detail.
Module Loading
It occurred to me after writing the last part of this series, I didn't go into more than high-level detail of drupal_bootstrap(). One of the biggest questions I had when I began this exploration was "How are modules loaded?" Coming from a self-taught C and C++ background, loading external code seemed a black art. Thankfully, PHP makes this very simple.
Apart from very simple applications or sample code, most programming projects are broken up into multiple files. C and C++ have a pre-processing directive called "#include". This isn't actual code, but a command sent to the compiler. What I failed to realize as I moved on to other languages -- especially those like PHP that are interpreted rather than complied -- is that PHP's method is actual code, and that's the key to how Drupal loads modules.
PHP has several ways to include a dependent file, include(), include_once(), require(), and require_once(). The difference between includes and requires is if an error is tossed if the file cannot be included. The *_once's prevent a file from being imported twice, thereby causing definition conflicts. You quickly learn that require_once() is the version you'll use the most. Another astonishing fact to C/C++ devs new to PHP is that all of these statements can accept variables.
How does Drupal load module code? Like this:
include_once($variable_of_module_file_path);
That's the core of it. You'll notice that the include_once() statement is used instead of the require_once(). This is because Drupal does not want to give you a White Screen of Death if a module's files have been misplaced. Drupal does use require_once() when loading other core files like bootstrap.inc or common.inc. After all, if those are missing, you're really in trouble!
It Can't be that Simple
You're right. It's not. While the basic idea of loading module code is an include_once() inside a foreach loop, the actual process is a bit more complicated. As we learned in the last part of this series, drupal_bootstrap() does not load all modules at once but in two distinct steps. During the DRUPAL_BOOTSTRAP_VARIABLES phase, several modules are loaded that are required for the bootstrap process to complete. If you're stepping through a default installation of Drupal, there are three bootstrap modules: devel, dblog, and overlay. The process looks like this:
drupal_bootstrap()
_drupal_bootstrap_variables()
module_load_all($bootstrap = TRUE)
module_list($bootstrap = TRUE)
Loop through list of bootstrap modules (devel, dblog, overlay)
drupal_load($type="module", $name)
We already know the first two, but the third, module_load_all() is new. This function gets a list of modules by calling module_list(). The $bootstrap parameter isn't used by module_load_all(), but is passed to module_list(), instructing it to return only bootstrap modules.
With an array of modules in hand, drupal_load() is called for each element. It checks to see if the file was already loaded, and then gets the module file name. A lot of care is taken in getting this file name and making sure that it's correct, and points to actual PHP code.
The module loading process is the same for non-bootstrap modules (including contrib modules) as it is for bootstrap modules. During the DRUPAL_BOOTSTRAP_FULL phase, a default installation of Drupal will load block, color, comment, contextual, dashboard, dblog[skipped], devel_generate, field, field_sql_storage, field_ui, file, filter, help, image, list, menu, node, number, options, overlay[skipped], path, rdf, search, shortcut, system, taxonomy, text, toolbar, update, user, devel[skipped], and standard.
Notice that in the above list, the bootstrap modules are drawn into the global module loading process. Thankfully, Drupal already knows that these modules have been loaded, and skips the process. The psudocode looks like it did earlier:
drupal_bootstrap()
_drupal_bootstrap_full()
module_load_all()
module_list($bootstrap = FALSE)
Loop through list of contrib modules
drupal_load($type="module", $name)
What about Hooks?
Loading modules isn't the only thing that's seemingly magic about modules. Module developers rely on a huge API of hooks into the Drupal process in order to add features, modify display, perform access restrictions, and so on.
It really comes down to a function called module_invoke(). It takes two parameters, the module name, and the hook to call. How it works its magic to call a function is via the PHP call_user_func_array() statement. This statement doesn't require a pointer or anything fancy to the function to invoke, just the function's name! Drupal modules implement individual hooks by creating functions with the moduleName_hookName() signature. This is very clearly represented in module_invoke():
module_invoke($moduleName, $hookName)
Get any additional unnamed $arguments as an array
If the module implements the hook
return call_user_func_array($moduleName . '_' . $hook, $arguments)
The module_invoke function actually can take more than the two named parameters thanks to PHP. These additional parameters are packaged up as array and passed to call_user_func_array(), which in turns passes the contents of the array as parameters to the hook implementation. This, and the fact that module_invoke() returns the result of the invoked hook, make it a smart function invoker cabable of working across modules.
Often in Drupal core, you do not simply invoke a single hook implementation, but call all the implementations of a hook at a single point. Handling this is a sister function to module_invoke(), module_invoke_all(). It's used the same exact way as module_invoke(), but lacks the $moduleName parameter.
Menu Routing
While modules provide Drupal's extensibility, Menu Routing does the real work of the CMS. At first blush, you may think that the "menu" refers to something like the primary and secondary links, or even the navigation block. After all, all of those are called "menus" in Drupal's own UI!
Repeat after me: Menu Routing has nothing to do with Menus, everything to do with Routing.
Page routing, specifically. The Menu [Routing] System is the core component of Drupal that takes a URL of the requested page and returns a viewable HTML web page. That is, it takes the part of the url after "?q=" in the follow example:
http://example.com/index.php?q=the/requested/page
In the above example, the page part of the URL is "the/requested/page", and this is exactly what the menu system handles. It matches up the page URL with the PHP function needed to generate the web page, and executes the function. When coding a module, the Menu System is often the first thing you'll code after an *.info. file. It's perhaps the most approachable piece of API in the entire project, which is why I bring it up here:
function motleymod_menu(){
$items[my/motley/page] = array(
'page callback' => 'motleymod_my_page',
);
return $items;
}
function motleymod_my_page(){
return "<p>This is my motley page.</p>";
}
The above code would work relatively unchanged as far back as Drupal 5.0. We have two functions, the first implements hook_menu(), and the other generates and returns the page content. You'll notice that the first function defines and returns an array with one element with the key 'my/motley/page'. As you might have guessed, this is the page URL! The content of the element is itself an array containing one element, 'Page Callback'.
The Page Callback parameter instructs Drupal what PHP function to invoke to generate the page. In this case, motleymod_my_page(), which returns raw HTML to display in the body section of the webpage. Drupal takes care of everything else -- headers, blocks, footer, and all.
But That's Not the End of the Story
If you think the above example was a little spare, you're right. Let's look at a more complex example of hook_menu():
function motleymod_menu{
$items[my/motley/page] = array(
'page callback' => 'motleymod_my_page',
);
$items[admin/config/motley] = array(
'title' => "Configure Motley Module!",
'page callback' => 'drupal_get_form',
'page arguments' => array('motleymod_admin_settings'),
'access arguments' => array('administer motleymod'),
'type' => MENU_NORMAL_ITEM,
'file' => 'motleymod.admin.inc'
);
return $items;
}
Whoa! What the heck is all that stuff? We see our original entry for 'my/motley/page', but now there's an additional entry for 'admin/config/motley'. This time, with a lot more parameters than just Page Callback:
- Title is the title of the page to display. It's used both in the <title> tag of the generated page, as well as in the <h1> tag in the body section of the page.
- Page Callback is the the magic parameter. It tells Drupal what function to call!
- Page Arguments specify the arguments to pass to the function specified in the Page Callback parameter.
- Access Arguments specify the access permissions (under admin/people/permissions) the current user must have in order to access the page.
- Type is the kind of menu item this item represents. More on that later.
- File tells Drupal in what file to find the function specified in the Page Callback parameter.
Again, we have a Page Callback, but something seems screwy: It's set to drupal_get_form() -- a function provided by Drupal itself. How the heck does that work? Over the history of Drupal, it was discovered that many module's Page Callbacks returned pages with similar structures. Furthermore, pages started falling into classifications of pages. Content pages usually have a title and a bit of text to display. Settings pages usually have a title and a form with a submit button. Drupal-provided page generators, like drupal_get_form(), handle a lot of rendering work for you, making module developer's lives a little easier. In this case, the function provides a module setting page.
menu_execute_active_handler()
Now that we have a framework, let's tie it back to where we were in our debugger. After drupal_bootstrap(), the last function called in index.php is menu_execute_active_handler(). Without any arguments, the function looks up the page URL, and then digs into the Menu System.
The first thing that it does is check if the site is "offline", that is, in Maintenance Mode. Administrators set this mode under admin/config/development/maintenance, and it temporarily blocks all other visitors save the Admin from accessing the site. This allows the Admin to perform site updates safely. If the site is offline, it doesn't matter what page was requested, all results are sent to _menu_site_is_offline(). This function checks to see if the user is the Admin, if so, normal page routing resumes.
The next thing menu_execute_active_handler() does is check if the Menu System needs to be rebuilt. This is where hook_menu() is invoked. Normally, Drupal 7 stores menu routing information in a database table -- menu_router. It does this because performing a database query is actually faster than searching through all implementations of hook_menu() to find a match. During a rebuild, the contents of menu_router are thrown out. Drupal then locks the database temporarily and recurses through each enabled module and invokes hook_menu(). This results in a huge array of menu items like we saw in the code sample above. This is then committed to the menu_router table.
After that, things get much more straightforward. The appropriate menu item is found, and the function specified in the Page Callback is called passing any Page Arguments as necessary. The result of the Page Callback is then sent to the user's browser for display.
Thirsty Yet?
After all we've covered, it's easy to simply accept that how Drupal is written is the best way it can be written. I know that when I started using Drupal, it was after I tried and failed to create my own content manager. "Let me learn from those more experienced than I!" This, however, blinded me to one of the biggest problems Drupal is facing today.
Drupal is heavy.
It used to be that each time a page was requested, you could assume that the entire page was requested. Graphics, HTML, and all. In the new world of refresh-less web apps, however, use AJAX requests to grab content or save information. Instead of sending the entire page, lighter packages of JSON formatted data are exchanged between the user's browser and the web server. While Drupal can handle these requests, it must still go through the entire initialization and routing process it would for a full web page. Worse yet, it must load all modules into memory with each request -- even if that module is not needed in that request.
I discovered this myself when I attended Crell's presentation during the Twin Cities Drupal Camp introducing the Web Services and Context Core Initiative. The goal of WSCCI (pronounced like the drink) is to ultimately replace the heavy drupal_bootstrap() and menu_router() system with a more agile core. Intead of Drupal being just a first-class CMS, it will be a REST server with a first-class CMS on top.
It's an ambitious but, I believe, necessary evolution of the platform. While targeted for Drupal 8, I have my doubts it will be fully realized until Drupal 9.
Unless we help, that is.
What's Next?
We've reached the end of index.php, but not of our series. There's still a lot more to explore, but the going gets more treacherous from here.
- tess's blog
- Login to post comments
How does Drupal 7 Work, Part 3: drupal_bootstrap()
Submitted by tess on Mon, 2011-12-12 23:25Click here to read Part 1.
Click here to read Part 2.
When looking at Drupal code, it can be hard to know where to start. Dive into any of the directories in a standard installation, and you'll find file after file of PHP code. In the root directory alone, you'll find five files! Where do we start? Determining this is quite simpler than it seems; all you have to do is look at the URL of any Drupal site.
http://example.com/node/1234
The above is a typical URL for a Drupal site. Most Drupal sites use a feature called "Clean URLs". This removes a lot of the nuts and bolts of the address that helps us understand it. Without Clean URLs enabled, the above address looks like this:
http://example.com/?q=node/1234
Okay, that's a little helpful, but it doesn't tell us what we want to know. What file amongst all the files in Drupal do we look at? It turns out that many websites will look for a default file in the site's root directory if one isn't specified in the URL. In the Web 1.0 days, this was "index.html", for modern PHP websites this is "index.php".
Four Lines to Rule Them
When we open of index.php, one might expect a lot of code. Instead (aside from comments) you'll find four lines:
define('DRUPAL_ROOT', getcwd());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
menu_execute_active_handler();
The first two lines are very straightforward. The first line defines a constant, DRUPAL_ROOT, containing the file path to the Drupal installation. This constant is then used in the second line, to load bootstrap.inc in the includes/ subdirectory. Despite the file extension, bootstrap.inc contains PHP code. Drupal uses the *.inc extension to prevent files from being executed directly. This way, someone cannot plug in http://example.com/includes/bootstrap.inc and get back a valid page.
That leaves two more lines, and that's where all the fun starts. At this point we've only defined the DRUPAL_ROOT constant and imported an include file. We have yet to execute any real code. Any Drupal page request can be thought of as a two step process (if you're a core dev, insert your groans here): Initialize the Drupal environment, and then handle a page request. The third line of code, drupal_bootstrap() does the initialization -- it forges a connection to the database, loads modules, loads needed data into memory, and prepares everything for the final line of code in index.php.
The menu_execute_active_handler() function handles the page request. This is the part that takes the ?q= half of the URL and produces a web page for the visitor to see. This is actually a new function in Drupal 7. Drupal 6 preferred to bury the request handling within drupal_bootstrap(). Separating the two makes things much, much cleaner.
Making Invocation Easier
In the last article in this series, I mentioned that invoking the debugger was somewhat tricky. Eclipse assumes that any code you're debugging is in a project and not external files. It turns out that the PHP Development Toolkit actuall anticipates this problem and solves it rather easily.
- Create a new PHP project by using the File menu:
File -> New -> PHP Project - In the provided field, enter a Name of your choice that is unique within your workspace.
- Under the Contents box, select the Create Project at existing location (from existing source) radio button.
- Click the Browse button adjacent to the radio button. Select the root of your Drupal install.
- Click Finish.
This creates a new project in Eclipse importing all of Drupal's files. This mode of project creation does not create a copy of the files within the Eclipse workspace, but rather creates references to the actual files on the web server. Thus, any changes you make to the files in the Eclipse UI affect Drupal's actual files. This is great for our purpose of exploration, but can problematic. Remember, don't hack core!
Once the project is created, invoking the debugger is easy, easy, easy. Double-click index.php in the project explorer, then start the debugger with Run -> Debug As -> PHP Web Page.
Booting Up Drupal
Once you've started a new debugging session, we can dig into drupal_bootstrap(). The function looks a little circuitous at first: An array of phases is initialized, and then a while loop begins, iterating through a seven step process in which key subsystems and dependents of those subsystems are initialized in the correct order. Here's how it boils down:
- DRUPAL_BOOTSTRAP_CONFIGURATION -- Do some basic setup and load settings.php.
- DRUPAL_BOOTSTRAP_PAGE_CACHE -- If page caching is enabled, and the request is asking for a cached page, return the page.
- DRUPAL_BOOTSTRAP_DATABASE -- Connect to the database.
- DRUPAL_BOOTSTRAP_VARIABLES -- Load variables and enabled modules required for bootstrap.
- DRUPAL_BOOTSTRAP_SESSION -- Load the user's session from the DB. If the request isn't from a logged in user, return an anonymous user.
- DRUPAL_BOOTSTRAP_PAGE_HEADER -- Invoke hook_boot(), send default HTTP headers.
- DRUPAL_BOOTSTRAP_LANGUAGE -- Initialize the language system for translations.
- DRUPAL_BOOTSTRAP_FULL -- The phase name is better thought as "Last", rather than "full". Load all enabled modules. Invoke hook_init().
Why the added complexity? Why not just use a static series of functions? The initialization process can be very complicated. For example, you may be in the middle of one phase, like DRUPAL_BOOTSTRAP_PAGE_CACHE, and you'll need to load something from the database. The code that's initializing the page cache will invoke drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE). Furthermore, each phase is dependent on each preceding phase -- you cannot do the DRUPAL_BOOTSTRAP_VARIABLES phase without doing DRUPAL_BOOTSTRAP_DATABASE, DRUPAL_BOOTSTRAP_PAGE_CACHE, DRUPAL_BOOTSTRAP_CONFIGURATION. This is used by index.php itself when it calls drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL). Since DRUPAL_BOOTSTRAP_FULL is the last phase in the list, it is dependent on all previous phases.
Each phase of the bootstrap process has a lot of code behind it. While I could write an article for each, there's so much more Drupal to cover. We haven't even served a page yet! That's what we'll do next when we cover menu_execute_active_handler().
| Attachment | Size |
|---|---|
| Screenshot at 2011-12-12 21:27:47.png | 162.81 KB |
- tess's blog
- Login to post comments
Gender-Inverted Babylon Squared
Submitted by tess on Wed, 2011-11-30 10:32My gender-inverted version of the famous Babylon 5 "Fasten then Zip" scene from the episode Babylon Squared.
Garibaldi: Mind if I ask you a question?
Sinclair: Sure.
Garibaldi: Okay, it's morning. You get ready to go to work. You put on your bra. Do you clasp in the front and then twist it around or just clasp it in the back?
Sinclair: What kind of question is that?
Garibaldi: Look, we got two hours to kill...
Sinclair: Forget it!
Sinclair: Why do you wanna know?
Garibaldi: Why do I wanna know? Because I think of these things sometimes. I was getting dressed this morning - then I stopped and started thinking about it. Does everybody do it the same way? Does it have to do with cup size? Band size? Wrist strength?
Sinclair: Do you think about this stuff a lot?
Garibaldi: Yeah.
Sinclair: *sighs* Clasp, then twist. You?
Garibaldi: No twist, just clasp.
Sinclair: Huh.
Garibaldi: Do you put your arms through the straps first?
Sinclair: We're done.
- tess's blog
- Login to post comments
How does Drupal 7 Work, Part 2: The Development Environment
Submitted by tess on Tue, 2011-11-22 23:46Click here to read Part 1 of this series.
If your'e going to debug Drupal, or any PHP project, you're going to need tools. There's more than a few options to choose from. The most basic would be instrumenting code with print() or echo() statements. While it would be serviceable, it would mean modifying core itself, and that's generally considered a Very Bad Thing. For professional development, it appears the KomodoIDE is the most popular. It's reputation is that it "just works". If I were looking into professional tools, it might be worth the $300 price tag. Given my open source, Linux using, bent, what is there?
Eclipse
The Eclipse project is a IBM-backed, Open Source Integrated Development Environment (IDE). It provides source file editing, syntax highlighting, code completion, project storage, and it's extendable through plugins. Eclipse was born out the myrad of IDEs and GUI tools that IBM provided to develop and administer their various middleware projects. IBM no longer wanted to maintain all these separate tools, and set out to create One IDE to Rule Them.
Instead of one generic interface, Perspectives provide the appropriate views, editors, and functionality suited to the project at hand. This can be as simple as different programming languages, or a separate development and administration perspectives for the same enterprise product (such as WebSphere Message Broker). While Perspectives are Eclipse's greatest feature, they also cause huge amounts of confusion for new users. IMHO, Eclipse's bad usability reputation is due to a disconnect between an enterprise IT mentality from which Eclipse hails, and the expectations of independent developers that are expecting a domain specific IDE.
This is not to say that Eclipse doesn't have problems. It's a hulking beast of a program. It takes some time to load. And yes, configuration can be weird for some users (I have sadly noted many of those users are also particularly fond of a fruity brand of consumer tech). I'm actually quite comfortable with Eclipse thanks to my background in Middleware. It runs on multiple platforms, and I can easily acquire plugins for other languages.
PHP Developer Toolkit
One of those plugins is the PHP Developer Toolkit (PDT). It extends Eclipse's functionality, providing the IDE the necessary know how to work with PHP code. This includes syntax highlighting and code completion. It's the bit that makes plain Ecplise into a PHP IDE.
There are two options to install PDT into Eclipse. You can download a pre-bundled tarball of Eclipse with PDT already installed. This is easiest for many users. The other option is install a base copy of Eclipse and then use Help -> Install New Software to install all the required modules. I prefer this method on Linux platforms as it allows Eclipse to be installed with the Linux distro's native package manager.
Some users will be shocked at just how many clicks this requires, and it is a lot. You have to select the modules, agree to the license agreement for each module, wait for it to download, then restart the IDE. As enterprise software goes, this is a cakewalk. The record holder for installation time I've worked with was three weeks. And no, you don't want to know what the installer looked like and how many clicks it requires.
XDebug
One component that PDT does not supply, is a debugger. I've never used a debugger with PHP before. Before I started using Drupal -- when I did most of my PHP coding -- they didn't even have debuggers. I needed something that was relatively easy to install, something current, and something open source. XDebug hit the sweet spot.
XDebug also has a bad rap among Drupal developers. It's often thought of too complicated to install, too fritzy, and does not work consistently.
I had XDebug working in 10 minutes flat.
How did I pull this off? XDebug only provides binaries for Windows systems, and source for all other platforms. Given the predominance of fruity computers in Drupal development, it's no surprise to me that attempting to build XDebug from source is a huge hurdle. (Besides, if you can afford one of their systems, why not plunk down $300 for the KomodoIDE?)
Being an FLOSS wackaloon, I use Linux. XDebug doesn't provide binary builds for Linux either, but that's not the end of the story. Many distros of Linux will provide a build of XDebug in their package manager. The distro I'm currently fond of is Arch, a rolling-release distro that does not even provide a graphical installer. Arch provides a build of XDebug in the Arch User Repository (AUR). I needed to only run the AUR wrapper script to install XDebug.
Getting XDebug and Eclipse PDT to Play Nice
XDebug is actually an Apache 2 module. You configure it as you would any other Apache module. When initiating a debug session, a $_GET variable is passed containing the debug session key. The PDT knows how to issue that key, so all you need to do is configure Eclipse to use XDebug.
First of all, you will need to configure Apache to use XDebug correctly. When I tried this, it turned out that AUR did all the work for me. However, you can hit up this page for a solid reference for getting XDebug up on Arch. Once configured, restart Apache.
Now Eclipse needs to be configured. This is best described as clumsy.
- Go to Window -> Preferences to open the Preference window.
- Expand the tree view on the left and select PHP -> Debug.
- Select the PHP Debugger as XDebug. If this option is not available, click the Configure link to the right of the pop-up menu and add the configuration. The default port of XDebug is 9000.
- Click the PHP Servers link. Add your server (localhost is OK!). Select your new server in the Servers popup menu.
- Click the PHP Executables link. Add a new PHP executable configuration with the following options:
- Set the Executable Path to /usr/bin/php. This is the default for Arch. Your distro may vary.
- Set the PHP ini file to /etc/php/php.ini. This is the default for Arch.
- Select the SAPI type to CLI.
- Select the PHP Debugger as XDebug.
- Return to the Preferences window. Click OK.
Initiating a Debug Session
I admit this one is more fussy than I had wanted, mostly because for this project I'm not developing any code. Eclipse PDT assumes that you have created a project with code to debug. When initiating a debug session, the expected workflow is to open the source file you intend to debug. Then select Run -> Debug As -> PHP Web Server. This switches Eclipse to the PHP Debug Perspective, and loads the file path you entered in step 4 above, passing the all important debug session key.
Currently, I have a project set up for a patch to Organic Groups. When I invoke Debug as PHP Web Server, it attempts to load the project file path, og-rules-patch/og.module, on the webserver, http://localhost/og-rules-patch/og.module. This would obivously result in a 404, but that's all that we need to start exploring!
Once we drop into the debugger, we can start stepping through Drupal code. Our first stop is how Drupal initializes -- drupal_bootstrap(). That's where we'll pick up next time.
| Attachment | Size |
|---|---|
| Screenshot at 2011-11-22 23:23:09.png | 154.2 KB |
| Screenshot at 2011-11-02 20:58:55.png | 138.02 KB |
- tess's blog
- Login to post comments
Recent Activity
- 1 of 188
- ››









Recent comments
7 weeks 3 days ago
19 weeks 6 days ago
20 weeks 4 days ago
25 weeks 6 days ago
33 weeks 2 days ago
41 weeks 6 days ago
1 year 5 weeks ago
1 year 6 weeks ago
1 year 40 weeks ago
1 year 44 weeks ago