Re: Can't Initialize Isabellenhütte ISA Sensor.
Posted: Sat Dec 11, 2021 3:45 pm
fellas can we keep this on the downlow please, and I'm gonna hide it on the Web so no one can see it
openinverter Community
https://openinverter.org/forum/
Code: Select all
-----------------------------
Get data from ID: 0x411
34 0 1 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
20 42 0 60 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
21 42 0 72 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
22 42 0 84 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
23 42 0 96 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
24 42 0 A8 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
25 42 0 BA 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
26 42 0 CC 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
27 42 0 DE 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
28 42 0 F0 0 0 0 0
-----------------------------
Get data from ID: 0x411
32 0 0 0 0 0 0 0
-----------------------------
Get data from ID: 0x411
34 1 1 0 0 0 0 0
Code: Select all
-----------------------------
Get data from ID: 0x680
6 D 0 0 0 0
-----------------------------
Get data from ID: 0x680
6 4 0 0 0 0
-----------------------------
Get data from ID: 0x620
0 E FF FF FF DB
-----------------------------
Get data from ID: 0x680
6 F 0 0 0 0
-----------------------------
Get data from ID: 0x680
6 5 0 0 0 0
-----------------------------
Get data from ID: 0x680
6 B 0 0 0 0
-----------------------------
Get data from ID: 0x680
6 1 0 0 0 0
-----------------------------
Get data from ID: 0x620
0 8 FF FF FF E7
-----------------------------
Get data from ID: 0x620
0 D FF FF FF E7
-----------------------------
Get data from ID: 0x680
6 4 0 0 0 0
-----------------------------
Get data from ID: 0x620
0 62 0 0 0 3E
Did you inspect the shunt for origin? Last year i got similar ISA shunt out from the Jaguar pack.alexbeatle wrote: ↑Tue Sep 26, 2023 5:03 am Did your shunt talk in 0x680 and 0x620 IDs too? I'm having difficulty with mine.
I received similar ISA (only 1x port) and having difficulty initialising.
....
Appreciate looking into this...
No markings other than what I've posted above.arber333 wrote: ↑Wed Sep 27, 2023 9:26 pm Did you inspect the shunt for origin? Last year i got similar ISA shunt out from the Jaguar pack.
I recorded some messages of current. viewtopic.php?t=1282
You may have OEM programmed ISA.
Code: Select all
// demo: CAN-BUS Shield, receive data with check mode
// send data coming to fast, such as less than 10ms, you can use this way
// loovee, 2014-6-13
#include <SPI.h>
#define CAN_2515
// #define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat:
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// 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 = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
unsigned char len = 0;
unsigned char buf[8];
void setup() {
SERIAL_PORT_MONITOR.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
/*
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, 0x620); // there are 6 filters in mcp2515
CAN.init_Filt(1, 0, 0x620); // 0x521 is the CAN message ID for IVT-S Current value
CAN.init_Filt(2, 0, 0x620);
CAN.init_Filt(3, 0, 0x620);
CAN.init_Filt(4, 0, 0x620);
CAN.init_Filt(5, 0, 0x620);
}
void loop() {
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if data coming
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
unsigned long canId = CAN.getCanId();
if (canId == 0x620) {
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.println(reading);
}
}
// Refresh every 250ms
delay(250);
}
Code: Select all
Data received from IVT_Msg_Result_I -37
Data received from IVT_Msg_Result_I 25
Data received from IVT_Msg_Result_I 150
Data received from IVT_Msg_Result_I 37
Data received from IVT_Msg_Result_I 12
Data received from IVT_Msg_Result_I 0
Data received from IVT_Msg_Result_I 0
Data received from IVT_Msg_Result_I 125
Data received from IVT_Msg_Result_I -25
Tried this without success.
Code: Select all
void ISA::deFAULT()
{
//Returns module to original defaults
outframe.id = 0x411; // Set our transmission address ID
outframe.length = 8; // Data payload 8 bytes
outframe.extended = 0; // Extended addresses 0=11-bit1=29bit
outframe.rtr=1; //No request
outframe.data.bytes[0]=0x3D;
outframe.data.bytes[1]=0x00;
outframe.data.bytes[2]=0x00;
outframe.data.bytes[3]=0x00;
outframe.data.bytes[4]=0x00;
outframe.data.bytes[5]=0x00;
outframe.data.bytes[6]=0x00;
outframe.data.bytes[7]=0x00;
canPort->sendFrame(outframe);
if(debug)printCAN(&outframe); //If the debug variable is set, show our transmitted frame
}
Brilliant! Thanks for your help!
Code: Select all
#include <FlexCAN_T4.h>
/*
THIS CODE WAS ORIGINATED BY JACK RICKARD AND CONTAINED THE FOLLOWING MESSAGE:
"This library supports ISA Scale IVT Modular current/voltage sensor device. These devices measure current, up to three voltages, and provide temperature compensation.
This library was written by Jack Rickard of EVtv - http://www.evtv.me
copyright 2014
You are licensed to use this library for any purpose, commercial or private,
without restriction."
I HAVE REMOVED A LOT OF STUFF AND RE-WITTEN FOR TEENSY 4.1 USING FLEXCAN_T4. ADDITIONALLY I HAVE CHANGED THE RSR BIT FROM 1 IN JACK'S CODE TO 0 IN THE COMMAND MESSAGES THAT GO TO THE SHUNT.
READ THE ISA DATA SHEET!
*/
template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; } //Allow streaming
float Version=1.00;
uint32_t datarate=500000;
class ISA
{
public:
ISA();
~ISA();
float Amperes; // Floating point with current in Amperes
double Voltage;
double Voltage1;
double Voltage2;
double Voltage3;
double Temperature;
double KW;
double KWH;
bool firstframe;
int framecount;
//unsigned long timestamp;
double milliamps;
long watt;
//long As;
//long wh;
};
ISA::ISA() // Define the constructor.
{
//timestamp = millis();
framecount=0;
firstframe=true;
}
ISA::~ISA() //Define destructor
{
}
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can1; //
ISA Sensor; //Instantiate ISA Module Sensor object to measure current and voltage
void setup()
{
Can1.begin();
Can1.setClock(CLK_60MHz);
delay(500);
Can1.setBaudRate(datarate);
Can1.setMaxMB(2);//NUM_TX_MAILBOXES + NUM_RX_MAILBOXES);
Can1.setMB((FLEXCAN_MAILBOX)0,RX,STD); //receive on MB0
Can1.setMB(MB1,TX); //transmit from MB1
Can1.setMBFilter(REJECT_ALL); //block all data before setting filters
//Can1.setMBFilter(MB0,0x521);
Can1.setMBFilterRange(MB0, 0x521, 0x528);
Can1.enableMBInterrupts();
Can1.onReceive(canSniff); //canSniff called when message received
Serial.begin(115200);
Serial.setTimeout(3000);
Can1.mailboxStatus(); //diagnostic only.
Serial.print("rate: "); Serial.println(Can1.getBaudRate());
Serial<<"\nISA Scale Startup Successful \n";
printMenu();
}
void loop()
{
Can1.events(); //supposedly needed for the callback to work but I think it may work anyway with can.receive above
checkforinput(); //Check keyboard for user input
}
void printStatus()
{
char buffer[40];
sprintf(buffer,"%4.2f",Sensor.Voltage1);
Serial<<"V1:"<<buffer<<"v ";
sprintf(buffer,"%4.2f",Sensor.Voltage2);
Serial<<"V2:"<<buffer<<"v ";
sprintf(buffer,"%4.2f",Sensor.Voltage3);
Serial<<"V3:"<<buffer<<"v ";
sprintf(buffer,"%4.3f",Sensor.Amperes);
Serial<<"Amps:"<<buffer<<"A ";
sprintf(buffer,"%4.3f",Sensor.KW);
Serial<<buffer<<"kW ";
// sprintf(buffer,"%4.3f",Sensor.ah);
// Serial<<buffer<<"Ah ";
// sprintf(buffer,"%4.3f",Sensor.KWH);
// Serial<<buffer<<"kWh";
sprintf(buffer,"%4.0f",Sensor.Temperature);
Serial<<buffer<<"C ";
Serial<<"Frame:"<<Sensor.framecount<<" \n";
}
void printMenu()
{
Serial<<"\f\n=========== ISA Shunt Configurator "<<Version<<" ==============\n************ List of Available Commands ************\n\n";
Serial<<" ? - Print this menu\n ";
Serial<<" i - initialize new sensor\n ";
Serial<<" 1 - STOP\n ";
Serial<<" 2 - STORE\n ";
Serial<<" 3 - START\n ";
Serial<<" 4 - START\n ";
Serial<<" r - Set new datarate\n ";
Serial<<" d - deFAULT\n ";
Serial<<"**************************************************************\n==============================================================\n\n";
}
void checkforinput()
{
//Checks for keyboard input from Native port
if (Serial.available())
{
int inByte = Serial.read();
switch (inByte)
{
case 'r':
getRate();
break;
case 'i':
initialize();
break;
case '?':
printMenu();
break;
case '1':
STOP();
break;
case '2':
sendSTORE();
break;
case '3':
START();
break;
case '4':
RESTART();
break;
case 'a':
deFAULT();
break;
}
}
}
void getRate()
{
Serial<<"\n Enter the Data Rate in kbps you want for CAN: ";
if (Serial.available())
{
uint32_t V = Serial.parseInt();
if(V>0)
{
Can1.setBaudRate(V);
}
Serial.print("new rate: "); Serial.println(Can1.getBaudRate()); //check to see if entered rate has been set
Can1.mailboxStatus();
}
}
void canSniff(const CAN_message_t &msg)
{
Serial.print("MB "); Serial.print(msg.mb);
Serial.print(" OVERRUN: "); Serial.print(msg.flags.overrun);
Serial.print(" LEN: "); Serial.print(msg.len);
Serial.print(" EXT: "); Serial.print(msg.flags.extended);
Serial.print(" TS: "); Serial.print(msg.timestamp);
Serial.print(" ID: "); Serial.print(msg.id, HEX);
Serial.print(" Buffer: ");
for ( uint8_t i = 0; i < msg.len; i++ )
{
Serial.print(msg.buf[i], HEX); Serial.print(" ");
}
Serial.println();
//CAN interrupt
switch (msg.id)
{
case 0x511: //this ID may be getting filtered, see setMBFilterRange above.
break;
case 0x521:
handle521(msg);
break;
case 0x522:
handle522(msg);
break;
case 0x523:
handle523(msg);
break;
case 0x524:
handle524(msg);
break;
case 0x525:
handle525(msg);
break;
case 0x526:
handle526(msg);
break;
case 0x527:
handle527(msg);
break;
case 0x528:
handle528(msg);
break;
}
printStatus();
}
void handle521(const CAN_message_t &msg) //AMperes
{
Serial.println("hande521");
Sensor.framecount++;
long current=0;
//https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
//https://www.geeksforgeeks.org/bitwise-operators-in-c-cpp/
// current = (long)((msg.buf[5] << 24) | (msg.buf[4] << 16) | (msg.buf[3] << 8) | (msg.buf[2])); //Little Endian ...
current = (long)(msg.buf[5] + (msg.buf[4] << 8) + (msg.buf[3] << 16) + (msg.buf[2] << 24)); //TdB Big Endian
Sensor.milliamps=current;
Sensor.Amperes=current/1000.0f;
}
void handle522(const CAN_message_t &msg) //Voltage .. note to me, what's all this framecount stuff?
{
Serial.println("hande522");
Sensor.framecount++;
long volt=0;
volt = (long)((msg.buf[5] << 24) | (msg.buf[4] << 16) | (msg.buf[3] << 8) | (msg.buf[2]));
//volt = (long)(msg.buf[5] + (msg.buf[4] << 8) + (msg.buf[3] << 16) + (msg.buf[2] << 24)); //TdB
Sensor.Voltage1=volt/1000.0f;
}
void handle523(const CAN_message_t &msg) //Voltage2
{
Serial.println("hande523");
Sensor.framecount++;
long volt=0;
volt = (long)((msg.buf[5] << 24) | (msg.buf[4] << 16) | (msg.buf[3] << 8) | (msg.buf[2]));
//volt = (long)(msg.buf[5] + (msg.buf[4] << 8) + (msg.buf[3] << 16) + (msg.buf[2] << 24)); //TdB
Sensor.Voltage2=volt/1000.0f;
}
void handle524(const CAN_message_t &msg) //Voltage3
{
Serial.println("hande524");
Sensor.framecount++;
long volt=0;
volt = (long)((msg.buf[5] << 24) | (msg.buf[4] << 16) | (msg.buf[3] << 8) | (msg.buf[2]));
//volt = (long)(msg.buf[5] + (msg.buf[4] << 8) + (msg.buf[3] << 16) + (msg.buf[2] << 24)); //TdB
Sensor.Voltage3=volt/1000.0f;
}
void handle525(const CAN_message_t &msg) //Temperature
{
Serial.println("hande525");
Sensor.framecount++;
long temp=0;
temp = (long)((msg.buf[5] << 24) | (msg.buf[4] << 16) | (msg.buf[3] << 8) | (msg.buf[2]));
Sensor.Temperature=temp/10;
//if(debug2)Serial<<"Temperature: "<<Temperature<<" C frames:"<<framecount<<"\n";
}
void handle526(const CAN_message_t &msg) //Kilowatts .... what voltage is this using? U1 I believe.
{
Serial.println("hande526");
Sensor.framecount++;
long watt=0;
watt = (long)((msg.buf[5] << 24) | (msg.buf[4] << 16) | (msg.buf[3] << 8) | (msg.buf[2]));
Sensor.KW=watt/1000.0f;
// if(debug2)Serial<<"Power: "<<watt<<" Watts "<<KW<<" kW frames:"<<framecount<<"\n";
}
void handle527(const CAN_message_t &msg) //Ampere-Hours
{
Serial.println("hande527");
Sensor.framecount++;
/*
//ignored
*/
}
void handle528(const CAN_message_t &msg) //kiloWatt-hours
{
Serial.println("hande528");
Sensor.framecount++;
/*
//ignored
*/
}
void STOP()
{
//SEND STOP///////
Serial.println("Stop called, status is ");
CAN_message_t outframe;
outframe.id = 0x411; // Set our transmission address ID
outframe.len = 8; // Data payload 8 bytes
outframe.flags.extended = 0; // Extended addresses 0=11-bit1=29bit
outframe.flags.remote = 0; //<--- THIS MUST BE SET TO ZERO. IF YOUR SENSOR IS IGNORING YOU CHECK THIS BIT
outframe.buf[0]=0x34;
outframe.buf[1]=0x00;
outframe.buf[2]=0x01;
outframe.buf[3]=0x00;
outframe.buf[4]=0x00;
outframe.buf[5]=0x00;
outframe.buf[6]=0x00;
outframe.buf[7]=0x00;
Can1.write(MB1,outframe);
Serial.println("Sent, status is ");
Can1.mailboxStatus();
}
void START()
{
Serial.println("Start called, status is ");
//SEND START///////
CAN_message_t outframe;
outframe.id = 0x411; // Set our transmission address ID
outframe.len = 8; // Data payload 8 bytes
outframe.flags.extended = 0; // Extended addresses 0=11-bit1=29bit
outframe.flags.remote=0; //<--- THIS MUST BE SET TO ZERO. IF YOUR SENSOR IS IGNORING YOU CHECK THIS BIT
outframe.buf[0]=0x34;
outframe.buf[1]=0x01;
outframe.buf[2]=0x01;
outframe.buf[3]=0x00;
outframe.buf[4]=0x00;
outframe.buf[5]=0x00;
outframe.buf[6]=0x00;
outframe.buf[7]=0x00;
Can1.write(MB1,outframe);
Serial.println("Sent, status is ");
Can1.mailboxStatus();
}
void RESTART()
{
//Has the effect of zeroing AH and KWH
Serial.println("Restart called, status is ");
CAN_message_t outframe;
outframe.id = 0x411; // Set our transmission address ID
outframe.len = 8; // Data payload 8 bytes
outframe.flags.extended = 0; // Extended addresses 0=11-bit1=29bit
outframe.flags.remote=0; //<--- THIS MUST BE SET TO ZERO. IF YOUR SENSOR IS IGNORING YOU CHECK THIS BIT
outframe.buf[0]=0x3F;
outframe.buf[1]=0x00;
outframe.buf[2]=0x00;
outframe.buf[3]=0x00;
outframe.buf[4]=0x00;
outframe.buf[5]=0x00;
outframe.buf[6]=0x00;
outframe.buf[7]=0x00;
Can1.write(MB1,outframe);
Serial.println("Sent, status is ");
Can1.mailboxStatus();
}
void deFAULT()
{
//Returns module to original defaults
Serial.println("Default called, status is");
Can1.mailboxStatus();
STOP();
delay(1000);
CAN_message_t outframe;
outframe.id =0x411; // Set our transmission address ID
outframe.len = 8; // Data payload 8 bytes
outframe.flags.extended = 0; // Extended addresses 0=11-bit1=29bit
outframe.flags.remote=0; //<--- THIS MUST BE SET TO ZERO. IF YOUR SENSOR IS IGNORING YOU CHECK THIS BIT
outframe.buf[0]=0x3D;
outframe.buf[1]=0x00;
outframe.buf[2]=0x00;
outframe.buf[3]=0x00;
outframe.buf[4]=0x00;
outframe.buf[5]=0x00;
outframe.buf[6]=0x00;
outframe.buf[7]=0x00;
Can1.write(MB1,outframe);
delay(1000);
sendSTORE();
delay(1000);
START();
delay(1000);
Serial.println("Done, status is ");
Can1.mailboxStatus();
}
void sendSTORE()
{
Serial.println("sendSTORE called, status is ");
Can1.mailboxStatus();
//SEND STORE///////
CAN_message_t outframe;
outframe.id = 0x411; // Set our transmission address ID
outframe.len = 8; // Data payload 8 bytes
outframe.flags.extended = 0; // Extended addresses 0=11-bit1=29bit
outframe.flags.remote=0; //<--- THIS MUST BE SET TO ZERO. IF YOUR SENSOR IS IGNORING YOU CHECK THIS BIT
outframe.buf[0]=0x32;
outframe.buf[1]=0x00;
outframe.buf[2]=0x00;
outframe.buf[3]=0x00;
outframe.buf[4]=0x00;
outframe.buf[5]=0x00;
outframe.buf[6]=0x00;
outframe.buf[7]=0x00;
Can1.write(MB1,outframe);
Serial.println("Sent, status is ");
Can1.mailboxStatus();
}
void initialize()
{
Sensor.firstframe=false;
STOP();
delay(2000);
for(int i=0;i<9;i++)
{
Serial.println("initialization \n");
CAN_message_t outframe;
outframe.id =1041;// 0x411; // Set our transmission address ID
outframe.len = 8; // Data payload 8 bytes
outframe.flags.extended = 0; // Extended addresses 0=11-bit1=29bit
outframe.flags.remote=0; //<--- THIS MUST BE SET TO ZERO. IF YOUR SENSOR IS IGNORING YOU CHECK THIS BIT
outframe.buf[0]=(0x20+i); //loop over each param to reset
outframe.buf[1]=0x42; //I think this sets Little Endian and Cyclic Running
outframe.buf[2]=0x00;
outframe.buf[3]=0xFA; //(0x60+(i*18)); //This sets varying transmission interevals. Not sure if we want this or just the same value for each message
outframe.buf[4]=0x00;
outframe.buf[5]=0x00;
outframe.buf[6]=0x00;
outframe.buf[7]=0x00;
Can1.write(MB1,outframe);
Can1.mailboxStatus();
delay(2000);
Can1.mailboxStatus();
delay(2000);
sendSTORE();
delay(2000);
}
START();
}