Getting started with an IVT-S and Arduino Uno CAN bus shield: Difference between revisions

From openinverter.org wiki
Jump to navigation Jump to search
No edit summary
(Add code)
Line 4: Line 4:


Here's the code:
Here's the code:
// IVT-S meter using CAN-BUS Shield
// electric_dart 2020


include <SPI.h>
<nowiki>
// IVT-S meter using CAN-BUS Shield
// electric_dart 2020


include "mcp_can.h"
#include <SPI.h>
 
#include "mcp_can.h"
/*SAMD core*/
 
ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE


/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
     #define SERIAL SerialUSB
     #define SERIAL SerialUSB
 
#else
else
 
     #define SERIAL Serial
     #define SERIAL Serial
#endif


endif
// the cs pin of the version after v1.1 is default to D9
 
// v0.9b and v1.0 is default D10
// the cs pin of the version after v1.1 is default to D9
const int SPI_CS_PIN = 10;
// v0.9b and v1.0 is default D10
const int CAN_INT_PIN = 2;
const int SPI_CS_PIN = 10;
const int CAN_INT_PIN = 2;
 
MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin


unsigned char flagRecv = 0;
MCP_CAN CAN(SPI_CS_PIN);                                   // Set CS pin
unsigned char len = 0;
unsigned char buf[8];
char str[20];


void setup() {
unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];


void setup() {
     SERIAL.begin(115200);
     SERIAL.begin(115200);
     while (!SERIAL) {
     while (!SERIAL) {
Line 56: Line 51:
     CAN.init_Mask(1, 0, 0x7ff);                        // 0x7ff is '11111111111' in binary, so we are checking 11 of the CAN message ID bits   
     CAN.init_Mask(1, 0, 0x7ff);                        // 0x7ff is '11111111111' in binary, so we are checking 11 of the CAN message ID bits   


<br>


     /*
     /*
Line 68: Line 62:
     CAN.init_Filt(5, 0, 0x521);                           
     CAN.init_Filt(5, 0, 0x521);                           


}
}
 
void MCP2515_ISR() {


void MCP2515_ISR() {
     flagRecv = 1;
     flagRecv = 1;
}


}
void loop() {
 
void loop() {
 
     if (flagRecv) {
     if (flagRecv) {
         // check if get data
         // check if get data
Line 103: Line 94:
         }
         }
     }
     }
 
}
}
</nowiki>

Revision as of 13:47, 15 June 2020

First of all, set up your Arduino Uno and CAN bus shield.

Once the data is coming in over CAN, we can write a simple program to read the current value from the IVT-S

Here's the code:

// IVT-S meter using CAN-BUS Shield // electric_dart 2020 #include <SPI.h> #include "mcp_can.h" /*SAMD core*/ #ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE #define SERIAL SerialUSB #else #define SERIAL Serial #endif // the cs pin of the version after v1.1 is default to D9 // v0.9b and v1.0 is default D10 const int SPI_CS_PIN = 10; const int CAN_INT_PIN = 2; MCP_CAN CAN(SPI_CS_PIN); // Set CS pin unsigned char flagRecv = 0; unsigned char len = 0; unsigned char buf[8]; char str[20]; void setup() { SERIAL.begin(115200); while (!SERIAL) {  ; // wait for serial port to connect. Needed for native USB port only } while (CAN_OK != CAN.begin(CAN_1000KBPS)) { // init can bus SERIAL.println("CAN BUS Shield init fail"); SERIAL.println("Init CAN BUS Shield again"); delay(100); } SERIAL.println("CAN BUS Shield init ok!"); attachInterrupt(digitalPinToInterrupt(CAN_INT_PIN), MCP2515_ISR, FALLING); // start interrupt /* set receive mask */ CAN.init_Mask(0, 0, 0x7ff); // there are 2 masks in mcp2515, you need to set both of them CAN.init_Mask(1, 0, 0x7ff); // 0x7ff is '11111111111' in binary, so we are checking 11 of the CAN message ID bits /* set receive filter */ CAN.init_Filt(0, 0, 0x521); // there are 6 filters in mcp2515 CAN.init_Filt(1, 0, 0x521); // 0x521 is the CAN mssage ID for IVT-S Current value CAN.init_Filt(2, 0, 0x521); CAN.init_Filt(3, 0, 0x521); CAN.init_Filt(4, 0, 0x521); CAN.init_Filt(5, 0, 0x521); } void MCP2515_ISR() { flagRecv = 1; } void loop() { if (flagRecv) { // check if get data flagRecv = 0; // clear flag // iterate over all pending messages // If either the bus is saturated or the MCU is busy, // both RX buffers may be in use and reading a single // message does not clear the IRQ conditon. while (CAN_MSGAVAIL == CAN.checkReceive()) { // read data, len: data length, buf: data buf CAN.readMsgBuf(&len, buf); unsigned long canId = CAN.getCanId(); if (canId == 0x521) { SERIAL.print("Data received from IVT_Msg_Result_I"); SERIAL.print("\t"); // Convert individual big endian byte values to actual reading long reading = (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | (buf[5]); SERIAL.print(reading); } SERIAL.println(); } } }