Thursday, June 16, 2011

Sunrise Alarm Clock - June 16, 2011

This post has been delayed by end of term schoolwork and a trip to Canada.

This time:
  • Replaced standard transistors with optoisolators
  • Tested with 6V lantern battery power
  • Cleaned up code and removed debug println statements
  • Re-added alarm sound code that now plays at the alarm time
  • Added alarm silencing switch, checked by software
  • Ran over a week of overnight tests
Problems (resolved):
  • LCD display corruption problem
    • Touch leads to the AC dimmers were noisy, test meter showed a range of about 6mV
    • Noise may be greater than that if it is 'too fast' for my handheld meter
    • An EE store employee suggested using optoisolators.  This appears to have fixed the corruption problem!  More details below and in the attached schematic.
    • The optoisolators that worked best were TIL 111 9490 six pin optoisolators, data sheet here: http://www.datasheetcatalog.org/datasheet/QT/TIL111.pdf

  • Battery power problems: tested 6V lantern battery
    • Output voltage appears much more stable than 9V combinations tried before
    • Estimated battery life is about 2 days (based on 10,500mAh for carbon-zinc battery)
Details:

I have now fixed most of the major issues and have used the sunrise alarm several nights in a row.

The major improvement this time was the addition of optoisolators to fix the LCD corruption problem.  Optoisolators work by separating the controlling circuit from the controlled circuit.  The controlling circuit powers a small LED inside of the optoisolator.  On the controlled circuit side, a phototransistor connects the collector to the emitter depending on how brightly the led is lit.  For my circuit, the touch leads to the dimmer are again connected to the collector.  This time, the emitter is connected to the negative lead of the supply to the Arduino, rather than the controlled ground provided by the Arduino.

With the electrical design of the alarm clock complete, I am uploading a finished schematic (drawn in a diagramming program called Dia).

I will upload the full software and sample configuration file once I have finished polishing the code.

Schematic:


The full schematic for the Sunrise Alarm Clock.  Click above for full-size image.
Next update (in a week or two):
  • Finish cleaning / commenting code for public use
  • Post all source code files and sample configuration file
  • Post parts list

Saturday, May 14, 2011

Sunrise Alarm Clock - May 14, 2011

This week:
  • Added dimmer leads to circuit board, connected via transistors
  • Added battery switch to side of case
  • Added switch and momentary button for LCD backlight
  • Implemented time logic needed for the alarm
  • Ran first successful full overnight test
  • Split the code from the .pde file into .cpp and .h files for easier IDE editing
Problems (resolved):
  • Hit maximum code size
    • temporarily switched out code sections
  • Int overflow in time calculation
    • switched to long
  • C++ modulus operator returns a negative value when using a negative value
    • Ex: -12 % 7 = 2, but arduino returns negative value for this operation (-5, I believe)
    • (needed modulus for time calculations)
    • Wrote custom modulus function to always return positive values
  • Difficulty getting am/pm correct when adding/subtracting time
    • lots of testing, println statements
    • to make this easier, should have tested this off-board (in java, etc.)
Problems (unresolved):
  • Trouble running on battery power - voltage falls quickly on standard 9V batteries, even with LCD backlight turned off.
    • Single used 9V battery (tried several)
      • Voltage quickly falls (to below 5V), but recovers after being disconnected
    • 3 x 9V batteries (all new) in parallel (still 9V, but 3 times the available current)
      •  Voltage fell to near 8V, but started to stabilize
      •  Seems like it may last for one night, but very expensive
    • 8 x AA batteries in series (1.4 V * 8 = 11.2 V total)
      • Seemed to be working and holding supply voltage above 10V
      • Also seems expensive (12 AA batteries for one device)
    • Putting battery-operation aside for now, leaving 9V connector and battery switch, which switches both (-) and (+) to help prevent draining
  • LCD display corrupted with the new code
    • a friend says this may be because of power supply issues
    • for future troubleshooting
Details:

This  week's work was more difficult than expected.  The time calculations (simple addition/subtraction) took quite a bit of work.  I ran into problems with integer number of seconds when I tried to add 5 or 6 hours (21600 seconds) to the current time.  I also had trouble with the update time calculation.  At first, I tried storing the next update time for each lamp separately.  In the end, I made an array of all of the update times, tagged with which light they were for.  The above may be confusing without more detail:

The idea of the alarm is to set an 'alarm time' by which one/both/all lights will be in the 'fully on' state.  The dimmers I use have 4 states: off, low, medium, and high.  Because I want the 'sunrise' to happen gradually, the clock increases the state of the dimmers in even time intervals.  The total duration of the 'sunrise' is given in the configuration file.

An example (not in config file format):

For two lamps both starting in the off state:

Alarm time:
8:00:00 am


Sunrise duration:
30 min

Update times:
7:30 am - change lamp 2 to low
7:36 am - change lamp 1 to low
7:42 am - change lamp 2 to med
7:48 am - change lamp 1 to med
7:54 am - change lamp 2 to high
8:00 am - change lamp 1 to high

By alternating lamps and incrementing the brightness slowly, the system simulates a 30-minute sunrise.  The sunrise can be as short as about 3 minutes or over an hour long (I assume, as I have not yet tested long durations).

Because of the large number of test-println's I needed to get this working correctly, I temporarily disabled the code to play a sound alarm and the code to read settings from the SD card.

Pictures:

The updated setup.  The switch and momentary in the middle are to control the backlight.  The orange and purple wires in the center-top connect to the dimmers.  They are attached to the collector of a transistor whose base is connected in parallel with LEDs.  When the program turns on the LEDs momentarily, the collector is connected to the base (resistor to ground), and the dimmer is updated.

