Showing posts with label user interface. Show all posts
Showing posts with label user interface. Show all posts

Thursday, October 9, 2025

Things I hate about the Mazda CX-70

It's been a little over a year since I bought a CX-70. Overall, I really like it: it's comfortable, handles well, looks great inside and out, has enough cargo space for my needs, and is able to pull my 3500 pound travel trailer with ease. But there are a few things that a really don't like, to the extent that Mazda might not be on my list the next time I look for a car.

I've listed them here in increasing order of annoyance.

Turning off the stereo

There have been a lot of professional reviewers slamming the infotainment unit. I'm going to focus on one very small part of it, that nonetheless makes me grumble every time I use it: turning the stereo off so that it stays off.

The Mazda has three ways to turn off the stereo. The first is the mute button: press the small round knob in the center console and the sound stops. But if you turn off the engine it's back on as soon as you start up again. If you hold down that button, you turn off the infotainment system entirely. It won't turn on again the next time you get in the car, but you also can't use the navigation system or even see the current time.

If you actually want to turn off just the stereo, you must press the large button, to bring up a menu. Then select “Audio Sources” from the that menu. Then scroll to the very end of that list where there's an “Audio Off” menu item. Finally, press the large button to select that item.

As I see it, there are two easy solutions: either remember the setting of the mute, or move “Audio Off” to the very top of the audio menu.

“Upcoming exits” navigation sub-panel

One of the reasons that I bought the CX-70 was that it had a built-in navigation system. And while “Miss Google” is easier to use and gives better directions, I've been in many places without Internet connectivity (and where I might not have already downloaded maps). I also like the navigation screen as a default display.

But then I get on a highway, and the system shows a list of upcoming exits with their distance and estimated ETA, blocking the right third of the screen. In principle, I might like such a list, if it showed the exit names and I could scroll through them to highlight the exit I wanted. But it doesn't, and I can't, and more importantly, I can't make it go away. The UI indicates that I should be able to do that: there's a downward pointing arrow at the top of the widget, which I would interpret as “minimize this window,” but I have not found any way to activate that control (if control it is).

If you go into the navigation menus, there's an sub-menu for what appears on the sidebar. I've told it to show nothing, but that doesn't disable the exit list. Clearly the team that put that checkbox in place never talked to the team that implemented the exit sidebar.

Repeated warning messages

When the CX-70 wants to tell you something, it blanks out most of the instrument console to do so. And requires you to press the "Info" key on the steering wheel to make the message go away.

Sometimes, this is annoying, as when it tells me that my windshield washer fluid is low (especially annoying because that message appears when the fluid is half empty, due to the design of the reservoir). And sometimes it's downright dangerous, such as when it told me — in separate messages — that my front collision avoidance system was no longer operational because I was driving in a torrential downpour. Seeing your gauges replaced by a big warning box is guaranteed to attract your attention, even if you have none to spare.

What raises this behavior to major annoyance is that the conditions that trigger the message reset: in the case of the torrential downpour, once I got out of a rain band the sensors would detect that they could see what was in front of me, and the collision avoidance system would be re-enabled. Only to be disabled again, with two messages, when I entered the next rain band.

Aside from the danger and annoyance, repeated messages desensitive users. After passing through two or three rain bands that day, I forced myself to ignore the messages flashing on my screen. Which, of course, meant that I wouldn't see a truly important message, such as dangerously low tire or oil pressure.

My recommendation here is simple: only show a message once per drive. Assume that I know there's a problem until I turn off the engine. Unfortunately, I think this is unlikely to happen, for the same reason that the CX-70's Owner's Manual prefaces every feature description with a warning that in effect says “don't rely on this feature.”

Rear auto-braking due to bicycle rack

A friend of mine has a Jeep Wrangler. When he shifts into reverse with a hitch-mounted bicycle rack, the car starts beeping. The CX-70 goes one step further: it slams on the brakes. I first discovered this “feature” on our first long trip, trying to turn around in a narrow dead-end street. Even if you're moving at a slow walking speed, suddenly slamming on the brakes will bounce your head off the seatback (try it!). When that happens every few feet, it's infuriating.

There is a way to turn this feature off, buried in the menu system. But it is a useful feature, so I don't want to turn it off permanently. This would be a perfect place for the warning system I described in the last section: apply the brakes (once), display a message, and then ignore the situation once the driver acknowledges the message (this is one case where the acknowledgment should not last for the entire drive).

