Small, Ergonomic, Portable and better than any other travel mouse
Hey it's been a while, eh?
In the time since my last post I have continued to futz around with my whole setup. I have spent hours and hours trying to figure out just why the heck things were not working. I even went so far as to just use the arduino code that was provided by Cirque on their Github page (if I have not already mentioned it).
After even more fruitless hours of just random data scrolling across my serial terminal I posted on Cirque's community product forums (link to thread). Let me tell you, what a fantastic customer service experience (even when the customer was a complete knucklehead).
We went through all sorts of troubleshooting scenarios once they realized that my issue might be more than just a simple "make sure that you read the pinout correctly" sort of situation. There was some great exchange of information and someone from the company went so far as to bring in their own personal Adafruit ESP32 Huzzah and hook it up to their logic analyzer. They sent me some great pictures!
Now I do not have one of those fancy logic analyzers (Hackaday, wanna help me out?) , but I can tell you that my setup would not have showed that. After a few more hours of testing continues and checking connection, I finally, FINALLY found out what was wrong.
Try real hard and see if you can spot it:
I know its a crappy picture let me zoom in a little bit and see if you can spot it then:
Right there. That connection wasn't a connection at all!!! Protip: transacting data over SPI is really really difficult when you don't actually have your MOSI line connected to anything! Literally 2 seconds with the soldering iron and the problem that had been plaguing me for weeks was suddenly solved. Of course that was after I shelled out 20 bucks for another trackpad because I thought the first one was broken.
I have also promised you break our boards, and here they are!
I tried to keep the design nice and sleek and made is specifically to match the pinouts for the SPI and I2C pins on the Adafruit ESP32 Feather. I have also added two spaces for the pullup resistors required to use I2C. A handy little board if I do say so myself!
I had seen some advertisements for some super cheap and fast PCBs by JLCPCB but after uploading my design (not nearly as trivial as oshpark makes it), I realized that while it may only be 2 dollars for 10 pcbs, shipping was going to be 25 dollars! First of all, I did not need 10 of these things. three would suffice. Second of all, I was able to get "super speedy" service on my PCBs at Oshpark for the same price as it would take for JLCPCB to ship to my door. Not to mention that JLCPCB could have taken 1-2 weeks longer to do so. I think there is still a clear winner in the hacker community for quick and cheap circuit boards.
With all that being said I think that just about wraps it up for now. While I am no longer getting garbage data, it is still inconsistent. It seems like only a certain region of the trackpad is reporting reliable data while the other parts are intermittent at best. Perhaps I will post a video in the coming days to show you up I mean.
Some other projects are finally wrapping so hopefully this project page will be a bit more active!
Pretty much sums up my experince since the last log.
The good news is that I actually got a breakout board for the FPC/FFC connector! The bad news is that is pretty much the only good news.
A (un)Beautiful Breakout Board
I ordered the 50 pin Adafruit breakout board from Amazon. With the HaD Prize deadline for Human Computer Interfaces mere days away, I had to limit myself only to what was available on Prime. So that is pretty much all I could find. There were many other suitable breakout board designs, i.e. only 12 pins and more breadboard friendly, but all of them would have taken weeks to get here. So I had to make do with what I could get.
I received the breakout board a few days later and soldered the connector so I could begin actually hooking up the trackpad for the first time. After working out the best way to mush everything onto a tiny breadboard, I tried to upload a standard "Hello, World!" program from the ESP-IDF, just to make sure that nothing was shorting or would be making smoke. I wanted to take baby steps with this project because I knew that something was going to go wrong.
Sure enough, something went wrong. My first issue was that the pins that I needed to use for the trackpad connections aligned perfectly with the UART pins that had been broken out on the ESP32 dev board that I am using. Originally my plan was just to disconnect the trackpad when I was going to upload code, but then of course I wouldn't be able to log anything to the terminal for debugging purposes..... In the end I determined that it would be easiest to just jump the 2 pins interfering with the UART pins to another location on the breakout board.
Besides the UART pins, I also needed to jump the GND pin as well as a few more GPIOs because of course out of all the GPIO pins that I needed to use, pins 34-39 on the ESP32 are input only. Long story short, here is what my breakout board looks like as of now. All bodged and jumped.
So you should be good to program, right?
I thought so too! I was very eager to try out the code that I wrote, and just as I suspected, I did have some issues. I was getting various I2C errors and what not but I actually managed to figure them all out. Not too bad for my first time working with I2C with this lower level of abstraction. While I wasn't getting any errors, I couldn't actually figure out how to get any data out of the sensor. Like I said, I am still new to this stuff.
The time was ticking to get this thing working though, so I broke down and tried to get the arduino code working. In therory that was already working code that just needed the write connections to make the trackpad chooch. However I encountered another issue. I needed to add the ESP32 to the arduino IDE. That would have been pretty trivial, if I was on my normal x86 laptop. Unfortunately, the USB controller on my laptop fried itself so I have been using my Raspberry Pi as a temporary desktop to do my programming. To add insult to injury I then needed to figure out how to build the xtensa-esp32 toolchain for ARM, and then figure out how to make the arduino IDE look for that special build instead of letting itself try to automagically set itself up. What a joy.
But you got it figured out, right?
I did finally manage to get the code from the arduino IDE to compile (very slowly) and upload to my dev board. I double checked all my connections and made sure that everything was inorder. I checked out put from the serial port to see if I was receiving and data that made sense, and sure enough, I was not!
Read more »
Supposedly, when the trackpad has data that should be read it will pull the "DR_PIN" high. By monitoring this pin, you can determine whether or not there is data that needs to be handled. For some reason this pin was not doing anything. I tried all sorts of pull up and pull downs and...
So the hardware side of things is shaping up pretty nicely. I have some parts picked out and I plan on doing to circuit board design in the coming days.
In the meantime I figured that I should probably start working on the equally important software side of things as well.
The biggest hurdle that I have to face here is actually interfacing with the touchpad itself. I looked around on Cirque's website and their resource section definitely leaves something to be desired. Nonetheless, I was able to find what I was looking for, a Github repo, albeit a pretty sparse one.
Up until this point I have not worked much with software so I was hoping for something that was somewhat plug and play. Unfortunately this piece of hardware isn't exactly in the hobbyist limelight, so I wasn't expecting much. In the repo there is some Arduino code for both I2C and SPI as a means of communication with the device. Which I have to say is pretty cool. All it takes is the removal of a single SMD resistor to change between I2C and SPI modes.
While the Arduino code was very tempting, at the start of this project I had committed myself to using the ESP-IDF provided by Esspressif. In my short experince with it, I have found it a pleasure to use, and it really helps the ESP32 live up to it's full potential.
So how do we actually talk to this thing?
Good question. I am still not entirely sure, but I have made a lot of progress. It seems like the time that Cirque could have spent developing their Github repo, was actually spent writing excellent hardware (PDF) and interfacing (PDF) documentation. After reading through the documents a couple times, I almost came close to feeling like I knew what I was doing!
The way they want you to interface with this device is I think is pretty clever. They call it Register Access Protocol, and it is pretty simple. This protocol only has two functions, read and write. With these read and write functions you can access a ton of different information about the device and what it is sensing. Below you can see a list of all the different registers that not only provide information to the user, but can also be written to in order to configure the device to suit your needs.
One of the most intriguing of these options is the have to do with the 0x0A and the 0x0B registers, which appear to contain some data on the Z-axis. I was initially confused about this because you know, it's a trackpad. After reading through some more of the documentation, it appears that the trackpad can sense a rough distance between your finger and the pad. This opens lots of possibilities for making various gestures and shortcuts to help improve the actual user experince.
....Anyway, here is the code
I decided to use the I2C mode of the trackpad for my application. I figured that while I2C may only be half-duplex, and therefore slower, I2C uses less pins and will hopefully make routing the PCB a little bit easier. I am just hoping that I2C is still fast enough.
Anyway, here is the code. After reading the ESP-IDF documentation it turns out that using I2C isn't actually too hard.
First, the write RAP_WRITE function. (Disclaimer: this code has not yet been tested and is probably incorrect).
This is pretty simple and has two arguments, the address of the register that you would like to write, and the value that will be written to said register.
Second the, RAP_READ function. This is really the one that will get used the most and will allow us to access data from registers containing position data. I know for a fact that I need to test this one and I have to admit that I don't fully understand it yet. ...Read more »
Parts and Design Choices
The heart and soul of the SmoothMove is going to be the ESP32 of course. However, this presents a bit of a design challenge. One of the most popular ESP32 modules is undoubtedly the WROOM-32. While it may seem pretty small (only 18mm by 25mm) for our application that is still going to be pretty large. I was able to fit a decapped WROOM-32 Module into my currently designed shell but that is far from the most optimal solution. Using a ready made module in such a space constrained application is hardly the best way to go about things anyway.
Enter the ESP32 PICO-D4
For those of you wtih a good memory, you will remember that [Brain] wrote a post about the ESP32 Pico back in September of 2017. This is essentially a ESP32 on a chip and really only requires a couple of bypass capacitors and an antenna on the PCB. All of the ROM and RAM and clock and pretty much everything else you could ever want or need is integrated right into the itty-bitty 7x7mm package. This is a match made in heaven!
Cool but this is supposed to be a tiny mouse, what about all that stuff?
I'm so glad that you asked! While the ESP32 Pico is certainly cool, the real star of the show is going to be the Cirque TM023023 (PDF). After looking around, and researching just what it would take to DIY a tiny capacitive touchpad from scratch I quickly realized that there weren't many good solutions. Any project that I found simple did not provide the level of fidelity that a mouse track pad would require. Not to mention the fact that no one really seemed to have found a circular touchpad that I wanted to make.
Yet I know that it could be done, the new(ish) Steam Controller and the Google DayDream Controller came to mind. They both had circular touch pads that replaced the typical analog sticks found on interface devices of yesteryear. I looked up a tear down of a steam controller and sure enough it led me right to a supplier: Cirque
This is pretty much just what the doctor ordered, the smallest touch pad is exactly the size I was looking for. It works on an SPI interface and while I have yet to look at the code, they provide Arduino compatible examples that should be pretty easy to port onto the ESP32 if not trivial. It appears that Cirque sells their custom made touch ASCI's so in the future, integrating the touch module right into the PCB will be feasible. For the time being though I will just be dealing with the daughter board.
Cool cool, but you mentioned that you are going to need to make a PCB antenna, how the heck do you do that?
To be entirely honest, I have no idea. I found a great place to start though. Back in 2014 there was a HaD post linking to a bunch of PCB antenna reference designs made by Texas Instruments. I will probably just end up using the stand squigly "F" design that you see on most cheap 2.4GHz devices. I'm not entirely certain on the size constraints that I have yet, so I may have to settle for a more inferior ceramic chip antenna. While I would sacrifice some range, it would take up less space and make the design process easier, despite adding to the BOM.
I have never delt with RF in PCB design before so I am excited to devel into this world.
So what else is there?
Welp. I still have to find out how I am actually going to integrate all of the rest of the things that make a mouse a mouse. i.e. buttons, and hopefully a scroll wheel. I want the device to be just as, if not more, convenient to use then an ordinary mouse. As such I would like to have all of the standard functions that you have on a normal mouse meaning: 3 buttons, and a scroll wheel.
I canabilzed a broken bluetooth mouse that I had laying around (the unfortunate victim of some percussive maintenance),...Read more »
Really the first few steps of this endeavour have been all about the designing of the device's case. You can see the progression below. I want it to be able to be comfortably grasped for a few hours at a time. This is a bit tricky because I also wanted the device to be so small. Anytime I think small, I always think uncomfortable. I hoping that I will be able to make an ergonomic form factor and still keep the device as small and portable as possible.
My answer to this issue of size versus comfort I am solving with a specifically shaped bottom half of the device. I am still nailing down just how I want the user to be able hold the device so it's a work in progress. This is what I have so far.
On the list of things that I still need to figure out: