Warranty Not Void If Removed

Occasionally, bureaucracy gets it right. But getting the word out is often another matter.

We’ve all seen devices with those “WARRANTY VOID IF REMOVED” stickers. We may be curious about what’s inside that Xbox or Roomba, but breaking the manufacturer’s seal would void the warranty.

Well, it turns out that, in the U.S. at least, those stickers not only have no legal force — but are themselves illegal. Manufacturers, according to a 2018 ruling by the Federal Trade Commission, shall not make warranty coverage contingent on using branded parts or service. Since one of the specific warnings in the press release refers to “the warranty seal,” it is implied that this extends to manufacturer warnings that opening the cover will void the warranty.

So go ahead — do that DIY repair. (It’s better for the manufacturer than RMA’ing it, and better for the environment than throwing it out.)

Posted in Current Events, Digital Citizenship, Electronics | Leave a comment

Comma Delimited

Some of the most useful tools are the simplest. I would argue that simplicity is often why those tools are the most useful.

The humble .csv file is a good example of this. It may even, other than the question of character encoding, be one of the only things nearly all programmers can agree on. It’s almost up there with “bytes have eight bits.”

.CSV files, named for the traditional file extension dating back to the days of DOS, are just about as simple a data format as there is. CSV stands for Comma Separated Values — and that’s just what these files are. Raw data, split into columns by commas and into rows by CR/LF combinations (okay, this varies by system, too.)

Although .csv files aren’t as flexible or self-documenting as modern formats such as JSON, they are both (generally) human-readable and very simple to programatically create and parse. Practically anything that works with data can export them, so they have become a significant lingua franca of data analysis.

It’s not as flashy as XML, but there’s something to be said for a format that’s easily readable by desktops, microcontrollers, and humans.

Posted in Coding, Tools | Leave a comment

Printing Large Numbers on Arduinos

2^32 (4,294,967,296) sounds like a big number. It’s over four billion, after all.

Large as it is, four billion (or more) is increasingly a perfectly reasonable number to be working with. For instance, it represents access to four gigabytes of memory, which isn’t much, these days. 32-bit math has become limiting, which is why computers switched to 64-bit hardware about ten years ago. (It was the memory addressing that made it happen.)

There’s good support for 64-bit numbers on desktop software, too. C provides the “unsigned long long int” (or uint64_t) type, which can hold numbers up to 2^64-1, and this covers nearly all of the cases that don’t fit in 32 bits.

Unfortunately, these large numbers, being newer than their 16-bit and 32-bit counterparts, aren’t always supported as well on smaller devices like microcontrollers. (After all, an 8-bit microcontroller has to do a lot of shuffling and carrying to do math with them.) Arduino C’s usual, super easy to use Serial.Print() function doesn’t understand how to handle anything larger than 32 bits. Trying an end run using tricks like sprintf(myString,”%llu”,bigValue) doesn’t work, either.

The proper solution would be to find a way to include 64-bit capable printf() code in the Arduino C compiler — but I suspect that if this were easy, someone would have done it by now. So I came up with a hack: use long division.

Integers, in any base, can be constructed digit by digit, and Arduinos can still do math with 64-bit numbers. So, to print out large numbers, take the number modulo ten, add that to the left end of your string, take it away from the original number, and divide it by ten. It’s not super efficient, needing an integer division operation for each digit — but it will still run in O(log(n)) time, and shouldn’t take very long at all, even for large numbers. It can be done in C readily enough, but the BASIC-like string concatenation capabilities of Arduino C make it easy.

Here’s the code, which should work for all Arduino-compatible devices:

void bigPrint(uint64_t n){
  //Print unsigned long long integers (uint_64t)
  //CC (BY-NC) 2020
  //M. Eric Carr / paleotechnologist.net
  unsigned char temp;
  String result=""; //Start with a blank string
  if(n==0){Serial.println(0);return;} //Catch the zero case
  while(n){
    temp = n % 10;
    result=String(temp)+result; //Add this digit to the left of the string
    n=(n-temp)/10;      
    }//while
  Serial.println(result);
  }

Now, 18,446,744,073,709,551,615 is the limit. Happy large-number computing!

Posted in Arduino, C, Coding, HOW-TO, Math | Tagged , , , , , , , , , | Leave a comment

DIY scroll wheel

