There's not a lot of hardware involved in the Neo Trinkey which also means its super fast to get started

Required Libraries

We only need two libraries for the Neo Trinkey, one for the NeoPixels and one for the capacitive touch

In the Arduino library manager, search for NeoPixel and install Adafruit NeoPixel (double check the name!)

Also install the Adafruit FreeTouch library

Shipping Demo Code

Here's an example that uses the NeoPixels plus two capacitive touch pads, which comes on the NeoTrinkey by default. If you want to just install the demo over, here's the UF2 firmware file:

To compile and upload through the Arduino IDE, plug in the NeoTrinkey. Make sure you've selected the Neo Trinkey in the boards drop-down and also have the matching COM port.

No Serial Port?

If the serial port is not appearing, maybe because some firmware on it is crashing, there's two solutions.

First, double-click the reset button to get it back into bootloader mode. The NeoPixels will be all green.

You can then either drag over the NeoTrinkey demo UF2

OR

You can select the new serial port that comes up from bootloader mode. (After uploading successfully, you'll have to re-select the original serial port that is missing)

NeoPixel Rainbow Example Code

Either way, you should eventually get a Neo Trinkey serial port you can select! Now compile and upload this code. Don't forget you need the libraries we mentioned earlier.

#include <Adafruit_NeoPixel.h>
#include "Adafruit_FreeTouch.h"

// Create the neopixel strip with the built in definitions NUM_NEOPIXEL and PIN_NEOPIXEL
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_NEOPIXEL, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);

// Create the two touch pads on pins 1 and 2:
Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(1, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
Adafruit_FreeTouch qt_2 = Adafruit_FreeTouch(2, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);

int16_t neo_brightness = 20; // initialize with 20 brightness (out of 255)

void setup() {
  Serial.begin(9600);
  //while (!Serial);
  strip.begin();
  strip.setBrightness(neo_brightness);
  strip.show(); // Initialize all pixels to 'off'

  if (! qt_1.begin())  
    Serial.println("Failed to begin qt on pin 1");
  if (! qt_2.begin())  
    Serial.println("Failed to begin qt on pin 2");
}

void loop() {
  uint16_t i, j;

  for(j=0; j<256; j++) { // cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(10);

    // measure the captouches
    uint16_t touch1 = qt_1.measure();
    uint16_t touch2 = qt_2.measure();

    // If the first pad is touched, reduce brightness
    if (touch1 > 500) {
      // subtract 1 from brightness but dont go below 0
      neo_brightness = max(0, neo_brightness-1);
      Serial.print("New brightness: "); Serial.println(neo_brightness);
      strip.setBrightness(neo_brightness);
    }

    // If the second pad is touched, increase brightness
    if (touch2 > 500) {
      // add 1 to brightness but dont go above 255
      neo_brightness = min(255, neo_brightness+1);      
      Serial.print("New brightness: "); Serial.println(neo_brightness);
      strip.setBrightness(neo_brightness);
    }

    // don't print touch data constantly, only every 10 runs  
    if (j % 10 == 0) {
      Serial.print("QT 1: "); Serial.print(touch1);
      Serial.print("\t\tQT 2: "); Serial.println(touch2);
    }
  }

}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

Note that you can use the onboard NeoPixels like any 4-LED strip. We have A full guide on NeoPixels and how to use and code them here.

We pre-define two constants, PIN_NEOPIXEL and NUM_NEOPIXEL so you don't have to remember the neopixel pin (digital 0) or qty (4)

For the capacitive touch pads, you can call .measure() on the touch object to get a quantity-count reading. We find 500 to be a good threshold to determine whether its touched or not! The first touch pad is on digital 1 and the second is on digital 2, easy to remember!

Keyboard Example

You may want to use the the Neo Trinkey as a little keyboard. Here's an example that uses the Arduino Keyboard library to press various keys for sending messages or commands. It's very powerful and fun, but be careful because it can 'take over' your computer. If that happens, double-click the reset button to put it back into bootloader mode where it will not send any keypresses.

After uploading, you can touch the second pad to open up notepad (on Windows) and then touch the first pad a few times, to see the incrementing number.

/*
  Keyboard Message test
  For the Adafruit Neo Trinkey
  Sends a text string when a one touchpad is pressed, opens up Notepad if the other is pressed
*/

#include <Adafruit_NeoPixel.h>
#include "Adafruit_FreeTouch.h"
#include "Keyboard.h"

// Create the neopixel strip with the built in definitions NUM_NEOPIXEL and PIN_NEOPIXEL
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_NEOPIXEL, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);

