Skip to content

Commit 61eb44e

Browse files
Merge pull request #17 from nexdome/release/3.1.0
Release/3.1.0
2 parents 3ed855c + c86eb5b commit 61eb44e

35 files changed

+330
-184
lines changed

.vscode/c_cpp_properties.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
"C:\\Users\\Tim\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\2.4.2\\**",
1010
"C:\\Users\\Tim\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.6.209\\**",
1111
"F:\\Arduino\\hardware\\arduino\\avr\\**",
12-
"F:\\Arduino\\tools\\**"
12+
"F:\\Arduino\\tools\\**",
13+
"C:\\Users\\Tim\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.6.23\\**"
1314
],
1415
"forcedInclude": [
1516
"C:\\Users\\Tim\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.6.21\\cores\\arduino\\Arduino.h",
1617
"C:\\Users\\Tim\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.6.209\\cores\\arduino\\Arduino.h",
17-
"F:\\Arduino\\hardware\\arduino\\avr\\cores\\arduino\\Arduino.h"
18+
"F:\\Arduino\\hardware\\arduino\\avr\\cores\\arduino\\Arduino.h",
19+
"C:\\Users\\Tim\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.6.23\\cores\\arduino\\Arduino.h"
1820
],
1921
"intelliSenseMode": "msvc-x64"
2022
}

SharedCode/Response.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ Response Response::NoResponse(Command& command)
3838
return Response{ "" };
3939
}
4040

41-
const std::string Response::terminator = "#";
42-
const std::string Response::header = ":";
41+
const char Response::terminator = '#';
42+
const char Response::header = ':';
4343

