02 February 2019

ESP32 with OLED and maybe LoRa

I've bought a few too many ESP8266 boards over the years. Done a couple projects but most are sitting looking lonely in a box of good intentions. So in order to fix the wrong, I've decided I'm going to buy too many ESP32 boards.

I have a few of these:

  • ESP32
  • 0.96" OLED SSD1306
  • About $8

And a couple of these:
  • ESP32
  • 0.96" OLED SSD1306
  • 18650 Battery Holder
  • About $10



And seriously considering these:


And want a couple of these:

  • ESP32
  • GPS NEO-6M
  • LoRa SX1278
  • 18650 Battery Holder
  • About $26


30 January 2011

Apache ActiveMQ Startup Exception

I don't use ActiveMQ a lot but when I get back to a project where I was using it, I seem to get startup exceptions pretty often.  The stack trace is really long and ugly.

java.io.EOFException: Chunk stream does not exist at page: 0

At first I wasn't sure what was going on, just deleted the activemq folder, unzipped the distro, and back running in minutes.  The next time it happened, I spent a few minutes looking at what I may have done to cause this.


Out of just dumb luck, I found that if I deleted the activemq/data folder contents (not the data folder itself, just the contents - kahadb, localhost, etc), I could restart without error.  Turns out that there's a bug in KahaDB, the default persistence store in ActiveMQ.

I've found no side effects from deleting the data folder contents, none of my deployed apps need to maintain message persistence between shutdowns.

YMMV.

What do you think? Leave a comment.

Android SMS XML Parsing

Using XML with SMS sounds kinda dumb.  After all an SMS text is only 140 characters (or less ...) and XML is horribly bloated.  But if the originating application is using XML and SMS is the convenient transport, then nothing's too stupid.

There's plenty of articles that describe the various Android options for parsing XML.  SAX, DOM, and XML Pull.  Actually, I'd prefer to use XStream for quick XML read/writing but with the XStream jar around 500k, it's not a good droid choice.

I'm going to quickly show you how I intercept incoming SMS messages and route them to an XML parser if the message starts with a tag (in my case <evt>).  After parsing, I then look at fields in the message and then start other processing that I won't go into here.

I'll show you some quick screen shots of the code and attempt to explain.  At the end of the article, you'll find a link to the entire Eclipse project.  This has been tailored down quite a bit from how I'm using it.  It simply sniffs incoming messages and then displays XML fields.

An example incoming XML SMS message looks like this.  I'm receiving XML SMS messages from several sources such as email (like below) and from Twitter (like I blogged about here and here).


Even though my sample SMS XML message shows line breaks so the XML is nicely formated, you don't want to do this.  Don't waste a precious character on a break.  Run all the XML tags together.  My XML Pull Parser class is expecting no line breaks.

In AndroidManifest.xml, add a receiver for the SMS_RECEIVED action to your application and add RECEIVE_SMS to your permissions:


...

In your receiver class (the one that you named in your manifest file), extend BroadcastReceiver and implement onReceive.  After jumping thru a few hoops to get the message content, determine if this is a message you care about.  My "special" messages all have the XML tag "" after a few header characters depending on the source (such as email or Twitter).  If I find this tag, I display a quick toast and then send the message for XML parsing.

 
Here's an example Eclipse app that parses incoming SMS message and checks if they have the tage.  If so, a toast message is displayed and the sent of for XML parsing.  After parsing, the app simply display the contents of a few of the XML tag contents.

My deployed app is actually an Android service, not a simple app like this example.

Download the example.

What do you think? Leave a comment.

28 January 2011

HTC G1 adb "No Permissions"

Update:  After I wrote this post, I had the No permissions and a device name of ???????? all over again.  After spending yet more time on this, I found that the key is to kill and restart the server as root (sudo).  See commands at end of this post.

--------------------------------------------------------
I bought a used HTC G1 from eBay so I could prototype a droid interface to a custom sensor.  I didn't want to brick my daily use DroidX and heard that the G1 had a pretty decent serial interface ability.

I paid a little more than I wanted but those suckers are selling for about $125 which ain't bad (for the seller) for a 2+ year old phone.  After a week or so of bidding, I ended up with a decent condition phone for $83 including shipping.

The phone is locked to T-Mobile and has no sim card but that's okay because I plan to use this as wifi only.  Unfortunately I haven't been able to run the Android Debug Bridge (adb) or use the Android Development Tools (ADT) plugin for Eclipse.

At first I thought my problem with getting the adb "no permission error" was because my phone wasn't activated.



I read thru a few links on how to activate a no sim card phone and decided that it wasn't the issue and needed to keep investigating other causes.

Squirrel.  Before I go into a little more detail, let me share a quick story.  My shiny used G1  didn't come with a USB cable so I bought a cable (also from eBay) for about $1.78 including shipping.  Unfortunately for that screaming deal, it was being shipped from a country far far away.  A few days after I paid (mid January), I received this email:

"we have sent the item you ordered from us today.It would take you 25-35
working days to get it.because of near merry christmas,at the airport were
plied so many package ,plane is not ebough ,every package are slow,hopey
you can understanding ,If you haven't got it within 35 days,please let me
know.,And"

And a week later, my package arrived.  That was a fast 35 days, I guess they found "ebough" planes ...  But the cable didn't work.  I looked at the auction again to make sure that it said it was for a G1.  Sure enough, it states:


USB Sync Data Cord Cable For GOOGLE HTC G1 Android

But in small print, says:


Compatible with: HTC G1(not include the cell phone)

Ok, so what's an HTC G1 that's not a cell phone?


I wasn't going to even waste my time for $1.78 to contact the seller, chalk it up as another buyer beware.


But I did what I should've done next.  Use my leftover unused Blackberry cable.  Fits perfect, charge light goes on and I can mount the G1's SD card. 

Back to the main story.

Besides the "no permissions" error with adb, I can't communicate via the Eclipse plug-in. 




I checked the devices android version to make sure that I had the corresponding SDK platform revision, which I did.

Mr Google yielded some ideas.  One hit suggested that I use sudo with adb.  I don't think that'll help but sure let's try.



Then came across a useful hit Using ADB in Linux that describes that we need to create a file to change permissions and ownership of a device node.  Here's how:

  • Create a file /etc/udev/rules.d/50-android.rules with this command:
sudo gedit /etc/udev/rules.d/51-android.rules
  •  Type in the contents of the file.  The version of linux may cause the syntax to differ slightly.  I'm using Ubuntu 11.04 Natty Narwhal and my contents are in the pic below.


    I've also seen instructions to use this:


    SUBSYSTEMS==”usb”, ATTRS{idVendor}==”0bb4″, ATTRS{idProduct}==”0c01″, MODE=”0666″  

    Note the diff between what I used SUBSYSTEM vs SUBSYSTEMS and ATTRS


    Here's an interesting read on Writing udev Rules.
  •  Change permissions of the file
sudo chmod a+r /etc/udev/rules.d/51-android.rules
  • Restart udev
    sudo restart udev
  • Stop and restart adb
sudo ./adb kill-server
sudo ./adb start-server
  • List the devices

Sweet!


What do you think? Leave a comment.

18 December 2010

Can't SSH to Amazon Elastic Compute Cloud (EC2) Instance

I've decided that I'm going to learn about Amazon Elastic Compute Cloud (EC2) over this Holiday break.  I've read a few articles, listened to a few podcasts so I have an idea what it's about, just haven't actually gone thru the motions myself.

What am I going to do with a virtual machine (VM) in the cloud?  Not much quite yet.  I have some ideas but first need to figure out how things work.

So on Friday night I signed up for an EC2 account and started to follow the Getting Started Guide on the Amazon site.  As usual, things went smooth for the first few minutes but as usual, progress came to an immediate screeching.

I started an plain vanilla Basic 64-bit Amazon Linux Amazon Machine Image (AMI) just to get things going and verify that I could SSH into the thing per the getting started guide.  But when I SSH'd, nothing, nada, zip.  Timeout.


This darn thing acts like it's not running.  I started, restarted, used different AMI, mucked with security group setting without any progress.  I even edited the default security group to open the thing wide open:


Still nothing.  Did the google thing to see what other people are doing and came across a few hits in the Amazon Web Services forums where people are claiming the the web services aren't starting up correctly in the US-East zone.  Hey, that's me!  Ok, I'm not stupid, its just some tech problem.  I'll take a break and try it again in a few hours.

Few hours later:  nothing, nada, zip.  Ok, I am stupid.  I can't even log into a stupid instance.  I probably started/stopped an EC2 AMI 10 times but can't do anything with it.  This new thing I've learned is frickin' amazing.

And as usual, as soon as I've convinced myself that all hope is lost, ding.  Wait, doesn't my Westell DSL modem block SSH?  Oh, frick of course it does.  Damn it so, the last 3-4 hours of trouble was caused by my own firewall??

Of course it was.  I really hate this Verizon provided modem and keep telling myself that I'm going to buy a different one.  But this is free and I'm cheap.  So I'll keep shooting myself in the foot and someday get smarter and dump this junk.

In the Firewall->Port Forwarding menu, I just added the SSH service to a dynamic host.


And now when I launch a new instance, I get this:


Amazing.  Only hours and hours of work to launch and connect.  Let the fun begin.

What do you think? Leave a comment.

29 November 2010

Working with the 90 Character Limit of Twitter

What?  Twitter has a 90 character limit?  No, it's 140.  Everyone knows that.

Mr Wikipedia says this about SMS length

"... resources in the system could be used to transport messages at minimal cost. However, it was necessary to limit the length of the messages to 128 bytes (later improved to 140 bytes, or 160 seven-bit characters) so that the messages could fit into the existing signaling formats."

Using the Groovy code that I did the other day to send a text message via a twitter Direct Message, if the message length is greater than 140 characters, twitter complains with this error:

403:The request is understood, but it has been refused.  An accompanying error message will explain why.
{"request":"\/1\/direct_messages\/new.json","error":"The text of your direct message is over 140 characters."}
TwitterException{exceptionCode=[6bcd7469-01bff100], statusCode=403, retryAfter=0, rateLimitStatus=null, version=2.1.7}


That kinda says that I can send 140 characters, so what's this nonsense about a 90 character limit?

Well, true, you can send 140 characters but if you're hacking the system for the purposes of having Twitter forward your message as a text message to a phone then different rules apply.

Take a look at what happens when you send a Direct Message of 140 characters to an account that is set up to send a txt:
String message = "12345678911234567892123456789312345678941234567895" +
                 "12345678961234567897123456789812345678991234567891" +
                 "1234567891123456789212345678931234567894"

DirectMessage directMessage = twitter.sendDirectMessage(screenName, message)
Twitter breaks the message into 2 separate texts (and my phone occasionally gets the 2nd text first).

For the app that I'm working on, I need my data in a single text message, I don't want the mess of re-assembling.

I think the message split is because a header of:

"Direct from" screen name:

and a footer of

"Reply with 'd" screen name "hi.'"

is added to each message.

I've found that the amount of data that you can actually send depends on the screen name.  Since screen names can be up to 15 chars, you lose:

Header:
Direct from screenname:
= up to 28 characters (12 + screen name)

Footer:
Reply with 'd screenname hi.'
= up to 34 characters (19 + screen name)

140 - 28 - 34 = 78

Uh, 78 is not 90.  What the heck? I guess my math has errors.

But check this out.  By adjusting my direct message, I find that a 90 character message is the sweet spot for a 15 character screen name and the message is sent as a single text.  91 characters will cause the message to be split over 2 texts.

Maybe that header and footer isn't as big as I think it is.

140 - 90 = 50 characters for header/footer?

If a screen name is used twice (2 * 15 = 30), then maybe the bloat is only 20 characters?


What happens if I send messages to a different screen name, one that is smaller than 15 characters?

What is I use a screen name of 8 characters?  Should I be able to send a message of

140 - 20 (bloat) - (2 * 8) = 104 characters?

After a quick reassignment of my phone to a different twitter account, I tried a test with a screen name that is 8 characters.  Could I send 104?  Durn right I could!  And I could also send 109.  But 110 would cause a message split.  So I have an extra 5 characters unaccounted  for.

What happens if I send to a ...  No, this is going on too long. 

The max screen name is 15 characters and that limits the max amount of data that can be sent in one message to 90 characters.

If the screen name is less than 15 characters, then you get 90 plus some extra.  YMMV


What do you think? Leave a comment.

27 November 2010

Send SMS Text Message from Java/Groovy - via Twitter

Writing code to send an SMS text message is fairly easy on a smart phone like an Android.  But from a desktop, sending texts is still a mess, not always free, and/or requires a phone connected to your server.

