Category Archives: Linux

towards a good night’s rest

Throughout college, suffice to say, I didn’t sleep much. If you know me well, you probably know the myriad reasons for this.

Nowadays, artificial lighting can cause the Dim-Light Melatonin Offset to be pushed back. Anyone who has lived on a farm or near a construction site knows that until recently, the light of the sun was the only light by which we could work, and our bodies adjusted accordingly.

It’s not much of a surprise, then, that staring into the bright light known as a “monitor” can impact some people’s sleep schedule vastly. It’s supplanted by the fact that for many people, night time frees them from the distractions of the day – people and the world outside in general.

amber on mac

I was fortunate enough to find an application for my Mac called Nocturne (from the makers of Quicksilver, in fact). It inverts the colors and can even tint a monochromed version of the inverted image – think green or amber terminal. An amber tint removes the blue light that is known to principally inhibit the production of melatonin, setting your monitor to this amber-on-black setting in the evening may help things out.

amber on linux

Compiz provides many of the shiny effects on Ubuntu. The CompizConfig Settings Manager (not installed by default – check apt) has a color filter plugin available primarily for those with colorblindness. However, negative and negative-green options are provided for low-light computing. Green is a nice choice, but amber will give us the best results. Unfortunately, there’s no easy way to set the tint from CompizConfig.

doing things the linux way

or, an adventure in OpenGL ARB fragment programs.

The filter configurations are hidden away in the

/usr/share/compiz/filters

folder. let’s check out the source for negative-green:

!!ARBfp1.0
TEMP temp, neg;
TEX temp, fragment.texcoord[0], texture[0], RECT;
RCP neg.a, temp.a;
MAD temp.rgb, -neg.a, temp, 1.0;
MUL temp.rgb, temp.a, temp;
MUL temp, fragment.color, temp;
SUB temp.rb, temp, temp;
MOV result.color, temp;
END

This is no GLSL, folks. This is the real deal: ARB OpenGL Assembly Language – specifically, a fragment program. It probably looks somewhat familiar if you’ve seen x86 or RISC assembly before.

I won’t say the approach used to invert the pixels is trivial, but we can eventually spot where the green tint is being applied:

SUB temp.rb, temp, temp;

This line takes the vector temp, subtracts temp (yielding the zero vector), and stores it in the .rb component of temp. Because temp is a color vector, the r and b stand for red and blue, leaving only the green component and alpha component intact.

Converting this to be a pure-red filter is simple enough – we’ll just subtract green instead of red and be set:

SUB temp.gb, temp, temp;

This makes a very nice red tinted inverted filter.

inevitable last 2% difficulty

Next, of course, I wanted it a bit dimmer – 100% red is still fairly blinding in the dark. Easy, except for the catch with open source:

Modifying someone else’s code is one thing. Writing your own is different.

I honestly had no idea what I was doing in ARB, but RenderGuild kindly provides an ARB assembly quick reference. Multiplying the .r component of my color seemed like the right thing to do, and to an extent, I was right. I also now believe that the alpha component (.a) has to be dimmed. Based on those two needs, I came up with these two instructions:

MUL tempColor.a, 0.6, tempColor.a;
MUL tempColor.r, 0.6, tempColor.r;

Perhaps there needs to only be one or the other, and perhaps they could be combined into a single instruction. It does, however, work to my liking.

notes on writing shaders

Mac OS X’s OpenGL Shader Builder was invaluable to checking the compilation of my sloppy coding and, more importantly, hinting at why it was wrong.

notes on Compiz filter switching

While I was working on the shader, I had some strange things such as near-all-red and near-all-black displays happen, with fading at the corners. I’m unsure why this happens, and may be a bug. Cycling back through again usually puts you back where you expect to be.

the grand results

Here’s the source to my fragment shader. It can be downloaded here.

!!ARBfp1.0
TEMP tempColor, negColor;
TEX tempColor, fragment.texcoord[0], texture[0], RECT;
RCP negColor.a, tempColor.a;
MAD tempColor.rgb, -negColor.a, tempColor, 1.0;
MUL tempColor.rgb, tempColor.a, tempColor;
MUL tempColor, fragment.color, tempColor;
SUB tempColor.gb, tempColor, tempColor;
# here is where we will dim.
MUL tempColor.a, .6, tempColor.a;
MUL tempColor.r, 0.6, tempColor.r;
MOV result.color, tempColor;
END

endnotes

I experimented with this kind of filtering during college starting at about 22h00 with a regular bedtime between 00h00 and 01h00. Now that I need to be sleeping sooner, I’ll likely push that back to… whenever sunset is.

This isn’t the solve-all for my sleep problems. Waking is still difficult to predict – blackout drapes are necessary for me to sleep, and therefore the natural light cues are absent for waking. With an alarm, I wake up to a dark vacuous room, which isn’t hugely motivating. I’ll be experimenting with an iPhone app (Climate) and perhaps building a gradual-wake LED light with my Arduino.

However, it has helped, and hopefully it can help someone else too.

Taking Arduino to the next level with avr-gcc: Part 2

Our AVR toolchain

For our example project, we will create two similar toolchains – one for Mac OS X and one for Linux. ┬áHere’s a visual overview of how code will flow:

toolchain.png

If you’ve developed with C or C++ before, the diagram should look familiar. I’m assuming just one object here – if we had more, avr-ld works much the same as our traditional linker does. And, of course, we can write C++, tossing avr-g++ in for avr-gcc.

On the Linux side, I chose not to set up an IDE, but maybe my Mac approach will help you set one up. For Mac, I set up a Makefile-based Xcode project and run script to invoke these tools in order and provide the “pretty” Build Results screen. Someday, I hope to introduce gdb on-device debugging, but for now, it’s Build and Run only.

Toolchain Construction: Mac OS X

I’m assuming that if you’re reading this, you probably already have Xcode. If not, it’s not strictly necessary – you can follow the text editor + command line formula outlined for Linux equally well on OS X.

Our big helper here is MacPorts. If you have the latest version already installed, you can skip the next section.

Installing MacPorts

MacPorts is a great package management tool for Mac OS X, akin to ports on BSD and apt-get on Linux. A .pkg (standard OS X) installer is available here. Download the .dmg, mount it, and double click the Installer package. The usual installer semantics apply here.

Updating MacPorts

I neglected this step and it bit me hard.

Fire up Terminal.app and issue:

sudo port -v selfupdate

which will ask you for your password. Now, we can start the fun of actually installing the appropriate packages from the repository.

Installing Relevant Packages

We may not need all of these right away, but here’s our grocery list:

  • avr-binutils – tools for cross-platform development with AVR
  • avr-gcc – the bread and butter of our toolchain, obvious from its name.
  • avr-gdb – again, from the name, the GNU debugger for AVR.
  • avr-libc – some core C functions for use on the AVR platform. Without this, our programs probably won’t be very useful (or pretty).
  • avrdude – AVR flasher software.

To install them, again use Terminal.app, this time with the command:

sudo port install avr-binutils avr-gcc avr-gdb avr-libc avrdude

You may see some unrecognized packages floating by; these are likely dependencies of the packages we wish to install. It is normal for this process to take quite some time. Let’s all go to the kitchen and have ourselves a snack!

Test the new toys

After some time, everything will be built and ready to go. This is the moment of truth where we see if your PATH environment variable is set up to play nicely with MacPorts.

Create a new Terminal window and try running the command:

avr-gcc -v

The response should end with something like

gcc version 4.0.2

If that’s so, it looks like you’re ready to rock!

Toolchain Construction: Linux

For Ubuntu users, grab the following packages via apt-get or synaptic:

  • binutils-avr – tools for cross-platform development with AVR
  • gcc-avr – the bread and butter of our toolchain, obvious from its name.
  • gdb-avr – again, from the name, the GNU debugger for AVR.
  • avr-libc – some core C functions for use on the AVR platform. Without this, our programs probably won’t be very useful (or pretty).
  • avrdude – AVR flasher software.
  • avarice – If we need to do GDB over JTAG.
  • simulavr – Simulates AVR hardware for debugging and testing.

If you’re down with the terminal (and I hope you are), grab them all at once with the command:

apt-get install binutils-avr gcc-avr gdb-avr avr-libc avrdude avarice simulavr

Create a new Terminal window and try running the command:

avr-gcc -v

The response should end with something like

gcc version 4.3.4

If that’s so, it looks like you’re ready to rock!


UPDATE: Part III is available here.