Jay's WebLog

Mobile Devices, Xbox, and all things fun

  • Digital Picture Frame now on windowsfordevices.com!

    The good folks over at windowsfordevices.com published my blog entries in a more readable format :). You can check it out here:

    http://www.windowsfordevices.com/articles/AT8361803439.html

  • Series Review: Riverworld

    I started reading the Riverworld series last year and finished the fourth book (the ending) tonight. It's a cool scifi concept - everyone who has ever died gets resurrected on a world with one big river running through it, in a valley bounded by unscalable mountains.  It essentially one big one-dimensional world, and it started off with such potential.  Unfortunately, the ending is disappointing. Just read the amazon.com reviews.

    I recommend reading the first book, and just leaving it at that (it's has a somewhat satisfying ending).  I don't have much else to say about this series, but you can tell that I'm a little incensed by the anti-climacticness because I'm bothering to blog about it !  I took quite a bit of pleasure just reading the amazon reviews of the fourth book, so I can nod my head "right on brother!"  As I said, the first book was well-written and is worth reading, so don't let my review turn you off completely. Just ignore the other three books.  I wished I had read reviews before picking up the series, but I figured it must be pretty good since the Sci-Fi channel was making a series of it.  A lesson I learned... :)

  • Digital Picture Frame Part 2

    Digital Picture Frame (Part 2)!

    (go read Part 1 if you haven't)

    Hardware time!  I opened up the laptop and folded the LCD back behind the keyboard.  When I took apart the Thinkpad, it took me about two hours end-to-end.  Later on, I took apart my Dell in a similar amount of time.  So it's not that hard, you can do it  too! Thankfully, I was able to read the Junktop Revival Wiki so that gave me tips on where I should concentrate my efforts, what to take apart, what not to, etc etc :).

    Tools

    • Big flathead screwdriver (for use as a lever to open up the laptop case)
    • Small flathead screwdriver (for use as a lever to open up the laptop case)
    • Small Phillips screwdriver (to unscrew the laptop screws)

    Here's an image of the tools I used, so you can see how their relative sizes (they are resting on top of the laptop LCD, partially dismantled :) ).

     

     The Laptop

    Let's start with the laptop:

    Nice and pristine, right? Not for long!

    First I used the flat head screwdriver to pry apart the top panel.  I later realized that I really didn't have to do it (but that's not the point).  After removing the top panel and seeing that I actually didn't have to, I started getting more directed in my dismantling.  So I looked at the hinge, where the LCD connected to the rest of the laptop. (Oh yeah, somewhere along the way, I removed the hard drive, too)

    Hmm... I took the flathead screwdriver and pried open that little covering.  I did that to both sides, and had access to the cables going to the LCD.

    From there, I could easily fold back the LCD and have a pseudo picture frame. (after some of the panels on the keyboard itself).

    Notice the pen drive at the bottom left of the image... I know, the image is a little dark. That's where the images are stored.

    These are all the pieces I extracted from the laptop to get it to that state, and in less than two hours:

    I was amazed by how simple it was.  But anyway, I wanted to do MORE.  The LCD covering was just not ideal to put on a picture frame, I needed to get rid of the housing. So with my flat head screwdriver, I went and pried apart the LCD front:

    I also had to shimmy and slide the LCD to unstick it from the back, and so I was finally left with just this:

    Here are the two pieces of the LCD that I removed:

    Notice how I also extracted the speakers since they were attached to the LCD. Good thing I wasn't planning on using them (although I would have if I had the CE drivers for them).

    The Frame

    The frame was, for me, the hardest part of this whole project.  I discovered that I don't know how to cut 90 degree angles, even with a T-square!  I didn't take many photos while it was getting constructed, but I essentially bought:

    • Foamboard
    • Black construction paper for matting
    • A shadowbox to fit my laptop

    I was able to cut the foamboard to fit into the shadowbox, and cut an opening for the laptop and LCD.  The foamboard was about the same thickness as the LCD, so it made a nice wedge... I could fit the LCD in there, and stick the rest of the laptop to it (via duct tape or two-sided tape).  Here is the result, without the matting:

    The next step was to cut the matting for the frame, at a minimum to hide all the circuitry and cut marks in the foamboard. I had my exacto knife and black stiff construction paper all ready, and I cut a few matting.  However, each one had a problem... it didn't fit perfectly, or it wasn't at a 90 degree angle, or some other issue, so I repeatedly had to open up the frame, take out the laptop, take out the matting, and redo it.

    At this point, there's a twist to my tale...

    After one of the times I removed the matting... ARGH! I dropped the laptop!!!!!!!!!!!!!!!

    Fortunately, the laptop was OK. Unfortunately, the backlight of the laptop broke! I was at first extremely despondent about this, but then decided to pull myself up frmo my bootstraps again and dismantle the Dell!!!

    I didn't take pictures of my Dell dismantling because I was in a hurry to get it done. The Dell was different in that I needed to unscrew some screws to completely detach the LCD from the laptop.  In the future, I'd prefer Thinkpads, but Dells are still doable :).

    I just ordered a new backlight for my Thinkpad on Ebay, so I'll fix it up in the future.

    In the meantime, I re-cut the foamboard and re-cut the matting.  I wasn't as much of a stickler for perfection as I was with the Thinkpad, since I didn't want to chance dropping something again!  As the old adage goes, "Perfection is the enemy of the good." :)

    Here's my digital picture frame, with the Dell Inspiron inside it, and with a bigger matting, displaying images at 1024x768x16! :)

     

    Future Directions

    There are a number of things I can do to enhance this picture frame.
     
    1. Get a 2.5" IDE to CF adapter, and use it as a hard drive to boot the image from (find one here).  This way I can get rid of the CD-ROM and have no moving parts!
    2. Bluetooth support.  Windows CE detected a Belkin USB Bluetooth Adapter I tried, so I know it will work with Bluetooth.  I may upgrade to Windows CE 5.0 because it comes with a number of built-in profiles.  I can use the BT DUN profile to connect to a LAN via a BT gateway, so i can access and control the picture frame from computers or PocketPCs from the network. I can add images, have the picture frame email images, etc.  O the possibilities are endless! :)
    3. One of the things that I'd like to see (or know) - since Windows XP and Windows CE both support NDIS drivers, would a driver that was written for Windows XP work on an x86 CE?  Well it shouldn't, but maybe parts of it that don't rely on the Win32 API might.  Just a thought... then I wouldn't have to have much hassle in getting drivers for various hardware :)!
     
    If you have any questions or comment, please email me :).
     
    Enjoy!
    Jay
  • Digital Picture Frame Part 1

    Digital Picture Frame (Part 1)!

    I was inspired to create a digital picture frame after seeing the Junktop Revival Wiki as well as Mike Hall's project. I wanted to reuse one of my old laptops, a Thinkpad, but the issue was that I didn't want a hard drive - a hard drive would just be too noisy for me. So out went XP, in came Windows CE.

    Here are the features of the laptop digital picture frame:

    • No hard drive
    • Boots off a CD-ROM
    • Recognizes and reads random pictures off of a USB Mass Storage device, fired by a timer. Storage device is hot-swappable.
    • no keyboard or mouse necessary for basic operation
    • two keyboard keys can increase or decrease the image display timer interval
    • spacebar can jump to the next image
    • after bootup, no more CD-ROM access is required. The whole Windows CE operating system is less than 10 megs, and fits neatly in ROM. (I can cut it down further if I looked hard enough )

    The Application

    The software was relatively straightforward.  Upon startup, it maximizes to take up the full screen and gives it a black background. It polls every five seconds for files.  The frequent polling is necessary because the USB storage device isn't ready immediately after the OS boots up.  Anyway, after the first time it reads the files, the timer interval goes to 60 seconds, which is adjustible by the keyboard.

    For each tick of the timer, the program gets a list of the files in "\Hard Disk" (that's what Windows CE recognizes the USB Mass Storage device as) and displays a random image.  That's pretty much it.  If there's an error reading a file, the program simply just leaves the existing image up and waits for the next tick.

    The image stretch logic is pretty simple - the app gets the dimensions from the Bitmap object, and stretches the picturebox that the Bitmap is displayed in to such that the proportions are maintained while maximizing the real estate of the screen.

    The Operating System

    I took Windows CE's Platform Builder 4.2, and generated a custom Windows CE OS.  I based it off the Mobile Handheld design, but took out a bunch of things, and added .Net CF and USB support.  Ideally, I wanted PCMCIA support in my device so then I could plug in a WiFi card, but I couldn't find a driver for the PCMCIA chipset, a TI1225 (note, this wasn't my Thinkpad I was looking at, this was in my Dell Inspiron. I flipped back and forth between the two laptops for this project ).

    Windows CE 4.2 and 5.0 both came with drivers for the TI1250 chipset, but not the 1225. I went online and found a vendor who offered a TI1225 driver, but they didn't seem to be interested in giving me a copy  so I decided to forego it.  I didn't want to write a driver for this project. So, as I said, I added USB support for Mass Storage.

    For the platforms, I added a CEPC and Emulator platform.

    There were two custom modifications I had to make: Change the taskbar to be auto-hide and not on top, and launch my app (called "pictureframe.exe" for you creative types).

    To set the taskbar state, I added these .reg keys to %_PROJECTOAKROOT%\files\project.reg

        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell]

        ; If your browser doesn't display it, there is an 0x01 ASCII below

        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell\AutoHide]
          @=""

        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell\OnTop]
          @=""

    I got these reg keys by manually setting them in the emulator, and using Platform Builder's remote registry editor to see what changes in HKLM\Software\Microsoft\Shell.

    The second task - to boot up my app, I first added this line to my project.bib file:

        pictureframe.exe pictureframe.exe NK S

    to include the application in the image. Then I added these lines to project.reg to have the OS automatically boot up my app:

        [HKEY_LOCAL_MACHINE\init]
        ; @CESYSGEN IF CE_MODULES_SHELL
             "Launch99"="pictureframe.exe"
             "Depend99"=hex:32,00

    The first value specifies that pictureframe.exe is to be launched, and the second line says to wait for Launch50 (hex 32) to be executed before launching pictureframe.  Launch50 is explorer.exe (you can find this in shell.reg in the release directory).

    That's pretty much it. Next is the:

    CD Preparation

    I took a standard CEPC boot floppy disk (there is none in the final version), and modified it so that it will mount the CD-ROM drive as drive R:, and execute:

        loadcepc /L:800x600x16 r:\nk.bin

    The image is nk.bin, and the /L flag is the resolution to run the OS at (the Thinkpad could only do 800x600, the Dell could do 1024x768).  After I created the CEPC boot disk, I booted up Nero, selected CD-ROM (boot) as the CD type, and had designated the floppy drive to be the source of the boot image.  I was surprised at how complicated this was, actually. I thought that Nero could just put a DOS boot sector on the CD, but it needs a source drive to copy it from. When you think about it, it kinda makes sense (copyrights of DOS 6.22 and all that). 

    In the end, I had a spanking usable Windows CE image with my software on it!  (OK, it wasn't this simple, it was a very iterative process ).

    I'll post the hardware hacking part next time. I'm trying to keep these entries short!  If anyone wants more specifics on the source code (ugly) or the Windows CE project (easy), just drop me a line.

  • Investment for retail code debugging

    Scenario:

    The OEM runs hopper, our test app to verify MTTF.  The app simulates a user using the device, at a much faster rate.  Hopper will uncover deadlocks, Data Aborts, Prefetch Aborts, and other nasty things.  When they hit an abort, the OEM may need someone from my team to look at it, in extreme cases.  That often ends up being me.

    Doesn't seem so hard at first, but get this:

    • The OEM may contract an Independent Software Vendor (ISV) to write software for their device.
    • The OEM therefore may not have access to the source code
    • The ISV may not feel the urgency in fixing their own bugs (ultimately they will have to fix the code, but they would have limited time).

    Dealing with retail-optimized assembly code without necessarily having all local variables readily available to you isn't really fun.  Lots of calculations need to be made to access variables in memory.

    Yes, I know I could:

    • Use the Windows calculator.  The issue is simple: screen real estate.  the OEM might be running the MTTF test on 10 laptops - and if one breaks, calc.exe takes up lots of screen real estate. And it doesn't let you easily switch between hex and dec mode (you need to use the mouse :) ). This is what I actually used.
    • Use the PocketPC calculator.  I like using one hand, without looking at the buttons. The lack of tactile feedback is a disincentive.

    So today, I saw this, and was totally psyched!  A free scientific calculator that does hex!  We'll see how handy this is next time I get called to look at some breaking code.

  • Digital PictureFrame Info

    Mike Hall recently blogged about me building a digital picture frame. It is true :).  I'm going to post some images and some text about it once I write something up - I downloaded BlogJet for that very purpose.  It's written in .netCF, running on a custom Windows CE OS. The reason I used Windows CE is that I wanted something compact that could operate without a hard drive - no noise! I was then able to burn the whole OS and app onto a CD (flipping necessary reg keys to start up my app).  Another advantage of CE is that I could potentially copy this onto a CF card, and use an IDE-to-CF adapter to completely remove the laptop of moving parts.

    Here's a quick preview:

     

    BTW if anyone knows of anyplace where I can download cool 1024x768 wallpaper for free without any watermarks, let me know ;)

  • Image Triage app?

    What is a good app for image triage?  When I say image triage, I mean something that will:

    • Read images off a storage card (I generally don't use USB/Camera cables)
    • Allow me to quickly decide whether I wish to keep an image or not
    • Rename and file the picture into a directory

    Currently, I use BreezeBrowser. It's pretty good, and it reads Canon .CRW files.  If anyone has a better app recommendation, let me know.  I have a Canon Powershot G1 (main "art photography" camera) as well as a Nikon Coolpix 3700.

  • BlogJet test - first post

    Thanks to mikehall, I'm up and running on blogjet now. Testing an image upload... I took this at the 2002 Tulip festival (overexposed so it looks great).  OK I admit I edited the sky since the original pic was all white :)

     

  • Peeve: Long URL names for RSS feeds

    Request to RSS providers, PLEASE use short feed URLS! If I have a PocketPC or Smartphone with an RSS Reader on it, I'd like to add your feed quickly! :).  Having long names makes it a disincentive for mobile device users to read your pages.

    Example (sorry BBC): http://news.bbc.co.uk/rss/newsonline_world_edition/technology/rss091.xml

    How about shortening that to:

    rss.bbc.co.uk/news/tech/rss091.xml ?

    I think that is sufficient to capture the hierarchy presented in the original URL.

    Rant off.

  • .Net CF Newbie on Smartphone!

    As some of you may know, I’m in the process of writing an RSS reader for my Microsoft Smartphone 2003.  It will be running on Net CF.  Since it is an offline RSS reader, I wanted to have the ability to download RSS files for offline reading.  So I had a function, StartDownloadAll() which would iterate through each feed that I’m subscribed to, download the data, eliminate dupes and old items, and save them. In the code, sprinkled throughout, I have lines like:

    this.text = “Getting data”;

    this.text = “Saving data”;

    where this refers to the form.

    When I ran through my prototypes, I realized that it was too slow to do this synchronously, I needed to spawn a thread to do this so the UI can still be responsive to the user.  So because C# makes it so easy to create new threads, I ran StartDownloadAll() asynchronously, in its own thread (I’m glossing over some hairy synchronization details, which I’ll get to below).

    The problem with doing this is that in C#, you’re not allowed to update a control from a thread that did not create it.  If this was Win32, I would have been more alert, but C# lulled me into a false sense of “everything will work, or else it will throw an exception”.  However…

    After I did this, my program started behaving erratically. I’d get random Close() events (and who knows what else could have gone wrong?).  Eventually, I realized my mistake and converted offending functions to use Control.Invoke() (Actually, I used a modified ControlInvoker class).  This leads me to the questions:

    1. Should NetCF throw an exception instead of just providing undefined behavior when someone updates the UI from a separate thread? In light of .Net’s attempts to prevent users from shooting themselves in the foot, would this be a good philosophy to follow? I recall hearing that Avalon will provide this functionality, but it’s just a rumor…  I don’t even work in the Windows division so I probably wouldn’t know :)
    2. Would it be costly to have a class verify that a control was created on a different thread before calling Invoke? I might actually code something up, but I don’t think it will be trivial – I’d probably have to manually keep track of which controls were created on which threads.

    OK, enough of that.

    I mentioned some hairy synchronization details.  Here’s something that I found out (and probably you .NetCF experts have better workarounds)… suppose I have


    void myForm_Closing(object sender, CancelEventArgs e)
    {
                lock(this)
                {
                            QuitDownloadingStuff();
                }
    }

    The QuitDownloadingStuff() method will cause the running download thread to quit, and wait for it to quit before proceeding.  However, as part of the quitting in the other thread, it does the Control.Invoke() equivalent of:

                this.text = “Aborting…”;

    This calls back into the UI thread, which is waiting for this function to exit, and thus we end up in a deadlock!  I was sorely confused when this was happening to me – since I didn’t have any double-locking going on.  I fixed this by having QuitDownloadingStuff() return immediately, and I launched a timer to detect whether the thread is actually dead before allowing closing to proceed.

    If anyone has any better ways of doing this, let me know, I’m all ears! :)

  • Howdy yall!

    Howdy, I'm one of the developers on the Windows Mobile Partner Response Team.  I'm interested in a .Net CF development on the side - I'm in the process of writing an offline RSS Reader, and hitting across the features (and limitations :) ) of the framework :).  As for the SDK's, it looks like one of the things that would be useful for developers (perhaps part of opennetcf?) is some managed wrappers around WM2003 SDK features (off the top of my head - Connection Manager, services.exe integration, etc).

    Anyway, feel free to drop me a line if you have any ideas (on the app or anything else :) )


© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker