Thursday, September 8, 2022

Roomba 655 DIY virtual wall

 I had the good fortune to get a Roomba 655 from thrifting the other day.  Along with it, I got two Roomba bases and a Goovi F007 base, just in case I might find it useful.  I gave everything thorough cleaning and then started into the electronics.

Putting the Roomba onto the base, I would see it light up to charge, and then immediately turn off.  This is typical of fully discharged, rechargeable battery packs that no longer have (or can sustain) a minimum charge.  The Roomba bases appeared to be generating a clean 3+ VDC charge, so they looked ok.

I removed the underside panel per documentation, and found the power pack..  Sure enough, there wasn't any power coming from it.  I don't understand why the power packs have four contact points on the bottom.  One clearly seemed to be a direct connection to GND (based on ohming out the lines between the battery pads and the charger connection points), but the purpose of the other three wasn't clear.

I was hoping to find some instructions for refreshing a pack outside of the machine using a NiMh charger, but there wasn't one on the web.  So, I ended up ordering a $20 pack online.  It arrived, and I put it in, and charged it up.  With just that, the Roomba worked!

My next step was to build a virtual wall.  There are multiple pages out there, but they seem to root to https://github.com/MKme/Roomba and the YouTube video linked from there.

The very basic idea of this: use the IRremote library for an Arduino, run it at 38 kHz, and pulse one for a second, and then off for a second.  That's all.  You get an infrared LED, which can be pulled from most any remote (these show up regularly in the thrifting bins for cheap).  The anode connects to 5v and the cathode (the side with the visibly larger metal inside the LED) goes through a 110- or 220-ohm resistor to the IRremote output pin.

I verified I had working components by connecting the IR LED with 5v - anode - LED - cathode - resistor - GND, and then looked at the LED through my phone camera.  It would show up pink-ish there when on.  That way, I knew I had the orientation correct, and that the LED wasn't burnt out.

Attempt 1

I tried setting up the sketch for an Arduino Pro Micro, and connected to pin 3 as defined.  After wiring it up, I got no light from the LED.  I read some other articles indicating there were issues with the IRremote library and the Pro Micro (32U4).

Attempt 2

I then tried the same sketch using an Arduino Mega 2560.  Again, no luck.  I read one article saying that the Mega 2560 uses pin 9, and if I were to just pinMode(9,OUTPUT) and digitalWrite(9, LOW), it would work.  Uh, no.

For both Attempts 1 and 2, there were pages suggesting making modifications to the IRremote library directly.  I looked into that, and found the lines they were suggesting to modify weren't even in the library any more.

Somewhere in this, too, I saw an example referring to "IrSender" as a known object instance or there were class-level methods associated to it, whereas the original MKme code used Irsend.

At this point, I realized I might be working off of the wrong library version.

Attempt 3 (success)

For my third attempt, I went to a plain Arduino Uno.  It turns out I got one from thrifting.  It was within a Thames & Kosmos electronics kit.  Nice build.  The Uno is buried inside of a handheld gamepad-type thing, and has its own rechargeable battery under the board.  The one I got had a faulty roller switch thing, but the Uno worked.

I first got rid of the old IRremote library that was at

$ARDUINO_HOME/libraries/IRremote

Next, I downloaded the IRremote library version 3.9.0.  I installed it as

$ARDUINO_HOME/libraries/IRremote-3.9.0/{examples, pictures, src, etc.}

Then, I looked at the example

$ARDUINO_HOME/libraries/IRremote-3.9.0/examples/SendDemo/

In that folder you'll find  

PinDefinitionsAndMore.h

and

SendDemo.ino

The sketch first includes the .h file before including <IRremote.hpp>.  Then, it does things based on the pin definitions within setup().  I didn't really care about what it was doing in loop(), since I knew I'd be replacing that.

So, I created my own sketch, vwall2.ino.  As normal, once I saved it, it went into $ARDUINO_HOME/vwall2/.

I copied the example's PinDefinitionsAndMore.h into that folder.

Then the sketch basically was:

#include PinDefinitionsAndMore.h

