Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Systemic changes to support garter carriage on the full bed #196

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
60d299e
Start G-carriage earlier to avoid overflowing m_position
clholgat Jul 31, 2024
efefaf1
Cleanup
clholgat Jul 31, 2024
702e55b
Whitespace
clholgat Jul 31, 2024
f273377
Rethink how solenoids are calculated
clholgat Aug 18, 2024
1d0d6cf
Finally works
clholgat Aug 25, 2024
600d0e3
Cleanup
clholgat Aug 25, 2024
b013100
Fix knit carriage belt shift
clholgat Aug 25, 2024
5f24490
Update offsets
clholgat Aug 25, 2024
2d56775
Belt shift experimentation
clholgat Aug 27, 2024
20bbb23
Fix Right to Left
clholgat Aug 27, 2024
d28c392
It works
clholgat Aug 30, 2024
fe3a180
Fix lace carriage
clholgat Aug 30, 2024
9bcfd16
Remove unused variable
clholgat Aug 30, 2024
fc9ba8c
Start G-carriage earlier to avoid overflowing m_position
clholgat Jul 31, 2024
b490d6f
Cleanup
clholgat Jul 31, 2024
44f5b36
Whitespace
clholgat Jul 31, 2024
696b9b7
Rethink how solenoids are calculated
clholgat Aug 18, 2024
cdd1afd
Finally works
clholgat Aug 25, 2024
ba29a37
Cleanup
clholgat Aug 25, 2024
03149f7
Fix knit carriage belt shift
clholgat Aug 25, 2024
5560a08
Update offsets
clholgat Aug 25, 2024
e99ebeb
Belt shift experimentation
clholgat Aug 27, 2024
95c11ae
Fix Right to Left
clholgat Aug 27, 2024
4d7b11b
It works
clholgat Aug 30, 2024
ea8733f
Fix lace carriage
clholgat Aug 30, 2024
b309e39
Remove unused variable
clholgat Aug 30, 2024
284371b
Update src/ayab/encoders.cpp
dl1com Aug 30, 2024
67affda
Update src/ayab/encoders.cpp
dl1com Aug 30, 2024
030c5f3
Fixed existing tests, removed the ones that are no longer relevant
clholgat Aug 31, 2024
52cd583
Merge branch 'clholgat/garter_carriage' of https://github.com/clholga…
clholgat Sep 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/ayab/beeper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ void Beeper::endWork() {
}
}

void Beeper::error() {
if (m_enabled) {
beep(BEEP_NUM_ERROR);
}
}

/*!
* Beep handler scheduled from main loop
*/
Expand Down
4 changes: 4 additions & 0 deletions src/ayab/beeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ constexpr unsigned int BEEP_DELAY = 50U; // ms
constexpr uint8_t BEEP_NUM_READY = 5U;
constexpr uint8_t BEEP_NUM_FINISHEDLINE = 3U;
constexpr uint8_t BEEP_NUM_ENDWORK = 10U;
constexpr uint8_t BEEP_NUM_ERROR = 15U;

constexpr uint8_t BEEP_ON_DUTY = 0U;
constexpr uint8_t BEEP_OFF_DUTY = 20U;
Expand All @@ -49,6 +50,7 @@ class BeeperInterface {
virtual void ready() = 0;
virtual void finishedLine() = 0;
virtual void endWork() = 0;
virtual void error() = 0;
virtual void schedule() = 0;
};

Expand All @@ -72,6 +74,7 @@ class GlobalBeeper final {
static void ready();
static void finishedLine();
static void endWork();
static void error();
static void schedule();
};