I ended up solving the problem with a hack. We have the factory installed trailer hitch, which disables the rear warning systems when you plug in a trailer's umbilical. So I bought a set of magnetic towing lights (used when you're towing another car or a utility trailer that doesn't have lights), and plug them in whenever we have the bicycle rack installed.

Driver personalization system

Everything up to this point has been an annoyance that, on balance, I can live with This “feature” is the reason that I don't think that I'll buy another Mazda.

Like many upscale cars, the CX-70 can save your preferences for seat, steering wheel, and mirror position. There are two buttons on the dash; one for myself, the other for my wife. And if that was all the CX-70 provided, I would be happy. But Mazda decided to add the “Driver Personalization System,” which uses facial recognition to figure out who is driving the car.

It's cool technology, right? What could go wrong? The answer: a lot.

First off, it takes a subjectively long time to figure out who the driver is in the best of cases. Objectively, I've timed it as over 10 seconds in the worst case. It doesn't seem to work at all if you have the camera display turned on. And if you shift into gear without waiting for it to finish, it gives up.

Second, it's not very good: at least half the time it doesn't figure out that it's me, even though I've “trained” it with multiple postures, with and without sunglasses. To get a good reading, you must stare at the infotainment screen and remain rigidly in place, like you're posing for an 1800s photo. Even then, the failure rate is pretty high.

Third, it appears to operate asynchronously. Not a problem, except when the ”don't look at the infotainment unit while driving” warning pops up (something that happens for every drive). If you acknowledge that warning, then the DPS seems to give up (or maybe it interprets the button press as accepting whatever driver it thinks you are).

None of this would be intolerable, if it simply defaulted to the previous driver's settings. But for some reason, Mazda decided to default to a “guest” setting. The point of this completely eludes me: if you're loaning your car to someone, why would they need their own configuration? And why would Mazda think that the next person to borrow the car would want the same settings?

And that brings me to the real problem: the Driver Personalization System doesn't just adjust the seat, mirrors, and steering wheel. It appears to remember every menu configuration item, from the position of the heads-up display (good) to the selected radio station and audio volume (not so good, although thankfully we don't have a teenager). Over the past year I've tried to make the guest settings the same as my normal settings, and every time I find a new one to change I curse the Mazda designers and developers.

So I have one recommendation: get rid of the friggin' “guest” mode and just default to the last driver.

Wrapping Up

I wrote this post at least partly to vent, and partly in the hope that a Mazda product manager might see it and instigate change (hey, it's worked for my posts critical of AWS services!).

But a bigger reason — and why it's on my programming-focused blog — is that each of these problems is a user interface failure. Likely caused by design and development teams that are working in isolation, trying to tick features off a product manager's list and meet an imposed deadline, without a QA team that acts as the voice of the customer. Fortunately, as software problems all of them can be corrected by that same development team, and installed during a scheduled service.

If enough people show their annoyance.

Wednesday, July 25, 2012

Business Logic and Interactive Web Applications

By the mid-2000s, the structure of an MVC web-app had gelled: business logic belonged in the model (which was usually divided into a service layer and persistent objects), a thin controller would invoke model methods and select data to be shown to the user, and a view held markup and the minimal amount of code needed to generate repeating or optional content. There might be some client-side validation written in JavaScript, but it was confined to verifying that fields were filled in with something that looked like the right value. All “real” validation took place on the server, to ensure that only “good” data got persisted.

Then along came client-side JavaScript frameworks like JQuery. Not only could you make AJAX calls, but they let you easily access field values and modify the rendered markup. A few lines of JavaScript, and you have an intelligent form: if option “foo” is selected, hide fields argle and bargle, and make fields biff and bizzle read-only.

The problem with intelligent front-ends is that they almost always duplicate the logic found in the back end. Which means that, inevitably, the two will get out of sync and the users will get upset: bargle was cleared but they expected it to hold the concatenated values of biff and bizzle.

There's no good solution to this problem, although it's been faced over and over. The standard solution with a “thick client” application was layered MVC: each component had its own model, which would advertise its changes to the rest of the app via events. These events would be picked up by an application-level controller, which would initiate changes in an application-level model, which would in turn send out events that could be processed by the components. If you were fastidious, you could completely separate the business logic of both models from the GUI code that rendered those models.

I don't think that approach would work with a web-app. The main reason is that the front-end and back-end code are maintained separately, using different languages. There's simply no way to look one place and see all the logic that applies to bizzle.

Another problem is validation. The layered approach assumes that each component sends data that's already been validated; there's no need for re-validation at the lower levels. That may be acceptable for internal applications, but certainly not for something that's Internet-facing.

One alternative is that every operation returns the annotated state of the application model: every field, its value, and a status code — which might be as simple as used/not-used. The front-end code can walk that list and determine how to change the rendered view. But this means contacting the server after every field change; again, maybe not a problem on an internal network, but not something for the Internet.

Another alternative is to write all your code in one language and translate for the front end. I think the popularity of GWT says enough about this approach.

I don't have an answer, but I'm seeing enough twisted code that I think it's an important topic to think about.

Thursday, December 29, 2011

Why I Don't Use Emacs

I didn't start developing code on *nix systems until around 1987. At the time, I was doing a gig with BBN, which a former coworker described as “a halfway house for MIT postgrads.” As such, emacs was clearly the editor of choice, although we used Sun hardware, so vi was available.

On my first day, I sat down with the emacs tutorial. And after a few minutes, tried to save my file. Nothing happened. In fact, nothing I typed had any effect. It took me a few more minutes to figure out what had happened.

I was using a VT-100-compatible terminal (I can't remember the name, but it was a very nice machine with a rotating display that would either show 48 rows or 120 columns). And a VT-100, like all of the ASCII-based terminals that preceded it, used Ctrl-S and Ctrl-Q to suspend and enable the flow of data.

Emacs uses Ctrl-X Ctrl-S to save a file.

My coworkers tried to convince me that this was not a problem: “just remap your keyboard.” But I decided that any editor that could not be used, as-is, on the world's most popular computer terminal was the product of a design ethos that I wanted nothing to do with. I switched to vi and haven't looked back.

Tuesday, December 6, 2011

Actron CP9580: How Not To Do An Update

The Actron CP9580 is an automotive scantool. For those who aren't DIY mechanics, it connects to your car's on-board computer and reports on engine operation and trouble codes (ie, why your “check engine” light is on). My car has passed 100,000 miles, and received its first (hopefully spurious) trouble code a few weeks ago; the $200 investment seemed worthwhile.

Except that right now, the tool is an expensive doorstop, sitting in the manufacturer's repair shop, and I wasted a couple of hours last week. All because I ran the manufacturer-supplied update, which failed catastrophically. As I look back on the experience, I see several problems with their update process, some of which are rooted in a 1990-vintage design mentality, but all of which represent some fundamental failing that every developer should avoid.

#1: They used their own protocol to communicate with the device

In 1990, most embedded devices used an RS-232 serial port to communicate with the outside world. Manufacturers had no choice but to develop their own communications protocol, using something like X-Modem for file transfers.

But the CP9580 has a USB port. And I'm betting that it has flash memory to store its data files. Both of which mean that a custom protocol doesn't make sense. Instead, expose the flash memory as a removable drive and let the operating system — any operating system — manage the movement of data back and forth. Doing so should actually reduce development costs, because it would leverage existing components. And it would make user-level debugging possible: simply look at what files are present.

#2: They deleted the old firmware before installing the new

Again, a vestige of 1990, when devices used limited-size EEPROMs for their internal storage. Not only was the amount of space severely limited, but so were the number of times you could rewrite the chip before it failed. Better to simply clear the whole thing and start fresh.

This is another case where flash memory and a filesystem-based design change the game entirely. Consumer demand for memory cards has pushed the price of flash memory to the point where it's not cost-effective to use anything less than a gigabyte. And with a filesystem, version management is as simple as creating a new directory.

It's also a case where the game changed and the system designers half-changed. In the old days, communications code was in permanent ROM. If an update failed, no problem: you could try again (or reload the previous version). However, it seems that the CP9580 stores everything in flash memory, including the loader program (at least, that's what I interpret from the tech support person's comments, but maybe he was just being lazy).

The iPhone is a great example of how to do updates right: you can install a new revision of iOS, run it for months, and then decide that you want to roll back; the old version is still there. But it's not alone; even an Internet radio is smart enough to hold onto its old software while installing an update.

#3: They kept the update on their website, even though they'd had reports of similar failures

The previous two failings can be attributed to engineers doing things the same way they always have, even when the technology has moved forward. This last failure runs a little deeper. After the update failed, the second time I called tech support I was told that “we've had several cases where this happened.” Yet the software was still on the website, without a warning that it might cause problems. And it's still there today.

One of the best-known parts of the Hippocratic Oath is the exhortation to “do no harm.” Programmers don't have to swear a similar oath, but I think they should — if only to themselves. Too often we look at the technical side of a problem, forgetting that there's a human side. Sometimes the result ends up on The Daily WTF, but more often it ends up quietly causing pain to the people who use our software.