AYAB Arduino Firmware 0.95
The goal of the AYAB project is to provide an alternative way to control the famous Brother KH-9xx range of knitting machines using a computer
encoders.h
Go to the documentation of this file.
1
24#ifndef ENCODERS_H_
25#define ENCODERS_H_
26
27#include <Arduino.h>
28
29// Enumerated constants
30
31
32enum class Direction : unsigned char {
33 NoDirection = 0xFF,
34 Left = 0,
35 Right = 1
36};
37constexpr int NUM_DIRECTIONS = 2;
38using Direction_t = enum Direction;
39
40enum class Carriage : unsigned char {
41 NoCarriage = 0xFF,
42 Knit = 0,
43 Lace = 1,
44 Garter = 2
45};
46constexpr int NUM_CARRIAGES = 3;
47using Carriage_t = enum Carriage;
48
49enum class MachineType : unsigned char {
50 NoMachine = 0xFF,
51 Kh910 = 0,
52 Kh930 = 1,
53 Kh270 = 2
54};
55constexpr int NUM_MACHINES = 3;
56using Machine_t = enum MachineType;
57
58enum class BeltShift : unsigned char { Unknown, Regular, Shifted, Lace_Regular, Lace_Shifted };
59using BeltShift_t = enum BeltShift;
60
61// Machine constants
62
63constexpr uint8_t NUM_NEEDLES[NUM_MACHINES] = {200U, 200U, 112U};
64constexpr uint8_t LINE_BUFFER_LEN[NUM_MACHINES] = {25U, 25U, 14U};
65constexpr uint8_t END_OF_LINE_OFFSET_L[NUM_MACHINES] = {12U, 12U, 6U};
66constexpr uint8_t END_OF_LINE_OFFSET_R[NUM_MACHINES] = {12U, 12U, 6U};
67
68constexpr uint8_t END_LEFT[NUM_MACHINES] = {0U, 0U, 0U};
69constexpr uint8_t END_RIGHT[NUM_MACHINES] = {255U, 255U, 167U};
70constexpr uint8_t END_OFFSET[NUM_MACHINES] = {28U, 28U, 28U};
71
72// The following two arrays are created by combining, respectively,
73// the arrays END_LEFT and END_RIGHT with END_OFFSET
74constexpr uint8_t END_LEFT_PLUS_OFFSET[NUM_MACHINES] = {28U, 28U, 28U};
75constexpr uint8_t END_RIGHT_MINUS_OFFSET[NUM_MACHINES] = {227U, 227U, 139U};
76
77constexpr uint8_t ALL_MAGNETS_CLEARED_LEFT[NUM_MACHINES] = {56U, 56U, 38U};
78constexpr uint8_t ALL_MAGNETS_CLEARED_RIGHT[NUM_MACHINES] = {199U, 199U, 129U};
79
80// The garter slop is needed to determine whether or not we have a garter carriage.
81// If we didn't have it, we'd decide which carriage we had when the first magnet passed the sensor.
82// For the garter carriage we need to see both magnets.
83constexpr uint8_t GARTER_SLOP = 2U;
84// Spacing between a garter carriage's outer (L-carriage-like) magnets.
85// For consistency between a garter carriage starting on the left or the right,
86// we need to adjust the position by this distance when starting from the right.
87constexpr uint8_t GARTER_L_MAGNET_SPACING = 24U;
88
89constexpr uint8_t START_OFFSET[NUM_MACHINES][NUM_DIRECTIONS][NUM_CARRIAGES] = {
90 // KH910
91 {
92 // K, L, G
93 {42U, 32U, 32U}, // Left
94 {16U, 24U, 48U} // Right
95 },
96 // KH930
97 {
98 // K, L, G
99 {42U, 32U, 32U}, // Left
100 {16U, 24U, 48U} // Right
101 },
102 // KH270
103 {
104 // K
105 {28U + 6U, 0U, 0U}, // Left
106 {28U - 6U, 0U, 0U} // Right
107 }};
108
109// Should be calibrated to each device
110// Below filter minimum -> Lace carriage
111// Above filter maximum -> Knit carriage
112// KH910 KH930 KH270
113constexpr uint16_t FILTER_L_MIN[NUM_MACHINES] = { 200U, 200U, 200U};
114constexpr uint16_t FILTER_L_MAX[NUM_MACHINES] = { 600U, 600U, 600U};
115constexpr uint16_t FILTER_R_MIN[NUM_MACHINES] = { 200U, 200U, 200U};
116constexpr uint16_t FILTER_R_MAX[NUM_MACHINES] = {1023U, 600U, 600U};
117
118constexpr uint16_t SOLENOIDS_BITMASK = 0xFFFFU;
119
126public:
127 virtual ~EncodersInterface() = default;
128
129 // any methods that need to be mocked should go here
130 virtual void encA_interrupt() = 0;
131 virtual uint16_t getHallValue(Direction_t pSensor) = 0;
132 virtual void init(Machine_t machineType) = 0;
133 virtual Machine_t getMachineType() = 0;
134 virtual BeltShift_t getBeltShift() = 0;
135 virtual Carriage_t getCarriage() = 0;
136 virtual Direction_t getDirection() = 0;
137 virtual Direction_t getHallActive() = 0;
138 virtual uint8_t getPosition() = 0;
139};
140
141// Container class for the static methods for the encoders.
142// Dependency injection is enabled using a pointer to a global instance of
143// either `Encoders` or `EncodersMock`, both of which classes implement the
144// pure virtual methods of `EncodersInterface`.
145
146class GlobalEncoders final {
147private:
148 // singleton class so private constructor is appropriate
149 GlobalEncoders() = default;
150
151public:
152 // pointer to global instance whose methods are implemented
153 static EncodersInterface *m_instance;
154
155 static void encA_interrupt();
156 static uint16_t getHallValue(Direction_t pSensor);
157 static void init(Machine_t machineType);
158 static Machine_t getMachineType();
159 static BeltShift_t getBeltShift();
160 static Carriage_t getCarriage();
161 static Direction_t getDirection();
162 static Direction_t getHallActive();
163 static uint8_t getPosition();
164};
165
167public:
168 Encoders() = default;
169
170 void encA_interrupt() final;
171 uint16_t getHallValue(Direction_t pSensor) final;
172 void init(Machine_t machineType) final;
173 Machine_t getMachineType() final;
174 BeltShift_t getBeltShift() final;
175 Carriage_t getCarriage() final;
176 Direction_t getDirection() final;
177 Direction_t getHallActive() final;
178 uint8_t getPosition() final;
179
180private:
181 Machine_t m_machineType;
182
183 volatile BeltShift_t m_beltShift;
184 volatile Carriage_t m_carriage;
185 volatile Carriage_t m_previousDetectedCarriageLeft;
186 volatile Carriage_t m_previousDetectedCarriageRight;
187 volatile Direction_t m_direction;
188 volatile Direction_t m_hallActive;
189 volatile uint8_t m_position;
190 volatile bool m_oldState;
191 volatile bool m_passedLeft;
192 volatile bool m_passedRight;
193
194 Carriage_t detectCarriageLeft();
195 Carriage_t detectCarriageRight();
196 void encA_rising();
197 void encA_falling();
198};
199
200#endif // ENCODERS_H_
Definition encoders.h:166
void init(Machine_t machineType) final
Initialize machine type.
Definition encoders.cpp:70
void encA_rising()
Interrupt service subroutine.
Definition encoders.cpp:164
BeltShift_t getBeltShift() final
Get beltShift member.
Definition encoders.cpp:94
uint16_t getHallValue(Direction_t pSensor) final
Read hall sensor on left and right.
Definition encoders.cpp:55
Direction_t getHallActive() final
Get hallActive member.
Definition encoders.cpp:108
Direction_t getDirection() final
Get direction member.
Definition encoders.cpp:101
Carriage_t getCarriage() final
Get carriage member.
Definition encoders.cpp:115
void encA_interrupt() final
Service encoder A interrupt routine.
Definition encoders.cpp:38
Machine_t getMachineType() final
Get machine type.
Definition encoders.cpp:122
void encA_falling()
Interrupt service subroutine.
Definition encoders.cpp:255
uint8_t getPosition() final
Get position member.
Definition encoders.cpp:87
Encoder interface.
Definition encoders.h:125
Definition encoders.h:146