Expand All @@ -86,6 +89,7 @@ class Beeper : public BeeperInterface {
void ready() final;
void finishedLine() final;
void endWork() final;
void error() final;
void schedule() final;

private:
Expand Down
98 changes: 75 additions & 23 deletions src/ayab/encoders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ void Encoders::init(Machine_t machineType) {
m_beltShift = BeltShift::Unknown;
m_carriage = Carriage_t::NoCarriage;
m_oldState = false;
m_passedLeft = false;
m_passedRight = false;
}

/*!
Expand Down Expand Up @@ -133,20 +135,13 @@ void Encoders::encA_rising() {
m_direction = digitalRead(ENC_PIN_B) != 0 ? Direction_t::Right : Direction_t::Left;

// Update carriage position
if ((Direction_t::Right == m_direction) && (m_position < END_RIGHT[static_cast<uint8_t>(m_machineType)])) {
m_position = m_position + 1;
}

// The garter carriage has a second set of magnets that are going to
// pass the sensor and will reset state incorrectly if allowed to
// continue.
if (m_carriage == Carriage_t::Garter) {
return;
}
if (Direction_t::Right == m_direction) {
m_position = m_position + (uint8_t) 1;

// If the carriage is already set, ignore the rest.
if ((m_carriage == Carriage_t::Knit) && (m_machineType == Machine_t::Kh270)) {
return;
// Reset carriage passed state when we know all magnets have cleared the turn mark.
if (m_position > ALL_MAGNETS_CLEARED_LEFT[static_cast<uint8_t>(m_machineType)]) {
m_passedLeft = false;
}
}

// In front of Left Hall Sensor?
Expand All @@ -155,6 +150,38 @@ void Encoders::encA_rising() {
(hallValue > FILTER_L_MAX[static_cast<uint8_t>(m_machineType)])) {
m_hallActive = Direction_t::Left;

// Only set the belt shift the first time a magnet passes the turn mark.
// Headed to the right.
if (!m_passedLeft && Direction_t::Right == m_direction) {
// Belt shift signal only decided in front of hall sensor
m_beltShift = digitalRead(ENC_PIN_C) != 0 ? BeltShift::Shifted : BeltShift::Regular;
X-sam marked this conversation as resolved.
Show resolved Hide resolved
m_passedLeft = true;

if (Carriage_t::Garter == m_carriage) {
// This has to be the first magnet and the belt shift needs to be swapped
// But only for the G-carriage
if (m_position < 30) {
if (BeltShift::Regular == m_beltShift) {
m_beltShift = BeltShift::Shifted;
} else {
m_beltShift = BeltShift::Regular;
}
}
}
}

// The garter carriage has a second set of magnets that are going to
// pass the sensor and will reset state incorrectly if allowed to
// continue.
if (Carriage_t::Garter == m_carriage) {
return;
}

// If the carriage is already set, ignore the rest.
if ((Carriage_t::Knit == m_carriage) && (Machine_t::Kh270 == m_machineType)) {
return;
}

Carriage detected_carriage = Carriage_t::NoCarriage;
uint8_t start_position = END_LEFT_PLUS_OFFSET[static_cast<uint8_t>(m_machineType)];

Expand All @@ -176,16 +203,25 @@ void Encoders::encA_rising() {
} else if (m_carriage != detected_carriage && m_position > start_position) {
m_carriage = Carriage_t::Garter;

// We swap the belt shift for the g-carriage because the point of work for
// the g-carraige is 13 needles behind the first magnet which puts it in a different
dl1com marked this conversation as resolved.
Show resolved Hide resolved
// belt shift.
// And we need to know the belt shift when the point of work is at needle 0.
// Conveniently, the magnet distance on the K and L carraiges puts the point of
dl1com marked this conversation as resolved.
Show resolved Hide resolved
// work within the same belt shift.
if (BeltShift::Regular == m_beltShift) {
m_beltShift = BeltShift::Shifted;
} else {
m_beltShift = BeltShift::Regular;
}

// Belt shift and start position were set when the first magnet passed
// the sensor and we assumed we were working with a standard carriage.
return;
} else {
m_carriage = detected_carriage;
}

// Belt shift signal only decided in front of hall sensor
m_beltShift = digitalRead(ENC_PIN_C) != 0 ? BeltShift::Regular : BeltShift::Shifted;

// Known position of the carriage -> overwrite position
m_position = start_position;
}
Expand All @@ -203,8 +239,13 @@ void Encoders::encA_falling() {
m_direction = digitalRead(ENC_PIN_B) ? Direction_t::Left : Direction_t::Right;

// Update carriage position
if ((Direction_t::Left == m_direction) && (m_position > END_LEFT[static_cast<uint8_t>(m_machineType)])) {
m_position = m_position - 1;
if (Direction_t::Left == m_direction) {
m_position = m_position - (uint8_t) 1;
X-sam marked this conversation as resolved.
Show resolved Hide resolved

// Reset carriage passed state when we know all magnets have cleared the turn mark.
if (m_position < ALL_MAGNETS_CLEARED_RIGHT[static_cast<uint8_t>(m_machineType)]) {
m_passedRight = false;
}
}

// In front of Right Hall Sensor?
Expand All @@ -219,15 +260,26 @@ void Encoders::encA_falling() {
if (hallValueSmall || hallValue > FILTER_R_MAX[static_cast<uint8_t>(m_machineType)]) {
m_hallActive = Direction_t::Right;

// The garter carriage has a second set of magnets that are going to
// Only set the belt shift when the first magnet passes the turn mark.
// Headed to the left.
if (!m_passedRight && Direction_t::Left == m_direction) {
// Belt shift signal only decided in front of hall sensor
m_beltShift = digitalRead(ENC_PIN_C) != 0 ? BeltShift::Regular : BeltShift::Shifted;
X-sam marked this conversation as resolved.
Show resolved Hide resolved
m_passedRight = true;

// Shift doens't need to be swapped for the g-carriage in this direction.
}

// The garter carriage has extra magnets that are going to
// pass the sensor and will reset state incorrectly if allowed to
// continue.
if (hallValueSmall && (m_carriage != Carriage_t::Garter)) {
m_carriage = Carriage_t::Knit;
if (m_carriage == Carriage_t::Garter) {
return;
}

// Belt shift signal only decided in front of hall sensor
m_beltShift = digitalRead(ENC_PIN_C) != 0 ? BeltShift::Shifted : BeltShift::Regular;
if (hallValueSmall) {
m_carriage = Carriage_t::Knit;
}

// Known position of the carriage -> overwrite position
m_position = END_RIGHT_MINUS_OFFSET[static_cast<uint8_t>(m_machineType)];
Expand Down
13 changes: 9 additions & 4 deletions src/ayab/encoders.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ constexpr uint8_t END_OFFSET[NUM_MACHINES] = {28U, 28U, 5U};
constexpr uint8_t END_LEFT_PLUS_OFFSET[NUM_MACHINES] = {28U, 28U, 5U};
constexpr uint8_t END_RIGHT_MINUS_OFFSET[NUM_MACHINES] = {227U, 227U, 135U};

constexpr uint8_t ALL_MAGNETS_CLEARED_LEFT[NUM_MACHINES] = {56U, 56U, 10U};
constexpr uint8_t ALL_MAGNETS_CLEARED_RIGHT[NUM_MACHINES] = {199U, 199U, 130U};

// The garter slop is needed to determine whether or not we have a garter carriage.
// If we didn't have it, we'd decide which carriage we had when the first magnet passed the sensor.
// For the garter carriage we need to see both magnets.
Expand All @@ -83,14 +86,14 @@ constexpr uint8_t START_OFFSET[NUM_MACHINES][NUM_DIRECTIONS][NUM_CARRIAGES] = {
// KH910
{
// K, L, G
{40U, 40U, 32U}, // Left
{16U, 16U, 56U} // Right
{42U, 32U, 32U}, // Left
{16U, 32U, 50U} // Right
},
// KH930
{
// K, L, G
{40U, 40U, 32U}, // Left
{16U, 16U, 56U} // Right
{42U, 32U, 32U}, // Left
{16U, 32U, 50U} // Right
},
// KH270
{
Expand Down Expand Up @@ -181,6 +184,8 @@ class Encoders : public EncodersInterface {
volatile Direction_t m_hallActive;
volatile uint8_t m_position;
volatile bool m_oldState;
volatile bool m_passedLeft;
volatile bool m_passedRight;

void encA_rising();
void encA_falling();
Expand Down
4 changes: 4 additions & 0 deletions src/ayab/global_beeper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ void GlobalBeeper::endWork() {
m_instance->endWork();
}

void GlobalBeeper::error() {
m_instance->error();
}

void GlobalBeeper::schedule() {
m_instance->schedule();
}
52 changes: 16 additions & 36 deletions src/ayab/knitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ void Knitter::knit() {
}

if (!calculatePixelAndSolenoid()) {
// no valid/useful position calculated
// This will only happen if there's an error
GlobalBeeper::error();
return;
}

Expand Down Expand Up @@ -386,7 +387,8 @@ void Knitter::reqLine(uint8_t lineNumber) {
*/
bool Knitter::calculatePixelAndSolenoid() {
uint8_t startOffset = 0;
uint8_t laceOffset = 0;

bool beltShift = BeltShift_t::Shifted == m_beltShift;

switch (m_direction) {
// calculate the solenoid and pixel to be set
Expand All @@ -395,51 +397,29 @@ bool Knitter::calculatePixelAndSolenoid() {
case Direction_t::Right:
startOffset = getStartOffset(Direction_t::Left);

// We have to start setting pixels earlier when the lace carriage is selected because we shift
// the lace pixel selection up HALF_SOLENOIDS_NUM in this direction. Doesn't matter going back
// the other way.
// The Lace carriage is special
// See page 7 of the 930 service manual https://mkmanuals.com/downloadable/download/sample/sample_id/27/
if (Carriage_t::Lace == m_carriage) {
laceOffset = HALF_SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
beltShift = !beltShift;
}

if (m_position >= startOffset - laceOffset) {
m_pixelToSet = m_position - startOffset;

if ((BeltShift::Regular == m_beltShift) || (m_machineType == Machine_t::Kh270)) {
m_solenoidToSet = m_position % SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
} else if (BeltShift::Shifted == m_beltShift) {
m_solenoidToSet = (m_position - HALF_SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)]) % SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
}
if (Carriage_t::Lace == m_carriage) {
m_pixelToSet = m_pixelToSet + HALF_SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
}
} else {
return false;
}
break;

case Direction_t::Left:
startOffset = getStartOffset(Direction_t::Right);
if (m_position <= (END_RIGHT[static_cast<uint8_t>(m_machineType)] - startOffset)) {
m_pixelToSet = m_position - startOffset;

if ((BeltShift::Regular == m_beltShift) || (m_machineType == Machine_t::Kh270)) {
m_solenoidToSet = (m_position + HALF_SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)]) % SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
} else if (BeltShift::Shifted == m_beltShift) {
m_solenoidToSet = m_position % SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
}
if (Carriage_t::Lace == m_carriage) {
m_pixelToSet = m_pixelToSet - SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
}
} else {
return false;
}
break;

