I was so excited about fixing that Polaroid DVD recorder on Thursday (see my last post) that I remembered I had an RCA DVD recorder also sitting around that had quit working. Quite a while ago, we had a power outage. When the power came back on, my RCA DRC8052NB DVD recorder wouldn’t turn on. The LCD on the front panel turned on, and the message “HELLO” scrolled across it. I couldn’t get it to stop without unplugging the power.

The normal behavior when you first plug it in is for the “HELLO” message to scroll across for a few seconds. Then it’ll say something like “NO DISC”. Finally, it’ll shut itself back down and display the time, waiting for you to power it back up. Then, when you press the power button to turn it on, the “HELLO” message will come back for a few seconds, and finally it will turn on and display the current channel number or “NO DISC” or whatever else, depending on the mode you left it in when it was last turned off.

Anyway, so “HELLO” kept scrolling indefinitely. I figured it was a similar problem to what I saw on the Polaroid DVD recorder. The difference was that in the Polaroid DVD recorder, nothing displayed on the front panel. At first thought, I figured it might have something to do with the power board. But because the LCD was displaying a message, that made me a bit skeptical because you’d think a program on the main DVD board would be displaying that message, which would mean the main DVD board would be getting a good 3.3V power input.

I went ahead and checked it out with my multimeter. This power supply board is a bit different because it needs some sort of signal to tell it to turn on. I tried powering it up with its cable that goes to the “motherboard” (I don’t know the technical term for it, so I’ll call it the motherboard from now on) disconnected, but nothing happened. So I had to leave the motherboard plugged into the supply while measuring the output voltages. Anyway, the 3.3V output was only 2.8V, and several of the other voltages were pretty far out of range too. Some of the 5V outputs were only 4.5V, and the 40V output was only 35V. Sounds like a power supply problem again…I guess the “HELLO” message doesn’t necessarily mean the output from the power supply is good.

My suspicion was confirmed when I found some other postings online about this exact same model. In fact, this question on FixYa has several answers all pointing to a single capacitor that was probably causing the problem. Another post on FixYa also seemed to point toward capacitors.

None of the capacitors on the power supply board looked weird. In the Polaroid DVD recorder I fixed earlier, two of the capacitors were bulging. In this one, nothing looked weird to me. But an answer to that first FixYa question I linked to above also pointed out that the capacitor looked OK but was still bad.

Based on the first FixYa question, I went ahead and desoldered the 1000uF, 6.3V capacitor (C22). Multiple answers in that question implied that particular capacitor was the source of the problem. Interestingly enough, the footprint on the board for that capacitor is a lot larger than the actual capacitor soldered in. It makes me think that perhaps the board was originally designed for a cap with higher ratings.

Luckily, when I fixed the Polaroid DVD recorder, I ordered two of each capacitor I replaced, even though I only needed one. As you’ll remember, one of those capacitors was a 1000uF, 16V capacitor. It perfectly fit the footprint on the RCA DVD recorder’s power board. Since it was the same capacitance with a higher max voltage, I was good to go.

I soldered it in, put the power board back into place and reconnected all of the wires going into it. I plugged the DVD recorder back into AC power. The “HELLO” message came on, and I crossed my fingers. A couple of seconds later, the “NO DISC” message appeared, and shortly thereafter, the display read “12:00 AM”. Awesome!

I pressed the power button to turn the DVD recorder back on. Then I measured some of the power board’s outputs. The 3.3V output now was correctly at 3.3V. The 40V output was still pretty low (36V) but it was higher than it was. I didn’t bother to check the 5V outputs because it was a tight fit and I didn’t want to short anything like I did in the Polaroid one!

Anyway, thanks to roybro123 and neveo1999 on FixYa. Their answers helped revive my DRC8052 DVD recorder.

Before I realized that I already had a 1000uF capacitor sitting around here, I ordered all new capacitors on DigiKey for the DVD recorder. Oh well–it’ll be nice to have the spare parts laying around in case another one goes bad.