I simply want to send a message to my phone when my app receives some data.  I don't need a complex library with lots of setup nor do I want to sign up for a pay service.

Now this isn't the cleanest solution to text from an app but Twitter can send messages to your phone when people you follow update their status, when someone mentions or replies to you, or when you get a direct message.

My last two write-ups, "Send a Simple Tweet with OAuth and Groovy" and "Send a Direct Message Tweet with Groovy" showed how easy it is to use Java/Groovy and the Twitter4J library to send messages to your own Twitter account or a message to anyone else.

By sending a tweet to an account that you follow or a Direct Message to your own account, Twitter can be setup to forward that message to a phone that you associate with your account.

Simply go to your Twitter account, Settings, Mobile and follow the easy instruction. Then use one of the sample apps from my previous posts and tweet-text away!

Note:
  • This only allows you to tweet-text to phones that have been setup to follow accounts. 
  • This does not allow you to send a text to a cell phone not registered with Twitter.
  • This works for what I need.
  • Do you know a better/easier, free method?  Write a comment!


What do you think? Leave a comment.

Send a Direct Message Tweet with Groovy

Alright.  Using the Twitter4J library and Groovy, I've beaten down the OAuth beast and have a simple example app to send a "update status" tweet.

Now instead of sending a message to my own account, let's do a real easy mod to send a Direct Message to a specific user   Using the same app as before, the only changes needed are:

  • import DirectMessage
  • change from twitter.updateStatus(message) to twitter.sendDirectMessage(screenName, message)
import twitter4j.DirectMessage;
import twitter4j.Twitter
import twitter4j.TwitterFactory
import twitter4j.Status
import twitter4j.http.AccessToken
import twitter4j.http.RequestToken
import java.io.BufferedReader
import com.thoughtworks.xstream.XStream

try{

   Twitter twitter = new TwitterFactory().getInstance();

   // set key and secret that you get from Twitter app registeration at:
   //     http://dev.twitter.com/pages/auth#register
   twitter.setOAuthConsumer("Your Consumer key", "Your Consumer secret");

   // load access token if it exists
   AccessToken accessToken = null
   def tokenFile = new File("accessToken.xml")

   if (tokenFile.exists()) {
      def xstream = new XStream()
      tokenFile.withInputStream { ins -> accessToken = xstream.fromXML(ins) }
      twitter.setOAuthAccessToken(accessToken)
   } 

   else {

     // get the URL to request access to Twitter acct
     RequestToken requestToken = twitter.getOAuthRequestToken();
     String authUrl = requestToken.getAuthorizationURL()
     System.out.println("Open the following URL and grant access to your account:");
     System.out.println(authUrl);

     // take the PIN and get access token
     System.out.print("Enter the PIN:");
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     String pin = ""
     pin = br.readLine();
     accessToken = twitter.getOAuthAccessToken(requestToken, pin);

     // persist token
     def xstream = new XStream()
     xstream.classLoader = getClass().classLoader
     new File("accessToken.xml").withOutputStream { out -> xstream.toXML(accessToken, out) }
   }

   String message = "from Groovy w/ token" + accessToken.getToken()
   String screenName ="ScreenNameToSendTo"

   DirectMessage directMessage = twitter.sendDirectMessage(screenName, message)
   System.out.println("Direct message sent to " + directMessage.getRecipientScreenName());

} catch (Exception e) {
   e.printStackTrace();
}

What do you think? Leave a comment.

Sending a Simple Tweet with OAuth and Java/Groovy

Come on, man!  What used to a be a simple task to send a tweet is now a OAuth nightmare.

A year or so ago, I built that tweet-a-w/e thing that sniffed XBee chirps and sent them to a twitter account that kindly routed them to my cell phone.

I have a need now to receive an XML stream, parse out a few tidbits and then send the results out as a SMS text message.  Remembering that tweet-a-w/e app, I thought that I would again leverage Twitter to send the text message.  All I need to do is send a tweet via a Twitter API and have my account set up to send the content to a phone number.

This time my XML receiver is in Java/Groovy, so I grabbed the latest Twitter4J, glanced at the UpdateStatus example and tried a quick test with Groovy.
import twitter4j.Twitter  
import twitter4j.TwitterFactory  
import twitter4j.Status  
    