break;
default:
return false;
}

m_pixelToSet = m_position - startOffset;

if (!beltShift) {
m_solenoidToSet = m_pixelToSet % SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
} else {
m_solenoidToSet = (m_pixelToSet + HALF_SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)]) % SOLENOIDS_NUM[static_cast<uint8_t>(m_machineType)];
}

// The 270 has 12 solenoids but they get shifted over 3 bits
if (m_machineType == Machine_t::Kh270) {
m_solenoidToSet = m_solenoidToSet + 3;
Expand Down
5 changes: 5 additions & 0 deletions test/mocks/beeper_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ void Beeper::finishedLine() {
gBeeperMock->finishedLine();
}

void Beeper::error() {
assert(gBeeperMock != nullptr);
gBeeperMock->error();
}

void Beeper::endWork() {
assert(gBeeperMock != nullptr);
gBeeperMock->endWork();
Expand Down
1 change: 1 addition & 0 deletions test/mocks/beeper_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class BeeperMock : public BeeperInterface {
MOCK_METHOD0(getState, BeepState());
MOCK_METHOD0(ready, void());
MOCK_METHOD0(finishedLine, void());
MOCK_METHOD0(error, void());
MOCK_METHOD0(endWork, void());
MOCK_METHOD0(schedule, void());
};
Expand Down
Loading
Loading