In conclusion, cheap capacitors suck. Companies are saving a few pennies by using cheap capacitors instead of high-quality ones. Or maybe they’re not allowing for proper ventilation and the capacitors are getting stressed from too much heat. Something along those lines. It’s a little disturbing to me that these products came from two different manufacturers and they both had bad caps as the problem. The problem was widespread enough that other people saw it too. Whatever happened to quality control? I actually bought both of these DVD recorders on Woot.com for a really good deal, refurbished. I think I now know why the manufacturers were getting rid of them for so cheap. But anyway, Woot is an awesome website you should check out some time. 10 PM pacific time every night–a new deal!

Now that I’ve done some electronics repair blogs, I think I’ll go back into my area of expertise–computer stuff. I’m an electronics newbie. My soldering technique is terrible and I really don’t have a clue what I’m doing. I probably have no business working on power supply boards. I work for a company that makes electronics, but I don’t do any of the electronics stuff–I write software. But having coworkers around to answer my questions about the hardware stuff helps, so I guess that’s why I feel comfortable working on this stuff without worrying about getting lethally shocked.

Anyway, I don’t know what my next blog will be about, but I’ll think of something soon! Until next time, goodbye!

So today I finally fixed this Panasonic DRA-01601A DVD recorder. The symptoms were the following: you plug in the DVD recorder. The device automatically powers on, the fan starts spinning, and nothing else happens. The front display stays completely black, nothing appears on the video screen.

If you actually plan on trying this, BEWARE. The power supply board can carry high voltages that are very dangerous. There’s a reason these devices have a sticker telling you not to open it because there’s an electric shock risk. The big black capacitor near where the AC power enters the board can hold high voltages and should be discharged before working on it. If you don’t know what you’re doing, get someone else who does know what they are doing to fix it for you. I left it unplugged for a day and it was discharged by then, but I still checked it with a multimeter to make sure it was safe to work on the board.

I opened it up and disconnected the ribbon cable going from the tan colored power supply board to the green DVD recorder board. I removed it on the power supply board side so I could measure the power supply outputs. Using a multimeter I checked each output. The 3.3V output was out of range, somewhere in the 2-ish volt range. The rest were fine. I figured this was the problem, since it’s likely the DVD board needs the 3.3V output to run.

Looking at the board’s capacitors, I noticed two of them were bulging at the top. I circled them in red in the picture below. It may be hard to see in the pic, but the tops of those two capacitors look quite a bit different from the tops of all the rest of them.

Both of those green capacitors were bulging. In fact, the shorter one on the right had actually let out some gunk underneath. I replaced them with caps with matching capacitance/voltage ratings. One was 2200uF 10V, and the other was 1000uF 16V. I powered it up again and checked the outputs. The 3.3V output was now correct! I plugged everything back in, fired up the DVD recorder, and everything worked fine again. Great success! Honestly I probably should have replaced all four of those green caps. They look pretty cheap, and I doubt the other two will last long either.

Sidenote: While I was testing the outputs the first time, I accidentally shorted the -12V output to a nearby pin. I should have been more careful, but I was not. Unfortunately this caused a spark, and the power supply turned off momentarily and came back up. After that, the -12V output was screwed up and measuring very low voltage. I checked out diode D11 on the board and I had blown it–it was appearing as a short in both directions, pulling the output down to ground. The marking on the diode was not very helpful–it said something like:

C12
ET

Not the greatest identification. I looked for “C12 diode” on Google and most of the matches were 12V Zener diodes, so I got a 12V, 1W Zener diode (BZX85C12) and it seemed to work OK, and the output was fine after that. It was a little thicker than the original so maybe the original wasn’t 1W. Anyway, my guess is the diode was just for overvoltage protection, and it definitely did its job! (Or maybe it was being used as a cheapo voltage regulator?)

Edit 2: It looks like Qt 5.0 will now give us public access to QWinEventNotifier, so the contents of this article are definitely still useful. Thank you Leo (see the comments below) for pointing that out!

Edit: On April 30, 2011, Sebastian informed me that this approach no longer works in Qt 4.7.2. It looks like we no longer have access to the private header files. See the comments for more information where I describe what has changed and mention a few workarounds. My post continues unmodified below in case people are using older versions, or if we regain access to the QWinEventNotifier class in the future.

Lately I’ve been working with a CAN-USB adapter. I’ve been interfacing to it through a Qt GUI app. When you’re dealing with CAN, you need some kind of notification that you’ve received a message. On a microcontroller, an interrupt tells you when a message has arrived. With this CAN adapter, the driver needs to send some kind of notification to your app. Otherwise, you’re constantly polling to see if a new CAN message has arrived (and using up your computer’s CPU time needlessly).

This particular CAN adapter has both Linux and Windows drivers. The two drivers use slightly different APIs, so I’ve been using #ifdefs for the Qt app to work on both platforms.

On Linux, the driver gives you a file descriptor that you can pass to select() or a similar function to wait for activity, similar to how you’d wait for activity from a socket. In fact, that’s exactly how you handle it in Qt — you make a QSocketNotifier with the file descriptor the driver library gave you, and then the QSocketNotifier fires its activated() signal whenever a CAN message comes in. So this effectively integrates the USB to CAN adapter into the main thread’s event loop.

Dealing with this device in Windows is a little more complicated. First of all, the driver DLL doesn’t work with MinGW out of the box, but there are tutorials on the web with instructions to get a DLL compiled with Microsoft’s compiler to work correctly with MinGW. I can’t remember exactly how I did it, but those tutorials helped me with that. It was something about the way the functions in the DLL export file were named. Maybe I’ll write another blog post about that later, if I can figure out how I did it the first time. Bad Doug!

Anyway, the other thing about the Windows driver is that it doesn’t give a file descriptor to notify you that a CAN message has arrived. Instead, you’re supposed to pass it a Windows event handle, which it will then put into the signaled state whenever a message comes in. So you’re supposed to create a Windows event object with CreateEvent() and give the newly created event handle to the CAN library. Then, in a Windows app, you would use WaitForSingleObject() or something like that to wait for the driver to signal you.

Using this info, you could already solve the problem in a Qt app. Create a new thread in Qt that sits in a while loop, calling WaitForSingleObject() with an unlimited timeout. Whenever the event object is signaled, emit a Qt signal. You can then attach a slot in the main thread to that signal, and then you will be notified whenever a new CAN message is ready. This approach works, but it just seems like overkill because you’re creating a new thread with its own mini event loop just to forward the event to Qt’s event loop. Qt’s main thread already has an event loop, so why not just get the main thread’s event loop to listen for the event directly?

It turns out this is definitely possible to do with Qt. It’s just that the class is kind of hidden in the bowels of Qt, probably because it’s a Windows-specific thing. The class is called QWinEventNotifier, and you can use it in a Qt app by doing:

#include <QtCore/private/qwineventnotifier_p.h>
(Thanks, QExtSerialPort, for showing how to #include this class in your code–I saw it in Qt’s source code, but I couldn’t figure out how to add it in my program.)

From this point on, it’s simple. 3weyuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu (Sorry, that was the kitten.) Just create a QWinEventNotifier, passing the event handle returned from CreateEvent() to the constructor. Connect the QWinEventNotifier’s activated(HANDLE) signal to a slot. That’s it! Qt will take care of it from there, giving you a notification whenever a CAN message is ready for reading.

You don’t have to do anything special to be able to call CreateEvent, at least in my experience. Just #include <windows.h> and then you have complete access to CreateEvent and whatever other Windows function you need. It all just works.

I’m sure this can be adapted to work with other Windows event type stuff. Since my description of this solution was a little abstract, I’ll provide a concrete (silly) code example. I create a thread that does nothing other than signal a Windows event object every second or so. This is basically simulating the CAN library signaling when a message is received. Other than that, the main thread just creates a QWinEventNotifier that receives that signal. Here ya go:

wineventtestthread.h:

#ifndef WINEVENTTESTTHREAD_H
#define WINEVENTTESTTHREAD_H

#include <windows.h>
#include <QThread>

class WinEventTestThread : public QThread
{
    Q_OBJECT
public:
    explicit WinEventTestThread(void *eventH, QObject *parent = 0);
    void run();
private:
    HANDLE eventHandle;
    bool keepRunning;
signals:

public slots:

};

#endif // WINEVENTTESTTHREAD_H

wineventtestthread.cpp:

#include "wineventtestthread.h"
#include <QDebug>

WinEventTestThread::WinEventTestThread(HANDLE eventH, QObject *parent) :
    QThread(parent)
{
    this->eventHandle = eventH;
    this->keepRunning = false;
}

void WinEventTestThread::run()
{
    qDebug() << "Test thread ID: " << QThread::currentThreadId();
    this->keepRunning = true;

    while (this->keepRunning)
    {
        // wait a second
        sleep(1);

        // signal the windows event
        if (SetEvent(this->eventHandle) == 0)
        {
            qDebug() << "Test thread: Error signaling event";
        }
        else
        {
            qDebug() << "Signaled event in thread " << QThread::currentThreadId();
        }
    }
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <windows.h>
#include <QMainWindow>
#include <QtCore/private/qwineventnotifier_p.h>
#include "wineventtestthread.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    WinEventTestThread *thread;
    HANDLE eventHandle;
    QWinEventNotifier *notifier;
private slots:
    void eventSignaled(HANDLE h);
};

#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // create the windows event
    qDebug() << "Main thread ID: " << QThread::currentThreadId();

    this->eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);

    if (this->eventHandle == NULL)
    {
        qDebug() << "Error creating event handle.";
    }
    else
    {
        // set up notifications when it's signaled
        notifier = new QWinEventNotifier(this->eventHandle);
        connect(notifier, SIGNAL(activated(HANDLE)), SLOT(eventSignaled(HANDLE)));
        thread = new WinEventTestThread(this->eventHandle);

        // start the test thread (it will start signaling the windows event)
        thread->start();
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::eventSignaled(HANDLE h)
{
    qDebug() << "Signal received in thread " << QThread::currentThreadId();
}

Voilà!

Recently I’ve been reading about how Flash has its own “cookies” where websites can store data, called Local Shared Objects. People who don’t like the possibility of being tracked often delete their browser’s cookies, but many people overlook the Flash Local Shared Object collection. I consider myself a savvy computer user, and I certainly didn’t think of them until the last couple of months.

Flash Player Settings Manager

You can edit the settings that specify which websites are allowed (and not allowed) to save flash cookies using Adobe’s web-based Website Storage Settings panel. Unfortunately, to be frank, it sucks. Why? I’ll tell you why:

  1. You can’t sort the list of websites. The order they appear in the list is totally arbitrary (to my knowledge). If I’m looking for a specific website to delete its cookies, I have to search through the entire list until I find it. I can’t use my brain to do a binary search on it, since it’s not sorted. 😉
  2. You can’t search for a specific website in the list. Honestly, if I could search for a site by name, I wouldn’t really care about complaint #1 above. But since I can’t, it also belongs on this list.
  3. The scrollable list of websites is only four items high. It’s bad enough that it’s in an arbitrary order, but searching through a long list is absolutely hellish when the list can only show four items at a time.

No offense intended toward the designer of this panel. I’m a developer, and I know I’ve made my fair share of UIs that could use some improvement. I doubt many people use the panel anyway, so it’s probably not high on any kind of priority list. Anyway, the point of this post is not to trash on Adobe’s settings manager, but it’s to recommend an alternative.

I was going to write my own editor for these storage settings, but then I discovered that BetterPrivacy already exists. It’s a Firefox extension that allows you to do pretty much everything the Website Storage Settings panel does, but in a much less masochistic manner. I didn’t do any searching for such an add-on for Internet Explorer, Safari, or Chrome, but they may exist. Anyway, I may still make an app to edit these suckers just for fun, although others probably already exist.

If you don’t mind forbidding all websites from saving Flash cookies, which may cause you to lose saved usernames in Flash websites (if that matters), you can forget having to deal with BetterPrivacy. Instead, delete all your Flash cookies in the Website Storage Settings panel I already mentioned, and then set the global size to zero (and “Never Ask Again”) at the Global Storage Settings panel. Doing so will prevent Flash from saving Local Shared Objects, period.

That’s all for now!

This is my first post. It’s nothing special–just making sure it all works okay.

So here’s the deal. In my time as a developer, I’ve done a lot of stuff. I’ve never bothered to document a lot of it. I’ve always thought it would be cool to write about stuff that I work on for future reference for anybody else (or even me). So now, when I do stuff, basic or advanced or whatever, I’m going to try to remember to write about it in this blog. It could be about compiling a toolchain on Mac OS X, it could be compiling an embedded Linux kernel, it could be about OpenOCD debugging on Windows with Eclipse, or anything else. The possibilities are endless. It might not even always have to do with computers. We’ll see!