The code for the Bionic Eye is fairly simple: There are 2 servos, programmed to make independent random movements at random times. The random ranges are selected so that the tilt servo moves on average about twice a second and the rotate servo moves about once per second. You can speed it up for a somewhat wackier non-stop motion effect, or slow it down for a creepy/sinister evil-eye effect
The random range for the tilt servo motion is restricted to about 30 degrees. The rotation servo is allowed to go the full 180 degrees.
The servos are allowed 100 milliseconds to reach their position, then they are detached to save power and reduce noise and jitter.
You will need to install the SoftServo Library. You can download it using the button below. For Library installation instructions, see this guide.
Then paste the following sketch into the IDE and upload it to your Trinket.
// SPDX-FileCopyrightText: 2018 Bill Earl and Mikey Sklar for Adafruit Industries // // SPDX-License-Identifier: MIT /******************************************************************* Bionic Eye sketch for Adafruit Trinket. by Bill Earl for Adafruit Industries 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 Trinket: Bat+ Gnd Pin #0 Pin #1 Connection: Servo+ Servo- Tilt Rotate (Red) (Brown) Servo Servo (Orange)(Orange) *******************************************************************/ #include <Adafruit_SoftServo.h> // SoftwareServo (works on non PWM pins) #define TILTSERVOPIN 0 // Servo control line (orange) on Trinket Pin #0 #define ROTATESERVOPIN 1 // Servo control line (orange) on Trinket Pin #1 Adafruit_SoftServo TiltServo, RotateServo; //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!) TiltServo.attach(TILTSERVOPIN); // Attach the servo to pin 0 on Trinket RotateServo.attach(ROTATESERVOPIN); // Attach the servo to pin 1 on Trinket delay(15); // Wait 15ms for the servo to reach the position } void loop() { delay(100); TiltServo.detach(); // release the servo RotateServo.detach(); // release the servo if(random(100) > 80) // on average, move once every 500ms { TiltServo.attach(TILTSERVOPIN); // Attach the servo to pin 0 on Trinket TiltServo.write(random(120, 180)); // Tell servo to go to position } if(random(100) > 90) // on average, move once every 500ms { RotateServo.attach(ROTATESERVOPIN); // Attach the servo to pin 1 on Trinket RotateServo.write(random(0, 180)); // Tell servo to go to 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; TiltServo.refresh(); RotateServo.refresh(); } }
Page last edited January 21, 2025
Text editor powered by tinymce.