// Create the two touch pads on pins 1 and 2:
Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(1, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
Adafruit_FreeTouch qt_2 = Adafruit_FreeTouch(2, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);


bool previousTouch1State = false;   // for checking the state of touch 1
bool previousTouch2State = false;   // for checking the state of touch 1
int touch1counter = 0;              // touch 1 counter

void setup() {
  Serial.begin(9600);
  //while (!Serial) delay(10);
  
  strip.begin(); // start pixels
  strip.setBrightness(20); // not too bright!
  strip.show(); // Initialize all pixels to 'off'

  if (! qt_1.begin())  
    Serial.println("Failed to begin qt on pin 1");
  if (! qt_2.begin())  
    Serial.println("Failed to begin qt on pin 2");
    
  // initialize control over the keyboard:
  Keyboard.begin();
}

void loop() {
  
  // measure the captouches
  uint16_t touch1 = qt_1.measure();
  uint16_t touch2 = qt_2.measure();
  // whether we think they are being touched
  bool Touch1State, Touch2State;

  // print out the touch readings
  Serial.print("QT 1: "); Serial.print(touch1);
  Serial.print("\t\tQT 2: "); Serial.println(touch2);

  // If the first pad is touched, turn on the #2 and #3 pixel red
  if (touch1 > 500) {
    Touch1State = true;  // is touched
    strip.setPixelColor(2, 0xFF0000);
    strip.setPixelColor(3, 0xFF0000);
  } else {
    // turn them off
    Touch1State = false;  // is not touched
    strip.setPixelColor(2, 0x0);
    strip.setPixelColor(3, 0x0);    
  }


  // If the second pad is touched, turn on the #0 and #1 pixel blue
  if (touch2 > 500) {
    Touch2State = true;  // is touched
    strip.setPixelColor(0, 0x0000FF);
    strip.setPixelColor(1, 0x0000FF);
  } else {
    // turn them off
    Touch2State = false;  // is not touched
    strip.setPixelColor(0, 0x0);
    strip.setPixelColor(1, 0x0);
  }
  
  strip.show(); // display pixel changes

  // If we are now touching #1, and we weren't before...
  if (Touch1State and !previousTouch1State) {
    touch1counter++; // increment the touch counter
    // type out a message
    Keyboard.print("You touched the captouch #1 ");
    Keyboard.print(touch1counter);
    Keyboard.println(" times.");
  }
  // save the current touch state for comparison next time:
  previousTouch1State = Touch1State;

  // If we are now touching #2, and we weren't before...
  if (Touch2State and !previousTouch2State) {
    // make a complex collection of commands for windows!
    Keyboard.press(KEY_LEFT_GUI);
    delay(100);
    Keyboard.releaseAll();
    delay(100);
    // run notepad
    Keyboard.print("notepad");
    delay(100);
    Keyboard.press(KEY_RETURN);
    delay(100);
    Keyboard.releaseAll();
    delay(1000); // wait for it to run
    Keyboard.println("hello world!");
  }
  // save the current touch state for comparison next time:
  previousTouch2State = Touch2State;
  
  delay(10);  // and pause a moment
}

There's two sections of the code after setup. First we check the capacitive touch pads, if they're touched we turn on the nearby NeoPixels to help give feedback. We also assign a State variable to track if the pad is currently touched

// If the first pad is touched, turn on the #2 and #3 pixel red
  if (touch1 > 500) {
    Touch1State = true;  // is touched
    strip.setPixelColor(2, 0xFF0000);
    strip.setPixelColor(3, 0xFF0000);
  } else {
    // turn them off
    Touch1State = false;  // is not touched
    strip.setPixelColor(2, 0x0);
    strip.setPixelColor(3, 0x0);    
  }

Later on, we can determine if we have changed state from not touched to touched, so we can send a message via the keyboard. In this case we print a string and a variable:

// If we are now touching #1, and we weren't before...
  if (Touch1State and !previousTouch1State) {
    touch1counter++; // increment the touch counter
    // type out a message
    Keyboard.print("You touched the captouch #1 ");
    Keyboard.print(touch1counter);
    Keyboard.println(" times.");
  }
  // save the current touch state for comparison next time:
  previousTouch1State = Touch1State;

More advanced commands can be sent, with various control characters. This example starts up notepad on windows and types in Hello World. If you want to do these sorts of command collections, make sure to add many delays because the Neo Trinkey types much faster than computers are expecting!

// If we are now touching #2, and we weren't before...
  if (Touch2State and !previousTouch2State) {
    // make a complex collection of commands for windows!
    Keyboard.press(KEY_LEFT_GUI);
    delay(100);
    Keyboard.releaseAll();
    delay(100);
    // run notepad
    Keyboard.print("notepad");
    delay(100);
    Keyboard.press(KEY_RETURN);
    delay(100);
    Keyboard.releaseAll();
    delay(1000); // wait for it to run
    Keyboard.println("hello world!");
  }
  // save the current touch state for comparison next time:
  previousTouch2State = Touch2State;

iOS Camera Shutter

This example uses the Neo Trinkey as a camera shutter release for an iOS device. You will need a  Lightning to USB adapter such as this one, as well as a USB extension cable.

/*
  Adafruit Neo Trinkey camera shutter release for iOS devices
  Sends a volume up command when one touchpad is pressed, sends volume down on the other
  Both of these trigger shutter on iOS camera for stills or video
*/

#include <Adafruit_NeoPixel.h>
#include "Adafruit_FreeTouch.h"
#include "HID-Project.h"

// Create the neopixel strip with the built in definitions NUM_NEOPIXEL and PIN_NEOPIXEL
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_NEOPIXEL, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);

