Trinket M0 & Gemma M0

The Trinket / Gemma M0 can use the default Servo library. The Arduino Code for 'Knob' is a good place to start.

The following pins on each controller can be used for driving servos with the default Servo Library:

  • Trinket M0 - Use PWM pins D0, D2, D3, D4 (pin D1 cannot be used)
  • Gemma M0 - Use PWM pins D0, D2 (pin D1 cannot be used)

Trinket & Gemma with ATtiny85

To control servos with the tiny microcontroller on the Trinket, we'll need a Servo library. The default Arduino Servo library is really only good for Uno/Leonardo/Due and similar beefy processors that can drive servos 'standalone'. Sadly, the Attiny85 can't quite do that as it does not have 16bit timers.

So instead we'll use a simpler servo library. Luckily, we wrote one that's perfect! Download the Adafruit_SoftServo library from https://github.com/adafruit/Adafruit_SoftServo by clicking the button below

Install the library into the Arduino libraries directory. See All About Installing Arduino Libraries for a guide.

Please ensure your Arduino IDE is augmented to support Trinket per the Introducing Trinket Guide.

The code below may be copied-and-pasted into a new project window in the Arduino IDE.

The Arduino code presented below works well on the Trinket Mini and Gemma v2. If you have an M0 board you can use the CircuitPython code on the next page of this guide.
// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries
//
// SPDX-License-Identifier: MIT

/*******************************************************************
  SoftServo sketch for Adafruit Trinket.  Turn the potentiometer knob
  to set the corresponding position on the servo 
  (0 = zero degrees, full = 180 degrees)
 
  Required library is the Adafruit_SoftServo library
  available at https://github.com/adafruit/Adafruit_SoftServo
  The standard Arduino IDE servo library will not work with 8 bit
  AVR microcontrollers like Trinket and Gemma due to differences
  in available timer hardware and programming. We simply refresh
  by piggy-backing on the timer0 millis() counter
 
  Required hardware includes an Adafruit Trinket microcontroller
  a servo motor, and a potentiometer (nominally 1Kohm to 100Kohm
 
  As written, this is specifically for the Trinket although it should
  be Gemma or other boards (Arduino Uno, etc.) with proper pin mappings
 
  Trinket:        USB+   Gnd   Pin #0  Pin #2 A1
  Connection:     Servo+  -    Servo1   Potentiometer wiper
 
 *******************************************************************/

#include <Adafruit_SoftServo.h>  // SoftwareServo (works on non PWM pins)

#define SERVO1PIN 0   // Servo control line (orange) on Trinket Pin #0

#define POTPIN   1   // Potentiometer sweep (center) on Trinket Pin #2 (Analog 1)

Adafruit_SoftServo myServo1, myServo2;  //create TWO servo objects
   
void setup() {
  // Set up the interrupt that will refresh the servo for us automagically
  OCR0A = 0xAF;            // any number is OK
  TIMSK |= _BV(OCIE0A);    // Turn on the compare interrupt (below!)
  
  myServo1.attach(SERVO1PIN);   // Attach the servo to pin 0 on Trinket
  myServo1.write(90);           // Tell servo to go to position per quirk
  delay(15);                    // Wait 15ms for the servo to reach the position
}

void loop()  {
  int potValue;  // variable to read potentiometer
  int servoPos;  // variable to convert voltage on pot to servo position
  potValue=analogRead(POTPIN);                // Read voltage on potentiometer
  servoPos = map(potValue, 0, 1023, 0, 179);  // scale it to use it with the servo (value between 0 and 180) 
  myServo1.write(servoPos);                    // tell servo to go to position

  delay(15);                              // waits 15ms for the servo to reach the position
}

// We'll take advantage of the built in millis() timer that goes off
// to keep track of time, and refresh the servo every 20 milliseconds
// The SIGNAL(TIMER0_COMPA_vect) function is the interrupt that will be
// Called by the microcontroller every 2 milliseconds
volatile uint8_t counter = 0;
SIGNAL(TIMER0_COMPA_vect) {
  // this gets called every 2 milliseconds
  counter += 2;
  // every 20 milliseconds, refresh the servos!
  if (counter >= 20) {
    counter = 0;
    myServo1.refresh();
  }
}

From the Tools→Board menu, select Adafruit Trinket 8 MHz (or Gemma). Connect the USB cable between the computer and Trinket, press the reset button on the board, then quickly click the upload button (right arrow icon) in the Arduino IDE.

If you get an error message (or a huge list of them), it’s usually one of the following:

  • Is the Arduino IDE properly configured for Trinket use? Try compiling and uploading a simple sketch (like the Blink example, set for pin #1).
  • Is the Adafruit_SoftServo library properly installed? It must be correctly named and in the right location (the Arduino libraries folder - see All About Installing Arduino Libraries for a guide).
  • If the code compiles but does not upload, press the reset button and try the upload again.

The code compiles to 1678 bytes of 5310 maximum.

Now you can try twisting the potentiometer to watch the servo spin! 

You can connect servos to pins #0, #1 and #2 but if you connect to #3 or #4 it will interfere with the USB bootloader. So if you want to use #3 or #4, unplug the servos while uploading!
Check this video for what you will see!

This guide was first published on Sep 12, 2013. It was last updated on Sep 12, 2013.

This page (Arduino Code) was last updated on Jan 09, 2023.

Text editor powered by tinymce.