The two large black boxes are simple touch-dimmers.  Normally, a user would touch the black disc to change the light strength.  In this case, the orange and purple wires allow the Arduino circuit to control the dimmers (see above for details).  These simple dimmers cost about $8 each, an excellent alternative to expensive relay circuits, etc.  The dimmers above can control up to 120 watts each.  Because they are a basic model, they are also easy to open (caution: live 120VAC inside).

The lamps controlled by the dimmers.  The left lamp has one 3-way 150Watt bulb, with the lamp switch set to 150W.  The right lamp has 3 x 40 Watt bulbs.  The dimmers only work (well) with incandescent lights, which is why the CFL in the left lamp is off.  The picture above shows both lamps at full brightness.

Next week:
  • Add sound alarm to play at the end of the sunrise
  • Re-enable reading settings from SD card
  • Remove or comment out unneeded testing println's
  • Fix LCD corruption problem
  • Clean up cpp/h structure (if time available)

Saturday, May 7, 2011

Sunrise Alarm Clock - May 7, 2011

Before today, the project already:

Connects to a US Navy time website (plaintext time in HTML), downloads, parses, and displays the current time on the LCD screen

Initializes the SD card library and prints the directory contents to the Serial output (functionality copied from SD card example library)

Keeps time fairly accurately, updating to the Navy site every 15 minutes.  In each 15 min interval, the device is fast or slow by less than 15 seconds.

Today:

Created alarm configuration file

Device now loads most alarm settings (time, sunrise duration, alarm song) from the configuration file on the SD card.

Device now beeps high when starting to update time.  Beeps low to warn if updating time failed.

Device now plays tune specified by frequency/duration pairs in the configuration file.

Pictures:

The device in it's box.  While there is a connection for a 9-volt battery, the batteries I have tried die quickly (few minutes to less than a few hours), so the device may draw too much power to be run from 9V batteries...

The LCD display shows the time of the last online time update, the current time, and the alarm time.

The Ethernet board works exceptionally well for this project, providing both Internet access and file access from microSD card.  However, I did have to re-select the pins for the LCD display to avoid interfering with the shield.
Next week:
  • implement calculation of when to update lights
  • add leads for lighting and run a full test (start using at night?)
  • post to arduino project blog

The beginning

Having worked on Arduino for some weeks now, I've decided to start recording my progress with this blog.  I hope it will be a place to share code and ideas with others.

At the moment, I have two main Arduino project ideas:

  1. Sunrise alarm clock (active)
  2. Virtual Memory on the Arduino Uno (waiting until summer)
Sunrise alarm clock

You may (or may not) have heard of these before.  Basically, a sunrise alarm clock is a clock that slowly raises the light level in the room to simulate a sunrise.  The idea is to clue your body in that it's almost time to wake up, so you can come out of deep sleep cycles and wake up naturally.  It may also help get your circadian rhythm on track in places with poor sunlight, like Seattle.  These sunrise clocks are available commercially, but they can be pretty expensive (most are $70+).

As an Arduino project, this has value because it requires:

Accurate clock time
- to change the brightness at the right time

Control of 120 volt AC
- to control the lighting

LCD display
- current time, alarm time, settings, etc.

SD card access (optional)
- loading clock settings from file

Web server (very optional)
- set clock settings via HTTP from an Arduino-hosted local webpage

Virtual Memory on the Arduino Uno

If you have used the Arduino Uno, you may have noticed that in complicated projects, the first thing to run out is your available RAM (The new UNO has 2Kb of stack/data space RAM).  Typically, the device just stops executing code when this happens.  The way this problem is solved currently in full-size computers is with virtual memory.

Basically, when the device is running low on memory,  the virtual memory manager takes a chunk of RAM, saves it somewhere else, and opens up the free space for other parts of the program to use.  When a value is needed that was moved out of RAM, the virtual memory manager moves the original chunk back to its place in RAM and swaps or pages the current RAM out.  On desktop systems, virtual memory is swapped/paged out to the hard disk.  This trading process allows each process (basically, each running program) on a 32-bit computer to have access to 2GB of virtual RAM, even if the computer itself has only 256 or 512 MB of actual RAM.  The tradeoff is that each virtual 'swap' takes time.

On the Arduino, we do not have a standard desktop hard drive.  Instead, with the Ethernet board, we get access to an SD card, essentially a flash memory hard drive.  My hope is that the flash memory will run fast enough to make the virtual memory operation reasonably quick, even with the UNOs 16MHz processor clock speed.

There is one very significant hurdle for building virtual memory on the Arduino UNO:  The processor does not have memory-based interrupts or a memory management unit.  In most desktop systems, the processor will stop and ask the operating system to interpret any virtual memory address it tries to use.  The memory management unit helps by remembering some of the operating system's answers, which makes virtual memory on a desktop (or laptop, etc) computer much faster.  In the Arduino UNO, the processor will not ask for a virtual address translation at all.  So how will we know when it is time to page the memory in and out to the SD card?

I talked with one of the professors at my university (University of Washington - Seattle; go Dawgs!) and we had some vague idea that it may be possible to change the assembly code of the program to make the memory conversion happen in software rather than in hardware.  A few Google searches brought up this paper, which also uses this idea.  Basically, we replace every data memory reference with a call to the virtual memory manager.

As an Arduino project, this has value because it requires:

Knowledge of the UNO's memory structure

Extensive programming in C++ with pointers/etc.

Familiarity and re-engineering of Bill Greiman's sdfatlib for the SD card (tutorial here)

Work with assembly code

Possible work with the compiler avr-gcc

Goal:

The goal of the project is to release a virtual memory library for the Ethernet shield that increases available RAM with little or no configuration from Arduino programmers like you!