// Create the two touch pads on pins 1 and 2:
Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(1, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);
Adafruit_FreeTouch qt_2 = Adafruit_FreeTouch(2, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);


bool previousTouch1State = false;   // for checking the state of touch 1
bool previousTouch2State = false; 

void setup() {
  
  strip.begin(); // start pixels
  strip.setBrightness(20); // not too bright!
  strip.show(); // Initialize all pixels to 'off'

  if (! qt_1.begin())  
    Serial.println("Failed to begin qt on pin 1");
  if (! qt_2.begin())  
    Serial.println("Failed to begin qt on pin 2");
    
  // initialize control over the keyboard:
  Consumer.begin();
}

void loop() {
  
  // measure the captouches
  uint16_t touch1 = qt_1.measure();
  uint16_t touch2 = qt_2.measure();
  // whether we think they are being touched
  bool Touch1State, Touch2State;


  // If the first pad is touched, turn on the #2 and #3 pixel red
  if (touch1 > 500) {
    Touch1State = true;  // is touched
    strip.setPixelColor(2, 0xFF0000);
    strip.setPixelColor(3, 0xFF0000);
  } else {
    // turn them off
    Touch1State = false;  // is not touched
    strip.setPixelColor(2, 0x0);
    strip.setPixelColor(3, 0x0);    
  }


  // If the second pad is touched, turn on the #0 and #1 pixel blue
  if (touch2 > 500) {
    Touch2State = true;  // is touched
    strip.setPixelColor(0, 0x0000FF);
    strip.setPixelColor(1, 0x0000FF);
  } else {
    // turn them off
    Touch2State = false;  // is not touched
    strip.setPixelColor(0, 0x0);
    strip.setPixelColor(1, 0x0);
  }
  
  strip.show(); // display pixel changes

  // If we are now touching #1, and we weren't before...
  if (Touch1State and !previousTouch1State) {
    Consumer.write(MEDIA_VOLUME_UP);
  }
  // save the current touch state for comparison next time:
  previousTouch1State = Touch1State;

  // If we are now touching #2, and we weren't before...
  if (Touch2State and !previousTouch2State) {
    Consumer.write(MEDIA_VOLUME_DOWN);

  }
  // save the current touch state for comparison next time:
  previousTouch2State = Touch2State;
  
  delay(10);  // and pause a moment
}

This guide was first published on Apr 10, 2021. It was last updated on Mar 29, 2024.

This page (Arduino Examples) was last updated on Mar 08, 2024.

Text editor powered by tinymce.