Twitter twitter = new TwitterFactory().getInstance("myAcct","myPassword");  
Status status = twitter.updateStatus("from Groovy");  
System.out.println("Successfully updated the status to [" + status.getText() + "].");  
Did that work?  Of course not.  Authentication FAIL.

Caught: 401:Authentication credentials were missing or incorrect.
{"errors":[{"code":53,"message":"Basic authentication is not supported"}]}
TwitterException{exceptionCode=[15bb6564-00e5bee0], statusCode=401, retryAfter=0, rateLimitStatus=null, version=2.1.7}

What the heck?  Basic Authentication is not supported?  Darn it, what is this stupid OAuth thing about?  Here's the Twitter page "Authenticating Requests with OAuth" that looks real interesting to read.  Arghhhhh.  I just want to send a flippin' tweet, I really don't have time to research this at Hueniverse.

After some more quick Googling, this isn't as bad as it first looks.It boils down to getting a key and secret pair.  The steps are:
  • Goto Twitter and register your app.
  • You'll get a consumer key and secret which are similar to the public and private keys used in protocols such as ssh. 
  • Use the key and secret to sign every request you make to the Twitter API
import twitter4j.Twitter  
import twitter4j.Twitter
import twitter4j.TwitterFactory
import twitter4j.Status
import twitter4j.http.AccessToken
import twitter4j.http.RequestToken
import java.io.BufferedReader

try{

   Twitter twitter = new TwitterFactory().getInstance();

   // set key and secret that you get from Twitter app registeration at:
   //     http://dev.twitter.com/pages/auth#register
   twitter.setOAuthConsumer("Your Consumer key", "Your Consumer secret");

   // get the URL to request access to Twitter acct
   RequestToken requestToken = twitter.getOAuthRequestToken();
   String authUrl = requestToken.getAuthorizationURL()
   System.out.println("Open the following URL and grant access to your account:");
   System.out.println(authUrl);

   // take the PIN and get access token
   System.out.print("Enter the PIN:");
   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
   String pin = ""
   pin = br.readLine();
   AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, pin);

   String message = "from Groovy w/ pin" + pin
   Status status = twitter.updateStatus(message);
   System.out.println("Successfully sent " + message);

} catch (Exception e) {
   e.printStackTrace();
} 

Ok, so that works.  But every time you run the program, you need to go and fetch the darn token.  According to Twitter, the token doesn't expire, so let's persist the thing.

I like using XStream to serialize Java/Groovy objects to/from XML.  A quick update to the code above lets us save an XML file that we can reload as needed.
import twitter4j.Twitter
import twitter4j.TwitterFactory
import twitter4j.Status
import twitter4j.http.AccessToken
import twitter4j.http.RequestToken
import java.io.BufferedReader
import com.thoughtworks.xstream.XStream

try{

   Twitter twitter = new TwitterFactory().getInstance();

   // set key and secret that you get from Twitter app registeration at:
   //     http://dev.twitter.com/pages/auth#register
   twitter.setOAuthConsumer("Your Consumer key", "Your Consumer secret");

   // load access token if it exists
   AccessToken accessToken = null
   def tokenFile = new File("accessToken.xml")

   if (tokenFile.exists()) {
      def xstream = new XStream()
      tokenFile.withInputStream { ins -> accessToken = xstream.fromXML(ins) }
      twitter.setOAuthAccessToken(accessToken)
   } 

   else {

     // get the URL to request access to Twitter acct
     RequestToken requestToken = twitter.getOAuthRequestToken();
     String authUrl = requestToken.getAuthorizationURL()
     System.out.println("Open the following URL and grant access to your account:");
     System.out.println(authUrl);

     // take the PIN and get access token
     System.out.print("Enter the PIN:");
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     String pin = ""
     pin = br.readLine();
     accessToken = twitter.getOAuthAccessToken(requestToken, pin);

     // persist token
     def xstream = new XStream()
     xstream.classLoader = getClass().classLoader
     new File("accessToken.xml").withOutputStream { out -> xstream.toXML(accessToken, out) }
   }

   String message = "from Groovy w/ token" + accessToken.getToken()
   Status status = twitter.updateStatus(message);
   System.out.println("Successfully sent " + message);

} catch (Exception e) {
   e.printStackTrace();
}

