With the experimental batteries in place, the computer boots up and stays up for longer than three seconds. I tried to run a vacuum cycle but that was too much for these batteries to handle, so for now I'll stick with digital exploration starting with the standard UI to dump revision information on components inside this particular Neato XV-21 robot vacuum.

Neato XV-21 info

After that, it's time to go exploring through its USB serial port diagnostics!

I went straight to the most interesting component: the laser distance scanner module. First I had to put my vacuum into test mode with testmode on. Followed by setldsrotation on to turn on the motor that sweeps the laser. And finally, fetch a set of laser distance data with getldsscan. This gave me a large set of numbers. According to the legend given in the first line of the response, a distance and intensity number per degree of sweep. Partial excerpt below:

AngleInDegrees,DistInMM,Intensity,ErrorCodeHEX
0,2378,82,0
1,2397,88,0
2,0,88,8021
3,2494,85,0
4,2505,82,0
5,2509,12,0
[...]
355,2289,99,0
356,2303,103,0
357,2303,99,0
358,2315,94,0
359,2367,91,0
ROTATION_SPEED,5.10

Future experimentation will determine what range of distance values are typical, similarly for intensity values. A quick web search failed to find a reference guide for error hex codes, but hopefully there'll be a small set that I can infer from context. More exploration to come!

In the meantime, I repeated the getldsscan command to verify the values are getting updated. They were - I received a similar but slightly different set of numbers. Hooray! the most important sensor looks like it is functioning.

Next item on the exploration list: querying analog sensor values with getanalogsensors.

SensorName,Value
WallSensorInMM,63,
BatteryVoltageInmV,16120,
LeftDropInMM,60,
RightDropInMM,60,
LeftMagSensor,-2,
RightMagSensor,-3,
UIButtonInmV,3317,
VacuumCurrentInmA,0,
ChargeVoltInmV,132,
BatteryTemp0InC,34,
BatteryTemp1InC,31,
CurrentInmA,622,
SideBrushCurrentInmA,29,
VoltageReferenceInmV,1225,
AccelXInmG,-8,
AccelYInmG,-12,
AccelZInmG,1092,

I see three distance sensors - wall and two drop sensors, one in each front corner. It's not immediately clear what "Mag" in left and right "MagSensor" referred to. Do they detect magnetic fields? Or are they measuring magnitude of something? Bottom three lines indicate the vacuum sensor suite includes a three-axis accelerometer which can measure in units of thousands of G, implied by a Z value nearly 1000 in this vacuum sitting on the floor. Remainder of the values are related to power management.

The 3-axis accelerometer values above from getanalogsensors partially overlap with results of getaccel. As the name indicates, this one is completely focused on accelerometer readings and includes results of additional calculation in the form of pitch and roll in degrees and a sum of acceleration vector.

Label,Value
PitchInDegrees, -0.64
RollInDegrees, -0.53
XInG,-0.012
YInG,-0.010
ZInG, 1.079
SumInG, 1.079

The list of digital sensor values from getdigitalsensorsis shorter, and for whatever reason, labelled in all capital letters.

Digital Sensor Name, Value
SNSR_DC_JACK_CONNECT,0
SNSR_DUSTBIN_IS_IN,1
SNSR_LEFT_WHEEL_EXTENDED,0
SNSR_RIGHT_WHEEL_EXTENDED,0
LSIDEBIT,0
LFRONTBIT,0
RSIDEBIT,0
RFRONTBIT,0

Here we can see whether the dustbin is installed, whether either or both wheels are at full extension, and it looks like there are four switches associated with the front bumper. The top line shows if a charging plug is connected, but that's only one of many parameters around power management. Most of the rest are in getcharger.

Label,Value
FuelPercent,88
BatteryOverTemp,0
ChargingActive,0
ChargingEnabled,0
ConfidentOnFuel,0
OnReservedFuel,0
EmptyFuel,0
BatteryFailure,0
ExtPwrPresent,0
ThermistorPresent[0],1
ThermistorPresent[1],1
BattTempCAvg[0],33
BattTempCAvg[1],31
VBattV,16.03
VExtV,0.16
Charger_mAH,0

If I were to create my own control logic for driving my Neato around, the most important parameter here is FuelPercent. I'll have to be responsible about not draining the battery too far, beyond that I can leave the rest in the capable hands of Neato's existing battery management system. Speaking of power consumption, the biggest drains are the motors, and I can monitor them all with getmotors.

Parameter,Value
Brush_RPM,0
Brush_mA,0
Vacuum_RPM,0
Vacuum_mA,0
LeftWheel_RPM,0
LeftWheel_Load%,0
LeftWheel_PositionInMM,-1
LeftWheel_Speed,0
RightWheel_RPM,0
RightWheel_Load%,0
RightWheel_PositionInMM,-1
RightWheel_Speed,0
Charger_mAH, 0
SideBrush_mA,28

Not very exciting at the moment, because all motors are at a stop. I imagine these numbers will get more interesting once the robot gets underway.

One final discovery in inputs: when in test mode, the user interface buttons on the top of the robot no longer trigger their usual functions. I could check for status of all five buttons via getbuttons which implies I could use these buttons in my own projects without worrying that I'll trigger the default vacuum behavior. Cool!

Button Name,Pressed
BTN_SOFT_KEY,0
BTN_SCROLL_UP,0
BTN_START,0
BTN_BACK,0
BTN_SCROLL_DOWN,0

But if I want to actually have my own user interface using those buttons, I would need to also display my own information on the LCD. Which brings us to phase 2 of playing over USB: start sending commands to see if components follow orders.