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.