// from rectifier : (requests for logins)
// 05014400 + SN + 00 00 from rectifier : HELLOOW where are you ! rectifier sends 05014400 and 6 bytes serial number and followed by 00 00 (login request)
// 0500xxyy + 1B + SN + 00 is send during normal voltage every second. xxyy is the last 2 bytes from the serial number
// after either of these send 05004804 every 5 seconds ! to keep logged in. rectifier does not send login requests so after 10 second the numbers stop until 05014400 is sent
// from rectifier : (status messages)
// 0501400C + status data : walkin and below 43 volts (error) and during walk-out (input voltage low)
// 05014010 + status data : walkin busy
// 05014004 + status data : normal voltage reached
// 05014008 + status data : current-limiting active
// send TO rectifier (act as controller)
// 05004804 + SN + 00 00 from controller : send 05004804 and 6 bytes ser number followed by 00 00
// 05FF4004 controller sends current and voltage limits (last 4 is 5 sec walk-in, for 60 second walk-in use 05FF4005)
// 05FF4005 controller sends current and voltage limits (last 5 is 60 sec walk-in, for 5 second walk-in use 05FF4004)
#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include <SPI.h>
#include <U8glib.h>
word maxcurrent = 370; // set initial maxcurrent (divide by 10)
word outputvoltage = 5300; // set output voltage to 57.50 Volt (divide by 100)
word overvoltage = 5500; // set the overvoltage protection limit at 59.50 Volt (divide by 100)
const int SPI_CS_PIN = 17; // set the input pin for the CANBUS receiver (on the leonardoboard = 17)
unsigned char len = 0; // this variable holds the length of the CANBUS message received
unsigned char serialnr[8]; // this variable holds the serialnumber of the Flatpack
int msgreceived; // this variable holds the number of messages received
int led = 23; // LED output pin for the leonardo CAN board= 23
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin for CANBUS shield
/* OLED connections
* CLK = Pin 12
* MOSI = Pin 11
* CS = Pin 8
* DC = Pin 9
* RST = Pin 10
*/
U8GLIB_SSD1306_128X64 u8g(12, 11, 8, 9, 10);
void setup() { // Initialisation routine
pinMode(led, OUTPUT); // pin 23 is the output pin for the LEONARDO CANBUS board
digitalWrite(led, LOW); // turn the LED of
Serial.begin(115200); // Set the baudrate for the seial connection to the PC at 115200
Serial.println("Starting...");
START_INIT:
if (CAN_OK == CAN.begin(CAN_125KBPS)) { // init can bus : baudrate = 125k !!
Serial.println("CAN BUS Shield init ok!");
} else {
Serial.println("CAN BUS Shield init fail");
Serial.println("Init CAN BUS Shield again");
goto START_INIT;
}
}
void can_bus(void) {
unsigned char buf[8] ;
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if data coming
digitalWrite(led,HIGH); // turn the LED on
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
unsigned long canId = CAN.getCanId(); // read the CAN Id
Serial.println(); // start on a new line
Serial.print("Received : 0"); // leading zero
Serial.print(canId,HEX); // output CAN Id to serial monitor
Serial.print("\t"); // send Tab
for (int i = 0; i<len; i++) { // print the data
if ( buf[i] < 0x10) {
Serial.print("0");
}
Serial.print(buf[i],HEX); // send a leading zero if only one digit
Serial.print(" "); // space to seperate bytes
}
digitalWrite(led,LOW); // turn the LED off
if (canId==0x05014400) {
//this is the request from the Flatpack rectifier during walk-in (start-up) or normal operation when no log-in response has been received for a while
for (int i = 0; i<8; i++) {
serialnr[i]=buf[i]; // transfer the message buffer to the serial number variable
}
Serial.print("\tSerial Number is : ");
for (int i = 0; i<6; i++) { // print the data
if ( serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
}
digitalWrite(led,HIGH);
CAN.sendMsgBuf(0x05004804, 1, 8, serialnr); //send message to log in (DO NOT ASSIGN AN ID use 00)
digitalWrite(led,LOW);
Serial.println();
Serial.print("TRANSMIT : 05004804");
Serial.print("\t");
for (int i = 0; i<len; i++) { // print the data
if (serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
Serial.print(" "); // space to seperate bytes
}
Serial.print("\tLog in with SrNr : ");
for(int i = 0; i<6; i++) { // print the data
if (serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
}
msgreceived++; // increase the variable "msgreceived"
unsigned char stmp7[8] = {
lowByte(maxcurrent), highByte(maxcurrent), lowByte(outputvoltage), highByte(outputvoltage), lowByte(outputvoltage), highByte(outputvoltage), lowByte(overvoltage), highByte(overvoltage)
};
// set rectifier to maxcurrent 57,0V (16 44) and OVP to 59.5V (17 3E) qnd long walk-in 4005 or short walk in 4004
digitalWrite(led,HIGH);
CAN.sendMsgBuf(0x05FF4004, 1, 8, stmp7);//(last 4 in header is for 5 sec walkin, 5 is for 60 second walkin)
digitalWrite(led,LOW);
Serial.println();
Serial.print("TRANSMIT : 05FF4004");
Serial.print("\t");
for (int i = 0; i<len; i++) { // print the data
if (stmp7[i] < 0x10) {
Serial.print("0");
}
Serial.print(stmp7[i],HEX); // send a leading zero if only one digit
Serial.print(" "); // space to seperate bytes
}
Serial.print("\tImax set to : ");
Serial.print(0.1*(stmp7[0]+stmp7[1]*256));
Serial.print(" A\t");
Serial.print("Vout set to : ");
Serial.print(0.01*(stmp7[2]+stmp7[3]*256));
Serial.print(" V\t");
Serial.print("OVP set to : ");
Serial.print(0.01*(stmp7[6]+stmp7[7]*256));
Serial.print(" V\tWalkin : ");
Serial.print("5 seconds");
}
else if (canId==(0x05000000+buf[6])) {
//if CANID = 0500xxyy where xxyy the last 2 digits of the serial nr
for (int i = 0;i<6; i++) {
serialnr[i] = buf[i+1];
}
// unsigned char serialnr[8] = {buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 0x00, 0x00}; //this is the serial number of the unit which is covered in the request (unit announces its serial number)
Serial.print("\tSerial Number is : ");
for (int i = 0; i<6; i++) { // print the data
if (serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
}
msgreceived++;
digitalWrite(led,HIGH);
CAN.sendMsgBuf(0x05004804, 1, 8, serialnr); //(last 4 in header is for 5 sec walkin, 5 is for 60 second walkin)
digitalWrite(led,LOW);
msgreceived=0;
Serial.println();
Serial.print("TRANSMIT : 05004804");
Serial.print("\t");
for (int i = 0; i<8; i++) { // print the data
if (serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
Serial.print(" "); // space to seperate bytes
}
Serial.print("\tLog in with SrNr : ");
for (int i = 0; i<6; i++) { // print the data
if (serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
}
unsigned char stmp7[8] = {
lowByte(maxcurrent), highByte(maxcurrent), lowByte(outputvoltage), highByte(outputvoltage), lowByte(outputvoltage), highByte(outputvoltage), lowByte(overvoltage), highByte(overvoltage)};
// set rectifiers maxcurrent, outputvoltage and OVP and long walk-in 4005 or short walk in 4004
digitalWrite(led,HIGH);
CAN.sendMsgBuf(0x05FF4004, 1, 8, stmp7);//(last 4 in header is for 5 sec walkin, 5 is for 60 second walkin)
digitalWrite(led,LOW);
Serial.println();
Serial.print("TRANSMIT : 05FF4004");
Serial.print("\t");
for (int i = 0; i<len; i++) { // print the data
if (stmp7[i] < 0x10) {
Serial.print("0");
}
Serial.print(stmp7[i],HEX); // send a leading zero if only one digit
Serial.print(" "); // space to seperate bytes
}
Serial.print("\tImax set to : ");
Serial.print(0.1*(stmp7[0]+stmp7[1]*256));
Serial.print(" A\t");
Serial.print("Vout set to : ");
Serial.print(0.01*(stmp7[2]+stmp7[3]*256));
Serial.print(" V\t");
Serial.print("OVP set to : ");
Serial.print(0.01*(stmp7[6]+stmp7[7]*256));
Serial.print(" V\tWalkin : ");
Serial.print("5 seconds");
}
else if ((canId==0x05014004) or (canId==0x05014008) or (canId==0x05014010) or (canId=0x0501400C)) {
// these are the status messages (05014004 is not current-limiting, 05014008 is current limiting 05014010 = busy with walkin, 0501400C in input voltage low)
Serial.print("\t");
Serial.print("Tin = ");
Serial.print(buf[0]); //first byte is temperature in (celcius)
Serial.print(" C\t");
Serial.print("Tout = ");
Serial.print(buf[7]); //last byte is temperature out (celcius)
Serial.print(" C\t");
Serial.print("Vin = ");
Serial.print(buf[5]); // sixth byte is input voltage in volts ac/dc
Serial.print(" V\t");
Serial.print("Iout = ");
Serial.print(buf[2]*256*0.1+buf[1]*0.1); // third (msb) and second byte are current in 0.1A (deciamp) calculated to show directly in Amps
Serial.print(" A\t");
Serial.print("Vout = ");
Serial.print(buf[4]*256*0.01+buf[3]*0.01); // fifth (msb) and fourth byte are voltage in 0.01V (centivolt) calculated to show directly in Volts dc
Serial.print(" V\t");
Serial.print("Pout = ");
Serial.print((2*buf[4]*256*0.01+2*buf[3]*0.01)*(buf[2]*256*0.1+buf[1]*0.1)); // Power is calculated from output voltage and current. Output is in Watts
Serial.print(" W\t");
msgreceived++; // record number of messages received
if (msgreceived>40) {
msgreceived=0;
digitalWrite(led,HIGH);
CAN.sendMsgBuf(0x05004804, 1, 8, serialnr); //send message to log in every 40 messages (DO NOT USE ID NR, USE 00) this because during walk-in the 0500xxyy is not send and the rectifier "logs out" because of no received log-in messages from controller
digitalWrite(led,LOW);
Serial.println();
Serial.print("TRANSMIT : 05004804");
Serial.print("\t");
for (int i = 0; i<8; i++) { // print the data
if (serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
Serial.print(" "); // space to seperate bytes
}
Serial.print("\tover 40 messages : Log in with SrNr : ");
for (int i = 0; i<6; i++) { // print the data
if (serialnr[i] < 0x10) {
Serial.print("0");
}
Serial.print(serialnr[i],HEX); // send a leading zero if only one digit
}
msgreceived++;
}
}
else {
Serial.println("\tUNKNOWN COMMAND");
}
/* Display the data */
u8g.setFont(u8g_font_fub17);
u8g.setPrintPos(5, 24); // x pos, y pos
u8g.print(buf[4]*256*0.01+buf[3]*0.01); // V out
u8g.setFont(u8g_font_fub17);
u8g.setPrintPos(5, 47);
u8g.print(buf[2]*256*0.1+buf[1]*0.1); // I out
u8g.setFont(u8g_font_7x14);
u8g.setPrintPos(8, 64);
u8g.print("Vin");
u8g.setFont(u8g_font_7x14);
u8g.setPrintPos(34, 64);
u8g.print(buf[5]);
u8g.setFont(u8g_font_7x14);
u8g.setPrintPos(84, 25);
u8g.print("Temp");
u8g.setFont(u8g_font_7x14);
u8g.setPrintPos(84, 40);
u8g.print(buf[0]);u8g.print((char)176);
u8g.setFont(u8g_font_6x12);
u8g.setPrintPos(106, 40);
u8g.print("in");
u8g.setFont(u8g_font_7x14);
u8g.setPrintPos(84, 55);
u8g.print(buf[7]);u8g.print((char)176);
u8g.setFont(u8g_font_6x12);
u8g.setPrintPos(106, 55);
u8g.print("out");
}
}
void loop(void) {
u8g.firstPage();
do {
can_bus();
} while (u8g.nextPage());
}