-
Notifications
You must be signed in to change notification settings - Fork 2
/
TCCharger-BlinkingNbettercode.ino
204 lines (152 loc) · 6.89 KB
/
TCCharger-BlinkingNbettercode.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
//Code von Lennart O.
#include <mcp_can.h>
#include <SPI.h>
#include <SimpleTimer.h>
#define SPI_CS_PIN 9 //CS Pin
int led = 7;
word outputvoltage = 1140; //set max Voltage to 114.0V (offset = 0.1) NOTE: pv_voltage if statement will force off charger at 116
word outputcurrent = 300; //set max Current to 30A (offset = 0.1)
unsigned char voltbuf[30]; // buffer for binary-ish version of voltage. i.e. 101011000 = 112v
unsigned int volth; // hundreds value
unsigned int voltt; //tens value
unsigned int volto; //ones value
unsigned int cyclecounter = 1; //tracks number of cycles since led started flashing i.e. 1010110 would take 7 cycles
unsigned long int sendId = 0x18E54024; //0x18E54024 send to CH4100
uint8_t j=0;
uint8_t k;
unsigned char len = 0; //Length of received CAN message
unsigned char buf[8]; //Buffer for CAN message
unsigned long int receiveId; //ID of Charger
unsigned char errorct = 0; //tracks number of cycles chargers not charging. Charger starts at around 17
byte chargeron = 0xFB; //yes(on) = FC, no(off) = FB or seemingly anything else - start charger at FB(off)
MCP_CAN CAN(SPI_CS_PIN); //CS Pin for SPI
SimpleTimer timer1; //timer Object generation
//Functions
/************************************************
** Function name: canRead
** Descriptions: read CAN message
*************************************************/
void canRead(){
if(CAN_MSGAVAIL == CAN.checkReceive()){ //Check for messages
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buffer
receiveId = CAN.getCanId(); //CAN-ID lesen
if(receiveId == 0x18EB2440){
// Serial.println("CAN Data received from Charger!");
Serial.print("CAN ID: ");
Serial.print(receiveId, HEX); //Output ID
Serial.print(" / CAN Data: ");
for(int i = 0; i<len; i++){ //Output Data
if( buf[i] < 0x10){ // display zero/null if only one digit
Serial.print("0");
}
Serial.print(buf[i],HEX);
Serial.print(" "); // Spaces
}
Serial.println(); //Prints Carriage Return
if (bitRead(buf[1],0) == 1) Serial.print("Charger off ");
if (bitRead(buf[1],0) == 0) Serial.print("Charger on ");
if (bitRead(buf[1],0) == 1) errorct++;
Serial.println(errorct);
if (chargeron == 0xFC & errorct > 28) chargeron = 0xFB; // if 'commanded' on but found off a couple times, force off to prevent cycling. Will be 17 after 1st on, ~21 after 2nd on
Serial.print("Battery voltage: ");
float pv_voltage = (((float)buf[3]*256.0) + ((float)buf[2]))/10.0; //highByte/lowByte + offset
Serial.print(pv_voltage);
Serial.println(" V");
Serial.print("Charging Current: ");
float pv_current = (3200-(((float)buf[5]*256.0) + ((float)buf[4])))/10.0; //highByte/lowByte + offset
Serial.print(pv_current);
Serial.println(" A");
if (millis() > 10000 & millis() < 16000) chargeron = 0xFC; // wait 10-ish seconds before turning on charger
if(pv_voltage > 116 || pv_voltage < 80) chargeron = 0xFB; // if voltage reaches this level turn off charger
if(cyclecounter==1){
volth = pv_voltage/100; //hundreds
voltt = pv_voltage/10 - volth*10; //tens
volto = pv_voltage - volth*100 - voltt*10; //ones
for(k=0; k<20; k++) { //clear blinking buffer
voltbuf[k] = 0;
}
k=0;
while(k<volth) { //hundreds
voltbuf[k] = 1;
k++;
}
voltbuf[k] = 0;
j = k;k=0;
while(k<voltt) { //tens
voltbuf[j+k+1] = 1;
k++;
}
voltbuf[j+k+1] = 0;
j = j+k+1;k=0;
while(k<volto) { //ones
voltbuf[j+k+1] = 1;
k++;
}
voltbuf[j+k+1] = 0;
j = j+k+1;
}
if(voltbuf[cyclecounter-1]==1) Blink();
cyclecounter++;
if(cyclecounter>j+5) cyclecounter = 1; // once 5 cycles have passed since blinking has stopped, reset counter (start blinking again).
if(bitRead(buf[0],0)) Serial.println("Error: CAN_BUS Error");
if(bitRead(buf[0],2)) Serial.println("Error: Hardware Issue");
if(bitRead(buf[0],4)) Serial.println("Error: Input Voltage Incorrect");
if(bitRead(buf[0],6)) Serial.println("Error: Charger Hot");
// if(bitRead(buf[1],0)) Serial.println("Not Charging"); // Listed above
if(bitRead(buf[1],2)) Serial.println("Error: Battery Voltage");
int k = errorct/2;
if((buf[0] != 0 || buf[1] > 1) && errorct > 30 && bitRead(k,3) && bitRead(k,0)==1) digitalWrite(led,HIGH); // flash led slowly if error (but let the voltage out now and then)
if((buf[0] != 0 || buf[1] > 1) && errorct > 30 && bitRead(k,3) && bitRead(k,0)==0) digitalWrite(led,LOW); //what he said...
}
}
}
void Blink(){
digitalWrite(led,HIGH);
delay(150);
digitalWrite(led,LOW);
}
/************************************************
** Function name: canWrite
** Descriptions: write CAN message
*************************************************/
String canWrite(unsigned char data[8], unsigned long int id){
byte sndStat = CAN.sendMsgBuf(id, 1, 8, data); //Send message (ID, extended Frame, Datalength, Data)
if(data[0] == 0xFC) Serial.println("Charger commanded on.");
if(data[0] == 0xFB) Serial.println("Charger commanded off.");
if(sndStat == CAN_OK) //Status byte for transmission
return "CAN message sent successfully to charger";
else
return "Error during message transmission to charger";
}
/************************************************
** Function name: myTimer1
** Descriptions: function of timer1
*************************************************/
void myTimer1() { //Cyclic function called by the timer
unsigned char voltamp[8] = {chargeron, lowByte(outputvoltage), highByte(outputvoltage), lowByte(3200-outputcurrent), highByte(3200-outputcurrent),0xFF,0xFF,0xFF}; //Generate the message
Serial.println(canWrite(voltamp, sendId)); //Send message and output results
canRead(); //Read output from charger
Serial.println(); //Carriage Return
}
/************************************************
** Function name: setup
** Descriptions: Arduino setup
*************************************************/
void setup() {
pinMode(led, OUTPUT);
digitalWrite(led,HIGH); //Start on so we'll know if CAN comms start.
Serial.begin(115200); //Serial Port Initialize
while(CAN_OK != CAN.begin(CAN_500KBPS)){ //CAN Bus initialisieren
Serial.println("CAN Initialization Failure, Restart");
delay(200);
}
Serial.println("CAN Initialization Successful");
timer1.setInterval(950, myTimer1); //Define the time and function of the timer.
}
/************************************************
** Function name: loop
** Descriptions: Arduino loop
*************************************************/
void loop() {
timer1.run(); //Timer start
}