DIY Electric Car Forums banner

Getting Curtis data into computer

10K views 21 replies 4 participants last post by  sundar@19 
#1 ·
I'm involved in a project where we're converting a diesel boat to electric. All the electronics and the motor work on the bench, no questions there. My main task in this is getting the data about the rpm, power and everything else from the Curtis 1236 controller, into a raspberry pi. I'm having trouble where to start. What pins on the controller and pi should connect, is something between necessary, what software do I need? Say I want to log the rpm to a file every second, as a start. Thanks!
 
#4 ·
Start looking into CAN. There's some info on google on CAN for the Curtis inverters if you look around. They use CAN open, so you'd have to do a lot of protocol implementation. Not much is available over Serial other than what displays on their cheapo little display.
 
#5 ·
CAN is a automotive bidirectional address-based bus. Each "frame" has an ID, length, and data bytes.
A Pi can use CAN if you add an MCP2515 module (cheap on Amazon etc.).
Python works well for CAN since there are lots of libraries you can use.

Software side:
Send an NMT message to put the inverter into state 5. Repeat at least every 100ms.
ID:0x000
DLC:2
Data: 0x01 0x00

Response will be sent with ID=0x700 + node ID. You need the Node ID for the next step (remember it's all in hex).

Then send PDO1 and PDO2 requests.
PDO1
ID:0x200
DLC:8
Data: Whatever

PDO2
ID:0x300
DLC:8
Data: Whatever

Have fun decoding the responses :)


Hardware:
[quick-guide] CAN bus on raspberry pi with MCP2515 - Raspberry Pi Forums

This sets up the MCP2515 CAN interface as a network connection, then you can use can-utils to see what's going on.

Try the python-can library on your Pi. It should work well.

-Isaac

EDIT Also check this thread out: Curtis 1234 and CAN bus
 
#11 ·
CAN is a automotive bidirectional address-based bus. Each "frame" has an ID, length, and data bytes.
A Pi can use CAN if you add an MCP2515 module (cheap on Amazon etc.).
Python works well for CAN since there are lots of libraries you can use.

Software side:
Send an NMT message to put the inverter into state 5. Repeat at least every 100ms.
ID:0x000
DLC:2
Data: 0x01 0x00

Response will be sent with ID=0x700 + node ID. You need the Node ID for the next step (remember it's all in hex).

Then send PDO1 and PDO2 requests.
PDO1
ID:0x200
DLC:8
Data: Whatever

PDO2
ID:0x300
DLC:8
Data: Whatever

Have fun decoding the responses :)


Hardware:
[quick-guide] CAN bus on raspberry pi with MCP2515 - Raspberry Pi Forums

This sets up the MCP2515 CAN interface as a network connection, then you can use can-utils to see what's going on.

Try the python-can library on your Pi. It should work well.

-Isaac

EDIT Also check this thread out: Curtis 1234 and CAN bus
Sir, @Isaac97
I have the hardware setup ready!
I also tested the CAN communication between RPi and arduino which works fine!!
I used CAN python in Pi and seedstudio mcp2515 library in arduino.
Now for connecting Pi to curtis do I need to use the python library called canopen?
Do I need to write VCL code for curtis?
Can you please explain how do I recieve data in RPi?
Thank you
 
#8 ·
While I'm waiting for the HAT to arrive, I'd like to make sure I understand the wiring between it and the controller. Page 22 of the controller manual is about CAN wiring.
1: Is it correct to connect pin 21 (CAN Term H) and 34 (CAN Term L) on the controller together with short wires? If yes, what does this accomplish? Enabling CAN?
2: Pin 23 (CANH) and 35 (CANL) correspond nicely with the CANH and CANL shown on the HAT here:
119982

Just connect pin 23 to CANH and 35 to CANL? Anything else I should connect?

Thanks for all the help :)
 
#9 ·
1. Yes, that is correct. Connecting those will enable the CAN termination resistors. I don't remember if I did that but my CAN adapter was terminated already.
Termination resistors place a load on the drivers -- I'm not really sure why this is necessary, it probably has something to do with making the signals cleaner (since there's a current flowing). It is definitely needed though, if you skip resistors the signals look really nasty and reflect around inside the wires and also don't work.

2. Correct. Also hook the CAN_GND_ISO to the Curtis ground :)

-Isaac
 
#10 ·
Hello again!
There has been some progress. I could not make the HAT work, so I also bought a USB CAN adapter. I like this better, as I can try it out on my laptop (also with Linux) before involving the Pi.

We had some wiring to do. The AmpSeal plug for the controller did not have any CAN wires, so I had to order the pins, wire them up and get them in there according to the manual. A lot of time spent on waiting for packages,

Today, we started actually trying to read something from the CANL and CANH. But first, we checked the resistance of the CANL and CANH from the controller when everything was powered off, 120 Ohms. And when connected to the USB CAN adapter, 60 Ohms. so far so good. We then turned the rig on and measured the voltage across ground (battery minus) and CANH. 2.8V. And across ground and CANL, 2.1V. We used a (high quality) voltmeter, so these would be averages. But since it's not 2.5V, it's a good sign right? 2.5V would mean no messages, if I understand the canbus correctly.

So I connected the adapter and I think the problem lies here. I struggle to find a guide specific to the adapter I purchased, so I can only try various guides. Most of them say roughly the same things. I tried this one. I could skip step 2, the rest went through without errors. But the candump said nothing, and ifconfig said no packets were received. This is where I'm stuck. I tried a few CAN speeds, still nothing.

What should I try next?
 
#12 ·
Fortunately, VCL is unnecessary.
Python canopen is not necessary either - I am not familiar with it, but it might make the job easier.
You should find some documentation on the CANOpen protocol and learn how to send a NMT message to all nodes. That will tell you which address to use for the next few steps.

-Isaac
 
#13 ·
Thank you so much sir, where can I find resources regarding sending nmt messages to nodes and finding out address? Is there any documentation from curtis regarding the same? Now I tried to scan nodes and found one of the node being successfully scanned and printed by python canopen. How do I proceed?
 
#21 ·
Hello again!
I've been trying a lot with slcand, ip, ifconfig and such on my computer with the motor running slowly and the CANbus seemingly correctly connected. Whatever I try, nothing comes out. There are those CAN speeds (-s1 (20kbps) to -s6 (500kbps)), whether or not it is can or vcan, and maybe more variables I'm not aware of. I've tried all the CAN speeds. My USB-CAN adapter has an "ACT" LED, I assume this stands for activity. This lights a solid orange/red.

I'm starting to suspect the controller does not send CAN signals at all. The controller was pulled from a G-Wiz/REVAi which did not use the CAN interface, so I would not be surprised if CAN is turned off in the controller. As far as I know, the only way to enable it is to buy the 1313 or 1314, which cost hundreds of dollars. Is this the case?

I'm also looking at the Curtis 840. I still want the data into my own computer, but the 840 points to the fact that the serial connection also can give me the information I want. If this is the route to go, can you guys point me to how I can read and parse the serial data from the Curtis 1236 on a computer?

Thanks :)
 
#22 · (Edited)
You can buy an Arduino and a cheap SPI to CAN module and connect it with arduino.
SPI 2 CAN module
A general example to send a NMT message via arduino to curtis to put it into operational state.
C:
#include <SPI.h>
#include <mcp_can.h>

const int spiCSPin = 10;
int ledHIGH    = 1;
int ledLOW     = 0;

MCP_CAN CAN(spiCSPin);

void setup()
{
    Serial.begin(115200);

    while (CAN_OK != CAN.begin(CAN_500KBPS,MCP_8MHz))
    {
        Serial.println("CAN BUS init Failed");
        delay(100);
    }
    Serial.println("CAN BUS Shield Init OK!");
}

unsigned char stmp[2] = {0,0};
 
void loop()
{
  stmp[0]=0x01;//Operational state
  stmp[1]=0x00;//target node ==> set 0x00 for all nodes
  Serial.println("In loop");
  CAN.sendMsgBuf(0x00, 0, 2, stmp);// COB-ID, 0 for standard ID and 1 for extended ID, 2 is the data length , stmp is the data
  delay(120);//heartbeat message rate
}
A general example to send a SDO message via arduino to curtis to retrieve Key Switch Voltage

C:
#include <SPI.h>
#include <mcp_can.h>

const int spiCSPin = 10;

MCP_CAN CAN(spiCSPin);


void recv()
{
  unsigned char len = 0;
  unsigned char buf[8];
  unsigned char a,b,c;
  int a1,b1,c1;
  if(CAN_MSGAVAIL == CAN.checkReceive())
    {
        CAN.readMsgBuf(&len, buf);

        unsigned long canId = CAN.getCanId();

        Serial.println("-----------------------------");
        Serial.print("Data from ID: 0x");
        Serial.println(canId, HEX);

        for(int i = 0; i<len; i++)
        {
            Serial.print(buf[i]);
            Serial.print("\t");
            a = buf[4];
            b = buf[5];
         

         }
        a1 = (int)a;
        b1 = (int)b;
        c1 = b1 << 8 | a1 ;
        Serial.print("\nKey_switch_voltage:");
        Serial.println(c1);
        Serial.println();
    }
}

void setup()
{
    Serial.begin(115200);

    while (CAN_OK != CAN.begin(CAN_500KBPS,MCP_8MHz))
    {
        Serial.println("CAN BUS init Failed");
        delay(100);
    }
    Serial.println("CAN BUS Shield Init OK!");
}

unsigned char stmp[8] = {0,0,0,0,0,0,0,0};
 
void loop()
{
  stmp[0]= 0x40; //Read Dictionary Object
  stmp[1]= 0x4D;//second eight bytes of hex value(sub index)
  stmp[2]= 0x32;// first eight bytes of hex value (index)
  stmp[3]= 0x00;
  stmp[4]= 0x00;
  stmp[5]= 0x00;
  stmp[6]= 0x00;
  stmp[7]= 0x00;
  Serial.println("In loop");
  CAN.sendMsgBuf(0x626, 0, 8, stmp);//... , 0 for standard ID and 1 for extended ID, ... , stmp is the data
  delay(100);// timeout
  recv();
}
 
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top