-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAurora.ino
1504 lines (1364 loc) · 44.2 KB
/
Aurora.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
#include "EmonLib.h"
#include <Thread.h>
#include <Wire.h>
#include <TimeLib.h>
#include <SoftwareSerial.h>
//RS485 control
#define SSerialTxControl 5
#define RS485Transmit HIGH
#define RS485Receive LOW
SoftwareSerial serDebug(10, 11); // RX, TX
void serDebugPrintData(byte *data) {
for (int i = 0; i < 8; i++) {
serDebug.print((int)data[i]);
serDebug.print(F(" "));
}
serDebug.println(F(" "));
}
class clsBottone {
private:
int Pin;
unsigned long lastDebounceTime = 0;
long debounceDelay = 250;
byte buttonState = 0;
byte lastButtonState = 0;
byte State = 0;
public:
clsBottone(int _Pin) {
Pin = _Pin;
pinMode(Pin, INPUT);
}
byte Stato() {
byte ret = State;
State = 0;
return ret;
}
void Aggiorna() {
unsigned long currentTime = millis();
byte reading = 0;
switch (analogRead(Pin)) {
case 0: // SWx
reading = 3;
break;
case 847:
case 848:
case 849: // SW1
reading = 1;
break;
case 682:
case 683:
case 684: // SW2
reading = 2;
break;
}
if (reading != lastButtonState) {
lastButtonState = reading;
lastDebounceTime = currentTime;
}
else if ((currentTime - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
State = reading;
}
}
}
};
class clsAurora {
private:
int MaxAttempt = 1;
byte Address = 0;
void clearData(byte *data, byte len) {
for (int i = 0; i < len; i++) {
data[i] = 0;
}
}
int Crc16(byte *data, int offset, int count)
{
byte BccLo = 0xFF;
byte BccHi = 0xFF;
for (int i = offset; i < (offset + count); i++)
{
byte New = data[offset + i] ^ BccLo;
byte Tmp = New << 4;
New = Tmp ^ New;
Tmp = New >> 5;
BccLo = BccHi;
BccHi = New ^ Tmp;
Tmp = New << 3;
BccLo = BccLo ^ Tmp;
Tmp = New >> 4;
BccLo = BccLo ^ Tmp;
}
return (int)word(~BccHi, ~BccLo);
}
bool Send(byte address, byte param0, byte param1, byte param2, byte param3, byte param4, byte param5, byte param6)
{
SendStatus = false;
ReceiveStatus = false;
byte SendData[10];
SendData[0] = address;
SendData[1] = param0;
SendData[2] = param1;
SendData[3] = param2;
SendData[4] = param3;
SendData[5] = param4;
SendData[6] = param5;
SendData[7] = param6;
int crc = Crc16(SendData, 0, 8);
SendData[8] = lowByte(crc);
SendData[9] = highByte(crc);
clearReceiveData();
for (int i = 0; i < MaxAttempt; i++)
{
digitalWrite(SSerialTxControl, RS485Transmit);
delay(50);
if (Serial.write(SendData, sizeof(SendData)) != 0) {
Serial.flush();
SendStatus = true;
digitalWrite(SSerialTxControl, RS485Receive);
if (Serial.readBytes(ReceiveData, sizeof(ReceiveData)) != 0) {
if ((int)word(ReceiveData[7], ReceiveData[6]) == Crc16(ReceiveData, 0, 6)) {
ReceiveStatus = true;
break;
}
}
}
}
return ReceiveStatus;
}
union {
byte asBytes[4];
float asFloat;
} foo;
union {
byte asBytes[4];
unsigned long asUlong;
} ulo;
public:
bool SendStatus = false;
bool ReceiveStatus = false;
byte ReceiveData[8];
clsAurora(byte address) {
Address = address;
SendStatus = false;
ReceiveStatus = false;
clearReceiveData();
}
void clearReceiveData() {
clearData(ReceiveData, 8);
}
String TransmissionState(byte id) {
switch (id)
{
case 0:
return F("Everything is OK.");
break;
case 51:
return F("Command is not implemented");
break;
case 52:
return F("Variable does not exist");
break;
case 53:
return F("Variable value is out of range");
break;
case 54:
return F("EEprom not accessible");
break;
case 55:
return F("Not Toggled Service Mode");
break;
case 56:
return F("Can not send the command to internal micro");
break;
case 57:
return F("Command not Executed");
break;
case 58:
return F("The variable is not available, retry");
break;
default:
return F("Sconosciuto");
break;
}
}
String GlobalState(byte id) {
switch (id)
{
case 0:
return F("Sending Parameters");
break;
case 1:
return F("Wait Sun / Grid");
break;
case 2:
return F("Checking Grid");
break;
case 3:
return F("Measuring Riso");
break;
case 4:
return F("DcDc Start");
break;
case 5:
return F("Inverter Start");
break;
case 6:
return F("Run");
break;
case 7:
return F("Recovery");
break;
case 8:
return F("Pausev");
break;
case 9:
return F("Ground Fault");
break;
case 10:
return F("OTH Fault");
break;
case 11:
return F("Address Setting");
break;
case 12:
return F("Self Test");
break;
case 13:
return F("Self Test Fail");
break;
case 14:
return F("Sensor Test + Meas.Riso");
break;
case 15:
return F("Leak Fault");
break;
case 16:
return F("Waiting for manual reset");
break;
case 17:
return F("Internal Error E026");
break;
case 18:
return F("Internal Error E027");
break;
case 19:
return F("Internal Error E028");
break;
case 20:
return F("Internal Error E029");
break;
case 21:
return F("Internal Error E030");
break;
case 22:
return F("Sending Wind Table");
break;
case 23:
return F("Failed Sending table");
break;
case 24:
return F("UTH Fault");
break;
case 25:
return F("Remote OFF");
break;
case 26:
return F("Interlock Fail");
break;
case 27:
return F("Executing Autotest");
break;
case 30:
return F("Waiting Sun");
break;
case 31:
return F("Temperature Fault");
break;
case 32:
return F("Fan Staucked");
break;
case 33:
return F("Int.Com.Fault");
break;
case 34:
return F("Slave Insertion");
break;
case 35:
return F("DC Switch Open");
break;
case 36:
return F("TRAS Switch Open");
break;
case 37:
return F("MASTER Exclusion");
break;
case 38:
return F("Auto Exclusion");
break;
case 98:
return F("Erasing Internal EEprom");
break;
case 99:
return F("Erasing External EEprom");
break;
case 100:
return F("Counting EEprom");
break;
case 101:
return F("Freeze");
default:
return F("Sconosciuto");
break;
}
}
String DcDcState(byte id) {
switch (id)
{
case 0:
return F("DcDc OFF");
break;
case 1:
return F("Ramp Start");
break;
case 2:
return F("MPPT");
break;
case 3:
return F("Not Used");
break;
case 4:
return F("Input OC");
break;
case 5:
return F("Input UV");
break;
case 6:
return F("Input OV");
break;
case 7:
return F("Input Low");
break;
case 8:
return F("No Parameters");
break;
case 9:
return F("Bulk OV");
break;
case 10:
return F("Communication Error");
break;
case 11:
return F("Ramp Fail");
break;
case 12:
return F("Internal Error");
break;
case 13:
return F("Input mode Error");
break;
case 14:
return F("Ground Fault");
break;
case 15:
return F("Inverter Fail");
break;
case 16:
return F("DcDc IGBT Sat");
break;
case 17:
return F("DcDc ILEAK Fail");
break;
case 18:
return F("DcDc Grid Fail");
break;
case 19:
return F("DcDc Comm.Error");
break;
default:
return F("Sconosciuto");
break;
}
}
String InverterState(byte id) {
switch (id)
{
case 0:
return F("Stand By");
break;
case 1:
return F("Checking Grid");
break;
case 2:
return F("Run");
break;
case 3:
return F("Bulk OV");
break;
case 4:
return F("Out OC");
break;
case 5:
return F("IGBT Sat");
break;
case 6:
return F("Bulk UV");
break;
case 7:
return F("Degauss Error");
break;
case 8:
return F("No Parameters");
break;
case 9:
return F("Bulk Low");
break;
case 10:
return F("Grid OV");
break;
case 11:
return F("Communication Error");
break;
case 12:
return F("Degaussing");
break;
case 13:
return F("Starting");
break;
case 14:
return F("Bulk Cap Fail");
break;
case 15:
return F("Leak Fail");
break;
case 16:
return F("DcDc Fail");
break;
case 17:
return F("Ileak Sensor Fail");
break;
case 18:
return F("SelfTest: relay inverter");
break;
case 19:
return F("SelfTest : wait for sensor test");
break;
case 20:
return F("SelfTest : test relay DcDc + sensor");
break;
case 21:
return F("SelfTest : relay inverter fail");
break;
case 22:
return F("SelfTest timeout fail");
break;
case 23:
return F("SelfTest : relay DcDc fail");
break;
case 24:
return F("Self Test 1");
break;
case 25:
return F("Waiting self test start");
break;
case 26:
return F("Dc Injection");
break;
case 27:
return F("Self Test 2");
break;
case 28:
return F("Self Test 3");
break;
case 29:
return F("Self Test 4");
break;
case 30:
return F("Internal Error");
break;
case 31:
return F("Internal Error");
break;
case 40:
return F("Forbidden State");
break;
case 41:
return F("Input UC");
break;
case 42:
return F("Zero Power");
break;
case 43:
return F("Grid Not Present");
break;
case 44:
return F("Waiting Start");
break;
case 45:
return F("MPPT");
break;
case 46:
return F("Grid Fail");
break;
case 47:
return F("Input OC");
break;
default:
return F("Sconosciuto");
break;
}
}
String AlarmState(byte id) {
switch (id)
{
case 0:
return F("No Alarm");
break;
case 1:
return F("Sun Low");
break;
case 2:
return F("Input OC");
break;
case 3:
return F("Input UV");
break;
case 4:
return F("Input OV");
break;
case 5:
return F("Sun Low");
break;
case 6:
return F("No Parameters");
break;
case 7:
return F("Bulk OV");
break;
case 8:
return F("Comm.Error");
break;
case 9:
return F("Output OC");
break;
case 10:
return F("IGBT Sat");
break;
case 11:
return F("Bulk UV");
break;
case 12:
return F("Internal error");
break;
case 13:
return F("Grid Fail");
break;
case 14:
return F("Bulk Low");
break;
case 15:
return F("Ramp Fail");
break;
case 16:
return F("Dc / Dc Fail");
break;
case 17:
return F("Wrong Mode");
break;
case 18:
return F("Ground Fault");
break;
case 19:
return F("Over Temp.");
break;
case 20:
return F("Bulk Cap Fail");
break;
case 21:
return F("Inverter Fail");
break;
case 22:
return F("Start Timeout");
break;
case 23:
return F("Ground Fault");
break;
case 24:
return F("Degauss error");
break;
case 25:
return F("Ileak sens.fail");
break;
case 26:
return F("DcDc Fail");
break;
case 27:
return F("Self Test Error 1");
break;
case 28:
return F("Self Test Error 2");
break;
case 29:
return F("Self Test Error 3");
break;
case 30:
return F("Self Test Error 4");
break;
case 31:
return F("DC inj error");
break;
case 32:
return F("Grid OV");
break;
case 33:
return F("Grid UV");
break;
case 34:
return F("Grid OF");
break;
case 35:
return F("Grid UF");
break;
case 36:
return F("Z grid Hi");
break;
case 37:
return F("Internal error");
break;
case 38:
return F("Riso Low");
break;
case 39:
return F("Vref Error");
break;
case 40:
return F("Error Meas V");
break;
case 41:
return F("Error Meas F");
break;
case 42:
return F("Error Meas Z");
break;
case 43:
return F("Error Meas Ileak");
break;
case 44:
return F("Error Read V");
break;
case 45:
return F("Error Read I");
break;
case 46:
return F("Table fail");
break;
case 47:
return F("Fan Fail");
break;
case 48:
return F("UTH");
break;
case 49:
return F("Interlock fail");
break;
case 50:
return F("Remote Off");
break;
case 51:
return F("Vout Avg errror");
break;
case 52:
return F("Battery low");
break;
case 53:
return F("Clk fail");
break;
case 54:
return F("Input UC");
break;
case 55:
return F("Zero Power");
break;
case 56:
return F("Fan Stucked");
break;
case 57:
return F("DC Switch Open");
break;
case 58:
return F("Tras Switch Open");
break;
case 59:
return F("AC Switch Open");
break;
case 60:
return F("Bulk UV");
break;
case 61:
return F("Autoexclusion");
break;
case 62:
return F("Grid df / dt");
break;
case 63:
return F("Den switch Open");
break;
case 64:
return F("Jbox fail");
break;
default:
return F("Sconosciuto");
break;
}
}
typedef struct {
byte TransmissionState;
byte GlobalState;
byte InverterState;
byte Channel1State;
byte Channel2State;
byte AlarmState;
bool ReadState;
} DataState;
DataState State;
bool ReadState() {
State.ReadState = Send(Address, (byte)50, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0);
if (State.ReadState == false) {
ReceiveData[0] = 255;
ReceiveData[1] = 255;
ReceiveData[2] = 255;
ReceiveData[3] = 255;
ReceiveData[4] = 255;
ReceiveData[5] = 255;
}
State.TransmissionState = ReceiveData[0];
State.GlobalState = ReceiveData[1];
State.InverterState = ReceiveData[2];
State.Channel1State = ReceiveData[3];
State.Channel2State = ReceiveData[4];
State.AlarmState = ReceiveData[5];
return State.ReadState;
}
typedef struct {
byte TransmissionState;
byte GlobalState;
String Par1;
String Par2;
String Par3;
String Par4;
bool ReadState;
} DataVersion;
DataVersion Version;
bool ReadVersion() {
Version.ReadState = Send(Address, (byte)58, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0);
if (Version.ReadState == false) {
ReceiveData[0] = 255;
ReceiveData[1] = 255;
}
Version.TransmissionState = ReceiveData[0];
Version.GlobalState = ReceiveData[1];
switch ((char)ReceiveData[2])
{
case 'i':
Version.Par1 = F("Aurora 2 kW indoor");
break;
case 'o':
Version.Par1 = F("Aurora 2 kW outdoor");
break;
case 'I':
Version.Par1 = F("Aurora 3.6 kW indoor");
break;
case 'O':
Version.Par1 = F("Aurora 3.0 - 3.6 kW outdoor");
break;
case '5':
Version.Par1 = F("Aurora 5.0 kW outdoor");
break;
case '6':
Version.Par1 = F("Aurora 6 kW outdoor");
break;
case 'P':
Version.Par1 = F("3 - phase interface (3G74)");
break;
case 'C':
Version.Par1 = F("Aurora 50kW module");
break;
case '4':
Version.Par1 = F("Aurora 4.2kW new");
break;
case '3':
Version.Par1 = F("Aurora 3.6kW new");
break;
case '2':
Version.Par1 = F("Aurora 3.3kW new");
break;
case '1':
Version.Par1 = F("Aurora 3.0kW new");
break;
case 'D':
Version.Par1 = F("Aurora 12.0kW");
break;
case 'X':
Version.Par1 = F("Aurora 10.0kW");
break;
default:
Version.Par1 = F("Sconosciuto");
break;
}
switch ((char)ReceiveData[3])
{
case 'A':
Version.Par2 = F("UL1741");
break;
case 'E':
Version.Par2 = F("VDE0126");
break;
case 'S':
Version.Par2 = F("DR 1663 / 2000");
break;
case 'I':
Version.Par2 = F("ENEL DK 5950");
break;
case 'U':
Version.Par2 = F("UK G83");
break;
case 'K':
Version.Par2 = F("AS 4777");
break;
default:
Version.Par2 = F("Sconosciuto");
break;
}
switch ((char)ReceiveData[4])
{
case 'N':
Version.Par3 = F("Transformerless Version");
break;
case 'T':
Version.Par3 = F("Transformer Version");
break;
default:
Version.Par3 = F("Sconosciuto");
break;
}
switch ((char)ReceiveData[5])
{
case 'W':
Version.Par4 = F("Wind version");
break;
case 'N':
Version.Par4 = F("PV version");
break;
default:
Version.Par4 = F("Sconosciuto");
break;
}
return Version.ReadState;
}
typedef struct {
byte TransmissionState;
byte GlobalState;
float Valore;
bool ReadState;
} DataDSP;
DataDSP DSP;
bool ReadDSP(byte type, byte global) {
if ((((int)type >= 1 && (int)type <= 9) || ((int)type >= 21 && (int)type <= 63)) && ((int)global >= 0 && (int)global <= 1)) {
DSP.ReadState = Send(Address, (byte)59, type, global, (byte)0, (byte)0, (byte)0, (byte)0);
if (DSP.ReadState == false) {
ReceiveData[0] = 255;
ReceiveData[1] = 255;
}
}
else {
DSP.ReadState = false;
clearReceiveData();
ReceiveData[0] = 255;
ReceiveData[1] = 255;
}
DSP.TransmissionState = ReceiveData[0];
DSP.GlobalState = ReceiveData[1];
foo.asBytes[0] = ReceiveData[5];
foo.asBytes[1] = ReceiveData[4];
foo.asBytes[2] = ReceiveData[3];
foo.asBytes[3] = ReceiveData[2];
DSP.Valore = foo.asFloat;
return DSP.ReadState;
}
typedef struct {
byte TransmissionState;
byte GlobalState;
unsigned long Secondi;
bool ReadState;
} DataTimeDate;
DataTimeDate TimeDate;
bool ReadTimeDate() {
TimeDate.ReadState = Send(Address, (byte)70, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0);
if (TimeDate.ReadState == false) {
ReceiveData[0] = 255;
ReceiveData[1] = 255;
}
TimeDate.TransmissionState = ReceiveData[0];
TimeDate.GlobalState = ReceiveData[1];
TimeDate.Secondi = ((unsigned long)ReceiveData[2] << 24) + ((unsigned long)ReceiveData[3] << 16) + ((unsigned long)ReceiveData[4] << 8) + (unsigned long)ReceiveData[5];
return TimeDate.ReadState;
}
typedef struct {
byte TransmissionState;
byte GlobalState;
byte Alarms1;
byte Alarms2;
byte Alarms3;
byte Alarms4;
bool ReadState;
} DataLastFourAlarms;
DataLastFourAlarms LastFourAlarms;
bool ReadLastFourAlarms() {
LastFourAlarms.ReadState = Send(Address, (byte)86, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0);
if (LastFourAlarms.ReadState == false) {
ReceiveData[0] = 255;
ReceiveData[1] = 255;
ReceiveData[2] = 255;
ReceiveData[3] = 255;
ReceiveData[4] = 255;
ReceiveData[5] = 255;
}
LastFourAlarms.TransmissionState = ReceiveData[0];
LastFourAlarms.GlobalState = ReceiveData[1];
LastFourAlarms.Alarms1 = ReceiveData[2];
LastFourAlarms.Alarms2 = ReceiveData[3];