-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEncoderPositionEthernet.ino
More file actions
232 lines (204 loc) · 5.77 KB
/
EncoderPositionEthernet.ino
File metadata and controls
232 lines (204 loc) · 5.77 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// Arduino Ethernet Communication -- Syd Lybert, Andrew Micklich -- July 2017
// ------------------------------------------
// SETUP:
// Connect Arduino MEGA digital pins 22-29 to D0-D7 on the HTCL
// Connect digital pin 31 to X/Y
// Connect digital pins 33 and 32 to EN1, EN2 respectively
// Connect digital pin 34 to SEL2
// Connect digital pin 36 to SEL1
// Connect digital pin 35 to RSTX
// Connect digital pin 30 to RSTY
// Connect digital pin 37 to OE
// Connect digital pin 38 to CLK
// Connect 5V Arduino pin to 5V input on optical encoder and V_DD on HTCL
// Connect GND Arduino pin to GND on optical encoder and V_SS on HTCL
// Connect Channel A on encoder to CHA_X on HTCL
// Connect Channel B on encoder to CHB_X on HTCL
// NOTE: Index Channel not yet supported in code
// TEST TEXT
// --------------------------------------------
// Known Bugs:
// None
// --------------------------------------------
// Known Limitations:
// If encoder is turned too rapidly, will not record (Hardware limits? Clock limits?)
// Only 16-bit count currently, eventually can support 32-bit if necessary
// Other Useful Info:
// Toggling between the X and Y channels is explained in the Decoder.h file as follows:
// ReadLSB and READ3SB take boolean arguements, 0 for x axis, and 1 for y axis
#include <Decoder.h>
#include <EEPROM.h>
#include <UIPEthernet.h>
#include <avr/wdt.h>
EthernetServer server = EthernetServer(1000);
EthernetClient client;
Decoder decoder;
//TODO: Clean up global variables, probably don't need this many
int ResultX;
int ResultY;
int Result_oldY;
int Result_oldX;
int Result_lo;
int Result_3rd;
int offsetX = 0;
int offsetY= 0;
char msg[256];
int motorAxis;
unsigned long timerX = millis();
unsigned long timerY = millis();
//setup code
void setup() {
Serial.begin(115200);
decoder.start();
//assign mac and ip addresses, start the server and ethernet communication
byte lastByte = EEPROM.read(0);
uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x02};
IPAddress myIP(192,168,0,2);
Ethernet.begin(mac,myIP);
server.begin();
watchdogSetup();
}
//main loop
void loop() {
//Need to read the ethernet port until we get values dictating what happens next
if(client = server.available())
{
int i = 0;
char c = 0;
while((client.available() > 0) && (c != '\n')){
//gather the message from the client
c = client.read();
if(c != '\n'){
msg[i] = c;
}
i++;
}
if(msg[0] == '5'){
Start();
}
if(msg[0] == '2'){
ReadReply();
}
if(msg[0] == '3'){
StatusReply();
}
if(msg[0] == '4'){
ResetEEPROM();
}
}
DecoderWrite();
EepromWrite();
wdt_reset();
}
//Sends "Start" back to client verifying the socket connection
void Start(){
client.println("Start\n");
}
//reads the arduino's serial number from the EEPROM
void StatusReply(){
client.println(EEPROM.read(0));
}
//writes the encoder position to the client
void ReadReply(){
int i = 0;
char c = 0;
while((client.available() > 0) && (c != '\n')){
//gather the message from the client
c = client.read();
if(c != '\n'){
msg[i] = c;
}
i++;
}
motorAxis = msg[0] - '0';
if(int(motorAxis) == 1){
client.println(ResultY);
}
if(int(motorAxis) == 0){
client.println(ResultX);
}
}
//Saves the current position of the encoders to global variables
void DecoderWrite(){
//Y position
Result_lo = decoder.readLSB(1);
Result_3rd = decoder.read3SB(1);
ResultY = Result_lo + (256*Result_3rd) - offsetY;
//X position
Result_lo = decoder.readLSB(0);
Result_3rd = decoder.read3SB(0);
ResultX = Result_lo + (256*Result_3rd) - offsetX;
}
//writes a position value to the eeprom (every ten seconds, if it changes)
void EepromWrite(){
if((millis()-timerY) >= 10000UL){
if(Result_oldY != ResultY){
EEPROMWrite16(2, ResultY);
Result_oldY = ResultY;
EEPROMCheck();
}
timerY = millis();
}
if((millis()-timerX) >= 10000UL){
if(Result_oldX != ResultX){
EEPROMWrite16(4, ResultX);
Result_oldX = ResultX;
EEPROMCheck();
}
timerX = millis();
}
}
//writes sixteen bit integers to the eeprom
void EEPROMWrite16(int address, int value){
//Decomposition from a int to bytes by using bitshift.
//One = Most significant, Two = Least significant byte
byte two = (value & 0xFF);
byte one = ((value >> 8) & 0xFF);
//Write the 2 bytes into the eeprom memory.
EEPROM.write(address, two);
EEPROM.write(address + 1, one);
}
//Reads in 16 bit integers from the eeprom
int EEPROMRead16(int address){
//Read the 2 bytes from the eeprom memory.
int two = EEPROM.read(address);
int one = EEPROM.read(address + 1);
//Return the recomposed int by using bitshift.
return ((two << 0) & 0xFF) + ((one << 8) & 0xFFFF);
}
//check if the Arduino is storing old positions
void EEPROMCheck(){
if(EEPROM.read(1) == 255){
EEPROM.write(1, 100);
}
}
//tells the arduino to forget previous positions
//This writes to the ethernet client and returns the reset condition
void ResetEEPROM(){
EEPROM.write(1, 255);
offsetX = offsetX + ResultX;
offsetY = offsetY + ResultY;
EEPROMWrite16(2, 0);
EEPROMWrite16(4, 0);
client.println(EEPROM.read(1));
}
//Sets up the watchdog timer to reset if it hangs for more than 2 seconds
void watchdogSetup(void)
{
cli(); // disable all interrupts
wdt_reset(); // reset the WDT timer
/*
WDTCSR configuration:
WDIE = 1: Interrupt Enable
WDE = 1 :Reset Enable
WDP3 = 0 :For 2s Time-out
WDP2 = 1 :For 2s Time-out
WDP1 = 1 :For 2s Time-out
WDP0 = 1 :For 2s Time-out
*/
// Enter Watchdog Configuration mode:
WDTCSR |= (1<<WDCE) | (1<<WDE);
// Set Watchdog settings:
WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
sei();
}