-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRotorControllerInterface.ino
9421 lines (8033 loc) · 358 KB
/
RotorControllerInterface.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
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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Arduino Rotator Controller
Anthony Good
K3NG
Code contributions, testing, ideas, bug fixes, hardware, support, encouragement, and/or bourbon provided by:
John W3SA
Gord VO1GPK
Anthony M0UPU
Pete VE5VA
Marcin SP5IOU
Hjalmar OZ1JHM
Sverre LA3ZA
Bent OZ1CT
Erick WB6KCN
Norm N3YKF
Jan OK2ZAW
Jim M0CKE
Mike AD0CZ
Paolo IT9IPQ
Antonio IZ7DDA
Johan PA3FPQ
Jurgen PE1LWT
Gianfranco IZ8EWD
Jasper PA2J
Pablo EA4TX
Máximo EA1DDO
Matt VK5ZM
...and others
Translations provided by
Máximo EA1DDO
Jan OK2ZAW
Paolo IT9IPQ
Ismael PY4PI
Robert DL5ROB
(If you contributed something and I forgot to put your name and call in here, *please* email me!)
***************************************************************************************************************
*
* This program is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
*
* http://creativecommons.org/licenses/by-nc-sa/3.0/
*
* http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode
*
*
***************************************************************************************************************
All copyrights are the property of their respective owners
Full documentation is currently located here: https://github.com/k3ng/k3ng_rotator_controller/wiki
Rules for using this code:
Rule #1: Read the documentation.
Rule #2: Refer to rule #1.
Rule #3: Help others.
Rule #4: Have fun.
New in this release:
HH-12 encoder support
OPTION_PULSE_IGNORE_AMBIGUOUS_PULSES
\P PWM command is now \W
\P is Park command
park_in_progress_pin // goes high when a park has been initiated and rotation is in progress
parked_pin // goes high when in a parked position
heading_reading_inhibit_pin
FEATURE_LIMIT_SENSE
#define az_limit_sense_pin 0 // input - low stops azimuthal rotation
#define el_limit_sense_pin 0 // input - low stops elevation rotation
\Axxx command - manually set azimuth, xxx = azimuth (FEATURE_AZ_POSITION_ROTARY_ENCODER or FEATURE_AZ_POSITION_PULSE_INPUT only)
\Bxxx command - manually set elevation, xxx = elevation (FEATURE_EL_POSITION_POTENTIOMETER or FEATURE_EL_POSITION_ROTARY_ENCODER only)
fixed bug with preset encoder start and kill button
FEATURE_AZ_POSITION_INCREMENTAL_ENCODER
FEATURE_EL_POSITION_INCREMENTAL_ENCODER
OPTION_INCREMENTAL_ENCODER_PULLUPS
#define AZ_POSITION_INCREMENTAL_ENCODER_PULSES_PER_REV 8000.0
#define EL_POSITION_INCREMENTAL_ENCODER_PULSES_PER_REV 8000.0
AZIMUTH_STARTING_POINT_DEFAULT and AZIMUTH_ROTATION_CAPABILITY_DEFAULT are now persistent
Yaesu P35, P45, and Z commands no longer write to eeprom
control_port points to the hardware port for computer interface
remote_unit_port points to the hardware port for interfacing to remote unit
removed OPTION_SERIAL1, 2, 3, 4
SS command: SS0 = control port, SS1 = remote unit port
No longer need to manually uncomment hh12.h or object declarations
No longer need to manually uncomment LiquidCrystal lcd()
No longer need to manually uncomment Adafruit_ADXL345 accel
No longer need to manually uncomment ADXL345 accel
No longer need to manually uncomment Adafruit_LSM303 lsm;
No longer need to manually uncomment HMC5883L compass;
FEATURE_4_BIT_LCD_DISPLAY
FEATURE_ADAFRUIT_I2C_LCD
FEATURE_YOURDUINO_I2C_LCD
FEATURE_RFROBOT_I2C_DISPLAY
No longer need to uncomment:
FEATURE_LCD_DISPLAY
FEATURE_I2C_LCD
any include files
serial led duration now set by SERIAL_LED_TIME_MS
#define CONTROL_PORT_MAPPED_TO &Serial // change this line to map the control port to a different serial port (Serial1, Serial2, etc.)
#define REMOTE_PORT_MAPPED_TO &Serial1 // change this line to map the remote_unit port to a different serial port
start of remote unit pin control
remote unit pin control (add 100 to a pin number define to map to remote unit pin)
FEATURE_CLOCK
FEATURE_MOON_TRACKING
#define DEFAULT_LATITUDE 40.889958
#define DEFAULT_LONGITUDE -75.585972
#define INTERNAL_CLOCK_CORRECTION 0.00145
\C - show clock
\O - set clock \OYYYYMMDDHHmm
\Mx - x = 0: deactive moon tracking; x = 1: activate moon tracking
\Gxxxxxx - set coordinates via grid square (example: \GFN20EV)
Park is now deactivated when issuing a Yaesu command (other than C) or when doing manual rotation
FEATURE_GPS
#define GPS_PORT_MAPPED_TO &Serial2
#define GPS_PORT_BAUD_RATE 9600
#define SYNC_TIME_WITH_GPS 1
#define SYNC_COORDINATES_WITH_GPS 1
#define GPS_SYNC_PERIOD_SECONDS 10 // how long to consider internal clock syncronized after a GPS reading
#define GPS_VALID_FIX_AGE_MS 10000 // consider a GPS reading valid if the fix age is less than this
FEATURE_SUN_TRACKING
\Ux - x = 0: deactive sun tracking; x = 1: activate sun tracking
FEATURE_AZ_POSITION_INCREMENTAL_ENCODER & FEATURE_EL_POSITION_INCREMENTAL_ENCODER coding
Updated debug output format
\XS - calibration az and el to sun heading - there are calculation bugs
fixed initialize_serial() compilaton error when neither yaesu or easycom protocol is selected in features
fixed bugs in \XS and \XM
\XS and\XM now working on all sensor types
moon_tracking_active_pin
sun_tracking_active_pin
moon_tracking_activate_line
sun_tracking_activate_line
moon_tracking_button
sun_tracking_button
\A azimuth calibration now also works with sensors other than rotary encoders and pulse input
\B elevation calibration now also works with sensors other than rotary encoders and pulse input
OPTION_BUTTON_RELEASE_NO_SLOWDOWN
Fixed God-awful bug that caused Arduino to crash when running FEATURE_GPS. Note to self: never declare a char in a switch case. It causes unpredicatable, unexplainable evil stuff to occur.
Fixed bug with elevation PWM
gps_sync pin - goes high when clock is GPS synchronized
FEATURE_RTC_PCF8583
\O command also programs realtime clocks now
Fixed bug in PWM outputs when changing direction
Ethernet now working with backslash commands, Yaesu commands, and Easycom commands
Fixed bug in Easycom (non-standard) AZ and EL commands
Ethernet remote unit slave support (slave only, master using ethernet not done yet)
#define GPS_MIRROR_PORT &Serial3
OPTION_DISPLAY_SMALL_CLOCK
#define LCD_SMALL_CLOCK_POSITION LEFT
OPTION_DISPLAY_GPS_INDICATOR
#define LCD_GPS_INDICATOR_POSITION RIGHT
OPTION_DISPLAY_MOON_TRACKING_CONTINUOUSLY
#define LCD_MOON_TRACKING_ROW 3
#define LCD_MOON_TRACKING_UPDATE_INTERVAL 5000
OPTION_DISPLAY_SUN_TRACKING_CONTINUOUSLY
#define LCD_SUN_TRACKING_ROW 4
#define LCD_SUN_TRACKING_UPDATE_INTERVAL 5000
#define LCD_ROWS 4
fixed bug with Yourduino LCD display initialization (thanks PA3FPQ)
added GPS counters to debug output
FEATURE_POWER_SWITCH
#define POWER_SWITCH_IDLE_TIMEOUT 15 (unit: minutes)
#define power_switch 0
OPTION_DISPLAY_MOON_OR_SUN_TRACKING_CONDITIONAL
#define LCD_MOON_OR_SUN_TRACKING_CONDITIONAL_ROW 3
OPTION_DISPLAY_BIG_CLOCK
#define GPS_UPDATE_LATENCY_COMPENSATION_MS 200
#define AZIMUTH_CALIBRATION_FROM_ARRAY {180,630}
#define AZIMUTH_CALIBRATION_TO_ARRAY {180,630}
#define ELEVATION_CALIBRATION_FROM_ARRAY {-180,0,180}
#define ELEVATION_CALIBRATION_TO_ARRAY {-180,0,180}
#define rotate_cw_ccw 0
#define az_stepper_motor_direction 0
#define el_stepper_motor_direction 0
bug fix for long clock display
performance improvement for az / el display on LCD
#define az_stepper_motor_pulse 0
#define el_stepper_motor_pulse 0
OPTION_DISPLAY_ALT_HHMM_CLOCK_AND_MAIDENHEAD
#define LCD_SMALL_CLOCK_AND_MAIDENHEAD_POSITION
#define LCD_SMALL_CLOCK_AND_MAIDENHEAD_ROW 4
#define LCD_GPS_INDICATOR_ROW 1
OPTION_EXTERNAL_ANALOG_REFERENCE
more debug_print conversion
OPTION_DISPLAY_SMALL_CLOCK renamed to OPTION_DISPLAY_HHMM_CLOCK
LCD_SMALL_CLOCK_POSITION renamed to LCD_HHMM_CLOCK_POSITION
OPTION_DISPLAY_HHMMSS_CLOCK
OPTION_DISPLAY_DISABLE_DIRECTION_STATUS
OPTION_DISPLAY_SMALL_CLOCK_AND_MAIDENHEAD renamed to OPTION_DISPLAY_ALT_HHMM_CLOCK_AND_MAIDENHEAD
OPTION_DISPLAY_CONSTANT_HHMMSS_CLOCK_AND_MAIDENHEAD
#define LCD_HHMM_CLOCK_POSITION LEFT //LEFT or RIGHT
#define LCD_HHMMSS_CLOCK_POSITION LEFT //LEFT or RIGHT
#define LCD_ALT_HHMM_CLOCK_AND_MAIDENHEAD_POSITION LEFT
#define LCD_ALT_HHMM_CLOCK_AND_MAIDENHEAD_ROW 1
#define LCD_CONSTANT_HHMMSS_CLOCK_AND_MAIDENHEAD_POSITION LEFT
#define LCD_CONSTANT_HHMMSS_CLOCK_AND_MAIDENHEAD_ROW 1
OPTION_DISPLAY_DISABLE_DIRECTION_STATUS changed to OPTION_DISPLAY_DIRECTION_STATUS
worked on FEATURE_TWO_DECIMAL_PLACE_HEADINGS
LANGUAGE_ENGLISH
Easycom improvements - space and LF are now also command delimiters. Also fixed bug with one decimal place. Works with PSTRotator
Fixed issue with LCD display updating when target az or target el was changed during rotation
I2C_LCD_COLOR also applies to Yourduino LCD display
HH-12 elevation bug fix
FEATURE_MASTER_WITH_SERIAL_SLAVE
FEATURE_MASTER_WITH_ETHERNET_SLAVE
FEATURE_EL_POSITION_MEMSIC_2125 under development - not working yet
fixed a bug with azimuth and elevation offset zeroing out first decimal place
Ethernet master/slave link!
#define ETHERNET_SLAVE_IP_ADDRESS 192,168,1,173
#define ETHERNET_SLAVE_TCP_PORT 23
#define ETHERNET_SLAVE_RECONNECT_TIME_MS 250
Changed master/slave AZ and EL command result format: AZxxx.xxxxxx EL+xxx.xxxxxx
Slave CL command
OPTION_SYNC_MASTER_CLOCK_TO_SLAVE
fixed "if (clock_status == SLAVE_SYNC) {clock_status = FREE_RUNNING;}" compile error
OPTION_CLOCK_ALWAYS_HAVE_HOUR_LEADING_ZERO
OPTION_DISABLE_HMC5883L_ERROR_CHECKING
HARDWARE_EA4TX_ARS_USB
HARDWARE_M0UPU
rotator_hardware.h file
rotator_features_ea4tx_ars_usb.h
rotator_pins_ea4tx_ars_usb.h
#define AZ_POSITION_INCREMENTAL_ENCODER_PULSES_PER_REV 2000.0
#define EL_POSITION_INCREMENTAL_ENCODER_PULSES_PER_REV 2000.0
FEATURE_EL_POSITION_INCREMENTAL_ENCODER now does 360 degrees of rotation rather than 720
OPTION_PRESET_ENCODER_0_360_DEGREES
service_rotation() - fixed rollover bug with az and el slow down
Fixed decimal place issue with Easycom AZ and EL query commands
FEATURE_EL_POSITION_INCREMENTAL_ENCODER - fixed storage and retrieval of elevation in eeprom
Bug fix - stop command wouldn't work when in slow down
AZ_INITIALLY_IN_SLOW_DOWN_PWM
EL_INITIALLY_IN_SLOW_DOWN_PWM
Fixed compilation error when FEATURE_JOYSTICK_CONTROL is activated and FEATURE_ELEVATION_CONTROL is disabled
FEATURE_ANALOG_OUTPUT_PINS (rotator_features.h) (documented 2015-04-16)
FEATURE_AZ_POSITION_LSM303 is now FEATURE_AZ_POSITION_ADAFRUIT_LSM303 (rotator_features.h) (documented 2015-04-16)
FEATURE_EL_POSITION_LSM303 is now FEATURE_EL_POSITION_ADAFRUIT_LSM303 (rotator_features.h) (documented 2015-04-16)
LANGUAGE_CZECH (rotator_features.h) (documented)
FEATURE_AZ_POSITION_POLOLU_LSM303 (rotator_features.h) (code contributed by AD0CZ) (documented 2015-04-16)
FEATURE_EL_POSITION_POLOLU_LSM303 (rotator_features.h) (documented 2015-04-16)
#define POLOLU_LSM_303_MIN_ARRAY {+59, +19, -731} (rotator_settings.h) (documented 2015-04-16)
#define POLOLU_LSM_303_MAX_ARRAY {+909, +491, +14} (rotator_settings.h) (documented 2015-04-16)
DEBUG_POLOLU_LSM303_CALIBRATION (rotator_features.h)
bug fixed with brake_release() affecting elevation brake (thanks Paolo, IT9IPQ)
LANGUAGE_ITALIAN code donated by Paolo, IT9IPQ
OPTION_DISPLAY_VERSION_ON_STARTUP code provided by Paolo, IT9IPQ
Fixed bug with LANGUAGE_CZECH (thanks Radek, OK2NMA)
Change in Easycom response terminator (now uses whatever command terminator was sent to it)
Easycom AZ EL command string response change to +xxx.xx +xxx.xx
OPTION_HAMLIB_EASYCOM_AZ_EL_COMMAND_HACK
LANGUAGE_PORTUGUESE_BRASIL (thanks Ismael, PY4PI)
check_brake_release() bug fix
configuration.az_stepper_motor_last_direction, configuration.az_stepper_motor_last_pin_state, configuration.el_stepper_motor_last_direction, configuration.el_stepper_motor_last_pin_state
OPTION_HAMLIB_EASYCOM_NO_TERMINATOR_CHARACTER_HACK ; HARDWARE_WB6KCN
FEATURE_STEPPER_MOTOR_EXPERIMENTAL_CODE_2
AZ_INCREMENTAL_ENCODER_ZERO_PULSE_POSITION
EL_INCREMENTAL_ENCODER_ZERO_PULSE_POSITION
OPTION_BLINK_OVERLAP_LED and OPTION_OVERLAP_LED_BLINK_MS setting
FEATURE_SUN_PUSHBUTTON_AZ_EL_CALIBRATION and FEATURE_MOON_PUSHBUTTON_AZ_EL_CALIBRATION; pin_sun_pushbutton_calibration, pin_moon_pushbutton_calibration
Rolled FEATURE_STEPPER_MOTOR_EXPERIMENTAL_CODE_2 into FEATURE_STEPPER_MOTOR
Working on FEATURE_AUTOCORRECT
Bug fix involving FEATURE_AZ_POSITION_HH12_AS5045_SSI and azimuth_offset (thanks Johan, PA3FPQ and Jurgen, PE1LWT)
Bug fix - wasn't initializing rotate_cw_ccw (thanks Erick, WB6KCN)
Bug fix with OPTION_DISPLAY_VERSION_ON_STARTUP and 2 row displays (thanks Gianfranco, IZ8EWD)
OPTION_EL_PULSE_DEBOUNCE code - (thanks Gianfranco, IZ8EWD)
#define EL_POSITION_PULSE_DEBOUNCE 500 // in ms
OPTION_HH12_10_BIT_READINGS in hh12.h (thanks Johan PA3FPQ)
Correction from Johan PA3FPQ on OPTION_HH12_10_BIT_READINGS
#define BRAKE_ACTIVE_STATE HIGH
#define BRAKE_INACTIVE_STATE LOW
OPTION_SCANCON_2RMHF3600_INC_ENCODER - thanks Jasper, PA2J
Fixed compile bug with OPTION_EL_MANUAL_ROTATE_LIMITS) when FEATURE_ELEVATION_CONTROL is not enabled
Eliminated az_stepper_motor_direction and el_stepper_motor_direction. Use rotate_* pins instead!
Self-resetting functionality
Fixed bug with OPTION_DISPLAY_DIRECTION_STATUS updating
Improved the self reset with a non-blocking 5 second delay
Added remote slave commands:
RC - read coordinates (returns RCxx.xxxx -xxx.xxxx)
GS - query GPS status (returns GS0 (no sync) or GS1 (sync))
OPTION_SYNC_MASTER_COORDINATES_TO_SLAVE
reset_pin
Updated for Arduino 1.6.1
Fixed compilation issue with FEATURE_ELEVATION_CORRECTION and Arduino 1.6.x
OPTION_RESET_METHOD_JMP_ASM_0
Change /E command to do setup() for system reset
Fixed calculation issues with FEATURE_ELEVATION_CORRECTION
Fixed bug with FEATURE_AZIMUTH_CORRECTION and FEATURE_ELEVATION_CORRECTION rounding off to nearest degree
2.0.2015040401 Changed configuration.azimuth_offset to use raw_azimuth rather than azimuth for calculation
2.0.2015040402 Fixed bug with compiling FEATURE_MASTER_WITH_ETHERNET_SLAVE without FEATURE_CLOCK
2.0.2015050401 Fixed bug with WNW being display on LCD direction indicator rather than WSW (Thanks Radek, OK2NMA)
2.0.2015051301
Fixed bug with remote slave AZ and EL commands not returning decimal places (i.e. xxx.000000)
Working on remote unit double backslash commands
2.0.2015051901 LANGUAGE_GERMAN (Thanks Ronny, DM2RM) (documented in wiki)
2.0.2015052501
Working on SEI Bus and A2 Encoders
Working on remote unit double backslash commands
2.0.2015061601
Working on converting over LCD display code to k3ngdisplay library
#define DISPLAY_DEGREES_STRING "\xDF"
last_az_incremental_encoder_position & az_incremental_encoder_position changed to long
k3ng_remote_rotator_controller class
2.0.2015070301
Fixed compile error involving clock_temp_string in display code when compiling multiple clock display widgets is attempted
Still working on new display code and local/remote unit code
2.0.2015070302
FEATURE_AZ_POSITION_INCREMENTAL_ENCODER conversion to long data types (Thanks Daniel Cussen)
2.0.2015070401
gps_sync pin bug fixed
2.0.2015071201
FEATURE_YWROBOT_I2C_DISPLAY (code provided by Máximo EA1DDO)
2.0.2015071701
FEATURE_AZ_POSITION_INCREMENTAL_ENCODER code fixed (Thanks Daniel Cussen)
2.0.2015090401
Breaking out portions of ino file into .h files...
#include "rotator_clock_and_gps.h"
#include "rotator_command_processing.h"
#include "rotator_moon_and_sun.h"
#include "rotator_ethernet.h"
#include "rotator_stepper.h"
2.0.2015090402
#include "rotator_language.h"
OPTION_SAVE_MEMORY_EXCLUDE_REMOTE_CMDS
/?FS command - Full Status Report
2.0.2015090601
Updates to rotator_language.h
Fixed k3ngdisplay.h / LiquidCrystal.h compilation problems with Arduino IDE
Integrated DebugClass (debug.h and debug.cpp) contributed from Matt VK5ZM
2.0.2015092001
LANGUAGE_FRENCH (contributed by Marc-Andre, VE2EVN)
fixed issue with rotator_analog_az inferring with other pins if defined but not used
2.0.2015092002
Fixed issue with compiling DEBUG_GPS
*/
#define CODE_VERSION "2.0.2015092002"
#include <avr/pgmspace.h>
#include <EEPROM.h>
#include <math.h>
#include <avr/wdt.h>
#include "rotator_hardware.h"
#ifdef HARDWARE_EA4TX_ARS_USB
#include "rotator_features_ea4tx_ars_usb.h"
#endif
#ifdef HARDWARE_WB6KCN
#include "rotator_features_wb6kcn.h"
#endif
#ifdef HARDWARE_M0UPU
#include "rotator_features_m0upu.h"
#endif
#ifdef HARDWARE_TEST
#include "rotator_features_test.h"
#endif
#if !defined(HARDWARE_CUSTOM)
#include "rotator_features.h"
#endif
#include "rotator_dependencies.h"
#include "debug.h"
#ifdef FEATURE_4_BIT_LCD_DISPLAY
#include <LiquidCrystal.h> // required for classic 4 bit interface LCD display (FEATURE_4_BIT_LCD_DISPLAY)
#endif // FEATURE_4_BIT_LCD_DISPLAY
#if defined(FEATURE_ADAFRUIT_I2C_LCD)
#include <Adafruit_MCP23017.h> // required for Adafruit I2C LCD display
#include <Adafruit_RGBLCDShield.h> // required for Adafruit I2C LCD display
#endif
#if defined(FEATURE_YOURDUINO_I2C_LCD) || defined(FEATURE_RFROBOT_I2C_DISPLAY)
#include <LiquidCrystal_I2C.h> // required for YourDuino.com or DFRobot I2C LCD display
#endif
#if defined(FEATURE_YOURDUINO_I2C_LCD)
#include <LCD.h> // required for YourDuino.com I2C LCD display
#endif
#ifdef FEATURE_LCD_DISPLAY
#include "k3ngdisplay.h" // if you're getting an error on this line when compiling, you probably need to move k3ngdisplay.h and k3ngdisplay.cpp to your ino directory
#endif
#ifdef FEATURE_WIRE_SUPPORT
#include <Wire.h> // required for FEATURE_I2C_LCD, any ADXL345 feature, FEATURE_AZ_POSITION_HMC5883L, FEATURE_EL_POSITION_ADAFRUIT_LSM303
#endif
#if defined(FEATURE_AZ_POSITION_HMC5883L)
#include <HMC5883L.h> // required for HMC5883L digital compass support
#endif
#if defined(FEATURE_EL_POSITION_ADXL345_USING_ADAFRUIT_LIB) || defined(FEATURE_AZ_POSITION_ADAFRUIT_LSM303) || defined(FEATURE_EL_POSITION_ADAFRUIT_LSM303)
#include <Adafruit_Sensor.h> // required for any Adafruit sensor libraries
#endif
#if defined(FEATURE_EL_POSITION_ADXL345_USING_LOVE_ELECTRON_LIB)
#include <ADXL345.h> // required for elevation ADXL345 accelerometer using Love Electronics ADXL345 library
#endif
#if defined(FEATURE_EL_POSITION_ADXL345_USING_ADAFRUIT_LIB)
#include <Adafruit_ADXL345_U.h> // required for elevation ADXL345 accelerometer using Adafruit ADXL345 library (FEATURE_EL_POSITION_ADXL345_USING_ADAFRUIT_LIB)
#endif
#if defined(FEATURE_EL_POSITION_ADAFRUIT_LSM303) || defined(FEATURE_AZ_POSITION_ADAFRUIT_LSM303)
#include <Adafruit_LSM303.h> // required for azimuth and/or elevation using LSM303 compass and/or accelerometer
#endif
#ifdef FEATURE_AZ_POSITION_POLOLU_LSM303
#include <LSM303.h>
#endif
#if defined(FEATURE_MOON_TRACKING) || defined(FEATURE_SUN_TRACKING)
#include "moon2.h"
#endif // defined(FEATURE_MOON_TRACKING) || defined(FEATURE_SUN_TRACKING)
#ifdef FEATURE_SUN_TRACKING
#include "sunpos.h"
#endif // FEATURE_SUN_TRACKING
#ifdef FEATURE_GPS
#include "TinyGPS.h"
#endif // FEATURE_GPS
#ifdef FEATURE_RTC_DS1307
#include "RTClib.h"
#endif // FEATURE_RTC_DS1307
#ifdef FEATURE_RTC_PCF8583
#include "PCF8583.h"
#endif //FEATURE_RTC_PCF8583
#ifdef FEATURE_ETHERNET
#include "SPI.h"
#include "Ethernet.h"
#endif
#include "rotator.h"
#ifdef HARDWARE_EA4TX_ARS_USB
#include "rotator_pins_ea4tx_ars_usb.h"
#endif
#ifdef HARDWARE_M0UPU
#include "rotator_pins_m0upu.h"
#endif
#ifdef HARDWARE_WB6KCN
#include "rotator_pins_wb6kcn.h"
#endif
#ifdef HARDWARE_TEST
#include "rotator_pins_test.h"
#endif
#if !defined(HARDWARE_CUSTOM)
#include "rotator_pins.h"
#endif
#ifdef HARDWARE_EA4TX_ARS_USB
#include "rotator_settings_ea4tx_ars_usb.h"
#endif
#ifdef HARDWARE_WB6KCN
#include "rotator_settings_wb6kcn.h"
#endif
#ifdef HARDWARE_M0UPU
#include "rotator_settings_m0upu.h"
#endif
#ifdef HARDWARE_TEST
#include "rotator_settings_test.h"
#endif
#if !defined(HARDWARE_CUSTOM)
#include "rotator_settings.h"
#endif
#ifdef FEATURE_STEPPER_MOTOR
#include "TimerFive.h"
#endif
/*----------------------- variables -------------------------------------*/
#define AZIMUTH_STARTING_POINT_DEFAULT 0
byte incoming_serial_byte = 0;
byte reset_the_unit = 0;
#ifdef FEATURE_TWO_DECIMAL_PLACE_HEADINGS
long azimuth = 0;
long raw_azimuth = 0;
long target_azimuth = 0;
long target_raw_azimuth = 0;
long azimuth_starting_point = AZIMUTH_STARTING_POINT_DEFAULT;
long azimuth_rotation_capability = AZIMUTH_ROTATION_CAPABILITY_DEFAULT;
#else
int azimuth = 0;
int raw_azimuth = 0;
int target_azimuth = 0;
int target_raw_azimuth = 0;
int azimuth_starting_point = AZIMUTH_STARTING_POINT_DEFAULT;
int azimuth_rotation_capability = AZIMUTH_ROTATION_CAPABILITY_DEFAULT;
#endif
byte control_port_buffer[COMMAND_BUFFER_SIZE];
int control_port_buffer_index = 0;
byte az_state = IDLE;
byte debug_mode = DEFAULT_DEBUG_STATE;
int analog_az = 0;
unsigned long last_debug_output_time = 0;
unsigned long az_last_rotate_initiation = 0;
byte azimuth_button_was_pushed = 0;
byte brake_az_engaged = 0;
byte brake_el_engaged = 0;
byte configuration_dirty = 0;
unsigned long last_serial_receive_time = 0;
byte az_slowstart_active = AZ_SLOWSTART_DEFAULT;
byte az_slowdown_active = AZ_SLOWDOWN_DEFAULT;
byte az_request = 0;
int az_request_parm = 0;
byte az_request_queue_state = NONE;
unsigned long az_slowstart_start_time = 0;
byte az_slow_start_step = 0;
unsigned long az_last_step_time = 0;
byte az_slow_down_step = 0;
unsigned long az_timed_slow_down_start_time = 0;
byte backslash_command = 0;
struct config_t {
byte magic_number;
int analog_az_full_ccw;
int analog_az_full_cw;
int analog_el_0_degrees;
int analog_el_max_elevation;
float last_azimuth;
float last_elevation;
//int last_az_incremental_encoder_position;
long last_az_incremental_encoder_position;
int last_el_incremental_encoder_position;
float azimuth_offset;
float elevation_offset;
byte az_stepper_motor_last_pin_state;
byte el_stepper_motor_last_pin_state;
byte az_stepper_motor_last_direction;
byte el_stepper_motor_last_direction;
} configuration;
#ifdef FEATURE_TIMED_BUFFER
int timed_buffer_azimuths[TIMED_INTERVAL_ARRAY_SIZE];
int timed_buffer_number_entries_loaded = 0;
int timed_buffer_entry_pointer = 0;
int timed_buffer_interval_value_seconds = 0;
unsigned long last_timed_buffer_action_time = 0;
byte timed_buffer_status = EMPTY;
#endif // FEATURE_TIMED_BUFFER
byte normal_az_speed_voltage = 0;
byte current_az_speed_voltage = 0;
#ifdef FEATURE_ELEVATION_CONTROL
int elevation = 0;
int target_elevation = 0;
byte el_request = 0;
int el_request_parm = 0;
byte el_request_queue_state = NONE;
byte el_slowstart_active = EL_SLOWSTART_DEFAULT;
byte el_slowdown_active = EL_SLOWDOWN_DEFAULT;
unsigned long el_slowstart_start_time = 0;
byte el_slow_start_step = 0;
unsigned long el_last_step_time = 0;
byte el_slow_down_step = 0;
unsigned long el_timed_slow_down_start_time = 0;
byte normal_el_speed_voltage = 0;
byte current_el_speed_voltage = 0;
int display_elevation = 0;
byte el_state = IDLE;
int analog_el = 0;
unsigned long el_last_rotate_initiation = 0;
#ifdef FEATURE_TIMED_BUFFER
int timed_buffer_elevations[TIMED_INTERVAL_ARRAY_SIZE];
#endif // FEATURE_TIMED_BUFFER
byte elevation_button_was_pushed = 0;
#endif // FEATURE_ELEVATION_CONTROL
#if defined(FEATURE_LCD_DISPLAY)
byte push_lcd_update = 0;
#endif // FEATURE_LCD_DISPLAY
#ifdef FEATURE_ROTARY_ENCODER_SUPPORT
#ifdef OPTION_ENCODER_HALF_STEP_MODE // Use the half-step state table (emits a code at 00 and 11)
const unsigned char ttable[6][4] = {
{ 0x3, 0x2, 0x1, 0x0 }, { 0x23, 0x0, 0x1, 0x0 },
{ 0x13, 0x2, 0x0, 0x0 }, { 0x3, 0x5, 0x4, 0x0 },
{ 0x3, 0x3, 0x4, 0x10 }, { 0x3, 0x5, 0x3, 0x20 }
};
#else // Use the full-step state table (emits a code at 00 only)
const unsigned char ttable[7][4] = {
{ 0x0, 0x2, 0x4, 0x0 }, { 0x3, 0x0, 0x1, 0x10 },
{ 0x3, 0x2, 0x0, 0x0 }, { 0x3, 0x2, 0x1, 0x0 },
{ 0x6, 0x0, 0x4, 0x0 }, { 0x6, 0x5, 0x0, 0x10 },
{ 0x6, 0x5, 0x4, 0x0 },
};
#endif // OPTION_ENCODER_HALF_STEP_MODE
#ifdef FEATURE_AZ_PRESET_ENCODER // Rotary Encoder State Tables
#if defined(FEATURE_ONE_DECIMAL_PLACE_HEADINGS) || defined(FEATURE_TWO_DECIMAL_PLACE_HEADINGS)
double az_encoder_raw_degrees = 0;
#else
int az_encoder_raw_degrees = 0;
#endif
volatile unsigned char az_encoder_state = 0;
#ifdef FEATURE_EL_PRESET_ENCODER
volatile unsigned char el_encoder_state = 0;
#if defined(FEATURE_ONE_DECIMAL_PLACE_HEADINGS) || defined(FEATURE_TWO_DECIMAL_PLACE_HEADINGS)
double el_encoder_degrees = 0;
#else
int el_encoder_degrees = 0;
#endif
#endif // FEATURE_EL_PRESET_ENCODER
byte preset_encoders_state = ENCODER_IDLE;
#endif // FEATURE_AZ_PRESET_ENCODER
#endif // FEATURE_ROTARY_ENCODER_SUPPORT
#ifdef DEBUG_PROFILE_LOOP_TIME
float average_loop_time = 0;
#endif // DEBUG_PROFILE_LOOP_TIME
#ifdef FEATURE_AZ_POSITION_PULSE_INPUT
volatile float az_position_pulse_input_azimuth = 0;
volatile byte last_known_az_state = 0;
#endif // FEATURE_AZ_POSITION_PULSE_INPUT
#ifdef FEATURE_EL_POSITION_PULSE_INPUT
volatile float el_position_pulse_input_elevation = 0;
volatile byte last_known_el_state = 0;
#ifdef OPTION_EL_PULSE_DEBOUNCE
unsigned long last_el_pulse_debounce = 0;
#endif //OPTION_EL_PULSE_DEBOUNCE
#endif // FEATURE_EL_POSITION_PULSE_INPUT
#if defined(FEATURE_REMOTE_UNIT_SLAVE) || defined(FEATURE_MASTER_WITH_SERIAL_SLAVE)
byte serial_read_event_flag[] = { 0, 0, 0, 0, 0 };
byte control_port_buffer_carriage_return_flag = 0;
#endif
#if defined(FEATURE_MASTER_WITH_SERIAL_SLAVE) || defined(FEATURE_MASTER_WITH_ETHERNET_SLAVE)
byte remote_unit_port_buffer[COMMAND_BUFFER_SIZE];
int remote_unit_port_buffer_index = 0;
byte remote_unit_port_buffer_carriage_return_flag = 0;
unsigned long serial1_last_receive_time = 0;
byte remote_unit_command_submitted = 0;
unsigned long last_remote_unit_command_time = 0;
unsigned int remote_unit_command_timeouts = 0;
unsigned int remote_unit_bad_results = 0;
unsigned long remote_unit_good_results = 0;
unsigned int remote_unit_incoming_buffer_timeouts = 0;
byte remote_unit_command_results_available = 0;
float remote_unit_command_result_float = 0;
byte remote_port_rx_sniff = 0;
byte remote_port_tx_sniff = 0;
byte suspend_remote_commands = 0;
#if defined(OPTION_SYNC_MASTER_CLOCK_TO_SLAVE) && defined(FEATURE_CLOCK)
byte clock_synced_to_remote = 0;
#endif
#endif //FEATURE_MASTER_WITH_SERIAL_SLAVE
#ifdef DEBUG_POSITION_PULSE_INPUT
// unsigned int az_position_pule_interrupt_handler_flag = 0;
// unsigned int el_position_pule_interrupt_handler_flag = 0;
volatile unsigned long az_pulse_counter = 0;
volatile unsigned long el_pulse_counter = 0;
volatile unsigned int az_pulse_counter_ambiguous = 0;
volatile unsigned int el_pulse_counter_ambiguous = 0;
#endif // DEBUG_POSITION_PULSE_INPUT
#ifdef FEATURE_PARK
byte park_status = NOT_PARKED;
byte park_serial_initiated = 0;
#endif // FEATURE_PARK
#ifdef FEATURE_AZ_POSITION_INCREMENTAL_ENCODER
volatile long az_incremental_encoder_position = 0;
volatile byte az_3_phase_encoder_last_phase_a_state = 0;
volatile byte az_3_phase_encoder_last_phase_b_state = 0;
#ifdef DEBUG_AZ_POSITION_INCREMENTAL_ENCODER
volatile long az_position_incremental_encoder_interrupt = 0;
#endif // DEBUG_AZ_POSITION_INCREMENTAL_ENCODER
#endif // FEATURE_AZ_POSITION_INCREMENTAL_ENCODER
#ifdef FEATURE_EL_POSITION_INCREMENTAL_ENCODER
volatile long el_incremental_encoder_position = 0;
volatile byte el_3_phase_encoder_last_phase_a_state = 0;
volatile byte el_3_phase_encoder_last_phase_b_state = 0;
#ifdef DEBUG_EL_POSITION_INCREMENTAL_ENCODER
volatile long el_position_incremental_encoder_interrupt = 0;
#endif // DEBUG_EL_POSITION_INCREMENTAL_ENCODER
#endif // FEATURE_EL_POSITION_INCREMENTAL_ENCODER
#ifdef FEATURE_AZ_POSITION_INCREMENTAL_ENCODER
volatile byte read_azimuth_lock = 0;
#endif
#ifdef FEATURE_EL_POSITION_INCREMENTAL_ENCODER
volatile byte read_elevation_lock = 0;
#endif
#if defined(FEATURE_AZ_POSITION_INCREMENTAL_ENCODER) || defined(FEATURE_EL_POSITION_INCREMENTAL_ENCODER)
volatile byte service_rotation_lock = 0;
#endif
#if defined(FEATURE_REMOTE_UNIT_SLAVE) || defined(FEATURE_YAESU_EMULATION) || defined(FEATURE_EASYCOM_EMULATION) || defined(FEATURE_CLOCK) || defined(UNDER_DEVELOPMENT_REMOTE_UNIT_COMMANDS)
HardwareSerial * control_port;
#endif
#if defined(FEATURE_MASTER_WITH_SERIAL_SLAVE)
HardwareSerial * remote_unit_port;
#endif
#if defined(FEATURE_GPS)
HardwareSerial * gps_port;
#ifdef GPS_MIRROR_PORT
HardwareSerial * (gps_mirror_port);
#endif //GPS_MIRROR_PORT
#endif //defined(FEATURE_GPS)
#if defined(FEATURE_MOON_TRACKING) || defined(FEATURE_SUN_TRACKING) || defined(FEATURE_CLOCK) || (defined(FEATURE_GPS) && defined(FEATURE_REMOTE_UNIT_SLAVE))
double latitude = DEFAULT_LATITUDE;
double longitude = DEFAULT_LONGITUDE;
#endif
#ifdef FEATURE_MOON_TRACKING
byte moon_tracking_active = 0;
byte moon_visible = 0;
double moon_azimuth = 0;
double moon_elevation = 0;
#endif // FEATURE_MOON_TRACKING
#ifdef FEATURE_SUN_TRACKING
float sun_azimuth = 0;
float sun_elevation = 0;
cTime c_time;
cLocation c_loc;
cSunCoordinates c_sposn;
byte sun_visible = 0;
byte sun_tracking_active = 0;
#endif // FEATURE_SUN_TRACKING
#ifdef FEATURE_CLOCK
unsigned long clock_years = 0;
unsigned long clock_months = 0;
unsigned long clock_days = 0;
unsigned long clock_hours = 0;
unsigned long clock_minutes = 0;
unsigned long clock_seconds = 0;
int clock_year_set = 2014;
byte clock_month_set = 1;
byte clock_day_set = 1;
byte clock_sec_set = 0;
unsigned long clock_hour_set = 0;
unsigned long clock_min_set = 0;
unsigned long millis_at_last_calibration = 0;
#endif // FEATURE_CLOCK
#if defined(FEATURE_GPS) || defined(FEATURE_RTC) || defined(FEATURE_CLOCK)
byte clock_status = FREE_RUNNING;
#endif // defined(FEATURE_GPS) || defined(FEATURE_RTC)
#ifdef FEATURE_GPS
byte gps_data_available = 0;
#endif // FEATURE_GPS
#ifdef FEATURE_ETHERNET
byte mac[] = {ETHERNET_MAC_ADDRESS};
IPAddress ip(ETHERNET_IP_ADDRESS);
IPAddress gateway(ETHERNET_IP_GATEWAY);
IPAddress subnet(ETHERNET_IP_SUBNET_MASK);
EthernetClient ethernetclient0;
EthernetServer ethernetserver0(ETHERNET_TCP_PORT_0);
#ifdef ETHERNET_TCP_PORT_1
EthernetClient ethernetclient1;
EthernetServer ethernetserver1(ETHERNET_TCP_PORT_1);
#endif //ETHERNET_TCP_PORT_1
#ifdef FEATURE_MASTER_WITH_ETHERNET_SLAVE
EthernetClient ethernetslavelinkclient0;
IPAddress slave_unit_ip(ETHERNET_SLAVE_IP_ADDRESS);
byte ethernetslavelinkclient0_state = ETHERNET_SLAVE_DISCONNECTED;
unsigned int ethernet_slave_reconnects = 0;
#endif //FEATURE_MASTER_WITH_ETHERNET_SLAVE
#endif //FEATURE_ETHERNET
#ifdef FEATURE_POWER_SWITCH
unsigned long last_activity_time = 0;
#endif //FEATURE_POWER_SWITCH
#ifdef FEATURE_STEPPER_MOTOR
volatile unsigned int az_stepper_freq_count = 0;
#ifdef FEATURE_ELEVATION_CONTROL
volatile unsigned int el_stepper_freq_count = 0;
#endif //FEATURE_ELEVATION_CONTROL
volatile unsigned long service_stepper_motor_pulse_pins_count = 0;
#endif //FEATURE_STEPPER_MOTOR
#ifdef FEATURE_AZIMUTH_CORRECTION
float azimuth_calibration_from[] = AZIMUTH_CALIBRATION_FROM_ARRAY;
float azimuth_calibration_to[] = AZIMUTH_CALIBRATION_TO_ARRAY;
#endif // FEATURE_AZIMUTH_CORRECTION
#ifdef FEATURE_ELEVATION_CORRECTION
float elevation_calibration_from[] = ELEVATION_CALIBRATION_FROM_ARRAY;
float elevation_calibration_to[] = ELEVATION_CALIBRATION_TO_ARRAY;
#endif // FEATURE_ELEVATION_CORRECTION
#ifdef FEATURE_AUTOCORRECT
byte autocorrect_state_az = AUTOCORRECT_INACTIVE;
float autocorrect_az = 0;
unsigned long autocorrect_az_submit_time = 0;
#ifdef FEATURE_ELEVATION_CONTROL
byte autocorrect_state_el = AUTOCORRECT_INACTIVE;
float autocorrect_el = 0;
unsigned long autocorrect_el_submit_time = 0;
#endif //FEATURE_ELEVATION_CONTROL
#endif //FEATURE_AUTOCORRECT
#ifdef FEATURE_AZ_POSITION_A2_ABSOLUTE_ENCODER
float az_a2_encoder = 0;
#endif //FEATURE_AZ_POSITION_A2_ABSOLUTE_ENCODER
#ifdef FEATURE_EL_POSITION_A2_ABSOLUTE_ENCODER
float el_a2_encoder = 0;
#endif //FEATURE_EL_POSITION_A2_ABSOLUTE_ENCODER
DebugClass debug;
#if defined(FEATURE_4_BIT_LCD_DISPLAY) || defined(FEATURE_ADAFRUIT_I2C_LCD) || defined(FEATURE_YOURDUINO_I2C_LCD) || defined(FEATURE_YWROBOT_I2C_DISPLAY)
K3NGdisplay k3ngdisplay(LCD_COLUMNS,LCD_ROWS,LCD_UPDATE_TIME);
#endif
#ifdef FEATURE_AZ_POSITION_HMC5883L
HMC5883L compass;
#endif //FEATURE_AZ_POSITION_HMC5883L
#ifdef FEATURE_EL_POSITION_ADXL345_USING_LOVE_ELECTRON_LIB
ADXL345 accel;
#endif //FEATURE_EL_POSITION_ADXL345_USING_LOVE_ELECTRON_LIB
#ifdef FEATURE_EL_POSITION_ADXL345_USING_ADAFRUIT_LIB
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
#endif //FEATURE_EL_POSITION_ADXL345_USING_ADAFRUIT_LIB
#if defined(FEATURE_EL_POSITION_ADAFRUIT_LSM303) || defined(FEATURE_AZ_POSITION_ADAFRUIT_LSM303)
Adafruit_LSM303 lsm;
#endif
#if defined(FEATURE_AZ_POSITION_POLOLU_LSM303) || defined(FEATURE_EL_POSITION_POLOLU_LSM303)
LSM303 compass;
LSM303::vector<int16_t> running_min = {32767, 32767, 32767}, running_max = {-32768, -32768, -32768};
char report[80];
#endif //FEATURE_AZ_POSITION_POLOLU_LSM303
#ifdef FEATURE_AZ_POSITION_HH12_AS5045_SSI
#include "hh12.h"
hh12 azimuth_hh12;
#endif //FEATURE_AZ_POSITION_HH12_AS5045_SSI
#ifdef FEATURE_EL_POSITION_HH12_AS5045_SSI
#include "hh12.h"
hh12 elevation_hh12;
#endif //FEATURE_EL_POSITION_HH12_AS5045_SSI
#ifdef FEATURE_GPS
TinyGPS gps;
#endif //FEATURE_GPS
#ifdef FEATURE_RTC_DS1307
RTC_DS1307 rtc;
#endif //FEATURE_RTC_DS1307
#ifdef FEATURE_RTC_PCF8583
PCF8583 rtc(0xA0);
#endif //FEATURE_RTC_PCF8583
#ifdef HARDWARE_EA4TX_ARS_USB
#undef LCD_COLUMNS
#undef LCD_ROWS
#define LCD_COLUMNS 16
#define LCD_ROWS 2
#endif //HARDWARE_EA4TX_ARS_USB
#ifdef HARDWARE_M0UPU
#undef LCD_ROWS
#define LCD_ROWS 2
#endif //HARDWARE_M0UPU
#ifdef FEATURE_AZ_POSITION_A2_ABSOLUTE_ENCODER
#define AZ_A2_ENCODER_RESOLUTION 32767 /*36000*/
#define AZ_A2_ENCODER_ADDRESS 0x00
#define AZ_QUERY_FREQUENCY_MS 250
#define AZ_A2_ENCODER_MODE MODE_TWO_BYTE_POSITION /*|MODE_MULTITURN*/
#endif //FEATURE_AZ_POSITION_A2_ABSOLUTE_ENCODER