satnogs-rotator-firmware
dc_motor_controller.ino
Go to the documentation of this file.
1 
25 #define SAMPLE_TIME 0.1
26 #define RATIO 54
27 #define MAX_PWM 180
28 #define MIN_PWM 5
29 #define POSITION_DEADZONE 0.2
30 #define PCA9540_ID 0x70
31 #define PCA9540_CH0 0x04
32 #define PCA9540_CH1 0x05
33 #define TC74_ID 0x48
34 #define OVER_TEMP 60
35 #define ENC_RATIO 2
36 #define MIN_M1_ANGLE 0
37 #define MAX_M1_ANGLE 360
38 #define MIN_M2_ANGLE 0
39 #define MAX_M2_ANGLE 180
40 #define DEFAULT_HOME_STATE HIGH
41 #define HOME_SPEED 100
42 
43 #include <PID_v1.h>
44 #include <Wire.h>
45 #include "../libraries/globals.h"
46 #include "../libraries/easycomm.h"
47 #include "../libraries/rotator_pins.h"
48 #include "../libraries/endstop.h"
49 #include "../libraries/watchdog.h"
50 #include "../libraries/i2c_mux.h"
51 #include "../libraries/tc74.h"
52 #include "../libraries/motor.h"
53 #include "../libraries/as5601.h"
54 
55 uint32_t t_run = 0; // run time of uC
59 PID pid_az(&control_az.input, &control_az.u, &control_az.setpoint, control_az.p,
60  control_az.i, control_az.d, P_ON_E, DIRECT);
61 PID pid_el(&control_el.input, &control_el.u, &control_el.setpoint, control_el.p,
62  control_el.i, control_el.d, P_ON_E, DIRECT);
68 
69 enum _rotator_error homing();
70 
71 void setup() {
72  // Homing switch
73  switch_az.init();
74  switch_el.init();
75 
76  // Serial Communication
78 
79  // Initialize DC motors
81  motor_az.init_timer(1, 8);
82  motor_az.enable();
84  motor_el.init_timer(2, 8);
85  motor_el.enable();
86 
87  // Initialize I2C MUX
88  pca9540.init();
89  // Initialize rotary encoders
92 
93  // Initialize control parameters
94  pid_az.SetSampleTime(SAMPLE_TIME);
95  pid_az.SetOutputLimits(-MAX_PWM, MAX_PWM );
96  pid_az.SetMode(AUTOMATIC);
97  pid_el.SetSampleTime(SAMPLE_TIME);
98  pid_el.SetOutputLimits(-MAX_PWM, MAX_PWM);
99  pid_el.SetMode(AUTOMATIC);
100 
101  // Initialize WDT
102  wdt.watchdog_init();
103 }
104 
105 void loop() {
106  // Update WDT
108 
109  // Get end stop status
112 
113  // Run easycomm implementation
115 
116  // Get Motor driver status
119  if (rotator.fault_az == LOW || rotator.fault_el == LOW) {
122  }
123 
124  // Get inside Temperature
128  temp_sensor.sleep();
132  }
133  // Get position of both axis
135  encoder_az.get_pos(&control_az.input);
137  encoder_el.get_pos(&control_el.input);
138 
139  // Check rotator status
140  if (rotator.rotator_status != error) {
141  if (rotator.homing_flag == false) {
142  // Check home flag
144  // Homing
146  if (rotator.rotator_error == no_error) {
147  // No error
149  rotator.homing_flag = true;
150  } else {
151  // Error
154  }
155  } else {
156  // Control Loop
157  if (millis() - t_run > SAMPLE_TIME * 1000) {
158  // Update control gains
159  pid_az.SetTunings(control_az.p, control_az.i, control_az.d);
160  pid_el.SetTunings(control_el.p, control_el.i, control_el.d);
161  if (rotator.control_mode == speed) {
162  control_az.setpoint += control_az.setpoint_speed
163  * SAMPLE_TIME;
164  control_el.setpoint += control_el.setpoint_speed
165  * SAMPLE_TIME;
167  } else {
169  }
170  // Move azimuth and elevation motors
171  pid_az.Compute();
173  pid_el.Compute();
175  // Calculate the speeds of both axis
176  control_az.speed = (control_az.input - control_az.input_prv)
177  / SAMPLE_TIME;
178  control_az.input_prv = control_az.input;
179  control_el.speed = (control_el.input - control_el.input_prv)
180  / SAMPLE_TIME;
181  control_el.input_prv = control_el.input;
182  // Update the run time
183  t_run = millis();
184  // Idle rotator, dead-band
185  if ((abs(control_az.setpoint - control_az.input) <=
186  POSITION_DEADZONE || (control_az.speed == 0)) &&
187  (abs(control_el.setpoint - control_el.input) <=
188  POSITION_DEADZONE || (control_el.speed == 0))) {
190  }
191  }
192  }
193  } else {
194  // Error handler, stop motors and disable the motor driver
195  motor_az.stop();
197  motor_el.stop();
200  // Reset error according to error value
203  }
204  }
205 }
206 
207 /**************************************************************************/
213 /**************************************************************************/
215  bool isHome_az = false;
216  bool isHome_el = false;
217 
218  // Reses position
223 
224  // Move motors with ~constant speed
227 
228  // Homing loop
229  while (isHome_az == false || isHome_el == false) {
230  // Update WDT
232  if (switch_az.get_state() == true && !isHome_az) {
233  // Find azimuth home
234  motor_az.stop();
235  isHome_az = true;
236  }
237  if (switch_el.get_state() == true && !isHome_el) {
238  // Find elevation home
239  motor_el.stop();
240  isHome_el = true;
241  }
242  // Get current position
244  encoder_az.get_pos(&control_az.input);
246  encoder_el.get_pos(&control_el.input);
247  // Check if the rotator goes out of limits or something goes wrong (in
248  // mechanical)
249  if ((abs(control_az.input) > MAX_M1_ANGLE && !isHome_az)
250  || (abs(control_el.input) > MAX_M2_ANGLE && !isHome_el)) {
251  return homing_error;
252  }
253  }
254 
255  // Set the home position and reset all critical control variables
259  control_az.setpoint = 0;
263  control_el.setpoint = 0;
264 
265  return no_error;
266 }
#define ENC_RATIO
Encoder AS5601 gear ratio.
#define SW1
Digital input, to read the status of end-stop for motor 1.
Definition: rotator_pins.h:25
AS5601 encoder_az
#define M1FB
Motor 1 analog input, current/load feedback.
Definition: rotator_pins.h:16
#define HOME_SPEED
Set speed to find home, duty cycle of 8-bit timer.
#define M2IN1
Motor 2 PWM pin.
Definition: rotator_pins.h:18
#define M2IN2
Motor 2 PWM pin.
Definition: rotator_pins.h:19
void set_gear_ratio(uint8_t enc_ratio)
Set the gear ratio between encoder and measure axis.
Definition: as5601.h:152
Class that functions for interacting with a watchdog timer.
Definition: watchdog.h:23
Definition: globals.h:17
void enable()
Enable motor driver.
Definition: motor.h:146
int8_t sleep()
Sleep device request to the sensor on the specified address.
Definition: tc74.h:110
void set_channel(uint8_t ch)
Change the channel.
Definition: i2c_mux.h:54
motor motor_el(M2IN1, M2IN2, M2FB, MOTOR_EN, M2SF, MAX_PWM, MIN_PWM)
void easycomm_proc()
Get the commands from RS485 and response to the client.
Definition: easycomm.h:48
#define MOTOR_EN
Digital output, to enable the motors.
Definition: rotator_pins.h:23
#define PCA9540_CH0
I2C Multiplexer CHO.
PID pid_el & control_el
#define PCA9540_ID
I2C Multiplexer ID.
Definition: globals.h:26
i2c_mux pca9540(PCA9540_ID, PCA9540_CH0, PCA9540_CH1)
Class that functions for interacting with I2C 1-of-2 multiplexer.
Definition: i2c_mux.h:28
void init()
Initialize the Input pin for end-stop.
Definition: endstop.h:35
wdt_timer wdt
bool switch_az
Definition: globals.h:48
endstop switch_el(SW2, DEFAULT_HOME_STATE)
#define PCA9540_CH1
I2C Multiplexer CH1.
tc74 temp_sensor(TC74_ID)
_rotator rotator
Definition: globals.h:57
Class that functions for interacting with end-stop.
Definition: endstop.h:22
enum _rotator_status rotator_status
Rotator status.
Definition: globals.h:41
enum _rotator_error rotator_error
Rotator error.
Definition: globals.h:42
uint32_t t_run
bool switch_el
End-stop vales.
Definition: globals.h:48
#define MAX_M1_ANGLE
Maximum angle of azimuth.
uint8_t set_zero()
Set zero by setting offset angle.
Definition: as5601.h:129
Class that functions for interacting with a TC74 Temperature sensor.
Definition: tc74.h:36
#define SAMPLE_TIME
Control loop in s.
int8_t wake_up()
Wake up request to the sensor on the specified address.
Definition: tc74.h:94
#define OVER_TEMP
Over temperature limit.
#define M2SF
Motor 2 digital input, status flag.
Definition: rotator_pins.h:20
AS5601 encoder_el
Class that functions for interacting with AS5601 magnetic rotary position sensor. ...
Definition: as5601.h:35
int8_t get_temp()
Reads the int8_t in temperature measurement register.
Definition: tc74.h:59
int8_t inside_temperature
Inside Temperature.
Definition: globals.h:45
#define M1IN1
Motor 1 PWM pin.
Definition: rotator_pins.h:13
#define M1SF
Motor 1 digital input, status flag.
Definition: rotator_pins.h:15
void watchdog_reset()
Reset the watchdog timer.
Definition: watchdog.h:45
easycomm comm
void stop()
Stop moving the DC motor.
Definition: motor.h:214
uint8_t fault_az
Definition: globals.h:47
void init_timer(uint8_t timer, uint16_t divisor)
Set timer frequency, for timers 0, 1, 2.
Definition: motor.h:95
void easycomm_init()
Initialize the RS485 bus.
Definition: easycomm.h:39
void init_pin()
Initialize pins of DC motor driver.
Definition: motor.h:55
#define M1IN2
Motor 1 PWM pin.
Definition: rotator_pins.h:14
uint8_t get_pos(double *new_pos)
Calculate an unwrap the position.
Definition: as5601.h:59
enum _rotator_error homing()
Move both axis with one direction in order to find home position, end-stop switches.
#define TC74_ID
Temperature Sensor ID.
void init()
Initialize the I2C bus.
Definition: i2c_mux.h:42
PID pid_az & control_az
void disenable()
Disable motor driver.
Definition: motor.h:155
bool homing_flag
Homing flag.
Definition: globals.h:44
#define MAX_M2_ANGLE
Maximum angle of elevation.
void loop()
uint8_t fault_el
Motor drivers fault flag.
Definition: globals.h:47
void setup()
Class that functions for interacting with a Motor Driver Carrier.
Definition: motor.h:35
void watchdog_init()
Initialize watchdog timer to 2sec time out and to set up interrupt routine.
Definition: watchdog.h:32
#define M2FB
Motor 2 analog input, current/load feedback.
Definition: rotator_pins.h:21
enum _control_mode control_mode
Control mode.
Definition: globals.h:43
uint8_t get_fault()
Get the status flag of motor driver.
Definition: motor.h:176
#define MIN_PWM
Set min Speed.
motor motor_az(M1IN1, M1IN2, M1FB, MOTOR_EN, M1SF, MAX_PWM, MIN_PWM)
#define SW2
Digital input, to read the status of end-stop for motor 2.
Definition: rotator_pins.h:26
Definition: globals.h:17
Class that functions for easycomm 3 implementation.
Definition: easycomm.h:31
#define MAX_PWM
Set max Speed.
void move(int16_t speed)
Move the DC motor with constant voltage (~speed)
Definition: motor.h:188
#define POSITION_DEADZONE
Control dead zone.
Definition: globals.h:17
endstop switch_az(SW1, DEFAULT_HOME_STATE)
#define DEFAULT_HOME_STATE
Change to LOW according to Home sensor.
_rotator_error
Definition: globals.h:20
void init_zero()
Reset zero position set the offset to zero.
Definition: as5601.h:141
bool get_state()
Get the state of end-stop.
Definition: endstop.h:45