…ghetto prince is my thing, makin’ love’s how I swing,
I’m your pusherman.
1972 © Curtis Mayfield, Pusherman
Running would certainly be appreciated, but we found the hard way we have to start walking first. And when I say walking, I mean crawling. We had to re-learn electronics basics, introduce ourselves to PWM (*) and practice self-control.
So we are to first connect everything to a single device and make sure control runs over wired connections, before moving on to wireless. The basic principle behind that thought is that once you make everything work in a wired environment, wireless would be a cinch. As we will later find out, that was not without its share of problems.
But in the meantime, little research was in order. Looking over the published patent of the Bescor MP-101, panning and tilting is achieved through the use of a mechanism of worm gears, ran by a pair of DC motors, rated at 6VDC. Arduino compatible microcontrollers can inherently control multiple DC motors, surely.
Controlling DC Motors
The Moteino will allow you to generate an analog signal at any one of its analog pins. A few of them are inherently special, however. Labeled PWM, these pins can generate a modulated signal which can be used to do anything from dimming a LED to spinning a DC motor. The Moteino we use has pins 3, 5, 6, 9, 10 and 11 labeled as PWM.
PWM pulses are generated using the AnalogWrite() statement, and [to simplify so that even I can understand] varying the argument for the function will produce a pulse of varying voltage. In the case of the Moteino, which runs on 3.3V as opposed to regular Arduinos which run on 5V, varying the argument will yield a pulse ranging from 0V to 3.3V.
Note: It is not very smart to connect a DC motor directly to the pins of the Moteino. Reverse current can occur, damaging the motor, the Moteino, or the USB port. When not using a motor shield, the motor should be connected, at the very least, through a transistor [to switch the pulse] and a diode [to eliminate reverse flow], such as shown here. We, it seems, liked to live dangerously and didn’t follow our own advise, but did not damage anything. Yet. So you’ve been warned.
Enough about boring stuff, on to making it click, er, work!
Wiring
The arcade style joystick uses 4 click micro-switches, and the movement of the joystick axle allows for any one of those to be clicked, or, with a 8-way joystick, and two adjoining ones to be clicked. The click micro-switches typically have three connecting pins, labeled G [ground], NC [normally closed] and NO [normally open]. For the purposes of this case study, we will use the switches in the normally open position.
And since Fritzing does not yet have a part for an arcade switch, in the following depiction, we’ve used momentary switches – the principle is identical.

For the wiring of the DIN jack, please see an earlier post. [*]
[*] Sure, I have gone against my own advice and used non-PWM pins here. But bear with me – for basic on/off logic, we don’t really need PWM. So why did I write about PWM, you ask?!?! (*&$#*) So that next time I write, speed control will be straightforward.
Coding
Coding the sketch for the principle proof of concept relies on two separate items [1] reading input from the switch based joystick, and [2] actuating each motor.
Reading Input
We developed a short function for this, that reads all four switches, and builds a binary value of the directions selected, assigning 1 for left, 2 for right, 4 for up and 8 for down, so that any click combination will present a unique sum.
1 2 3 4 5 6 7 8 9 |
int handle_button() { int button_pressed = 0; if (!digitalRead(BUTTON_LEFT)) { button_pressed = button_pressed + 1; } if (!digitalRead(BUTTON_RIGHT)) { button_pressed = button_pressed + 2; } if (!digitalRead(BUTTON_UP)) { button_pressed = button_pressed + 4; } if (!digitalRead(BUTTON_DOWN)) { button_pressed = button_pressed + 8; } return button_pressed; } |
Actuating Motors
For the motors themselves, we use a combination of AnalogWrite() [to initiate the movement] and DigitalWrite() [to terminate the movement]. Note that the Moteino will run the PWM pulse continously, once an AnalogWrite() is invoked, until the pin is set to LOW via DigitalWrite().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
#include "Wire.h" #define BUTTON_LEFT 14 #define BUTTON_RIGHT 15 #define BUTTON_UP 16 #define BUTTON_DOWN 17 #define ACT_LEFT 3 #define ACT_RIGHT 4 #define ACT_UP 7 #define ACT_DOWN 8 #define DELAY 100 int button_combo = 0; void setup() { pinMode(BUTTON_LEFT, INPUT); pinMode(BUTTON_RIGHT, INPUT); pinMode(BUTTON_UP, INPUT); pinMode(BUTTON_DOWN, INPUT); digitalWrite(BUTTON_LEFT, HIGH); digitalWrite(BUTTON_RIGHT, HIGH); digitalWrite(BUTTON_UP, HIGH); digitalWrite(BUTTON_DOWN, HIGH); Serial.begin(9600); } int handle_button() { int button_pressed = 0; if (!digitalRead(BUTTON_LEFT)) { button_pressed = button_pressed + 1; } if (!digitalRead(BUTTON_RIGHT)) { button_pressed = button_pressed + 2; } if (!digitalRead(BUTTON_UP)) { button_pressed = button_pressed + 4; } if (!digitalRead(BUTTON_DOWN)) { button_pressed = button_pressed + 8; } return button_pressed; } void loop() { int button_combo = handle_button(); if (button_combo == 0) { digitalWrite(ACT_LEFT, LOW); digitalWrite(ACT_RIGHT, LOW); digitalWrite(ACT_UP, LOW); digitalWrite(ACT_DOWN, LOW); } switch (button_combo) { case 1: digitalWrite(ACT_RIGHT, LOW); digitalWrite(ACT_UP, LOW); digitalWrite(ACT_DOWN, LOW); analogWrite(ACT_LEFT, 255); break; case 2: digitalWrite(ACT_LEFT, LOW); digitalWrite(ACT_UP, LOW); digitalWrite(ACT_DOWN, LOW); analogWrite(ACT_RIGHT, 255); break; case 4: digitalWrite(ACT_LEFT, LOW); digitalWrite(ACT_RIGHT, LOW); digitalWrite(ACT_DOWN, LOW); analogWrite(ACT_UP, 255); break; case 8: digitalWrite(ACT_LEFT, LOW); digitalWrite(ACT_RIGHT, LOW); digitalWrite(ACT_UP, LOW); analogWrite(ACT_DOWN, 255); break; case 5: digitalWrite(ACT_RIGHT, LOW); digitalWrite(ACT_DOWN, LOW); analogWrite(ACT_LEFT, 255); analogWrite(ACT_UP, 255); break; case 6: digitalWrite(ACT_LEFT, LOW); digitalWrite(ACT_DOWN, LOW); analogWrite(ACT_RIGHT, 255); analogWrite(ACT_UP, 255); break; case 9: digitalWrite(ACT_RIGHT, LOW); digitalWrite(ACT_UP, LOW); analogWrite(ACT_LEFT, 255); analogWrite(ACT_DOWN, 255); break; case 10: digitalWrite(ACT_LEFT, LOW); digitalWrite(ACT_UP, LOW); analogWrite(ACT_RIGHT, 255); analogWrite(ACT_DOWN, 255); break; } delay(DELAY); } |
Note that the code for the actuating of motors will only take into considerations combinations of directions which are valid, such as up-right, or down-left, but will ignore combinations such as up-down and left-right.
From this point on, code will also be published to a dedicated GitHub repository:
https://github.com/idebate/wireless-camera-control
Does it work?
Sure does. Click the switch, or move the joystick, and the head moves. In both axes at once, if you will it so. But it only moves at a preset speed, and that speed is the equivalent of the motor being run at 3.3VDC.
So no, not optimal. The torque and speed of DC motors is directly dependent on the voltage of the supplied signal, and the motors are rated at 6VDC. Also, speed control would be very welcome, as it would allow for more precise control. A long way to go still, but it does work.
Leave a Reply