-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathread-wheel-encoder.ino
133 lines (110 loc) · 3.17 KB
/
read-wheel-encoder.ino
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
/**
* @file motor-angular-rate.ino
* @author Joshua Marshall ([email protected])
* @brief Arduino program to estimate motor speed from encoder.
* @version 2.1
* @date 2022-12-09
*
* @copyright Copyright (c) 2021-2022
*
*/
// Wheel PWM pin (must be a PWM pin)
int EA = 11;
int EB = 9;
// Wheel direction digital pins
int I1 = 12;
int I2 = 10;
int I3 = 8;
int I4 = 7;
// Motor PWM command variable [0-255]
byte u = 0;
// Left wheel encoder digital pins
const byte SIGNAL_A_L = 5;
const byte SIGNAL_B_L = 6;
// Left wheel encoder digital pins
const byte SIGNAL_A_R = 2;
const byte SIGNAL_B_R = 3;
// Encoder ticks per (motor) revolution (TPR)
const int TPR = 3000;
// Wheel radius [m]
const double RHO = 0.0625;
// Counter to keep track of encoder ticks [integer]
volatile long encoder_ticks = 0;
// Variable to store estimated angular rate of left wheel [rad/s]
double omega_L = 0.0;
double omega_R = 0.0;
// Sampling interval for measurements in milliseconds
const int T = 1000;
// Counters for milliseconds during interval
long t_now = 0;
long t_last = 0;
// This function is called when SIGNAL_A goes HIGH
void decodeEncoderTicks()
{
if (digitalRead(SIGNAL_B_L) == LOW)
{
// SIGNAL_A leads SIGNAL_B, so count one way
encoder_ticks--;
}
else
{
// SIGNAL_B leads SIGNAL_A, so count the other way
encoder_ticks++;
}
}
void setup()
{
// Open the serial port at 9600 bps
Serial.begin(9600);
// Set the pin modes for the motor driver
pinMode(EA, OUTPUT);
pinMode(I1, OUTPUT);
pinMode(I2, OUTPUT);
// Set the pin modes for the motor driver
pinMode(EB, OUTPUT);
pinMode(I3, OUTPUT);
pinMode(I4, OUTPUT);
// Set the pin modes for the encoders
pinMode(SIGNAL_A_L, INPUT);
pinMode(SIGNAL_B_L, INPUT);
pinMode(SIGNAL_A_R, INPUT);
pinMode(SIGNAL_B_R, INPUT);
// Every time the pin goes high, this is a pulse
attachInterrupt(digitalPinToInterrupt(SIGNAL_A), decodeEncoderTicks, RISING);
// Print a message
Serial.print("Program initialized.");
Serial.print("\n");
}
void loop()
{
// Get the elapsed time [ms]
t_now = millis();
if (t_now - t_last >= T)
{
// Estimate the rotational speed [rad/s]
omega_L = 2.0 * PI * ((double)encoder_ticks_L / (double)TPR) * 1000.0 / (double)(t_now - t_last);
omega_R = 2.0 * PI * ((double)encoder_ticks_R / (double)TPR) * 1000.0 / (double)(t_now - t_last);
// Print some stuff to the serial monitor
Serial.print("Encoder ticks: ");
Serial.print(encoder_ticks);
Serial.print("\t");
Serial.print("Estimated left wheel speed: ");
Serial.print(omega_L);
Serial.print(" rad/s");
Serial.print("\n");
Serial.print(omega_L*RHO);
Serial.print(" m/s");
Serial.print("\n");
// Record the current time [ms]
t_last = t_now;
// Reset the encoder ticks counter
encoder_ticks = 0;
}
// Set the wheel motor PWM command [0-255]
u = 128;
// Select a direction
digitalWrite(I1, LOW);
digitalWrite(I2, HIGH);
// PWM command to the motor driver
analogWrite(EA, u);
}