SharedCode/Response.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
struct Response
1313
{
14-
static const std::string terminator;
15-
static const std::string header;
14+
static const char terminator;
15+
static const char header;
1616
std::string Message;
1717

1818
friend std::ostream& operator<<(std::ostream&, const Response&);

TA.NexDome.Rotator/CommandProcessor.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@
88
CommandProcessor::CommandProcessor(MicrosteppingMotor& rotator, PersistentSettings& settings, XBeeStateMachine& machine)
99
: rotator(rotator), settings(settings), machine(machine) { }
1010

11+
/*
12+
* Sends an encapsulated response to the host application
13+
*/
14+
void CommandProcessor::responseToHost(const std::string& rxMessage)
15+
{
16+
auto length = rxMessage.length();
17+
if (length < 1) return;
18+
if (rxMessage[0] != ':')
19+
std::cout << ':';
20+
std::cout << rxMessage;
21+
if (rxMessage[length - 1] != '#')
22+
std::cout << '#';
23+
std::cout << std::endl;
24+
}
25+
26+
1127
Response CommandProcessor::HandleDR(Command& command) const
1228
{
1329
const auto deadZone = getDeadZoneWholeSteps();
@@ -39,6 +55,8 @@ Response CommandProcessor::HandleHW(Command& command) const
3955

4056
void CommandProcessor::sendStatus() const
4157
{
58+
if (HomeSensor::homingInProgress())
59+
return;
4260
const char separator = ',';
4361
std::ostringstream status;
4462
status << std::dec << ":SER,"
@@ -61,6 +79,8 @@ void CommandProcessor::sendDirection(const int direction)
6179
std::cout << Response::header << clockwise << Response::terminator << std::endl;
6280
}
6381

82+
83+
6484
Response CommandProcessor::ForwardToShutter(Command& command) const
6585
{
6686
machine.SendToRemoteXbee(command.RawCommand);
@@ -121,9 +141,9 @@ Response CommandProcessor::HandleGA(Command& command) const
121141
const auto currentPosition = rotator.getCurrentPosition();
122142
const auto delta = target - currentPosition;
123143
const auto direction = sgn(delta);
124-
std::cout << delta << " [" << settings.deadZone << "]" << std::endl;
125144
if (abs(delta) >= settings.deadZone)
126145
{
146+
HomeSensor::cancelHoming();
127147
sendDirection(direction);
128148
rotator.moveToPosition(target);
129149
}

TA.NexDome.Rotator/CommandProcessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class CommandProcessor
1818
{
1919
public:
2020
CommandProcessor(MicrosteppingMotor& rotator, PersistentSettings& settings, XBeeStateMachine& machine);
21+
static void responseToHost(const std::string& rxMessage);
2122
Response HandleDR(Command& command) const;
2223
Response HandleDW(Command& command) const;
2324
Response HandleCommand(Command& command) const;

TA.NexDome.Rotator/HomeSensor.cpp

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
22
* Provides interrupt processing for the home sensor.
3-
*
3+
*
44
* The home sensor synchronizes the dome rotation step position when it is triggered.
55
* When rotating in the positive direction, we synchronise to the falling edge.
66
* When rotating in the negative direction, we synchronise to the rising edge.
77
* When not rotating, activity is ignored.
8-
*
8+
*
99
* Note: some fields have to be static because they are used during interrupts
1010
*/
1111

@@ -14,11 +14,9 @@
1414

1515
#pragma region static fields used within interrupt service routines
1616
MicrosteppingMotor* HomeSensor::motor;
17-
Home* HomeSensor::settings;
17+
Home* HomeSensor::homeSettings;
1818
uint8_t HomeSensor::sensorPin;
19-
volatile bool HomeSensor::state;
20-
volatile bool HomeSensor::homingInProgress;
21-
volatile bool HomeSensor::performingPostHomeSlew;
19+
volatile HomingPhase HomeSensor::phase;
2220
#pragma endregion
2321

2422
/*
@@ -31,7 +29,7 @@ HomeSensor::HomeSensor(MicrosteppingMotor* stepper, Home* settings, const uint8_
3129
: commandProcessor(processor)
3230
{
3331
motor = stepper;
34-
HomeSensor::settings = settings;
32+
HomeSensor::homeSettings = settings;
3533
HomeSensor::sensorPin = sensorPin;
3634
}
3735

@@ -42,19 +40,9 @@ HomeSensor::HomeSensor(MicrosteppingMotor* stepper, Home* settings, const uint8_
4240
*/
4341
void HomeSensor::onHomeSensorChanged()
4442
{
45-
state = digitalRead(sensorPin);
46-
if (homingInProgress)
43+
const auto state = digitalRead(sensorPin);
44+
if (state == 0 && phase==Detecting)
4745
foundHome();
48-
//if (!motor->isMoving()) // Ignore state change if rotator not moving
49-
// return;
50-
//const auto direction = motor->getCurrentDirection();
51-
//if ((state && direction < 0) || (!state && direction > 0))
52-
// {
53-
// // sync position on either the rising or falling edge, depending on rotation direction.
54-
// motor->SetCurrentPosition(settings->position);
55-
// if (homingInProgress)
56-
// foundHome();
57-
// }
5846
}
5947

6048
/*
@@ -63,67 +51,87 @@ void HomeSensor::onHomeSensorChanged()
6351
void HomeSensor::init()
6452
{
6553
pinMode(sensorPin, INPUT_PULLUP);
66-
state = digitalRead(sensorPin);
67-
homingInProgress = false;
68-
performingPostHomeSlew = false;
54+
setPhase(Idle);
6955
attachInterrupt(digitalPinToInterrupt(sensorPin), onHomeSensorChanged, CHANGE);
7056
}
7157

7258

59+
/// <summary>
60+
/// Indicates whether the dome is currently in the home position
61+
/// (only valid after a successful homing operation and before and slews occur)
62+
/// </summary>
7363
bool HomeSensor::atHome()
7464
{
75-
return !state && !homingInProgress && !performingPostHomeSlew;
65+
return phase == AtHome;
66+
}
67+
68+
void HomeSensor::setPhase(HomingPhase newPhase)
69+
{
70+
phase = newPhase;
71+
Serial.print("Phase ");
72+
Serial.println(phase);
7673
}
7774

7875
/*
7976
* Rotates up to 2 full rotations clockwise while attempting to detect the home sensor.
77+
* Ignored if a homing operation is already in progress.
8078
*/
8179
void HomeSensor::findHome(int direction)
8280
{
83-
homingInProgress = true;
84-
performingPostHomeSlew = false;
85-
const auto distance = 2 * settings->microstepsPerRotation; // Allow 2 full rotations only
86-
motor->moveToPosition(distance);
81+
if (phase == Idle || phase == AtHome)
82+
{
83+
const auto distance = 2 * homeSettings->microstepsPerRotation; // Allow 2 full rotations only
84+
setPhase(Detecting);
85+
motor->moveToPosition(distance);
86+
}
8787
}
8888

8989
/*
9090
* Stops a homing operation in progress.
9191
*/
9292
void HomeSensor::cancelHoming()
9393
{
94-
performingPostHomeSlew = false;
95-
homingInProgress = false;
94+
setPhase(Idle);
9695
if (motor->isMoving())
9796
motor->SoftStop();
9897
}
9998

10099
/*
101100
* Once the home sensor has been detected, we instruct the motor to soft-stop.
102-
* We also set the flaf performingPostHomeSlew.
101+
* We also set the flag performPostHomeSlew.
103102
* At some point in the future, the onMotorStopped method will be called, which will
104103
* then initiate the final slew to return exactly to the home sensor position.
105104
*/
106105
void HomeSensor::foundHome()
107106
{
108-
std::cout << "foundHome" << std::endl;
109-
motor->SetCurrentPosition(settings->position);
110-
homingInProgress = false;
111-
performingPostHomeSlew = true;
107+
setPhase(Stopping);
108+
motor->SetCurrentPosition(homeSettings->position);
112109
motor->SoftStop();
113110
}
114111

115-
void HomeSensor::onMotorStopped()
112+
/*
113+
* Handles the onMotorStopped event. Action depends on the homing phase.
114+
*/
115+
void HomeSensor::onMotorStopped() const
116116
{
117-
std::cout << "onMotorStopped" << std::endl;
118-
homingInProgress = false;
119-
if (performingPostHomeSlew)
117+
std::cout << "Hstop " << phase << std::endl;
118+
switch (phase)
120119
{
121-
performingPostHomeSlew = false;
122-
const auto target = commandProcessor.targetStepPosition(settings->position);
123-
std::cout << "Post slew from "
124-
<< motor->getCurrentPosition()
125-
<< " to " << target
126-
<< std::endl;
127-
motor->moveToPosition(target);
120+
case Reversing:
121+
setPhase(AtHome);
122+
break;
123+
case Stopping:
124+
setPhase(Reversing);
125+
const auto target = commandProcessor.targetStepPosition(homeSettings->position);
126+
motor->moveToPosition(target);
127+
break;
128+
default:
129+
setPhase(Idle);
130+
return;
128131
}
129132
}
133+
134+
bool HomeSensor::homingInProgress()
135+
{
136+
return !(phase == Idle || phase == AtHome);
137+
}

TA.NexDome.Rotator/HomeSensor.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@
1212
#include <AdvancedStepper.h>
1313
#include "CommandProcessor.h"
1414

15+
enum HomingPhase
16+
{
17+
Idle = 0,
18+
Detecting,
19+
Stopping,
20+
Reversing,
21+
AtHome,
22+
};
23+
1524
struct Home
1625
{
1726
int32_t position; // Home sensor azimuth in microsteps
1827
unsigned int width;
1928
int32_t microstepsPerRotation;
20-
Home(int32_t stepPosition, unsigned width, int32_t circumferenceMicrosteps)
29+
Home(int32_t stepPosition, unsigned width, int32_t circumferenceMicrosteps)
2130
: position(stepPosition), width(width), microstepsPerRotation(circumferenceMicrosteps) {}
2231
};
2332

@@ -29,17 +38,17 @@ class HomeSensor
2938
static bool atHome();
3039
static void findHome(int direction);
3140
static void cancelHoming();
32-
static void foundHome();
33-
void onMotorStopped();
41+
void onMotorStopped() const;
42+
static bool homingInProgress();
3443
private:
44+
static volatile HomingPhase phase;
3545
static uint8_t sensorPin;
36-
static volatile bool state;
3746
static MicrosteppingMotor* motor;
38-
static Home* settings;
47+
static Home* homeSettings;
3948
CommandProcessor& commandProcessor;
49+
static void foundHome();
4050
static void onHomeSensorChanged();
41-
static volatile bool homingInProgress;
42-
static volatile bool performingPostHomeSlew;
51+
static void setPhase(HomingPhase newPhase);
4352
};
4453

4554

TA.NexDome.Rotator/PersistentSettings.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//
2-
//
3-
//
1+
//
2+
//
3+
//
44

55
#include <EEPROM.h>
66
#include "NexDome.h"
@@ -21,25 +21,20 @@ PersistentSettings::PersistentSettings() :
2121

2222
/*
2323
Saves persistent settings to EEPROM.
24-
Uses update rather than write in an attempt to minimize unnecessary
25-
write cycles.
26-
Writes a 16-bit fingerprint into the first two EEPROM locations to indicate
27-
that valid settings exist.
24+
Uses update rather than write in an attempt to minimize unnecessary write cycles.
25+
The settings structure already includes the fingerprint. This is validated on loading.
2826
*/
2927
void PersistentSettings::Save()
3028
{
3129
uint16_t* destination = 0;
3230
const auto source = reinterpret_cast<const byte*>(this);
3331
const auto byteCount = sizeof(PersistentSettings);
3432
eeprom_update_block(source, destination, byteCount);
35-
// Now write a "fingerprint" immediately after the settings.
36-
destination += sizeof(PersistentSettings);
37-
eeprom_update_word(destination, fingerprint);
3833
}
3934

4035
/*
4136
Loads and returns persistent settings from EEPROM.
42-
The fingerprint must be valid, and the loaded settings must have the same
37+
The fingerprints must be valid, and the loaded settings must have the same
4338
major version as the firmware version. If these conditions are not met
4439
then default settings will be used.
4540
*/
@@ -50,9 +45,8 @@ PersistentSettings PersistentSettings::Load()
5045
auto loadedSettings = PersistentSettings();
5146
eeprom_read_block(&loadedSettings, source, sizeof(PersistentSettings));
5247
// Read the fingerprint and make sure it is valid
53-
source += sizeof(PersistentSettings);
54-
auto eepromFingerprint = eeprom_read_word(source);
55-
if (eepromFingerprint != fingerprint)
48+
49+
if (loadedSettings.fingerprintHead != fingerprint || loadedSettings.fingerprintTail != fingerprint )
5650
return defaultSettings; // use defaults if fingerprint is invalid
5751
// Ensure that the firmware major version is the same as when the settings were saved.
5852
if (loadedSettings.majorVersion != MajorVersion)

TA.NexDome.Rotator/PersistentSettings.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
#include "HomeSensor.h"
1414
#include "Version.h"
1515

16+
constexpr uint16_t fingerprint = 0x4AFB;
1617
struct PersistentSettings
1718
{
18-
static const uint16_t fingerprint = 0x4AFB;
19+
uint16_t fingerprintHead = fingerprint;
1920
uint8_t majorVersion = MajorVersion;
2021
uint8_t minorVersion = MinorVersion;
2122
struct MotorSettings motor{};
2223
struct Home home;
2324
int deadZone = 1000;
25+
uint16_t fingerprintTail = fingerprint;
2426
PersistentSettings();
2527
static PersistentSettings Load();
2628
void Save();

0 commit comments

Comments
 (0)