forked from jhoff/Split-Flap-Display
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSplitFlapModule.cpp
More file actions
148 lines (125 loc) · 4.61 KB
/
SplitFlapModule.cpp
File metadata and controls
148 lines (125 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "SplitFlapModule.h"
// Array of characters, in order, the first item is located on the magnet on the
// character drum
const char SplitFlapModule::StandardChars[37] = {' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
const char SplitFlapModule::ExtendedChars[48] = {
' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '\'', ':', '?', '!', '.', '-', '/', '$', '@', '#', '%',
};
bool hasErrored = false;
// Default Constructor
SplitFlapModule::SplitFlapModule()
: address(0), position(0), stepNumber(0), stepsPerRot(0), chars(StandardChars), numChars(37), charSetSize(37) {
magnetPosition = 710;
}
// Constructor implementation
SplitFlapModule::SplitFlapModule(
uint8_t I2Caddress, int stepsPerFullRotation, int stepOffset, int magnetPos, int charsetSize
)
: address(I2Caddress), position(0), stepNumber(0), stepsPerRot(stepsPerFullRotation), charSetSize(charsetSize) {
magnetPosition = magnetPos + stepOffset;
chars = (charsetSize == 48) ? ExtendedChars : StandardChars;
numChars = (charsetSize == 48) ? 48 : 37;
}
void SplitFlapModule::writeIO(uint16_t data) {
Wire.beginTransmission(address);
Wire.write(data & 0xFF); // Send lower byte
Wire.write((data >> 8) & 0xFF); // Send upper byte
byte error = Wire.endTransmission();
if (error > 0 && ! hasErrored) {
hasErrored = true; // Set the error flag
Serial.print("Error writing data to module ");
Serial.print(address);
Serial.print(", error code: ");
Serial.println(error); // Error codes:
// 0 = success
// 1 = data too long to fit in transmit buffer
// 2 = received NACK on transmit of address
// 3 = received NACK on transmit of data
// 4 = other error
}
}
// Init Module, Setup IO Board
void SplitFlapModule::init() {
float stepSize = (float) stepsPerRot / (float) numChars;
float currentPosition = 0;
for (int i = 0; i < numChars; i++) {
charPositions[i] = (int) currentPosition;
currentPosition += stepSize;
}
uint16_t initState = 0b1111111111100001; // Pin 15 (17) as INPUT, Pins 1-4 as OUTPUT
writeIO(initState);
stop(); // Write all motor coil inputs LOW
int initDelay = 100;
delay(initDelay);
step();
delay(initDelay);
step();
delay(initDelay);
step();
delay(initDelay);
step();
delay(initDelay);
stop();
}
int SplitFlapModule::getCharPosition(char inputChar) {
inputChar = toupper(inputChar);
for (int i = 0; i < charSetSize; i++) {
if (chars[i] == inputChar) {
return charPositions[i];
}
}
return 0; // Character not found, return blank
}
void SplitFlapModule::stop() {
uint16_t stepState = 0b1111111111100001;
writeIO(stepState);
}
void SplitFlapModule::start() {
stepNumber = (stepNumber + 3) % 4; // effectively take one off stepNumber
step(false); // write the "previous" step high again, in case turned off
}
void SplitFlapModule::step(bool updatePosition) {
uint16_t stepState;
switch (stepNumber) {
case 0:
stepState = 0b1111111111100111;
writeIO(stepState);
break;
case 1:
stepState = 0b1111111111110011;
writeIO(stepState);
break;
case 2:
stepState = 0b1111111111111001;
writeIO(stepState);
break;
case 3:
stepState = 0b1111111111101101;
writeIO(stepState);
break;
}
if (updatePosition) {
position = (position + 1) % stepsPerRot;
stepNumber = (stepNumber + 1) % 4;
}
}
bool SplitFlapModule::readHallEffectSensor() {
if (hasErrored) {
return false;
}
uint8_t requestBytes = 2;
Wire.requestFrom(address, requestBytes);
// Make sure the data is available
if (Wire.available() == 2) {
uint16_t inputState = 0;
// Read the two bytes and combine them into a 16-bit value
inputState = Wire.read(); // Read the lower byte
inputState |= (Wire.read() << 8); // Read the upper byte and shift it left
return (inputState & (1 << 15)) != 0; // If bit is 15, return HIGH, else LOW
}
return false;
}