Here's the first half of the code i have now due to a 20000 character limit of the forum
// from rectifier : (requests for logins)
// 05014400 + ser nr + 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 + ser nr + 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 + ser nr + 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)
// PID settings of 0.5 , 0.5 and 0.0 work excellent. Nice and slow buildup of voltage and current
#include <mcp_can.h> // library for CANBUS
#include <mcp_can_dfs.h> // library for CANBUS
#include <SPI.h>
#include <Wire.h>
#include <HT_SSD1306.h> // library for oled display
#include <SoftwareSerial.h> // library for SMS module
#include <PID_v1.h> // library for PID controller(s)
#define PIN_RESET 9 // Connect RST of oled display to pin 9
#define PIN_DC 10 // Connect DC of oled display to pin 8
#define PIN_CS 11 // Connect CS of oled display to pin 10
#define SIM800_TX_PIN 4 // Connect TX pin of SMS module to pin 4
#define SIM800_RX_PIN 5 // Connect RX pin of SMS module to pin 5
#define currentstep 50 // each press on the button is 10 amps more (divide by 10)
#define amphours 91 // amphours of my Zero SR 2014 (adjust accordingly)
#define onboardamps 12 // amount of amps the onboard cherger delivers (normally 12)
#define SPI_CS_PIN 17 // set the input pin for the CANBUS receiver (on the leonardoboard = 17)
#define buttonup 8 // inputpin for the pushbutton to step through the current steps
#define SMSinterval 300000 // interval in msec to send an SMS (300 sec = 5 minutes)
word currentsetpoint = 0; // set initial currentsetpoint (divide by 10)
word outputvoltage1 = 4350; // set output voltage of the first flatpack to 43.50 Volt (divide by 100)
word outputvoltage2 = 4350; // set output voltage of the second flatpack to 43.50 Volt (divide by 100)
word overvoltage = 5950; // set the overvoltage protection limit at 59.50 Volt (divide by 100)
double PIDSetpoint1, PIDInput1, PIDOutput1; // parameters for the first PID controller
double PIDSetpoint2, PIDInput2, PIDOutput2; // parameters for the second PID controller
unsigned char len = 0; // this variable holds the length of the CANBUS message received
unsigned char serialnr1[8] = {0x14,0x14,0x71,0x11,0x08,0x20,0x00,0x00}; // this variable holds the serialnumber of the first Flatpack
unsigned char serialnr2[8] = {0x16,0x02,0x71,0x12,0x76,0x44,0x00,0x00}; // this variable holds the serialnumber of the second Flatpack
int msgreceived1; // this variable holds the number of messages received from flatpack 1
int msgreceived2; // this variable holds the number of messages received from flatpack 2
int led = 23; // LED output pin for the leonardo CAN board= 23
long counter; // counter to determine when no new messages are available
unsigned long previousMillis = 0; // variable for the SMS function
int Ti1 = 0; // Temperature in from flatpack 1
int Ti2 = 0; // Temperature in from flatpack 2
int To1 = 0; // Temperature out from flatpack 1
int To2 = 0; // Temperature out from flatpack 2
int Vi1 = 0; // input voltage from flatpack 1
int Vi2 = 0; // input voltage from flatpack 2
float Vo1 = 0.0; // output voltage from flatpack 1
float Vo2 = 0.0; // output voltage from flatpack 2
float Io1 = 0.0; // output current from flatpack 1
float Io2 = 0.0; // output current from flatpack 1
int Po = 0; // output power variable
int SOC = 0; // State Of Charge variable
int TTG = 0; // Time To Go variable
int flatpackamount= 0; // amount of flatpacks used (only if serialnr is determined automatically)
SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN); // initialise the SMS module
SSD1306 oled(PIN_RESET, PIN_DC, PIN_CS); // initialise the oled display
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin for CANBUS shield
PID myPID1(&PIDInput1, &PIDOutput1, &PIDSetpoint1, 0.5,0.5,0,DIRECT); // PID controller settings
PID myPID2(&PIDInput2, &PIDOutput2, &PIDSetpoint2, 0.5,0.5,0,DIRECT); // PID controller settings
/********************
* SETUP
********************/
void setup() // Initialisation routine
{
pinMode(buttonup, INPUT); // Set pin 11 to input (pushbutton for up)
digitalWrite(buttonup, HIGH); // activate pull-up on A0
pinMode(led, OUTPUT); // pin 23 is the output pin for the LED on the LEONARDO CANBUS board
digitalWrite(led, LOW); // turn the LED of
oled.begin(); // initialise the oled display
oled.clear(ALL); // clear the oled display
oled.clear(PAGE); // set the cursor to home
oled.setFontType(1); // set the font size of the oled display
oled.flipHorizontal(1); // flip the display (because the way i mounted it)
oled.flipVertical(1); // flip the display (because the way i mounted it)
// delay(100); // delay to show the splash screen (do not use a long delay as the current may spike due to lack of communication with the flatpack
PIDInput1 = 0; // Initial input of the first PID controller
PIDInput2 = 0; // Initial input of the second PID controller
PIDSetpoint1 = currentsetpoint; // Initial Setpoint of the first PID controller
PIDSetpoint2 = currentsetpoint; // Initial Setpoint of the second PID controller
serialSIM800.begin(9600); // initialise the communication with the SMS module
Serial.begin(115200);
START_INIT:
if(CAN_OK == CAN.begin(CAN_125KBPS)) // init can bus : baudrate = 125k !!
{
oled.clear(PAGE); // clear the oled display
oled.setCursor(0,0); // set the cursor to home
oled.print("CAN OK"); // let the oled display show that the canbus initialised properly
oled.display(); // command to actually show on the oled display what has been printed just before
// delay(100); // delay to show the information for a short while
myPID1.SetMode(AUTOMATIC); // Start the first PID controller after the CANbus has initialised properly
myPID2.SetMode(AUTOMATIC); // Start the second PID controller after the CANbus has initialised properly
}
else
{
oled.clear(PAGE); // clear the oled display
oled.setCursor(0,0); // set the cursor to home
oled.print("CAN Fail"); // let the oled display that the canbus did not initialise properly
goto START_INIT; // return to the start of the canbus initialisation
}
digitalWrite(led,HIGH); // turn the LED on (indicating a message transmission)
CAN.sendMsgBuf(0x05004804, 1, 8, serialnr1); // send message to log in to the first flatpack and assign ID1 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
CAN.sendMsgBuf(0x05004808, 1, 8, serialnr2); // send message to log in to the second flatpack and assign ID2 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
digitalWrite(led,LOW); // turn the LED off
}
/********************
* MAIN PROGRAM
********************/
void loop() // MAIN PROGRAM (LOOP)
{
unsigned char buf[8] ;
if(CAN_MSGAVAIL == CAN.checkReceive()) // if data is available then :
{
unsigned char buf[8]={0,0,0,0,0,0,0,0};
counter=0; // reset the counter for non received messages
digitalWrite(led,HIGH); // turn the LED on (indicating a message reception)
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
INT32U canId = CAN.getCanId(); // read the CAN Id
digitalWrite(led,LOW); // turn the LED off
Serial.print(millis()*0.001);
Serial.print("\t");
Serial.print("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
}
Serial.println();
switch (canId)
{
case 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 (ID1 or ID2)
case 0x05024400:
{ // the message itself consists of the (decimal) serial number of the flatpack unit in HEX format !! the sernr is 6 bytes. the remaining 2 bytes are not used (0x00)
digitalWrite(led,HIGH); // turn the LED on (indicating a message transmission)
CAN.sendMsgBuf(0x05004804, 1, 8, serialnr1); // send message to log in to the first flatpack and assign ID1 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
CAN.sendMsgBuf(0x05004808, 1, 8, serialnr2); // send message to log in to the second flatpack and assign ID2 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
digitalWrite(led,LOW); // turn the LED off
msgreceived1++; // increase the variable "msgreceived" for flatpack 1
}
break;
case 0x05000820: // if CANID = 0500xxyy where xxyy the last 2 digits of the serial nr
{
digitalWrite(led,HIGH); // turn the LED on (indicating a message reception/transmission)
CAN.sendMsgBuf(0x05004804, 1, 8, serialnr1); // send message to log in to the first flatpack and assign ID1 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
digitalWrite(led,LOW); // turn the LED off
msgreceived1=0; // reset the variable "msgreceived" because we just logged in
}
break;
case 0x05003644: // if CANID = 0500xxyy where xxyy the last 2 digits of the serial nr
{
digitalWrite(led,HIGH); // turn the LED on (indicating a message reception/transmission)
CAN.sendMsgBuf(0x05004808, 1, 8, serialnr2); // send message to log in to the second flatpack and assign ID2 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
digitalWrite(led,LOW); // turn the LED off
msgreceived1=0; // reset the variable "msgreceived" because we just logged in
}
break;