#include <IRremote.hpp>

Duplicate (verbatim, I think), what's in setup().  Some of that stuff you don't necessarily need, but it didn't hurt to have it.  And, the diagnostic stuff printed to the Serial Monitor was interesting.

Then for the loop(), I did this:

void loop()
{
  //These values should work for pre i models of roomba
  // See timeline at https://en.wikipedia.org/wiki/Roomba
  IrSender.mark(1000);
  IrSender.space(1000);
 
  //For "i" models (i3, i7 etc) use the following
//  irsend.mark(500);
//  irsend.space(7500);
 
}

So, basically, the loop is the same as MKme/Roomba's, but using IrSender.

Also, I googled the Roomba model timelines and found that the 655 preceded the "i" series, so I used the 1000 / 1000 timings.

With that sketch, the default output on an Arduino Uno is pin 3, and I got about 1.1 VDC by voltmeter, and observed the IR LED showing pink through the camera lens.

Physical build

I grabbed a chunk of 30-hole perfboard, and soldered things up.  At one end, I made a 5-pin edge connector with part of an old wire-wrap header.  I bent the pins (using another chunk of perfboard for spacing) so that the pins would end up parallel to the board.

 


The intent was to put the board in where the pins say 5v, reset, 3.3v, Aref, and 5v.  I chose to use 5 pins for the edge connection for stability -- but of course if you do the same, be sure to make sure you don't solder-bridge any of those pins.  The circuit only touches one 5v pin, and since that appears at either end, it makes it so that I could mount the board either way.  I like having it so that the board is on the inside of the headers, so I'm using the 5v pin that's closer to Aref.

Kosmoduino board.  Red = either 5v point.  Blue = used for support.  Pink = IR LED signal

 

The 5v pin then wires up to the top of the board, and connects to the anode.  The cathode side connects to the 110 ohm resistor (in the picture I have two 220 ohm resistors in parallel).  From there, I just soldered to a patch wire, so it lets me plug the other end of the patch wire to pin 3 on the Uno.  It's not as elegant as bulding a real Arduino Uno shield, but having the wire stick out is a hacky way of letting it be reversible.

That's all there was to it.  The great thing is that the Thames & Kosmos "gamepad" serves as a stable platform, and also provides a physical switch and a rechargeable battery pack.  So, I can just put it on the floor somewhere, turn it on, and point it where I want it.


 

The LED stands about 4.25" (11cm) above the floor, and that's tall enough for the Roomba to see it.

The LED points out from the perfboard, which means it's shining a cone of light that's roughly along a plane parallel to the floor.  I'm not sure what the specific field of view is for the LED -- that is, how wide the cone is -- but it's pretty tight.

Examples of light on/off as seen by the camera (not visible to the naked eye):



I'm also not sure how far the LED shines. In practice, it's at least 4' (1.2m), which is all I need to keep the Roomba from running down a hallway.

Thanks to MKme for the IR frequency and pulse info, and original code. 

Next steps

I think there are a couple of things I want to do next for this project.

First, I measured the floor-to-light height of the Roomba base itself, and it looks like the LED is at a height of around 9.5 or 10cm.

Second, I don't really need a circuit board for this, but I could use a proper shield.  So I might recraft this as a shield on the Uno, and then have a flexible, bendable thing that leads to the LED.

Where that takes things, then, is to make something more interesting as the virtual wall LED holder.  What kinds of things are 10cm floor to ground?  Well...

- Mrs Potato Head's hand is about that height.

- The face mask of my translucent robot dude might work.  But he is a little tippy.

- My Lego Ninjago clock dude.  His hand can be positioned to hold something.

Or, 3d-print something more interesting.  So many possibilities!

I also want to try to build this using something simpler than an Arduino.  I saw someone using an ESP32.  Something cheap, cheap, cheap.  I wonder if I could fake it out using some 555 timers.  Some of the IR remote controls I've broken open don't even have a crystal inside of them.  They use a dedicated IR chip that has a selectable frequency, and can be programmed to emit different things.  But that would get more expensive in terms of tooling...


No comments:

Post a Comment