Double Servo Tester with Display


This is something I’ve already worked on but was never really happy with the result, mainly because the potentiometre that I used was of poor quality and hence non linear and “jumpy”…

The problem is simple: I need to have a reliable and easy to use servo tester, that I can use to test/play with a standard RC servo or ESC or anything else that uses the same control protocol.

This necessity has arisen again quite recently, while working on the 2nd iteration of my ball balancing device.

So here’s my 2nd (and hopefully last) attempt at making something nice and functional…

There’s not much to this project, except some patience for the wiring and a quite expensive BOM for what it does 🙂

Proof of concept

Proof of concept

Again, not many bits went into it:

  • 2 rotary encoders from Sparkfun (with RGB LED on them, but unused)
  • 1 monochrome OLED from Adafruit
  • an Arduino nano pro clone from eBay
The few standard components

The few standard components

Hardest bit was the manual wiring...

Hardest bit was the manual wiring…

Schematic

Schematic

And surprisingly it worked from the 1st try

Almost there...

Almost there…

And now with a nice case, necessary for its protection, though it doesn’t do justice to the nice and shiny OLED Display.

Finished

Finished

 

And of course, the Arduino code running on the microcontroller, using the adaencoder library for the rotary encoders which depends on ooPinChangeInt library.

This of course, beyond the standard Servo, SPI, Wire and Adafruit libraries…

/*
* trandi 25 Apr 2015
*/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#include <ooPinChangeInt.h>
#include <AdaEncoder.h>
#include "Switch.h"

#include <Servo.h>

// for ooPinChangeInt library
// #define NO_PORTB_PINCHANGES // to indicate that port b will not be used for pin change interrupts
#define NO_PORTC_PINCHANGES // to indicate that port c will not be used for pin change interrupts
#define NO_PORTD_PINCHANGES // to indicate that port d will not be used for pin change interrupts


#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

AdaEncoder encoderA = AdaEncoder('a', 10, 11);
AdaEncoder encoderB = AdaEncoder('b', 8, 9);
int16_t posA=1500, posB=1500, lastClicksA=0, lastClicksB=0, currentClicksA=0, currentClicksB=0;
int8_t pressesA=0, pressesB=0;

Switch swA = Switch(13);
Switch swB = Switch(12);

Servo servoA;
Servo servoB;




void setup(){
 display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64)
 display.clearDisplay();
 display.setTextSize(2);
 display.setTextColor(WHITE);
 
 servoA.attach(5);
 servoB.attach(6);
}

void loop(){
 currentClicksA = encoderA.getClicks();
 currentClicksB = encoderB.getClicks();
 pressesA = swA.getCount() + 1;
 if(pressesA > 5) {
 pressesA = 1;
 swA.reset();
 }
 pressesB = swB.getCount() + 1;
 if(pressesB > 5) {
 pressesB = 1;
 swB.reset();
 }
 
 posA += (currentClicksA - lastClicksA) * pressesA * 10;
 posB += (currentClicksB - lastClicksB) * pressesB * 10;
 posA = constrain(posA, 600, 2400);
 posB = constrain(posB, 600, 2400);
 
 display.clearDisplay();
 display.fillRect(0, 0, map(posA, 600, 2400, 0, 128), 15, WHITE);
 display.setCursor(0, 16);
 display.print(posA); display.print(" :"); display.print(pressesA);
 display.fillRect(0, 32, map(posB, 600, 2400, 0, 128), 15, WHITE);
 display.setCursor(0, 48);
 display.print(posB); display.print(" :"); display.print(pressesB);
 
 display.display();
 
 servoA.writeMicroseconds(posA);
 servoB.writeMicroseconds(posB);
 
 lastClicksA = currentClicksA;
 lastClicksB = currentClicksB;
}

And the small utility class Switch.h that you see imported in the above Arduino code:

#if defined(ARDUINO) && ARDUINO >= 100
 #include <Arduino.h>
#else
 #include <pins_arduino.h>
 #include <WProgram.h>
#endif


class Switch : public CallBackInterface {
 public:
 Switch (uint8_t _pin): pin(_pin){
 pinMode(pin, INPUT);
 PCintPort::attachInterrupt(pin, this, RISING);
 };

 void cbmethod() {
 // do NOT do any software debounce, as we plan on having a hardware one: a 100nF capacitor in parallel with the switch
 count++;
 };
 
 uint8_t getCount() {
 return count;
 }
 
 uint8_t reset() {
 count=0;
 }

 private:
 uint8_t count = 0;
 uint8_t pin;
};
Advertisements

3 Responses to Double Servo Tester with Display

  1. stet vasile says:

    It was more useful with a potentiometer. Encoder is not accurate and fast 🙂

    • trandi says:

      It is actually MUCH more accurate than the potentiometer, and you can see exactly the value generated on the display… That was the whole point of it 🙂
      As for the speed, one can change the increments by pressing on the button : from 1usec for super precision to 100usecs per increment for speed…

  2. Pingback: Arduino, when the Servo library is not good enough… | Robotics / Electronics / Physical Computing

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: