Difference between revisions of "MIA electric"

From wiki.bastelbude.grade.de
Jump to: navigation, search
(socketcand ('can over tcp/ip'))
Line 14: Line 14:
 
* setup
 
* setup
 
** install can-utils <pre>sudo apt-get install can-utils</pre>
 
** install can-utils <pre>sudo apt-get install can-utils</pre>
 
+
** install socketcand http://kayak.2codeornot2code.org/tutorial.html
 +
** run
 +
::<pre>slcand -o -s6 -t hw 115200 /dev/ttyusb0</pre>
 +
::<pre>ip link set up slcan0</pre>
 +
::<pre>socketcand -i slcan0</pre>
  
 
=== CANcool ===
 
=== CANcool ===

Revision as of 12:22, 3 January 2018

sandbox

CAN-bus sniffing

socketcand ('can over tcp/ip')

slcand -o -s6 -t hw 115200 /dev/ttyusb0
ip link set up slcan0
socketcand -i slcan0

CANcool

'Berechnungs-Term'

  • operators:
+  // addition
-  // subtraction
*  // multiplication
/  // division
<< // Bit shift left
>> // Bit shift right
&  // AND
|  // OR
~  // XOR
  • variables:
d0 1st byte (decimal)
d1 2nd byte (decimal)
d3 3rd byte (decimal)
d4 ... 
d5 ...
d6 ...
d7 ...
  • samples:
d0                                                                 // unsigned char (8-bit)
(d0 - ((d0 >> 7)*256))                                             // signed char (8-bit) Two's complement
((d0 << 8) + d1) ^= MSB * 256 + LSB                                // unsigned short (16-bit)
(((d0 << 8) + d1) - ((d0 >> 7)*65536))                             // signed short (16-bit) Two's complement
((d0 << 24) + (d1 << 16) + (d2 << 8) + d3)                         // unsigned integer (32-bit)
((d0 << 24) + (d1 << 16) + (d2 << 8) + d3)-((d0 >> 7)*4294967296)) // signed integer (32-bit) Two's complement

256 = (1 << 8)
65536 = (1 << 16)
16777216 = (1 << 24)
4294967296 = (1 << 32)

MIA >> Monitor = MIAtor

// MIA >> Monitor = MIAtor
// all about @ https://bastelbude.grade.de/mediawiki/index.php?title=MIA_electric#MIA_.3E.3E_Monitor_.3D_MIAtor
// based on Voltix's work @ https://miahammia.wordpress.com/2017/10/08/infobox/

// CANbus
#include <mcp_can.h>                   // https://github.com/coryjfowler/MCP_CAN_lib (clockset to MCP_8MHz at mcp_can.h line 98)
#include <SPI.h>

// LCD 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>        // https://github.com/marcoschwartz/LiquidCrystal_I2C 
LiquidCrystal_I2C lcd(0x3F,20,4);     // set the LCD address to 0x3F for a 20 chars and 4 line display

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
float Volts;
float Amps;
float Celsius;
int SOC;
int SOH;
String Status;
String Emergency;
String Regeneration;
float ChargeCurrent;
float ChargeVoltage;
char myBuf[8];
String LCDline[4];

MCP_CAN CAN0(10);                               // Set CS to pin 10


void myPrint(){
  Serial.println(LCDline[0]);
  Serial.println(LCDline[1]);
  Serial.println(LCDline[2]);
  Serial.println(LCDline[3]);

  lcd.setCursor(0,0); 
  lcd.print(LCDline[0]);
  lcd.setCursor(0,1);
  lcd.print(LCDline[1]);
  lcd.setCursor(0,2);
  lcd.print(LCDline[2]);
  lcd.setCursor(0,3);
  lcd.print(LCDline[3]);

  delay(1000);                     // 1 second
  }

void setup()
{
  lcd.init();                      // initialize the lcd 
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  LCDline[0] = "  Hello world!";
  LCDline[1] = "MIA>>Monitor=MIAtor";
  LCDline[2] = "bastelbude.grade.de";
  LCDline[3] = "  ver. 2017-12-21";

  Serial.begin(115200);
  CAN0.begin(CAN_500KBPS);                       // init can bus : baudrate = 500k 
  pinMode(2, INPUT);                            // Setting pin 2 for /INT input


  Serial.println("MCP2515 Library Receive Example...");
  //myPrint();

}

void loop()
{
    if(!digitalRead(2))                          // If pin 2 is low, read receive buffer
    {
      CAN0.readMsgBuf(&len, rxBuf);              // Read data: len = data length, rxBuf = data byte(s)
      rxId = CAN0.getCanId();                    // Get message ID

      if (rxId == 0x620)                                // battery related messageID 620
        {
        LCDline[0] = "Bat: ";
       
        Volts = ((float)(rxBuf[2]*256+rxBuf[3]))/100;   // Voltage with decimals
        Amps = ((float)(rxBuf[0]*256+rxBuf[1]))/10;     // current drawn or regenerated, allow negative
        Celsius = ((float)rxBuf[4]);                    // Temperature, allow negative
        SOC = ((int)rxBuf[5]);                          // State Of Charge

        LCDline[0] =  dtostrf(Volts,4,1,myBuf);        //set first line
        LCDline[0] += "V | ";
        LCDline[0] += dtostrf(Amps,6,1,myBuf);         //length of string=6 decimal places=1
        LCDline[0] += "A |";
        LCDline[0] += dtostrf(Celsius,2,0,myBuf);      //length of string=2 decimal places=0
        LCDline[0] += "C";

        switch (rxBuf[6]&0x07) {                       //mask lowest 3 bits (48+49+50) = status
          case 0:      
            Status = "Ready    | ";
            break;
          case 1:      
            Status = "Run      | ";
            break;
          case 2:      
            Status = "Downgrad.| ";
            break;
          case 3:      
           Status = "Charge    | ";
            break;
          case 4:       
            Status = "Error    | ";
            break;
          case 5:       
            Status = "Init     | ";
            break;
          case 6:       
            Status = "Stop     | ";
            break;
        }

        if ((rxBuf[6]&0x40)== 0)                         // bit 54 Emergency
          {
          Emergency = "noEmergcy";              
          } else {
          Emergency = "Emergency";                 
          }

        if ((rxBuf[6]>>7)== 1)                         // bit 55 Regeneration
          {
          Regeneration = "okRegen | ";           
          } else {
          Regeneration = "noRegen | ";       
          }
        
        SOH = ((int)rxBuf[7]);                          // State Of Health

        LCDline[1] =  Status;                           //set second line
        LCDline[1] += Emergency;
                        
        LCDline[2] =  Regeneration;                     // set third line
        LCDline[2] += "H=";
        LCDline[2] += SOH;
        LCDline[2] += " C=";
        LCDline[2] += SOC;
        LCDline[2] += "%";
       
        Serial.println();                         // new line

        Serial.print("ID 620 raw data: ");
        for(int i = 0; i<len; i++)                // Print each byte of the data
          {
          if(rxBuf[i] < 0x10)                     // If data byte is less than 0x10, add a leading zero
            {
            Serial.print("0");
            }
            Serial.print(rxBuf[i], HEX);
            Serial.print(" ");
            }
        Serial.println();
        
        LCDline[3] = "";                               // set fourth line
        for(int i = 0; i<len; i++)                     // Print each byte of the data
          {
          if(rxBuf[i] < 0x10)                          // If data byte is less than 0x10, add a leading zero
            {
            LCDline[3] += "0";
            }
            sprintf(myBuf,"%hhX",rxBuf[i]);
            LCDline[3] += myBuf;
          }
        
        myPrint();                                   // lcd-print and serial-print of all four lines
    } 

        
   
    if (rxId == 0x621)                                // BMS error messageID 621
        {
        Serial.print("ID 621 raw data: ");
        for(int i = 0; i<len; i++)                    // Print each byte of the data
          {
          if(rxBuf[i] < 0x10)                         // If data byte is less than 0x10, add a leading zero
            {
            Serial.print("0");
            }
            Serial.print(rxBuf[i], HEX);
            Serial.print(" ");
            }
        Serial.println();
        } 
    
    if (rxId == 0x622)                                        // BMS > Charger messageID 622
        {
        ChargeCurrent = ((float)(rxBuf[0]*256+rxBuf[1]))/10;  // Amps with decimals
        ChargeVoltage = ((float)(rxBuf[3]*256+rxBuf[4]))/100;  // Voltage with decimals

        Serial.print("ID 622 raw data: ");
        for(int i = 0; i<len; i++)                    // Print each byte of the data
          {
          if(rxBuf[i] < 0x10)                         // If data byte is less than 0x10, add a leading zero
            {
            Serial.print("0");
            }
            Serial.print(rxBuf[i], HEX);
            Serial.print(" ");
            }
        Serial.println();
        }    
    }

}

DC charging

CCS

  • parts
    • CCS-socket e.g. Phoenix Contact ~EUR 800,-
    • input voltage monitor
    • power contactor (+125A disconnecting device) Tyco ~EUR 150,-
    • current monitor
    • V2G in-vehicle-charge-controller e.g. EVAcharge SE ~EUR 750,-
      • ARM microcontroller
      • Linux OS
      • fully programmable
      • PWM duty cycle detection (CP low level communication)
      • switchable resistors (CP low level communication)
      • HomePlug Green PHY integration (PLC high level communication)
      • Proximity pilot signal input (PP)
      • lock-motor output
      • lock-motor end switch input
      • lock-motor fault pin
      • CAN transceiver (BMS communication)
      • 6 GPIOs (current-monitoring?, voltage-monitoring?, temprature-monitoring?, power contactor-driver?, (contactor-monitoring?))