So, some holiday madness from Spain. The [first] prototype for an arduino-driven GoTo bincoular mirror mount.

The pictures speak for themselves:
below is the prototype arduino code that worked after a few amends and tests.
/*
* capeMirror v2.0 (prototype)
* ---------------------------------------
*
* Start-up
* The Arduino is wired as follows:
* 1 x Bluesmirf Bluetooth chip which will receive instructions from
* a Windows program (Skymap Pro).
* 4 x Buttons which denote up, down, left, right.
* 2 x Stepper motors (4 wires for each).
*
* NB1: The key structural point about the code below is that the
* mount needs to be able to receive instructions from two different
* sources: (i) from the laptop via bluetooth and (ii) from the
* 4 buttons 'on-board' the mount itself.
*
* NB2: One trick that will be obvious reading the code but is easiest
* to point out at the outset is that for a mirror mount the altitude
* and azimuth have to be reversed - ie if the altitude of the point
* in the sky looked at RISES, then the mirror has to tilt DOWN (same for azimuth).
* I decided to 'hard-wire' this reversal into the code below. Look
* for the "Alt = Alt * -1" in the code.
*
* Now, the structure of the sketch:
* Part 1: Bluetooth data.
* The chip here receives instructions via bluetooth. The 2 steppers
* move according to those instructions. The format of the instructions
* is as follows "[5;-10;]". The first number carries the instructions
* for the movements in Azimuth, the second number carries instructions
* for Altitude. If the chip received the following "[-5;10;]", then Az would
* rotate left 5 times (positive Azimuth values rotate the mount right, negative
* value rotate it left), and then the Alt stepper would step 10 times up.
*
* If the chip receives X for the Az value (ie "[X;;]", then the mount
* knows to change to Mount control (ie not bluetooth).
* There is in fact a third number (between the second semi-colon and
* the right end square bracket) this is for future development.
*
* Also, during this 'bluetooth' phase, the chip also checks whether the
* UP button is pressed, if it is, then the bluetooth control ends.
*
* Part 2: On-board instructions
* The chip begins by polling the 4 buttons (up, down, left, right).
* These feed into 4 analog inputs. The rate at which the stepper
* steps is (in part) determined by how long a delay there is between
* the polling of the buttons. This is set in the variable
* ButtonPollDelay.
*
* Part 3: Hand-over to bluetooth instructions. If the user wants to
* handover control to the laptop, then the user has to press the
* 'left' and 'right' buttons at the same time. When that happens,
* the chip sends a brief message via bluetooth to the laptop.
* The chip then stops polling the buttons and instead
* starts to read any serial data received via bluetooth.
*
* Acknowledgements
* The difficult serial parsing bit was came from Nition
* see forum post at:
* http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203538464/2#2
*
* The AFSoftwareSerial library came from ladyada. It adds the
* serial.available functionality.
* download it here: http://www.ladyada.net/make/eshield/download.html
*
* The button wiring came from the standard arduino tutorial on
* digital inputs.
*
* created 21 August 2008
* by Ben
*/
// include the AFSoftSerial library
#include <AFSoftSerial.h>
#include <Stepper.h>
// define the button pins
#define switchPinUp 0 // analog pin 0 wired to the Up button
#define switchPinLeft 1 // analog pin 1 wired to the Left button
#define switchPinDown 2 // analog pin 2 wired to the Down button
#define switchPinRight 3 // analog pin 3 wired to the Right button
// define the bluetooth pins
#define rxPin 4 // pin 4 (receive) wired to tx-0 (transmit) on bluesmirf
#define txPin 5 // pin 5 (transmit) wired to rx-1 (receive) on bluesmirf
// define the polling delay for the buttons
#define ButtonPollDelay 250
// define the stepper motor constants
#define STEPS 200 // how many steps for the stepper motor(s)
#define AzStepSpeed 5 // speed for the az stepper motor (per min)
#define AltStepSpeed 10 // speed for the alt stepper motor (per min)
#define AzSteps 1 // how many steps per button press
#define AltSteps 1 // how many steps per button press
// create the steppers on pins 6-9 (az) and 10-13 (alt)
Stepper AzStepper(STEPS, 6, 8, 7, 9);
Stepper AltStepper(STEPS, 10, 12, 11, 13);
// define the LED pin which is used to read the alt and az scales on the mount
// it's normally on when laptop controlled and off when on-board controls are
// used, but the user can toggle it by pressing UP and DOWN together.
#define LEDPin 3 // Pin 3 is an LED.
boolean LEDOn = false; // Turn it off at the start.
// define the variables that will store the data from the buttons
// if 0 then not pressed, if 1 then pressed.
int UpBtnVal = 0;
int DownBtnVal = 0;
int LeftBtnVal = 0;
int RightBtnVal = 0;
// create the variables that will hold the Alt and Az sums (ie the total moves
// made by the mount while controlled by the user. These are stored and then
// sent back to the PC.
int AltTotal = 0;
int AzTotal = 0;
// create the variable that will record whether under 'onboard control'
boolean MountControl = false; // start with 'bluetooth control'
// Serial parsing variables and set up
#define tagLength 6 // each 'tag' or instructions will contains 6 bytes
#define semicolon 0x3b // create a shorthand reference to a semicolon
#define dataRate 9600 // create a shorthand reference to 9600kbps serial baud rate
#define leftbracket 0x5b // create a shorthand reference to a left squarebracket "["
#define rightbracket 0x5d // create a shorthand reference to a right squarebracket "]"
int tagIndex = 0; // counter for number of bytes read
int allComplete = false; // whether all tags have been read
char AzVal[tagLength]; // create the variable that will hold the Az instructions
char AltVal[tagLength]; // create the variable that will hold the Alt instructions
char rVal[tagLength]; // create the spare (unused) variable for future instructions
int AzComplete = false; // variable to indicate whether the Az instructions are complete
int AltComplete = false; // variable to indicate whether the Alt instructions are complete
int rComplete = false; // variable to indicate whether the sprare (r) instructions are complete
AFSoftSerial mySerial = AFSoftSerial(rxPin, txPin); // create a new serial connection using the AFSoftSerial library
//*****************
// Setup Procedure
//*****************
void setup()
{
// define the pins
pinMode(rxPin, INPUT); // sets the digital pin as input to rx serial data
pinMode(txPin, OUTPUT); // sets the digital pin as output to tx serial data
pinMode(LEDPin, OUTPUT); // LED to communicate
// set the speeds (different) for the stepper motors.
AzStepper.setSpeed(AzStepSpeed);
AltStepper.setSpeed(AltStepSpeed);
// set the data rate for the serial port
mySerial.begin(dataRate);
// turn on LED 3 times to show mount working
for (int i=0;i<3;i++){
digitalWrite(LEDPin, LOW);
delay(125);
digitalWrite(LEDPin, HIGH); // LED left on
delay(250);
} // end: for
} // end: setup
//*****************************************************
// Loop (main) procedure
//*****************************************************
void loop() {
///////////////////////////////////////////////////////
// Part 1: Obtain the serial data over bluetooth
///////////////////////////////////////////////////////
if (mySerial.available() > 0) { // wait til some data available
digitalWrite(LEDPin, LOW); // LED off to show receiving
delay(1500); // wait for all data to be in. 1500 works fine.
// run the readData procedure for data that's been received
readData();
// check to see if told to hand-over control to the mount
if (AzVal[0]== 'X'){
// if so, then set mount control to True and reset variables
MountControl = true;
AzTotal = 0;
AltTotal = 0;
for (int i=0;i<5;i++){ // this empties the arrays
AzVal[i] = 0x00;
AltVal[i] = 0x00;
rVal[i] = 0x00;
} // end: for
} // end: if
// Move the Azimuth (Az) stepper
int AzInt = atoi(AzVal);
AzInt = (AzInt * -1); // reverse the direction
AzStepper.step(AzInt);
AzInt = (AzInt * -1); // put back in case report it later
// Move the Altitude (Alt) stepper
int AltInt = atoi(AltVal);
AltInt = (AltInt * -1); // reverse the direction
AltStepper.step(AltInt);
AltInt = (AltInt * -1); // put back in case report it later
// this would be where to use the rVal data
// run the DataComplete procedure
DataComplete();
digitalWrite(LEDPin, HIGH); // LED on to show completed
} // End: If Serial.Available > 0
// check to see if Up button pressed, if so stop handover to on-board control
UpBtnVal = analogRead(switchPinUp);
if (UpBtnVal > 500){ // check the up button
MountControl = true; // set the mount control to true
AzTotal = 0;
AltTotal = 0;
for (int i=0;i<5;i++){ // this empties the arrays
AzVal[i] = 0x00;
AltVal[i] = 0x00;
rVal[i] = 0x00;
} // end: for
} // end: if button pressed
///////////////////////////////////////////////////////
// Parts 2 & 3: Control of the Mount via the 4 buttons
///////////////////////////////////////////////////////
if (MountControl == true) {
// flash LED 3 times to show mount got control
for (int i=0;i<3;i++){
digitalWrite(LEDPin, HIGH);
delay(250);
digitalWrite(LEDPin, LOW); // Leave off for mount control
delay(125);
} // end: for
// Loop through this section until left and right pressed together
do {
// Poll the 4 buttons to see if any pressed
UpBtnVal = analogRead(switchPinUp);
DownBtnVal = analogRead(switchPinDown);
LeftBtnVal = analogRead(switchPinLeft);
RightBtnVal = analogRead(switchPinRight);
// Part 3: check to see if user wanting to 'end mount control'
if (LeftBtnVal > 500 && RightBtnVal > 500){ // Bail out if both pressed
MountControl = false; // reset the MountControl variable
digitalWrite(LEDPin, HIGH);
ReportBack(); // run the ReportBack procedure
break;
} // end: if
// Turn LED on/off if user presses up and down together
if (UpBtnVal > 500 && DownBtnVal > 500){ // Toggle LED if both pressed
if (LEDOn == false){
digitalWrite(LEDPin, HIGH);
LEDOn = true;
} // end: if LEDOn == false
else
{
digitalWrite(LEDPin, LOW);
LEDOn = false;
} // end: else
} // end: if toggling
// Now step the motors according to buttons pressed
if (LeftBtnVal > 500){ // the left button
AzStepper.step(-AzSteps);
AzTotal = AzTotal + 1;
} // end if left
if (RightBtnVal > 500){ // the right button
AzStepper.step(AzSteps);
AzTotal = AzTotal - 1;
} // end if right
if (UpBtnVal > 500){ // check the up button
AltStepper.step(-AltSteps);
AltTotal = AltTotal + 1;
} // end if up
if (DownBtnVal > 500){ // the down button
AltStepper.step(AltSteps);
AltTotal = AltTotal - 1;
} // end if down
// delay before re-reading
delay(ButtonPollDelay);
} while (MountControl == true); // End: the Do-While loop
} // End: if (MountControl = true)
} // End: Loop
//************************************
// readData procedure - for Bluetooth
//************************************
void readData() {
// Reset all the variables
AzComplete = false;
AltComplete = false;
rComplete = false;
for (int i=0;i<5;i++){
AzVal[i] = 0x00;
AltVal[i] = 0x00;
rVal[i] = 0x00;
}
// Read the serial data
char thisChar = mySerial.read();
if (thisChar == leftbracket){
// read all first data section (Az)
while (AzComplete == false && mySerial.available() > 0){
char thisChar = mySerial.read();
if (thisChar == semicolon){
AzComplete = true;
break;
}
else {
AzVal[tagIndex] = thisChar;
tagIndex++;
}
}
tagIndex = 0;
// read all second data section (Alt)
while (AltComplete == false && mySerial.available() > 0){
char thisChar = mySerial.read();
// Serial.println("y-loop");
if (thisChar == semicolon){
AltComplete = true;
break;
}
else {
AltVal[tagIndex] = thisChar;
tagIndex++;
}
}
tagIndex = 0;
// read all r
while (rComplete == false && mySerial.available() > 0){
char thisChar = mySerial.read();
// Serial.println("r-loop");
if (thisChar == rightbracket){
rComplete = true;
break;
}
else {
rVal[tagIndex] = thisChar;
tagIndex++;
}
}
tagIndex = 0;
if (AzComplete == true && AltComplete == true && rComplete == true){
// For debugging purposes only. Data now all read.
}
}
}
//*****************************************************
// ReportBack procedure - after left and right pressed
//*****************************************************
void ReportBack(){
// send back the total via bluetooth
mySerial.print("[");
mySerial.print(AzTotal);
mySerial.print(";");
mySerial.print(AltTotal);
mySerial.print(";");
mySerial.print("X");
mySerial.print("]");
AzTotal = 0;
AltTotal = 0;
}
//****************************************
// DataComplete procedure - for Bluetooth
//****************************************
void DataComplete(){
// Used for debugging purposes only.
// mySerial.print("[Arduino;Bluesmirf;Baltaz]");
}
Ben



























post a comment...
you must be logged in to post a comment.