The capeMirror Wiring
On the right can be seen the pin mapping.
The capeMirror Library
Now it’s just a question of combining the following libraries into one: Stepper_Aclr8_2, Stepper_Aclr8_i, Matrix_Steppers, and SerialParse.
/*
* capeMirror v2a
*
* created by Ben @ Cape Ealing
* 24 January 2010
*
*/
//********************************************************************
// Initial Definitions
//********************************************************************
// include the libraries
// -------------------------------------------------------------------
#include "NewSoftSerial.h"
#include "CapeMirror.h"
// map all the pins
// -------------------------------------------------------------------
#define pReceiveBT 2
#define pTransmitBT 3
#define pAzStep1 4
#define pAzStep2 5
#define pAzStep3 6
#define pAzStep4 7
#define pAltStep1 8
#define pAltStep2 9
#define pAltStep3 10
#define pAltStep4 11
#define pKeypadCol1 12
#define pKeypadCol2 13
#define pKeypadCol3 14
#define pTransmitLCD 15
#define pKeypadRow1 16
#define pKeypadRow2 17
#define pKeypadRow3 18
#define pKeypadRow4 19
// the LCD constants and variables
// -------------------------------------------------------------------
#define lcdDataRate 9600
#define pLCDNoReceivePin 255
#define lcdLine1 1
#define lcdLine2 2
int lcdBright = 100;
// the bluetooth constants and variables
// -------------------------------------------------------------------
#define btDataRate 9600
#define btHandshake1 1234567
#define btHandshake2 7654321
#define btNewCoords 1111112
#define btPark 2222222
#define btUnpark 333333
#define btSlew 4444444
// the keypad constants and variables
// -------------------------------------------------------------------
int keypadResult = 13;
// the stepper motors constants and variables
// -------------------------------------------------------------------
// Azimuth stepper
#define azSteps 200
#define azMinSpeed 1
#define azMaxSpeed 30
#define azAccSteps 400
#define azMoveSpeed 10
// Altitude stepper
#define altSteps 200
#define altMinSpeed 1
#define altMaxSpeed 30
#define altAccSteps 100
#define altMoveSpeed 10
// ancillary set-up
// -------------------------------------------------------------------
boolean pcControl = false;
int azStepsToDo = 0; // variable to hold the 'az steps to take' data
int altStepsToDo = 0; // variable to hold the 'alt steps to take' data
// variables for the data
long azVal = 0;
long altVal = 0;
long cmdVal = 0;
// global variables for mount's azimuth and altitude (in arcseconds)
long azGlobal = 0;
long altGlobal = 187826;
boolean initialised = false;
// initialise the classes
// -------------------------------------------------------------------
NewSoftSerial cmBlueTooth(pReceiveBT, pTransmitBT);
NewSoftSerial cmLCD(pLCDNoReceivePin, pTransmitLCD);
CapeMirror cmMount = CapeMirror(&azGlobal, &altGlobal); // DB change name
//********************************************************************
// Setup Procedure
//********************************************************************
void setup()
{
// define the (lcd) serial communication
cmMount.setLCDaddress(&cmLCD);
cmMount.beginLCD(lcdDataRate);
cmMount.lcdOn();
cmMount.lcdClear();
cmMount.lcdBacklight(100);
cmMount.lcdDisplay(lcdLine1, 1, " capeMirror");
cmMount.lcdDisplay(lcdLine2, 1, " created by Ben");
delay(3000);
// define the (bluetooth) serial communication with the laptop
cmMount.setBTaddress(&cmBlueTooth);
cmMount.beginBT(btDataRate);
// define the keypad (fires columns, and reads rows)
cmMount.setKeypadCols(pKeypadCol1, pKeypadCol2, pKeypadCol3);
cmMount.setKeypadRows(pKeypadRow1, pKeypadRow2, pKeypadRow3, pKeypadRow4);
cmMount.setInterruptPins(pKeypadCol2, pKeypadRow2);
// define each stepper motor
// (no of steps per rev, pin1, pin2, pin3, pin4)
cmMount.azStepper(azSteps, pAzStep1, pAzStep3, pAzStep2, pAzStep4);
cmMount.altStepper(altSteps, pAltStep1, pAltStep3, pAltStep2, pAltStep4);
// define the rates of each motor:
// min, max, steps take to accelerate, and 'move speed' (when keypad pressed)
cmMount.azStepperSpeeds(azMinSpeed, azMaxSpeed, azAccSteps, azMoveSpeed);
cmMount.altStepperSpeeds(altMinSpeed, altMaxSpeed, altAccSteps, altMoveSpeed);
// pass the address of the 'steps to take variables'
cmMount.setStepsAddress(&azStepsToDo, &azStepsToDo);
// run the startup routine
do
{
userStart();
} while (initialised == false);
cmMount.lcdDisplayCoords();
cmMount.lcdDisplayDegsMins();
cmMount.lcdDisplaySecs();
if (pcControl == true) {cmMount.lcdDisplayControlPC();} else {cmMount.lcdDisplayControlMT();}
delay(2000);
} // End: setup
//********************************************************************
// Loop procedure (the main procedure)
//********************************************************************
void loop()
{
// read the keypad
keypadResult = cmMount.readKeypad();
if (keypadResult != 13){cmMount.move(keypadResult);}
if (keypadResult == 0){
// wait until key no longer pressed
do {keypadResult = cmMount.readKeypad();} while (keypadResult == 0);
// vary the backlight
cmMount.lcdBacklightShift();
}
//SCENARIO A
// read the serialcomm
// if available...parse the data
// if under pcControl = true {}
// then 'switch case' the cmd value
// do as required: ie slew, or acceptnewcoords, or park
// need to be able to handle a 'move' command (ie slew can be interrupted by serial data)
// else (not under pcControl
// then check pc wants to take control
// if not, error
// if does want to take control, then
// toggle pcControl
// read the keypad
// if pressed then:
// if pcControl = true, see if mount wants to take over. if so, then park (same as park above?) otherwise ignore
// if pcControl = false, then move as required, but if '#' pressed, then part (same as park above?)
// always check for 0. If 0 pressed then increase brightness by 20% (set to zero if result > 100).
// NOTE: Whenever stepping on whatever instruction, need to
// 1. read the mount interrupt pin (*), to check user hasn't cancelled at that end
// if cancelled by keypad, then
// if under MT control just stop (coords will have been saved anyway)
// if under PC control then need to report to PC the interruption and the new coords
// and turn to MT control
// 2. read the serial data, to check not cancelled by PC (eg a 'move')
// if cancelled by bluetooth, then
// if under PC control then report to PC the interruption and the new coords
// if under MT control then report to PC the interruption and the new coords
// and turn to PC control
//SCENARIO B
// if pcControl = true {
// }
// Either PC control: waiting for BlueTooth Data and reading '#' pin
// hash says 'i want control': if hash pressed then the scope is 'parked'
// if it's in the middle of a move routine, then can only interrupt by
// pressing the 'abandon' key (*)
// That just means that the mount is interrupted, it sends its new position
// to the PC. Waits for the PC to confirm that OK to proceed.
// if pcControl = false {
// }
// Or Mount control: waiting for BlueTooth and reading keypad (possible)
// scope is 'parked' as far as PC is concerned
// read the keypad, move as necesssary, store alt and az position
// if user presses '#' then unparks and goes over to pc control
// also PC can regain control, so needs to read bluetooth too
if (cmBlueTooth.available() > 0)
{
// the call parseData method
cmMount.btParseData(&azVal, &altVal, &cmdVal);
// the integers xVal, yVal, zVal now hold the values received
cmBlueTooth.print("[");
cmBlueTooth.print(azVal);
cmBlueTooth.print(";");
cmBlueTooth.print(altVal);
cmBlueTooth.print(";");
cmBlueTooth.print(cmdVal);
cmBlueTooth.print("]");
} // end if
}
//********************************************************************
// All subsidiary procedures
//********************************************************************
// start up routine
// -------------------------------------------------------------------
void userStart()
{
// 1. Ask if making a PC connection
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Control by PC?");
cmMount.lcdDisplay(lcdLine2, 1, "1 = Yes, 2 = No");
// loop through until a result is obtained
do
{
keypadResult = cmMount.readKeypad();
}
while (keypadResult != 1 && keypadResult != 2);
if (keypadResult ==1)
{
cmMount.lcdDisplay(lcdLine2, 1, " Yes ");
do {keypadResult = cmMount.readKeypad();} while (keypadResult != 13);
keypadResult = 1;
}
else
{
cmMount.lcdDisplay(lcdLine2, 1, " No");
do {keypadResult = cmMount.readKeypad();} while (keypadResult != 13);
keypadResult = 2;
}
delay(1000);
if (keypadResult ==1){
// PC control
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Run PC software,");
cmMount.lcdDisplay(lcdLine2, 1, "waiting... s");
// wait for bluetooth commands (or max 5 mins)
int waiting=90;
while ((cmMount.btAvailable() == 0) && waiting > 0)
{
if (waiting > 9)
{
cmMount.lcdDisplay(lcdLine2, 13, waiting);
}
else
{
cmMount.lcdDisplay(lcdLine2, 13, " ");
cmMount.lcdDisplay(lcdLine2, 14, waiting);
}
waiting--;
cmMount.btAvailable(); // needed with NewSoftSerial library
delay(1000);
}
// if timed out, start the loop within setup again
if (waiting==0)
{
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Error: timed out");
delay(5000);
keypadResult = 3;
}
// or got serial data, so handshake
else
{
pcHandShaking();
}
}
// Mount control
if (keypadResult ==2){
mtCoordObtaining();
}
} // end userStart
// pcHandshaking procedure
// -------------------------------------------------------------------
void pcHandShaking()
{
// parse the data received
cmMount.btParseData(&azVal, &altVal, &cmdVal);
if (azVal == btHandshake1 && altVal == btHandshake1 && cmdVal == btHandshake1)
{
// report that 'good data' has been recieved
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Data received,");
cmMount.lcdDisplay(lcdLine2, 1, "handshaking...");
cmMount.btAvailable(); // needed with NewSoftSerial library
delay(2000);
// write data back to the laptop
cmMount.btWrite("[");
cmMount.btWrite(btHandshake2);
cmMount.btWrite(";");
cmMount.btWrite(btHandshake2);
cmMount.btWrite(";");
cmMount.btWrite(btHandshake2);
cmMount.btWrite("]");
}
else
{
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Error:");
cmMount.lcdDisplay(lcdLine2, 1, "Bad data recd");
keypadResult = 3; // loop round startup procedures again
delay(2000);
}
// if PC control proceeding successully
if (keypadResult == 1)
{
cmMount.lcdDisplay(lcdLine1, 1, "Now, polar align");
cmMount.lcdDisplay(lcdLine2, 1, "#=Done; *=Cancel");
do
{
keypadResult = cmMount.readKeypad();
//move using keypad until press # or cancel
}
while (keypadResult != 10 && keypadResult != 11);
// HERE NEED TO PUT IN POLAR ALIGN ROUTINE
// HAVING SENT THE DATA OUT
// JUST GO INTO KEYPAD READING / MOVING ROUTINE
// CARRY ON UNTIL PRESSSES # AT THIS END.
// THEN MOUNT WAITS FOR PC RESPONSE
// PC ONLY RESPONDS WHEN USER PRESSES 'OK' ON PC
// (AMEND PC INSTRUCTIONS SO IT SAYS, POLAR ALIGN MOUNT,
// THEN PRESS '#' ON MOUNT.
// AFTER PRESSSING '#', CLICK OK HERE.
// ON PC:
// IF PC RECEIVES GOOD DATA, THEN WILL POP UP QUESTION (ABOVE)
// IF PC RECEIVES BAD DATA, THEN WILL NOT POP UP.
// SO NEED TO BE ABLE CANCEL POLAR ALIGN ON THE MOUNT
// WOULD SUGGEST THAT * ON THE KEYPAD ABANDONS POLAR ALIGN
// THEN STARTS AT BEGINNING OF START UP ROUTINE AGAIN
// on 'OK' on PC, the PC sends through the mounts coords
// assuming that the cmdVal is correct (ie new coords
// - which will be used as 'synch' later too.
// then store the new coords.
// Display the new coords as (need routine for this):
// cmMount.lcdDisplay(lcdLine1, 1, "Az: 359.59'59" P");
// cmMount.lcdDisplay(lcdLine2, 1, "Alt: 89.59'59" C");
// display routines:
// 1. Initialise for coords (ie put in Az:, Alt: etc)
// 2. just display coords
// 3. PC control
// 4. MT control
// if good data received then wait for more data back
// this contains the az and alt coords
// if good data received back then store it and
// successfully connected
pcControl = true;
initialised = true;
}
} // end pcHandShaking
void mtCoordObtaining()
{
// Get the Coords
boolean azCoordsOK = false;
boolean altCoordsOK = false;
char azCoordsInput[10] = {0,0,0,0,0,0,0,0,0,0};
char altCoordsInput[10] = {0,0,5,2,0,1,0,0,2,6};
do
{
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Enter Az: #=OK");
cmMount.lcdDisplay(2, 1, "000");
cmMount.lcdDisplay(2, 4, (char)223);
cmMount.lcdDisplay(2, 5, "00");
cmMount.lcdDisplay(2, 7, (char)39);
cmMount.lcdDisplay(2, 8, "00");
cmMount.lcdDisplay(2, 10, (char)34);
cmMount.lcdDisplay(2, 11, " *=Del");
cmMount.lcdPosition(2,1);
cmMount.lcdBlockCursor();
// Az input loop
int entrypos = 1;
do
{
// wait until get a response
do {keypadResult = cmMount.readKeypad();} while (keypadResult == 13);
// check the result
switch (keypadResult){
case 10: // *
entrypos -=1;
if (entrypos==0){entrypos=1;}
if (entrypos==4 || entrypos==7) {entrypos -=1;}
cmMount.lcdPosition(2,entrypos);
break;
case 11: // #
entrypos = 13;
break;
default:
azCoordsInput[entrypos] = char(keypadResult);
cmMount.lcdDisplay(2,entrypos, keypadResult);
entrypos +=1;
if (entrypos==4 || entrypos==7) {entrypos +=1;}
if (entrypos==10){entrypos=9;}
cmMount.lcdPosition(2,entrypos);
} // end: switxh
do {keypadResult = cmMount.readKeypad();} while (keypadResult != 13);
} while (entrypos != 13); // end: do Az input loop
// Az coords have been entered
long azDegs = (int(azCoordsInput[1]) * 100) + (int(azCoordsInput[2]) * 10) + (int(azCoordsInput[3]));
azDegs = azDegs * 3600;
long azMins = (int(azCoordsInput[5]) * 10) + (int(azCoordsInput[6]));
if (azMins>59) {azDegs=400;} // throw an error if over 59 mins
azMins = azMins * 60;
long azSecs = (int(azCoordsInput[8]) * 10) + (int(azCoordsInput[9]));
if (azSecs>59) {azDegs=400;} // throw an error if over 59 secs
azSecs = azSecs + azMins + azDegs;
// Az coords: check within 2 degrees of zero degrees
if (azSecs == 1296000){azSecs = 0;} // change to zero if 360 degrees entered
if ((azSecs <= 7200) || ((azSecs >= 1288800) && (azSecs < 1296000)))
{
azCoordsOK = true;
cmMount.lcdNoCursor();
cmMount.lcdClear();
azGlobal = azSecs;
}
else
{
cmMount.lcdNoCursor();
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Error");
cmMount.lcdDisplay(lcdLine2, 1, "Bad Az data");
delay(2000);
}
} while (azCoordsOK == false); // End: Get the Az Coords
// Get the Az Coords
do
{
// clear the screen
cmMount.lcdDisplay(lcdLine1, 1, "Enter Alt: #=OK");
cmMount.lcdDisplay(2, 1, " 52");
cmMount.lcdDisplay(2, 4, (char)223);
cmMount.lcdDisplay(2, 5, "10");
cmMount.lcdDisplay(2, 7, (char)39);
cmMount.lcdDisplay(2, 8, "26");
cmMount.lcdDisplay(2, 10, (char)34);
cmMount.lcdDisplay(2, 11, " *=Del");
cmMount.lcdPosition(2,2);
cmMount.lcdBlockCursor();
// Alt input loop
int entrypos = 2;
do
{
// wait until get a response
do {keypadResult = cmMount.readKeypad();} while (keypadResult == 13);
// check the result
switch (keypadResult){
case 10: // *
entrypos -=1;
if (entrypos==1){entrypos=2;}
if (entrypos==4 || entrypos==7) {entrypos -=1;}
cmMount.lcdPosition(2,entrypos);
break;
case 11: // #
entrypos = 13;
break;
default:
altCoordsInput[entrypos] = char(keypadResult);
cmMount.lcdDisplay(2,entrypos, keypadResult);
entrypos +=1;
if (entrypos==4 || entrypos==7) {entrypos +=1;}
if (entrypos==10){entrypos=9;}
cmMount.lcdPosition(2,entrypos);
} // end: switch
do {keypadResult = cmMount.readKeypad();} while (keypadResult != 13);
} while (entrypos != 13); // end: do Az input loop
// Alt coords have been entered
long altDegs = (int(altCoordsInput[2]) * 10) + (int(altCoordsInput[3]));
altDegs = altDegs * 3600;
long altMins = (int(altCoordsInput[5]) * 10) + (int(altCoordsInput[6]));
if (altMins>59) {altDegs=400;} // throw an error if over 59 mins
altMins = altMins * 60;
long altSecs = (int(altCoordsInput[8]) * 10) + (int(altCoordsInput[9]));
if (altSecs>60) {altDegs=400;} // throw an error if over 59 secs
altSecs = altSecs + altMins + altDegs;
// Alt coords: check over 20 degrees and less then 90 degrees
if ((altSecs >= 72000) && (altSecs < 324000))
{
altCoordsOK = true;
cmMount.lcdNoCursor();
cmMount.lcdClear();
altGlobal = altSecs;
}
else
{
cmMount.lcdNoCursor();
cmMount.lcdClear();
cmMount.lcdDisplay(lcdLine1, 1, "Error");
cmMount.lcdDisplay(lcdLine2, 1, "Bad Alt data");
delay(2000);
}
} while (altCoordsOK == false); // End: Get the Alt Coords
// report successful
cmMount.lcdDisplay(lcdLine1, 1, "Startup complete");
cmMount.lcdDisplay(lcdLine2, 1, "Mount control");
delay(2000);
initialised = true;
}
this is the test
/*
CapeMirror.h
v. 2a
by Ben @ Cape Ealing
*/
// ensure this library description is only included once
#ifndef CapeMirror_h
#define CapeMirror_h
#define moveStep 1
#define slewStep 2
// create shorthand refs for "[" and "]" and ";"
#define leftbracket 0x5b
#define rightbracket 0x5d
#define semicolon 0x3b
#define dataLength 8
// LCD definitions
#define _line1 127
#define _line2 191
#define _cmd 254
#define _cmdSp 124
#define _clear 1
#define _on 12
#define _off 8
#define _nocursor 12
#define _block 13
#define _line 14
#define _lcddelay 50
//#define _blightshiftdelay 500
// stepper motor definitions
// azimuth resolution: 0.045 degrees (162 arcsecs)
// altitude resolution: 0.09 degrees (324 arcsecs)
#define _azRes 162
#define _altRes 324
#define _azMax 1296000
#define _altMax 324000
#define _altMin 72000
/*
CapeMirror library
*/
class CapeMirror {
// public methods and variables
// ----------------------------
public:
// Initialise the class
CapeMirror(long* gAz, long* gAlt);
// define the 'address' for the bluetooth serial connection
void setBTaddress(NewSoftSerial *btAddress);
// define the 'address' for the LCD serial connection
void setLCDaddress(NewSoftSerial *lcdAddress);
// wrappers for the NewSoftSerial begin method
void beginBT(int btBaudRate);
void beginLCD(int lcdBaudRate);
// Create the parse method
void btParseData(long *azVal, long *altVal, long *cmdVal);
// bluetooth write methods
void btWrite (char msg);
void btWrite (const char msg[]);
void btWrite (uint8_t msg);
void btWrite (int msg);
void btWrite (unsigned int msg);
void btWrite (long msg);
void btWrite (unsigned long msg);
// wrapper for NewSoftSerial available method
uint8_t btAvailable(void);
// serLCD
// ----------------
// selection of methods from the serLCD library
void lcdOn();
void lcdOff();
void lcdClear();
void lcdBlockCursor();
void lcdLineCursor();
void lcdNoCursor();
void lcdBacklight(int blight);
void lcdBacklightShift();
void lcdPosition (int line, int character);
void lcdDisplay ( int line, int character, char );
void lcdDisplay ( int line, int character, const char[] );
void lcdDisplay ( int line, int character, uint8_t );
void lcdDisplay ( int line, int character, int );
void lcdDisplay ( int line, int character, unsigned int );
void lcdDisplay ( int line, int character, long );
void lcdDisplay ( int line, int character, unsigned long );
void lcdDisplay ( int line, int character, long, int );
void lcdDisplayCoords();
void lcdDisplayDegsMins();
void lcdDisplaySecs();
void lcdDisplayAzSecs();
void lcdDisplayAltSecs();
void lcdDisplayControlMT();
void lcdDisplayControlPC();
// ----------------
// Matrix_Steppers
// ----------------
// define the rows and columns
void setKeypadRows(int row1, int row2, int row3, int row4);
void setKeypadCols(int col1, int col2, int col3);
// read the keypad
int readKeypad(void);
// ----------------
// The movement methods (slew and move)
// ----------------
void slew (int steps_to_move1, int steps_to_move2);
void move (int keyResult);
// ----------------
// Stepper_Aclr8_2
// ----------------
// Stepper constructors: 4 wire stepper motors only
void azStepper(int number_of_steps1, int motor1_pin_1, \
int motor1_pin_2, int motor1_pin_3, int motor1_pin_4);
void altStepper(int number_of_steps2, int motor2_pin_1, \
int motor2_pin_2, int motor2_pin_3, int motor2_pin_4);
// Define each stepper's rates (min speed, max speed, acceleration)
void azStepperSpeeds(long minSpeed1, long maxSpeed1, double Accel1, long moveSpeed1);
void altStepperSpeeds(long minSpeed2, long maxSpeed2, double Accel2, long moveSpeed2);
// ----------------
// Stepper_Aclr8_i
// ----------------
// define interupt pins method:
void setInterruptPins(int firePin, int readPin);
void setStepsAddress(int* azStepsAddress, int* altStepsAddress);
// return the version if asked
int version(void);
// ********************************************************
// private methods and variables
// ********************************************************
private:
// variable to hold a references to the serial connections
NewSoftSerial* cmBlueToothRef;
NewSoftSerial* cmLCDRef;
long* gAzimuth;
long* gAltitude;
// ----------------
// The keypad
// ----------------
int col1;
int col2;
int col3;
int row1;
int row2;
int row3;
int row4;
int keyResult;
// ----------------
// Stepper_Aclr8_2
// ----------------
// setup the motors
void takeSteps(int steps_to_move1, int steps_to_move2, int step_type);
void stepMotor1(int thisStep1);
void stepMotor2(int thisStep2);
// Direction of rotation
int direction1;
int direction2;
// Speed in RPMs
int speed1;
int speed2;
// delay between steps, in ms, based on speed1
double step_delay1;
double step_delay2;
double move_step_delay1;
double move_step_delay2;
// total number of steps this motor can take
int number_of_steps1;
int number_of_steps2;
// delay at 1 rev per minute
double delay_1revpermin1;
double delay_1revpermin2;
// which step the motor is on
int step_number1;
int step_number2;
//steps left
int steps_left1;
int steps_left2;
// motor pin numbers:
int motor1_pin_1;
int motor2_pin_1;
int motor1_pin_2;
int motor2_pin_2;
int motor1_pin_3;
int motor2_pin_3;
int motor1_pin_4;
int motor2_pin_4;
// time stamp in ms of when the last step was taken
long last_step_time1;
long last_step_time2;
//motor speeds
long motorMinSpeed1;
long motorMinSpeed2;
long motorMaxSpeed1;
long motorMaxSpeed2;
long motorAccSteps1;
long motorAccSteps2;
double motorAccelVal1;
double motorAccelVal2;
long minSpeed1;
long minSpeed2;
// which step number of steps to take
int steps_no1;
int steps_no2;
// total steps for both motors
int total_steps_left;
// interupt pins
int firePin;
int readPin;
// references to variables in sketch
//NewSoftSerial* theSerial;
int* azStepsToDoAddress;
int* altStepsToDoAddress;
// counter for number of bytes read
int btByteIndex;
// whether all data has been read
int btAllComplete;
// arrays for each of the three values received
char azData[dataLength], altData[dataLength], cmdData[dataLength];
// the character being read
char thisChar;
// variable to hold whether any partic value is complete
int azComplete, altComplete, cmdComplete;
long azDegLCD;
long azMinLCD;
long azSecLCD;
long altDegLCD;
long altMinLCD;
long altSecLCD;
int blightShift;
bool moveSingleStep;
void moveSingleStepToggle();
int t;
};
#endif
/*
CapeMirror.cpp
v. 2a
by Ben @ Cape Ealing
*/
#include "WProgram.h"
#include "NewSoftSerial.h"
#include "CapeMirror.h"
/*
* Initialise the class
*/
CapeMirror::CapeMirror(long* gAz, long* gAlt)
{
gAzimuth = gAz;
gAltitude = gAlt;
}
// define the 'address' for the bluetooth serial connection
void CapeMirror::setBTaddress(NewSoftSerial* btAddress)
{
cmBlueToothRef = btAddress;
}
// start the bluetooth connection
void CapeMirror::beginBT(int btBaudRate)
{
cmBlueToothRef->begin(btBaudRate);
}
uint8_t CapeMirror::btAvailable(void)
{
return cmBlueToothRef->available();
}
// define the 'address' for the LCD serial connection
void CapeMirror::setLCDaddress(NewSoftSerial* lcdAddress)
{
cmLCDRef = lcdAddress;
}
// start the lcd connection
void CapeMirror::beginLCD(int lcdBaudRate)
{
blightShift = 5;
cmLCDRef->begin(lcdBaudRate);
}
void CapeMirror::lcdOn()
{
cmLCDRef->print(_cmd, BYTE); // instruction
cmLCDRef->print(_on, BYTE); // turn on
delay(_lcddelay);
}
void CapeMirror::lcdOff()
{
cmLCDRef->print(_cmd, BYTE); // instruction
cmLCDRef->print(_off, BYTE); // turn off
delay(_lcddelay);
}
void CapeMirror::lcdClear()
{
cmLCDRef->print(_cmd, BYTE); // instruction
cmLCDRef->print(_clear, BYTE); // clear the LCD 0x01 or 1
delay(_lcddelay);
}
void CapeMirror::lcdBlockCursor()
{
cmLCDRef->print(_cmd, BYTE); // instruction
cmLCDRef->print(_block, BYTE); // block cursor: 0X0D or 13
delay(_lcddelay);
}
void CapeMirror::lcdLineCursor()
{
cmLCDRef->print(_cmd, BYTE); // instruction
cmLCDRef->print(_line, BYTE); // block cursor: 0X0D or 13
delay(_lcddelay);
}
void CapeMirror::lcdNoCursor()
{
cmLCDRef->print(_cmd, BYTE); // instruction
cmLCDRef->print(_nocursor, BYTE); // block cursor: 0X0D or 13
delay(_lcddelay);
}
void CapeMirror::lcdBacklight(int blight)
{
blight = int((blight*30)/100);
blight = (blight<3)?3:blight;
blight = (blight>30)?30:blight;
blight += 127;
cmLCDRef->print(_cmdSp, BYTE); // instruction coming
cmLCDRef->print(blight, BYTE); // backlight instruction
delay(_lcddelay);
}
void CapeMirror::lcdBacklightShift()
{
blightShift -= 1;
if (blightShift == -1){blightShift = 5;}
lcdBacklight ((blightShift*20));
// delay(_blightshiftdelay);
}
void CapeMirror::lcdPosition (int line, int character)
{
int pos = 0;
if(line==2)
{
pos = _line2;
}
else
{
pos = _line1;
}
pos = pos + character;
cmLCDRef->print(_cmd, BYTE); // command
cmLCDRef->print(pos, BYTE); // set the position
}
void CapeMirror::lcdDisplay ( int line, int character, char v ) { lcdPosition (line,character); cmLCDRef->print(v); }
void CapeMirror::lcdDisplay ( int line, int character, const char v[] ) { lcdPosition (line,character); cmLCDRef->print(v); }
void CapeMirror::lcdDisplay ( int line, int character, uint8_t v ) { lcdPosition (line,character); cmLCDRef->print(v); }
void CapeMirror::lcdDisplay ( int line, int character, int v ) { lcdPosition (line,character); cmLCDRef->print(v); }
void CapeMirror::lcdDisplay ( int line, int character, unsigned int v ) { lcdPosition (line,character); cmLCDRef->print(v); }
void CapeMirror::lcdDisplay ( int line, int character, long v ) { lcdPosition (line,character); cmLCDRef->print(v); }
void CapeMirror::lcdDisplay ( int line, int character, unsigned long v ) { lcdPosition (line,character); cmLCDRef->print(v); }
void CapeMirror::lcdDisplay ( int line, int character, long v, int t ) { lcdPosition (line,character); cmLCDRef->print(v,t); }
void CapeMirror::btWrite (char msg) {cmBlueToothRef->print(msg);}
void CapeMirror::btWrite (const char msg[]) {cmBlueToothRef->print(msg);}
void CapeMirror::btWrite (uint8_t msg) {cmBlueToothRef->print(msg);}
void CapeMirror::btWrite (int msg) {cmBlueToothRef->print(msg);}
void CapeMirror::btWrite (unsigned int msg) {cmBlueToothRef->print(msg);}
void CapeMirror::btWrite (long msg) {cmBlueToothRef->print(msg);}
void CapeMirror::btWrite (unsigned long msg) {cmBlueToothRef->print(msg);}
void CapeMirror::lcdDisplayControlMT() {lcdDisplay(1,16,"M"); lcdDisplay(2,16,"T");}
void CapeMirror::lcdDisplayControlPC() {
lcdDisplay(1,16,"P");
lcdDisplay(2,16,"C");
}
void CapeMirror::btParseData(long* azVal, long* altVal, long* cmdVal)
{
// reset the variables
*azVal = 0;
*altVal = 0;
*cmdVal = 0;
azComplete = false;
altComplete = false;
cmdComplete = false;
for (int i=0;iread();
if (thisChar == leftbracket)
{
// read all first data section
while (azComplete == false && cmBlueToothRef->available() > 0)
{
char thisChar = cmBlueToothRef->read();
if (thisChar == semicolon)
{
azComplete = true;
break;
}
else
{
azData[btByteIndex] = thisChar;
btByteIndex++;
}
}
btByteIndex = 0;
// read the second data section
while (altComplete == false && cmBlueToothRef->available() > 0)
{
char thisChar = cmBlueToothRef->read();
if (thisChar == semicolon)
{
altComplete = true;
break;
}
else
{
altData[btByteIndex] = thisChar;
btByteIndex++;
}
}
btByteIndex= 0;
// read the third data section
while (cmdComplete == false && cmBlueToothRef->available() > 0)
{
char thisChar = cmBlueToothRef->read();
if (thisChar == rightbracket)
{
cmdComplete = true;
break;
}
else
{
cmdData[btByteIndex] = thisChar;
btByteIndex++;
}
}
btByteIndex= 0;
// report back the values
*azVal = atol(azData);
*altVal = atol(altData);
*cmdVal = atol(cmdData);
}
}
/*
* Set up the keypad
*/
// define the rows
void CapeMirror::setKeypadRows(int row1, int row2, int row3, int row4)
{
this->row1 = row1;
this->row2 = row2;
this->row3 = row3;
this->row4 = row4;
moveSingleStep = false;
}
// define the columns
void CapeMirror::setKeypadCols(int col1, int col2, int col3)
{
this->col1 = col1;
this->col2 = col2;
this->col3 = col3;
// set them as outputs
pinMode(this->col1, OUTPUT);
pinMode(this->col2, OUTPUT);
pinMode(this->col3, OUTPUT);
}
/*
* Read the keypad
*/
int CapeMirror::readKeypad(void)
{
keyResult = 13;
// Read the 1st column
digitalWrite(col1, HIGH);
if (digitalRead(row1) == HIGH){keyResult = 1;}
if (digitalRead(row2) == HIGH){keyResult = 4;}
if (digitalRead(row3) == HIGH){keyResult = 7;}
if (digitalRead(row4) == HIGH){keyResult = 10;}
digitalWrite(col1, LOW);
if (keyResult<12){return keyResult;}
// Read the 2nd column
digitalWrite(col2, HIGH);
if (digitalRead(row1) == HIGH){keyResult = 2;}
if (digitalRead(row2) == HIGH){keyResult = 5;}
if (digitalRead(row3) == HIGH){keyResult = 8;}
if (digitalRead(row4) == HIGH){keyResult = 0;}
digitalWrite(col2, LOW);
if (keyResult<12){return keyResult;}
// Read the 3rd column
digitalWrite(col3, HIGH);
if (digitalRead(row1) == HIGH){keyResult = 3;}
if (digitalRead(row2) == HIGH){keyResult = 6;}
if (digitalRead(row3) == HIGH){keyResult = 9;}
if (digitalRead(row4) == HIGH){keyResult = 11;}
digitalWrite(col3, LOW);
return keyResult;
}
/* First motor
* Constructor for four-pin stepper motor
* Sets which wires should control the motor and
* primary variables used by motor.
*/
void CapeMirror::azStepper(int number_of_steps1, \
int motor1_pin_1, int motor1_pin_2, \
int motor1_pin_3, int motor1_pin_4)
{
// which step the motor is on
this->step_number1 = 0;
// the motor speed1, in revolutions per minute
this->speed1 = 0;
// motor direction1
this->direction1 = 0;
// time stamp in ms of the last step taken
this->last_step_time1 = 0;
// total number of steps for this motor
this->number_of_steps1 = number_of_steps1;
// find the delay nec at 1 rev per min
this->delay_1revpermin1 = 60L * 1000L / number_of_steps1;
// Arduino pins for the motor control connection
this->motor1_pin_1 = motor1_pin_1;
this->motor1_pin_2 = motor1_pin_2;
this->motor1_pin_3 = motor1_pin_3;
this->motor1_pin_4 = motor1_pin_4;
// setup the pins on the microcontroller
pinMode(this->motor1_pin_1, OUTPUT);
pinMode(this->motor1_pin_2, OUTPUT);
pinMode(this->motor1_pin_3, OUTPUT);
pinMode(this->motor1_pin_4, OUTPUT);
}
/* Second motor
* Constructor for four-pin stepper motor
* Sets which wires should control the motor and
* primary variables used by motor.
*/
void CapeMirror::altStepper(int number_of_steps2, \
int motor2_pin_1, int motor2_pin_2, \
int motor2_pin_3, int motor2_pin_4)
{
// which step the motor is on
this->step_number2 = 0;
// the motor speed, in revolutions per minute
this->speed2 = 0;
// motor direction
this->direction2 = 0;
// time stamp in ms of the last step taken
this->last_step_time2 = 0;
// total number of steps for this motor
this->number_of_steps2 = number_of_steps2;
// find the delay nec at 1 rev per min
this->delay_1revpermin2 = 60L * 1000L / number_of_steps2;
// Arduino pins for the motor control connection
this->motor2_pin_1 = motor2_pin_1;
this->motor2_pin_2 = motor2_pin_2;
this->motor2_pin_3 = motor2_pin_3;
this->motor2_pin_4 = motor2_pin_4;
// setup the pins on the microcontroller
pinMode(this->motor2_pin_1, OUTPUT);
pinMode(this->motor2_pin_2, OUTPUT);
pinMode(this->motor2_pin_3, OUTPUT);
pinMode(this->motor2_pin_4, OUTPUT);
}
/* First motor
Set the min speed, max speed, and steps taken to accelerate
*/
void CapeMirror::azStepperSpeeds(long minSpeed1, long maxSpeed1, double Accel1, long moveSpeed1)
{
this->motorMinSpeed1 = minSpeed1;
this->motorMaxSpeed1 = maxSpeed1;
// Number of steps to accelerate over
this->motorAccSteps1 = Accel1;
// Change in speed1 needed per step
this->motorAccelVal1 = (this->motorMaxSpeed1 -this->motorMinSpeed1) / (Accel1-1);
// Set the move speed (ie the speed when 'moving' in response to keypad press
this->move_step_delay1 = 60L * 1000L / this->number_of_steps1 / moveSpeed1;
}
/* Second motor
Set the min speed, max speed, and steps taken to accelerate
*/
void CapeMirror::altStepperSpeeds(long minSpeed2, long maxSpeed2, double Accel2, long moveSpeed2)
{
this->motorMinSpeed2 = minSpeed2;
this->motorMaxSpeed2 = maxSpeed2;
// Number of steps to accelerate over
this->motorAccSteps2 = Accel2;
// Change in speed1 needed per step
this->motorAccelVal2 = (this->motorMaxSpeed2 -this->motorMinSpeed2) / (Accel2-1);
// Set the move speed (ie the speed when 'moving' in response to keypad press
this->move_step_delay2 = 60L * 1000L / this->number_of_steps2 / moveSpeed2;
}
/*
Set the interrupt pins
*/
void CapeMirror::setInterruptPins(int firePin, int readPin)
{
// Pin to fire as an output pin (here a keypad column)
this->firePin = firePin;
// Pin to read (here a keypad row)
this->readPin = readPin;
}
/*
Get the address of the 'steps to do' variables
*/
void CapeMirror::setStepsAddress(int* azStepsAddress, int* altStepsAddress)
{
azStepsToDoAddress = azStepsAddress;
altStepsToDoAddress = altStepsAddress;
}
void CapeMirror::slew (int steps_to_move1, int steps_to_move2)
{
takeSteps(steps_to_move1, steps_to_move2, slewStep);
}
void CapeMirror::move(int keyResult)
{
switch (keyResult) {
case 0:
break;
case 1: // up and left
takeSteps(-1,1, moveStep);
break;
case 2: // up
takeSteps(0, 1, moveStep);
break;
case 3: // up and right
takeSteps(1, 1, moveStep);
break;
case 4: // left
takeSteps(-1, 0, moveStep);
break;
case 5:
// toggle whether only moving in single steps
do {t = readKeypad();} while (t != 13);
moveSingleStepToggle();
break;
case 6: // right
takeSteps(1, 0, moveStep);
break;
case 7: // left and down
takeSteps(-1, -1, moveStep);
break;
case 8: // down
takeSteps(0, -1, moveStep);
break;
case 9: // right and down
takeSteps(1, -1, moveStep);
break;
}
delay(move_step_delay1);
if (moveSingleStep == true)
{
do {t = readKeypad();} while (t != 13);
}
}
void CapeMirror::moveSingleStepToggle()
{
moveSingleStep = (moveSingleStep==false)?true:false;
}
/*
Step method for both motors
*/
void CapeMirror::takeSteps(int steps_to_move1, int steps_to_move2, int step_type)
{
if (step_type == slewStep){
// if slewing, set the interrupt 'fire' pin high
digitalWrite(this->firePin, HIGH);
}
// steps taken
int steps_no1= 1;
int steps_no2= 1;
// Steps for each motor to complete, and the total
// how many steps to take for the motor
int steps_left1 = abs(steps_to_move1);
int steps_left2 = abs(steps_to_move2);
int total_steps_left = steps_left1 + steps_left2;
// determine direction1 based on whether steps_to_mode is + or -:
if (steps_to_move1 > 0) {this->direction1 = 1;}
else {this->direction1 = 0;}
if (steps_to_move2 > 0) {this->direction2 = 1;}
else {this->direction2 = 0;}
// if a slew, reset the motor speed
if (step_type == slewStep)
{
this->speed1 = this->motorMinSpeed1;
this->speed2 = this->motorMinSpeed2;
}
// this is the loop for both motor
while(total_steps_left > 0) {
// set new values for the StepsToTake address (ie StepsToTake variable)
*azStepsToDoAddress = steps_left1;
*altStepsToDoAddress = steps_left2;
// if a slew, read the interrupt pin
if (step_type == slewStep)
{
int readVal = digitalRead(this->readPin);
// if high then exit
if (readVal==HIGH){
break;
}
}
//First motor
//If the motor steps not completed it's steps then
if (steps_left1 > 0) {
//if a slew, work out the speed
if (step_type == slewStep)
{
//1.a. if in the first third of total steps AND
if ((steps_left1 > abs(steps_to_move1/3)) && \
(steps_left1 > (abs(steps_to_move1/3)*2))) {
// 1.b if not yet at max speed1
if (this->speed1 < this->motorMaxSpeed1){
// get the new speed1
this->speed1 = ((steps_no1 -1) * this->motorAccelVal1) + this->motorMinSpeed1;
// get the new delay
step_delay1 = (this->delay_1revpermin1 / this->speed1);
} // i.b. end if: not yet max speed1
} //1.a. end if: first third of total steps
//2. if in middle third of steps do nothing
//3.a. if in the last third of total steps AND
if (steps_left1 <= (abs(steps_to_move1)/3)) {
//3.b. if within deceleration zone
if (steps_left1 <= this->motorAccSteps1) {
// get the new speed1
this->speed1 = ((steps_left1-1) * this->motorAccelVal1) + this->motorMinSpeed1;
// get the new delay
step_delay1 = (this->delay_1revpermin1 / this->speed1);
} //3.b. end if: within deceleration zone
} //3.a. end if: last third of total steps
} // end: if this is a 'slew'
else // if this is a 'move' not a 'slew'
{
step_delay1 = move_step_delay1;
}
// move only if the appropriate delay has passed:
if (millis() - this->last_step_time1 >= this->step_delay1) {
// get the timeStamp of when you stepped:
this->last_step_time1 = millis();
// increment or decrement the step number,
// depending on direction1:
if (this->direction1 == 1) {
this->step_number1++;
if (this->step_number1 == this->number_of_steps1) {
this->step_number1 = 0;
}
}
else
{
if (this->step_number1 == 0) {
this->step_number1 = this->number_of_steps1;
}
this->step_number1--;
}
// in/decrement the steps left:
steps_no1++;
steps_left1--;
total_steps_left--;
// Adjust the Azimuth variable
if (this->direction1 >0) { *gAzimuth += _azRes;}
else {*gAzimuth -= _azRes;}
if (*gAzimuth >= _azMax) { *gAzimuth -= _azMax; }
if (*gAzimuth < 0) { *gAzimuth += _azMax; }
// only report the arcseconds at the end of the slew
if (steps_left1 == 0) {lcdDisplayAzSecs();}
// step the motor to step number 0, 1, 2, or 3:
stepMotor1(this->step_number1 % 4);
} // End: if suitable delay passed
} //End: if (steps_left1 > 0)
//Second motor
//If the motor steps not completed it's steps then
if (steps_left2 > 0) {
//if a slew, work out the speed
if (step_type == slewStep)
{
//1.a. if in the first third of total steps AND
if ((steps_left2 > abs(steps_to_move2/3)) && \
(steps_left2 > (abs(steps_to_move2/3)*2))) {
// 1.b if not yet at max speed1
if (this->speed2 < this->motorMaxSpeed2){
// get the new speed1
this->speed2 = ((steps_no2 -1) * this->motorAccelVal2) + this->motorMinSpeed2;
// get the new delay
step_delay2 = (this->delay_1revpermin2 / this->speed2);
} // i.b. end if: not yet max speed1
} //1.a. end if: first third of total steps
//2. if in middle third of steps do nothing
//3.a. if in the last third of total steps AND
if (steps_left2 <= (abs(steps_to_move2)/3)) {
//3.b. if within deceleration zone
if (steps_left2 <= this->motorAccSteps2) {
// get the new speed1
this->speed2 = ((steps_left2-1) * this->motorAccelVal2) + this->motorMinSpeed2;
// get the new delay
step_delay2 = (this->delay_1revpermin2 / this->speed2);
} //end if: within deceleration zone
} //3.a. end if: last third of total steps
} // end: if this is a 'slew'
else // if this is a 'move' not a 'slew'
{
step_delay2 = move_step_delay2;
}
// move only if the appropriate delay has passed:
if (millis() - this->last_step_time2 >= this->step_delay2) {
// get the timeStamp of when you stepped:
this->last_step_time2 = millis();
// increment or decrement the step number,
// depending on direction1:
if (this->direction2 == 1) {
this->step_number2++;
if (this->step_number2 == this->number_of_steps2) {
this->step_number2 = 0;
}
}
else
{
if (this->step_number2 == 0) {
this->step_number2 = this->number_of_steps2;
}
this->step_number2--;
}
// in/decrement the steps left:
steps_no2++;
steps_left2--;
total_steps_left--;
// Adjust the Altitude variable
if (this->direction2 >0) { *gAltitude += _altRes;}
else {*gAltitude -= _altRes;}
if (*gAltitude >= _altMax) {
// gone too high, end stepping
*gAltitude -= _altRes;
steps_left2=0;
if (step_type == slewStep) {digitalWrite(this->firePin, LOW);}
lcdDisplayDegsMins();
lcdDisplaySecs();
break;
}
if (*gAltitude < _altMin) {
// gone too low, end stepping
*gAltitude += _altRes;
steps_left2=0;
if (step_type == slewStep) {digitalWrite(this->firePin, LOW);}
lcdDisplayDegsMins();
lcdDisplaySecs();
break;
}
// only report the arcseconds at the end of the slew
if (steps_left2 == 0) { lcdDisplayAltSecs(); }
// step the motor to step number 0, 1, 2, or 3:
stepMotor2(this->step_number2 % 4);
} // end: if suitable delay passed
} //End: if (steps_left1 > 0)
// Display the results
lcdDisplayDegsMins();
} //End: WHILE statement
// if a 'slew', set the interrupt 'fire' pin low
if (step_type == slewStep) {digitalWrite(this->firePin, LOW);}
} //End: void step()
/* First motor
* Moves the motor forward or backwards
*/
void CapeMirror::stepMotor1(int thisStep1)
{
switch (thisStep1) {
case 0: // 1010
digitalWrite(motor1_pin_1, HIGH);
digitalWrite(motor1_pin_2, LOW);
digitalWrite(motor1_pin_3, HIGH);
digitalWrite(motor1_pin_4, LOW);
break;
case 1: // 0110
digitalWrite(motor1_pin_1, LOW);
digitalWrite(motor1_pin_2, HIGH);
digitalWrite(motor1_pin_3, HIGH);
digitalWrite(motor1_pin_4, LOW);
break;
case 2: //0101
digitalWrite(motor1_pin_1, LOW);
digitalWrite(motor1_pin_2, HIGH);
digitalWrite(motor1_pin_3, LOW);
digitalWrite(motor1_pin_4, HIGH);
break;
case 3: //1001
digitalWrite(motor1_pin_1, HIGH);
digitalWrite(motor1_pin_2, LOW);
digitalWrite(motor1_pin_3, LOW);
digitalWrite(motor1_pin_4, HIGH);
break;
}
}
/* Second motor
* Moves the motor forward or backwards
*/
void CapeMirror::stepMotor2(int thisStep2)
{
switch (thisStep2) {
case 0: // 1010
digitalWrite(motor2_pin_1, HIGH);
digitalWrite(motor2_pin_2, LOW);
digitalWrite(motor2_pin_3, HIGH);
digitalWrite(motor2_pin_4, LOW);
break;
case 1: // 0110
digitalWrite(motor2_pin_1, LOW);
digitalWrite(motor2_pin_2, HIGH);
digitalWrite(motor2_pin_3, HIGH);
digitalWrite(motor2_pin_4, LOW);
break;
case 2: //0101
digitalWrite(motor2_pin_1, LOW);
digitalWrite(motor2_pin_2, HIGH);
digitalWrite(motor2_pin_3, LOW);
digitalWrite(motor2_pin_4, HIGH);
break;
case 3: //1001
digitalWrite(motor2_pin_1, HIGH);
digitalWrite(motor2_pin_2, LOW);
digitalWrite(motor2_pin_3, LOW);
digitalWrite(motor2_pin_4, HIGH);
break;
}
}
void CapeMirror::lcdDisplayCoords()
{
lcdClear();
lcdDisplay(1, 1, "Az: ");
lcdDisplay(1, 8, (char)223);
lcdDisplay(1, 9, " ");
lcdDisplay(1, 11, (char)39);
lcdDisplay(1, 12, " ");
lcdDisplay(1, 14, (char)34);
lcdDisplay(1, 15, " ");
lcdDisplay(2, 1, "Alt: ");
lcdDisplay(2, 8, (char)223);
lcdDisplay(2, 9, " ");
lcdDisplay(2, 11, (char)39);
lcdDisplay(2, 12, " ");
lcdDisplay(2, 14, (char)34);
lcdDisplay(2, 15, " ");
}
void CapeMirror::lcdDisplayDegsMins()
{
//Azimuth
azDegLCD = int(*gAzimuth/3600);
azMinLCD = int((*gAzimuth-(azDegLCD*3600))/60);
if (azDegLCD > 99){lcdDisplay(1, 5, azDegLCD);}
else if (azDegLCD < 10) {lcdDisplay(1, 5, " "); lcdDisplay(1, 7, azDegLCD);}
else {lcdDisplay(1, 5, " "); lcdDisplay(1, 6, azDegLCD);}
if (azMinLCD < 10) {lcdDisplay(1, 9, " "); lcdDisplay(1, 10, azMinLCD);}
else {lcdDisplay(1, 9, azMinLCD);}
//Altitude
altDegLCD = int(*gAltitude/3600);
altMinLCD = int((*gAltitude-(altDegLCD*3600))/60);
if (altDegLCD < 10) {lcdDisplay(2, 6, " "); lcdDisplay(2, 7, altDegLCD);}
else {lcdDisplay(2, 6, altDegLCD);}
if (altMinLCD < 10) {lcdDisplay(2, 9, " "); lcdDisplay(2, 10, altMinLCD);}
else {lcdDisplay(2, 9, altMinLCD);}
}
void CapeMirror::lcdDisplaySecs()
{
lcdDisplayAzSecs();
lcdDisplayAltSecs();
}
void CapeMirror::lcdDisplayAzSecs()
{
//Azimuth
azDegLCD = int(*gAzimuth/3600);
azMinLCD = int((*gAzimuth-(azDegLCD*3600))/60);
azSecLCD = int(*gAzimuth-((azDegLCD*3600)+(azMinLCD*60)));
if (azSecLCD < 10) {lcdDisplay(1, 12, " "); lcdDisplay(1, 13, azSecLCD);}
else {lcdDisplay(1, 12, azSecLCD);}
}
void CapeMirror::lcdDisplayAltSecs()
{
//Altitude
altDegLCD = int(*gAltitude/3600);
altMinLCD = int((*gAltitude-(altDegLCD*3600))/60);
altSecLCD = int(*gAltitude-((altDegLCD*3600)+(altMinLCD*60)));
if (altSecLCD < 10) {lcdDisplay(2, 12, " "); lcdDisplay(2, 13, altSecLCD);}
else {lcdDisplay(2, 12, altSecLCD);}
}
/*
version() returns the version of the library:
*/
int CapeMirror::version(void)
{
return 2;
}










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