For almost thirty years, I’ve preferred trackballs to traditional mice. Flipping the mouse geometry upside-down means that you can give the trackball a spin to move the cursor quickly, without having to bother with picking up the mouse and moving it back onto the mousepad over and over. Also, more importantly, trackballs don’t need to move around like a traditional mouse does, and so take up a lot less desktop real estate. It’s like having a mouse with an infinitely large mousepad and an infinitely long arm. I honestly don’t know why traditional mice are still a thing.

A Logitech Trackman Marble(tm).
Image shamelessly snagged from Logitech’s site. (Go buy one. They’re good.)

The one drawback to trackballs, however, is that they generally don’t come with scroll wheel functionality of any kind. And while the scroll wheel is still not up there with the left and right mouse buttons in terms of importance on a PC, there are still far too many apps that require it, and a lot more than can make good use of it. The map in Skyrim, for example, can be zoomed to some extent — but only with a scroll wheel. Zooming the view in and out in X-Plane, while possible using the keyboard, is much faster and more intuitive using a wheel input. Also, all of the many knob-based inputs in a typical simulator cockpit can be used with a scroll wheel if the mouse cursor is on them. This is a lot more realistic than trying to click on the correct edge of the image of a multi-function knob on your screen.

Scroll wheel functionality would be useful — but the hassle of moving back to a traditional mouse just isn’t worth it. (I brought in my own Logitech Marble Mouse to work so I wouldn’t have to use a traditional mouse.)

Boards like the Arduino Leonardo now make this a very easy problem to solve! The Leonardo can implement a “HID” (Human Interface Device) via USB, and can appear as a USB keyboard and/or USB mouse to a host computer. Since it’s pretty straightforward to get an Arduino to read a quadrature encoder (see code below), a few lines of code are all that’s needed to get it emulating a scroll wheel.

Here’s the encoder I used — any similar quadrature (relative position / “jog dial”) encoder should work.

Hookup is almost as simple as it gets: 5V to 5V, Ground to Ground, then pick GPIO pins to use for switch (the pushbutton), data, and clock. (Really, phase A and phase B.) I used pins 2, 7, and 8 (more or less arbitrarily), but as long as your pin choices match the ones you set in the code below, it should work.

Here’s the code (designed for an Arduino Leonardo).

//Simple scroll wheel implementation for Arduino Leonardo and similar
//Uses quadrature encoder and USB HID library
//CC-BY-NC 2020, M. Eric Carr / eric at paleotechnologist dot net

#include<Mouse.h>

const int SWITCHPIN = 2; //Push switch function of encoder (for future use)
const int DATAPIN = 7;   //Phase A of encoder
const int CLOCKPIN = 8;  //Phase B of encoder

void setup() {
  pinMode(SWITCHPIN, INPUT); //For future use
  pinMode(DATAPIN, INPUT);
  pinMode(CLOCKPIN, INPUT);
  }

void loop() {
  //Quick-and-dirty quadrature tracking. Counts when A high and B changed;
  //this should produce one count per set of four quadratures.
  //TODO: Give this a little hysteresis by not incrementing and decrementing
  //the count at the same place in the cycle.

  //DO NOT PUT SIGNIFICANT DELAYS IN THIS LOOP; it relies on running fast enough
  //to not miss any transitions. 1ms delay may be too much. 10ms can cause problems.
  //There are four transitions per "click" of the dial; if you spin it quickly,
  //you could go through several dozen transitions in a fraction of a second, causing
  //the count to be in error if this loop is too slow.

  static int oldA=0,oldB=0;
  int a,b;

  a=digitalRead(DATAPIN);
  b=digitalRead(CLOCKPIN);

  if(oldA!=a || oldB!=b){

    if(a==HIGH){
      if(b==LOW && oldB==HIGH){Mouse.move(0,0,1);}  //Scroll up
      if(b==HIGH && oldB==LOW){Mouse.move(0,0,-1);} //Scroll down
      }

    oldA=a;
    oldB=b;

    }//if

  }//loop()

Once everything was wired and tested, I modified a Leonardo case I found on Thingiverse to expand the lid, allowing space for the encoder. It’s even somewhat ergonomic, considering it’s a prototype…

The Leonardo is more-or-less Uno sized,
but with a microUSB cable instead of Type B.
The completed scroll wheel prototype. It doesn’t look like much, but it’s certainly useful.

Happy scrolling!

Posted in Arduino, C, Coding, Digital, HOW-TO, User Interface Design | Tagged , , , , , , , , , , , , | Leave a comment