The serialized Access Token looks like this:


  5555555-AbCdEF
  1oKiOlOlOlOl
  
    oauth_token=5555555-AbCdEF
    oauth_token_secret=1oKiOlOlOlOl
    user_id=007
    screen_name=bond

  
  bond
  007

Notes:

For the above examples, I used:
  • Groovy Version: 1.7.0 JVM: 1.6.0_22
  • Twitter4J 2.1.7  For this, I copied only the twitter4j-core-2.1.7.jar into the Groovy lib folder.  On Linux, this is /usr/share/Groovy/lib
  • XStream 1.3.1  For this, I copied the xstream-1.3.1.jar and xpp3_min-1.1.4c.jar into the Groovy lib
What do you think? Leave a comment.

13 August 2010

Sad Day for the Great White Boxster

After a little more than a year of ownership and the main reason that I haven't been updating my blog, I sold my Boxster (the Great White). She was a good car but after buying a 911 in early Spring, I just wasn't driving her much.

My family is much sadder than me though cause they liked the Boxster better than the 911.

I really love the mid-engine Boxster and will probably buy a Cayman S in the near future.  After getting the Porsche bug, I wasn't happy until I had a 911.  What a complete different experience.  The Boxster is refined and hugs the curves like no other car I ever driven.  The 911 is raw, loud and dares you to give it too much gas so it can swing its ass around and make you look like a noob driver.  But it's so fast and the power is addicting.

09 August 2010

Sanyo DP26648 White Screen of Death

 Santa brought my game player son a Sanyo SP2664 26-inch Widescreen LCD HD Television last Christmas.  A few months into the year, the TV started getting occasional white lines diagonally across the screen, the greens looked weird, and then the audio went in/out.  I could've/should've hauled it back to Wally Mart but grumbled about it and did nothing.

We came home from our July 4th vacation and the darn TV is dead.  White Screen of death.  No sound, just a stupid looking white screen.

An interesting thread on the Electronics Repair Google Group led my son and I to think that we could fix this beast.

According to the thread, "it has been reported that there is a defective ribbon cable that causes this problem".  And the possible fix is "Clean glue like material from spaced further apart trace of FFC ribbon or replace the ribbon wire P/N: N6CD FFC".

Well, I'm pleased to report that we hacked and smashed and tore that darn TV up, finally got to the elusive cable.  And it looks nothing like that picture.  Our cable looked fine, no glue, seemed like a good connection.  And the TV remains broken and in 300-bazillion parts.

We had fun exploring the TV but it would have been a better story if the darn thing would have actually been easy to fix.  I think our TV had more wrong with it than just the cable.  But if your TV is showing the white screen of death, read the link and good luck.

25 December 2009

LG Washer LE Error

UPDATE:  I've had quite a few hits on this posting and received lots of great comments - thanks very much.

This post explains how to replace the hall sensor on your LG washer.  Before you decide that you have to replace your hall sensor, please try unplugging your washer for 5-10 minutes and see if it will reset all on its own.

Also, even after replacing the sensor, sometimes these washers will display "LE" a week or month later and they just need a time-out (unplugged).  Good luck!

I've also had a few questions on what the heck is a hall sensor. Here's a whitepaper with a good description, design notes and ideas on what else you can do with these things.

-------------------------------------------------------------------------

We had a really nice Maytag washer and dryer set. They were a billion years old (maybe 15 actually) but ran strong and had zero problems. Spring 2007 we decided to remodel our laundry room and of course we had to have the super duper LG WM2075CW 27" Front-Load Washer with 3.72 cu. ft. Capacity, 7 Cycles, 6 Options, SenseClean and 8 Hours Delay Wash.

About $800 delivered. Nothing but the best for my socks and undies (boxers btw).

Everything has been great except the week before Christmas 2009, Mr LG wouldn't work. It would grunt and click and then put "LE" on the display. A quick Google yields lots and lots and lots of hits with the Load Error (LE).

A number of things can cause an LE but the most common is a malfunctioning Hall Sensor. Seems that LG washers are pieces of crap and this is a well known problem. LG has extended the warranty on the part to 7 years but they won't ship the in-warranty part to consumers. They'll only ship to a certified service company. After several phone calls to LG and way too many minutes on hold, I finally just ordered the damn thing from MCM Electronics, part number 6501KW2002A for $18. Plus tax and shipping, at my door for $29.75.

Actually the LG washer and dryer have been great, I'm just very ticked that LG has a known problem but won't do a recall to fix the part with a more reliable piece. And even more ticked that they won't ship me an in-warranty part so I can do it myself. So for now on, I will refer to the washer as a piece of crap and LG as a seller of crap. My next washer will be a Bosch.


The Google hit that explained the error, the part number and how to replace is FixYa. Their how-to was a little brief and a picture is worth a thousand so I thought I would help out the next sucker that also has a piece of crap that needs to be fixed.

Read thru that FixYa article and make a decision if your problem is also the Hall Sensor. If so, follow along.

This is a pretty simple fix. If you can change a sparkplug than you can easily do this one. (I compared this to a sparkplug change cause you'll get a little dirty, gotta pull some cables, and work a socket wrench).

You'll need a phillips head screw driver, 17mm and 10mm sockets or wrenches.

A quick note:  Even though the pictures are somehow dated 1/7/2006, they were actually taken in December 2009.  Someone reset my camera date and I didn't notice until pics were all taken.

Ok, First step, UNPLUG the washer. And carefully move the washer so that you can access the back panel. If your washer and dryer are stacked, please be careful and make sure there is nothing on top that will fall and hit you in the head. Ask someone to help you, don't blame me if you hurt your self moving the thing. Be careful!
  • Remove the 4 phillips head screws on the back panel
  • With a 17mm socket, remove the bolt that holds on the motor rotor. Turn the bolt to the left (counter clockwise) to remove. The drum will probably turn as you're trying to get the bolt loose so with your free hand, grab the rotor around 10 o'clock and hold tight while you turn the bolt. Be patient and it'll come right out.
  • Next,you need to pull the motor rotor off to expose the stator. This will be a little tough because of the magnets and a tight fit. Use both hands on opposite sides and gently tug one side, then the other, then both. Try your hands at 1 o'clock and 7 o'clock. Then switch to 5 and 11. Be patient and tug gently. Watch the white center and you'll see it slowly pull away from the shaft.


  • Set the rotor to the side and remove the 10mm bolts holding the stator on. I wasn't sure what to expect when I started removing it and I wanted to make sure I put it on right side up so I made pencil marks to line things back up. These really aren't needed cause it'll be obvious as to which side is up.
  • When you remove the 6th bolt, use your free hand to hold on to the stator cause it will fall right off. There are two connectors at the bottom, one the goes to the motor windings, the other to the hall sensor that we're replacing. If you don't hold onto the stator, you might damage the wires or connectors. Go slow on the last bolt and hang on.
  • Here's what those connector look like from the bottom side. I didn't have any luck trying to get them free from the bottom though. I was kinda squeezed in between the wall and washer so I didn't have much room to wiggle. I let the stator lean towards me like the picture above and then gently pulled both connectors free. Don't go Rambo on these connectors, you don't need to replace extra stuff. Breathe deep and squeeze the little tabs, they'll come free.
  • Almost there. That shiny looking thing on the bottom right of the stator ring is the hall sensor. It's held on with 3 clips on the back side, 1 clip on the front. Simple pry up the 1 clip and it will pop free.
  • The new sensor snaps back on just like you'd expect. Hook up the 3 clips first and then snap it on to the 1 clip side.
  • I don't have pictures of these next steps cause it's just the opposite of the above. Just look at the pictures in the reverse order and it'll all go right back together.
  • Hook up the two connectors. Make sure they click all the way back on.
  • Line the stator back up with the bolt holes and screw the bolts back in with a 10mm socket. Tighten them firm but don't over do it.
  • Push the rotor back onto the shaft. Because of the magnets and the shaft grooves, it will feel like it's not going. It will, line it up and apply pressure at the edges.
  • Tighten the big bolt with a 17mm socket. As it tightens, the drum will start to rotate. Grab the edge with your free hand and tighten firmly.
  • Put the back panel back onand tighten down the 4 phillips head screws.
  • Plug the washer back in and carefully push the washer back into place.
  • Test.
  • Your piece of crap washer is fixed.
Total time was 38 minutes. If I didn't stop and take pictures, easily under 30 minutes.

What do you think? Leave a comment, buy me a beer!