Управление автомобилем посредством CAN шиной

yamkin
Offline
Зарегистрирован: 29.08.2017
// на основе демо: can-шине щита, отправить данные
#включить <mcp_can.ч>
#включить <спи.ч>

// штырь CS версии после v1.1 по умолчанию в Д9
// версия V0.9б и v1.0 по умолчанию Д10
константный инт SPI_CS_PIN = 10;

MCP_CAN может(SPI_CS_PIN); // Устанавливаем пин в CS

байт константный high2 = 7;
байт константный high4 = 4;
константный байт low4 = 5;
/*--------------------------------------------------------*/
установка пустоты()
{
Серийный.методы begin(9600);

 pinMode(high2, INPUT_PULLUP);
 pinMode(high4, INPUT_PULLUP);
 pinMode(low4, INPUT_PULLUP);
/*--------------------------------------------------------*/ 
START_INIT:

 если(CAN_OK == может.начать(CAN_500KBPS)) // инициализации can-шина : скорость передачи = 500к
{
 Серийный.код println("can шина щит инит ок!");
}
еще
{
 Серийный.код println("can шина щит инит незачет");
 Серийный.код println("init может автобус снова щит");
задержка(1000);
 гото START_INIT;
}
}
/*-------------------------------------------------*/
инт crcTable[256] = {
 0х00, 0x1D, 0x3A, 0x27 раздел, 0x74, 0x69, 0x4E, 0x53,
 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81 до, 0xA6, 0xBB,
 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
 0х25, 0x38 ошибкой, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
 0x87, 0x9A, 0xBD, 0xa0 и 0xF3, 0xEE, 0xC9, 0xD4,
 0x6F, 0x72, 0x55, 0x48, 0x1B, 0х06, 0x21, 0x3C,
 0x4A, 0х57, 0x70, 0x6D, 0x3E, 0x23, 0х04, 0x19,
 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, на 0x40,
 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
 0xDE, 0xC3, 0xE4, 0xF9, как 0xaa, 0xB7, 0x90, 0x8D,
 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
 0x94, 0x89, 0хае, 0xB3, это 0xE0, 0xFD, 0xDA, 0xC7,
 0x7C, 0x61, 0x46, 0x5B, бит 0x08, 0x15, 0x32 в, с 0x2f,
 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xff, что 0xE2,
 0x26, 0x3B, 0x1C, 0х01, 0x52, 0x4F, 0x68, 0x75,
 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0х80, 0x9D,
 0xEB, 0xF6, 0xD1, 0xCC, 0x9f в, 0x82, 0xA5, 0xB8,
 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0х50,
 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
 0x49, 0x54, 0x73, 0x6E, 0x3D, 0х20, 0x07, 0x1A,
 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
 0x84, 0x99, 0xbe для того, 0xA3, 0xf0 в системе, 0xED, 0xCA, 0xD7,
 0x35, отличается от значения 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
 Как 0xdd, от 0xc0, 0xE7, 0xFA, с кодом 0xa9, 0xB4, 0x93, 0x8E,
 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
 0х10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, до 0xfc, 0xE1,
 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
 0х7f, 0x62, 0х45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
 0x97, 0x8A, 0xAD, 0xB0, 0xE3, кодами 0xfe, 0xD9, 0xC4 };


инт calculateCRC (Тип int msgLen, инт crcPos, байт *мсг) {

 Тип int curPos = 0;
 инт crc8 = 255;
 инт pduLength = 0;

 для (pduLength = msgLen; pduLength > 0 ; pduLength--) {
 если (curPos != crcPos) {
 crc8 = crcTable[crc8 ^ мсг[curPos]];
}
curPos++;
}

 crc8 = (байта)((~crc8) & значение 0xff); дополнения /* вычислить по j1850 от спецификаций. */
 мсг[crcPos] = crc8;

 возврат 0;

}

пустота setBit (байт * msgByte, байт пос) {

 *msgByte |= 1 << пос;

}

пустота clrBit( байт * msgByte, байт пос ) {

 *msgByte &= ~(1 << пос);

}

пустота updBtnByte( байт * msgByte, бтн байт, байт пос ) {

 если ( digitalRead(бтн) == низкий ) {

 setBit( msgByte, пос );

 } еще {

 clrBit( msgByte, пос );

}
}
/*-----------------------------------------------------------------------------------*/
байт msgCC_SLStatus[] = {0, 0, 0, 0, 0, 0, 0, 0};
байт msgCC_SLStatus_LC = 0х00;



недействительными петля()
{ 

 // Расчета ЛНР
 если (msgCC_SLStatus_LC < 15) {

msgCC_SLStatus_LC++;

 } еще {

 msgCC_SLStatus_LC = 0;

}

 если (digitalRead (high2) == высокая){
 msgCC_SLStatus[0] = 0х00;
 } 

 если (digitalRead (high4) == высокая){
 msgCC_SLStatus[0] = 0х01;
}

 если (digitalRead (low4) == высокая){
 msgCC_SLStatus[0] = 0x02;
}

 msgCC_SLStatus[6] = msgCC_SLStatus_LC; // смещаемся влево по матрице

 calculateCRC(8, 7, msgCC_SLStatus);

 // передачи данных: идентификатор, каркас стандартный, данных лен, данных баф
 Может.sendMsgBuf(0x3E8, 0, 8, msgCC_SLStatus);

 задержка(100); // отправка данных в 10мс
}

/*********************************************************************************************************
 КОНЕЦ ФАЙЛА
*********************************************************************************************************/

 

yamkin
Offline
Зарегистрирован: 29.08.2017

Всем доброго вечера!

Не могу разобраться где я ошибся с кодом.

а именно:

if (digitalRead (high2) == HIGH){
      msgCC_SLStatus[0] = 0x00;
      } 
    
    if (digitalRead (high4) == HIGH){
      msgCC_SLStatus[0] = 0x01;
      }
    
    if (digitalRead (low4) == HIGH){
      msgCC_SLStatus[0] = 0x02;
      }
 когда переключаю пины на шилде не могу перейти из одного состояния в другие 2
 
Где ошибся, подскажите? 
CheS_66
CheS_66 аватар
Offline
Зарегистрирован: 08.02.2017

Ээээ.... А зачем скетч на русский перевели?

установка пустоты()

Повеселило)))

 Серийный.код println("can шина щит инит ок!");
}
еще
{
 Серийный.код println("can шина щит инит незачет");
 Серийный.код println("init может автобус снова щит");
задержка(1000);

Убило))))

yamkin
Offline
Зарегистрирован: 29.08.2017
// based on demo: CAN-BUS Shield, send data
#include <mcp_can.h>
#include <SPI.h>

// 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;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

const byte high2  = 7;
const byte high4  = 4;
const byte low4  = 5;
/*--------------------------------------------------------*/
void setup()
{
    Serial.begin(9600);
    
    pinMode(high2, INPUT_PULLUP);
    pinMode(high4, INPUT_PULLUP);
    pinMode(low4, INPUT_PULLUP);
/*--------------------------------------------------------*/    
START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS))                   // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(1000);
        goto START_INIT;
    }
}
/*-------------------------------------------------*/
int crcTable[256] = {
		0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
		0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
		0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
		0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
		0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
		0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
		0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
		0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
		0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
		0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
		0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
		0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
		0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
		0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
		0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
		0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
		0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
		0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
		0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
		0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
		0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
		0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
		0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
		0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
		0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
		0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
		0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
		0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
		0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
		0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
		0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
		0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4  };

	
int calculateCRC (int msgLen, int crcPos, byte *msg) {
  	
	int curPos = 0;
	int crc8 = 255;
	int pduLength = 0;

	for (pduLength = msgLen; pduLength > 0 ; pduLength--) {
		if (curPos != crcPos) {
			crc8 = crcTable[crc8 ^ msg[curPos]];
		}
		curPos++;
	}

	crc8 = (byte)((~crc8) & 0xFF); /* calculate one's complement according to J1850 spec. */
	msg[crcPos] = crc8;
	
	return 0;

}

void setBit (byte * msgByte, byte pos) {
  
  *msgByte |= 1 << pos;
  
}

void clrBit( byte * msgByte, byte pos ) {
  
  *msgByte &= ~(1 << pos);
  
}

void updBtnByte( byte * msgByte, byte btn, byte pos ) {
  
  if ( digitalRead(btn) == LOW ) {
    
    setBit( msgByte, pos );
    
  } else {
    
    clrBit( msgByte, pos );
    
  }
}
/*-----------------------------------------------------------------------------------*/
byte msgCC_SLStatus[] = {0, 0, 0, 0, 0, 0, 0, 0};
byte msgCC_SLStatus_LC = 0x00;



void loop()
{  
  
    // LC calculation
    if (msgCC_SLStatus_LC < 15) {
      
      msgCC_SLStatus_LC++;
    
    } else {
      
      msgCC_SLStatus_LC = 0;
    
    }

    if (digitalRead (high2) == HIGH){
      msgCC_SLStatus[0] = 0x00;
      } 
    
    if (digitalRead (high4) == HIGH){
      msgCC_SLStatus[0] = 0x01;
      }
    
    if (digitalRead (low4) == HIGH){
      msgCC_SLStatus[0] = 0x02;
      }
    
    msgCC_SLStatus[6] = msgCC_SLStatus_LC; // shifted left according to matrix
              
    calculateCRC(8, 7, msgCC_SLStatus);

    // send data:  id, standrad frame, data len, data buf
    CAN.sendMsgBuf(0x3E8, 0, 8, msgCC_SLStatus);

    delay(100);                       // send data per 10ms
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

 

yamkin
Offline
Зарегистрирован: 29.08.2017

Добрый вечер!

Перезалил, скетч открывал с помощью Notepad++ по этому перевелся на русский язык

b707
Offline
Зарегистрирован: 26.05.2017

yamkin - в том куске, что вы спрашиваете - явных ошибок нет, разбирайтесь с логикой программы.

MaksVV
Offline
Зарегистрирован: 06.08.2015

yamkin пишет:

Всем доброго вечера!

Не могу разобраться где я ошибся с кодом.

а именно:

if (digitalRead (high2) == HIGH){
      msgCC_SLStatus[0] = 0x00;
      } 
    
    if (digitalRead (high4) == HIGH){
      msgCC_SLStatus[0] = 0x01;
      }
    
    if (digitalRead (low4) == HIGH){
      msgCC_SLStatus[0] = 0x02;
      }
 когда переключаю пины на шилде не могу перейти из одного состояния в другие 2
 
Где ошибся, подскажите? 

не понятно что значит "переключаю пины на шилде". Вы проверяете состояния трёх разных пинов (входов) ардуино последовательно и в зависимости от их состояния присваеваете значение нулевому байту массива (в данном случае фрейма CAN) msgCC_SLStatus . Т.е. в основном будет записываться по пину low4 т.к. проверка по нему в последнюю очередь, а так как включена внутренняя подтяжка, пины будут в HIGH по умолчанию. и в этот байт будет записываться 0х02.  Даже если в LOW любой из этих входом перевести , ничего не произойдет, т.к. в скетче нет проверки пинов на LOW.  А что у вас не работает? 

и вместо этого 

const byte high2  = 7;
const byte high4  = 4;
const byte low4  = 5;

лучше так наверное 

#define high2   7
#define high4   4
#define low4   5

 

yamkin
Offline
Зарегистрирован: 29.08.2017

Добрый день,

Суть работы в чем.

Есть автомобиль с раздаточной коробкой которая работает по CAN протоколу.

Есть комбинация приборов которая зажигает режимы раздаточной коробки по проводу (аналоговый сигнал).

Для начала хочу симитировать режимы переключения раздатки для загорания соответствующей лампочки в комбинации приборов. Отпраляю соответствующий CAN сигнал режима раздатки с ардуино и при замыкании пинов 7,4,5, загораю соответствующую лампочку. 

Следующим этапом хочу попробовать принимать на ардуино CAN сигналы раздаточной коробки и перекодировать их в аналоговый сигнал для комбинации приборов, что бы та в свою очередь загорала соответствующий сигнализатор. Как это сделать пока еще не знаю т.к новичок в этом деле. 

yamkin
Offline
Зарегистрирован: 29.08.2017

MaksVV пишет:

yamkin пишет:

Всем доброго вечера!

Не могу разобраться где я ошибся с кодом.

а именно:

if (digitalRead (high2) == HIGH){
      msgCC_SLStatus[0] = 0x00;
      } 
    
    if (digitalRead (high4) == HIGH){
      msgCC_SLStatus[0] = 0x01;
      }
    
    if (digitalRead (low4) == HIGH){
      msgCC_SLStatus[0] = 0x02;
      }
 когда переключаю пины на шилде не могу перейти из одного состояния в другие 2
 
Где ошибся, подскажите? 

не понятно что значит "переключаю пины на шилде". Вы проверяете состояния трёх разных пинов (входов) ардуино последовательно и в зависимости от их состояния присваеваете значение нулевому байту массива (в данном случае фрейма CAN) msgCC_SLStatus . Т.е. в основном будет записываться по пину low4 т.к. проверка по нему в последнюю очередь, а так как включена внутренняя подтяжка, пины будут в HIGH по умолчанию. и в этот байт будет записываться 0х02.  Даже если в LOW любой из этих входом перевести , ничего не произойдет, т.к. в скетче нет проверки пинов на LOW.  А что у вас не работает? 

и вместо этого 

const byte high2  = 7;
const byte high4  = 4;
const byte low4  = 5;

лучше так наверное 

#define high2   7
#define high4   4
#define low4   5

 

 

Добрый день!

Я новичек в этом деле, как программно мне необходимо написать проверку состояния пинов?

Можете в качестве примера написать код?

 

b707
Offline
Зарегистрирован: 26.05.2017

yamkin пишет:

Добрый день!

Я новичек в этом деле, как программно мне необходимо написать проверку состояния пинов?

Вам надо сначала определиться с логикой. Если ОДНОВРЕМЕННО будут включены несколько пинов - что должно происходить? - от ответа на этот вопрос зависит код

yamkin
Offline
Зарегистрирован: 29.08.2017

b707 пишет:

yamkin пишет:

Добрый день!

Я новичек в этом деле, как программно мне необходимо написать проверку состояния пинов?

Вам надо сначала определиться с логикой. Если ОДНОВРЕМЕННО будут включены несколько пинов - что должно происходить? - от ответа на этот вопрос зависит код

Добрый день!

Вариант одновременного включения нескольких пинов не возможен.

Мне необходимо что бы значения которые я присвоил к пинам, отображались(переключались) в нулевом байте данного кадра.

Пример: замыкаю 7 пин в [0] байте значение 0x00 загорается соответствующий индикатор;

замыкаю 4 пин в [0] байте значение 0х01 загорается соответствующий индикатор;

когда ни один из контактов не замкнут, состояние в [0] бите должно быть = 0.

Как то так)))

 

b707
Offline
Зарегистрирован: 26.05.2017

yamkin пишет:

Мне необходимо что бы значения которые я присвоил к пинам, отображались(переключались) в нулевом байте данного кадра.

Пример: замыкаю 7 пин в [0] байте значение 0x00 загорается соответствующий индикатор;

замыкаю 4 пин в [0] байте значение 0х01 загорается соответствующий индикатор;

когда ни один из контактов не замкнут, состояние в [0] бите должно быть = 0.

Пожалуйста, перечитайте внимательно, что вы написали. Байты и биты не путаете? И чем отличается состояние 0х00 при замкнутом пине 7 от состояния, когда не замкнуто ничего?

yamkin
Offline
Зарегистрирован: 29.08.2017

b707 пишет:

yamkin пишет:

Мне необходимо что бы значения которые я присвоил к пинам, отображались(переключались) в нулевом байте данного кадра.

Пример: замыкаю 7 пин в [0] байте значение 0x00 загорается соответствующий индикатор;

замыкаю 4 пин в [0] байте значение 0х01 загорается соответствующий индикатор;

когда ни один из контактов не замкнут, состояние в [0] бите должно быть = 0.

Пожалуйста, перечитайте внимательно, что вы написали. Байты и биты не путаете? И чем отличается состояние 0х00 при замкнутом пине 7 от состояния, когда не замкнуто ничего?


Нулевой байт данного кадра должен нести в себе 3 состояния
1) 0x00 1й бит данного байта
2) 0x01 2й бит данного байта
3) 0x02 3й бит данного байта

0x00 первое состояние раздаточной коробки
0х01 второе состояние
0x02 третье состояние

Получается что мне необходимы всего два пина для второго и третьего состояний

b707
Offline
Зарегистрирован: 26.05.2017

yamkin пишет:
Нулевой байт данного кадра должен нести в себе 3 состояния 1) 0x00 1й бит данного байта 2) 0x01 2й бит данного байта 3) 0x02 3й бит данного байта 0x00 первое состояние раздаточной коробки 0х01 второе состояние 0x02 третье состояние Получается что мне необходимы всего два пина для второго и третьего состояний

Вы продолжаете путать байты и биты. Если каждое из состояний коробки кодируется своим битом, то это будет так:

0х01 - нулевой бит установлен в "1"

0х02 - первый бит установлен в "1"

0х04 - второй бит установлен в "1"

 

yamkin
Offline
Зарегистрирован: 29.08.2017

b707 пишет:

yamkin пишет:
Нулевой байт данного кадра должен нести в себе 3 состояния 1) 0x00 1й бит данного байта 2) 0x01 2й бит данного байта 3) 0x02 3й бит данного байта 0x00 первое состояние раздаточной коробки 0х01 второе состояние 0x02 третье состояние Получается что мне необходимы всего два пина для второго и третьего состояний

Вы продолжаете путать байты и биты. Если каждое из состояний коробки кодируется своим битом, то это будет так:

0х01 - нулевой бит установлен в "1"

0х02 - первый бит установлен в "1"

0х04 - второй бит установлен в "1"

 

В том месте где подчеркнуто меняется состояние раздаточной коробки:

0x00 - постоянное состояние

0x01 - один из режимов

0x02 - один из режимов

0x03 - не тспользуется

0x04 - ошибочный режим (в случае какой либо поломки)

yamkin
Offline
Зарегистрирован: 29.08.2017

yamkin пишет:

b707 пишет:

yamkin пишет:
Нулевой байт данного кадра должен нести в себе 3 состояния 1) 0x00 1й бит данного байта 2) 0x01 2й бит данного байта 3) 0x02 3й бит данного байта 0x00 первое состояние раздаточной коробки 0х01 второе состояние 0x02 третье состояние Получается что мне необходимы всего два пина для второго и третьего состояний

Вы продолжаете путать байты и биты. Если каждое из состояний коробки кодируется своим битом, то это будет так:

0х01 - нулевой бит установлен в "1"

0х02 - первый бит установлен в "1"

0х04 - второй бит установлен в "1"

 

В том месте где подчеркнуто меняется состояние раздаточной коробки:

0x00 - постоянное состояние

0x01 - один из режимов

0x02 - один из режимов

0x03 - не тспользуется

0x04 - ошибочный режим (в случае какой либо поломки)

Картина получается следующая, если я даже не замыкаю один из назначенных контактов, ардуино выдает состояние 0x02. Т.е мне программно как я понимаю необходимо реализовать сброс последнего состояния после того как контакт будет разомкнут.

b707
Offline
Зарегистрирован: 26.05.2017

yamkin пишет:

Картина получается следующая, если я даже не замыкаю один из назначенных контактов, ардуино выдает состояние 0x02. Т.е мне программно как я понимаю необходимо реализовать сброс последнего состояния после того как контакт будет разомкнут.

А вам об этом MaksVV еще в сообщении #6 писал.

Вам, кроме проверки каждого из пинов - необходимо предусмотреть условие "если ни один пин не включен".И проще всего это сделать в виде цепочки if... elseif....elseif....else

MaksVV
Offline
Зарегистрирован: 06.08.2015
всегда когда что то спрашиваете, нужно описывать максимально понятно и подробно. Чтобы экономить себе время и тему не наращивать. Правильно заданный вопрос - половина ответа. 
 
yamkin пишет:
Для начала хочу симитировать режимы переключения раздатки для загорания соответствующей лампочки в комбинации приборов. Отпраляю соответствующий CAN сигнал режима раздатки с ардуино и при замыкании пинов 7,4,5, загораю соответствующую лампочку.
 
Мне это не понятно. Вы должны обяъснить как должно изначально всё работать в штатном варианте. И для чего вы хотите использовать ардуино. Т.е. почему должна вмешиваться ардуино. Я так понял,  ардуино используется, потому что какой то элемент (панель?) установлен не штатный? Почему в штатном варианте не отображается на панели режим раздатки?
 
Просто вы сказали

yamkin пишет:

Есть комбинация приборов которая зажигает режимы раздаточной коробки по проводу (аналоговый сигнал).

yamkin пишет:
Для начала хочу симитировать режимы переключения раздатки для загорания соответствующей лампочки в комбинации приборов.

Дак для этого НЕ нужен CAN. Нужно сделать просто как вы сами сказали 

yamkin пишет:
при замыкании пинов 7,4,5, загораю соответствующую лампочку

 

Т.е. подать соответствующий АНАЛОГОВЫЙ сигнал на щиток приборов для имитации индикации режима раздатки

MaksVV
Offline
Зарегистрирован: 06.08.2015

yamkin пишет:
Пример: замыкаю 7 пин

Замыкаю на что? на массу (gnd)? Если да, то это правильно при вашем скетче. 

Моё видение такое. Изначально, в штатном варианте, панель приборов принимала положение раздатки по CAN шине. По какой то причине вам пришлось поменять панель приборов, в которой индикация положения раздатки осуществляется по аналоговым сигналам, а не по CAN. Ардуино должна быть переводчиком сигналов положения раздатки из CAN в аналоговые сигналы на щиток приборов, чтобы он показывал режим раздатки. 

Если да, то так и надо было написать. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

yamkin пишет:
Можете в качестве примера написать код?

может так? 

// based on demo: CAN-BUS Shield, send data
#include <mcp_can.h>
#include <SPI.h>

// 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;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

#define high2   7
#define high4   4
#define low4   5

/*--------------------------------------------------------*/
void setup()
{
    Serial.begin(9600);
    
    pinMode(high2, INPUT_PULLUP);
    pinMode(high4, INPUT_PULLUP);
    pinMode(low4, INPUT_PULLUP);
/*--------------------------------------------------------*/    
START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS))                   // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(1000);
        goto START_INIT;
    }
}
/*-------------------------------------------------*/
int crcTable[256] = {
    0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
    0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
    0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
    0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
    0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
    0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
    0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
    0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
    0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
    0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
    0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
    0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
    0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
    0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
    0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
    0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
    0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
    0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
    0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
    0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
    0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
    0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
    0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
    0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
    0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
    0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
    0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
    0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
    0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
    0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
    0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
    0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4  };

  
int calculateCRC (int msgLen, int crcPos, byte *msg) {
    
  int curPos = 0;
  int crc8 = 255;
  int pduLength = 0;

  for (pduLength = msgLen; pduLength > 0 ; pduLength--) {
    if (curPos != crcPos) {
      crc8 = crcTable[crc8 ^ msg[curPos]];
    }
    curPos++;
  }

  crc8 = (byte)((~crc8) & 0xFF); /* calculate one's complement according to J1850 spec. */
  msg[crcPos] = crc8;
  
  return 0;

}

void setBit (byte * msgByte, byte pos) {
  
  *msgByte |= 1 << pos;
  
}

void clrBit( byte * msgByte, byte pos ) {
  
  *msgByte &= ~(1 << pos);
  
}

void updBtnByte( byte * msgByte, byte btn, byte pos ) {
  
  if ( digitalRead(btn) == LOW ) {
    
    setBit( msgByte, pos );
    
  } else {
    
    clrBit( msgByte, pos );
    
  }
}
/*-----------------------------------------------------------------------------------*/
byte msgCC_SLStatus[] = {0, 0, 0, 0, 0, 0, 0, 0};
byte msgCC_SLStatus_LC = 0x00;



void loop()
{  
  
    // LC calculation
    if (msgCC_SLStatus_LC < 15) {
      
      msgCC_SLStatus_LC++;
    
    } else {
      
      msgCC_SLStatus_LC = 0;
    
    }
// если замыкаем пин 7 на массу, остальные не замкнуты не на что. 
    if (digitalRead (high2) == LOW && digitalRead (high4) == HIGH && digitalRead (low4) == HIGH){
      msgCC_SLStatus[0] = 0x00;
      } 
// если замыкаем пин 4 на массу, остальные не замкнуты не на что. 
    if (digitalRead (high2) == HIGH && digitalRead (high4) == LOW && digitalRead (low4) == HIGH){
      msgCC_SLStatus[0] = 0x01;
      }
// если замыкаем пин 5 на массу, остальные не замкнуты не на что. 
    if (digitalRead (high2) == HIGH && digitalRead (high4) == HIGH && digitalRead (low4) == LOW){
      msgCC_SLStatus[0] = 0x02;
      }

// если все пины ни на что не замкнуты
 if (digitalRead (high2) == HIGH && digitalRead (high4) == HIGH && digitalRead (low4) == HIGH){
      //msgCC_SLStatus[0] = 0x00; тут написать значение байта в этом режиме состояния пинов. 
      //из вашего описания не понятно
      }




      
    
    msgCC_SLStatus[6] = msgCC_SLStatus_LC; // shifted left according to matrix
              
    calculateCRC(8, 7, msgCC_SLStatus);

    // send data:  id, standrad frame, data len, data buf
    CAN.sendMsgBuf(0x3E8, 0, 8, msgCC_SLStatus);

    delay(100);                       // send data per 10ms
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

 

yamkin
Offline
Зарегистрирован: 29.08.2017
void loop() 
 { 
     unsigned char len = 0; 
     unsigned char buf[8]; 
 
     if(CAN_MSGAVAIL == CAN.checkReceive())  // проверка кан сигналов 
     { 
         CAN.readMsgBuf(&len, buf);    // как задать в данной строке что бы принимались определенные кан сигналы, с определенными данными
          unsigned int canId = CAN.getCanId(); //здесь вообще не понятно что происходит



//Начал писать код, какую функцию использовать для того что бы ардуино принял кан сигнал я не знаю.
// Понимаю что должны быть условия при определенных значениях которые примет ардуино.



#include <SPI.h>
#include "mcp_can.h"


// 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
;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin

#define ledPin_4H 5
#define ledPin_4L 6
#define ledPin_4WD_CHECK 7

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

    while (CAN_OK != CAN.begin(CAN_500KBPS))              // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println(" Init CAN BUS Shield again");
        delay(100);
    }
    Serial.println("CAN BUS Shield init ok!");


    pinMode(ledPin_4H,OUTPUT);
    pinMode(ledPin_4L,OUTPUT);
    pinMode(ledPin_4WD_CHECK,OUTPUT);
}

byte ipcDriveModeInfo[8] = {0,0,0,0,0,0,0,0};

void loop() {
  if()

}

yamkin пишет:
Пример: замыкаю 7 пин

Замыкаю на что? на массу (gnd)? Если да, то это правильно при вашем скетче. 

Моё видение такое. Изначально, в штатном варианте, панель приборов принимала положение раздатки по CAN шине. По какой то причине вам пришлось поменять панель приборов, в которой индикация положения раздатки осуществляется по аналоговым сигналам, а не по CAN. Ардуино должна быть переводчиком сигналов положения раздатки из CAN в аналоговые сигналы на щиток приборов, чтобы он показывал режим раздатки. 

Если да, то так и надо было написать. 

[/quote]

Добрый день!

Изначально в качесте эксперимента я хотел реализовать что бы поток CAN генерила ардуино.

Но теперь передомной стоит задача которую Вы описали выше.

Т.к я новичок в этом деле, можете подсказать как мне нужно прописать в коде для того, что бы ардуино понимал какие сообщения ему нужно ловить. Я знаю какие конкретно необходимо ловить, только не знаю как прописать это программно. Можете написать примерный код?

Возможно это делается как я вложил код выше?

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

yamkin пишет:
Изначально в качесте эксперимента я хотел реализовать что бы поток CAN генерила ардуино.

Не очень понятно, что бы это дало. У вас и так в шине уже летает инфа о режимах раздатки. Ну послали бы вы ещё своё сообщение в CAN. И что? на чем вы собирались увидеть результат? Щиток то ведь по аналогу состояние раздатки получает. 

В общем нарисуйте схему проводов щитка приборов, на которых присутствуют аналоговые сигналы о режимах раздатки. Распишите все режимы - т.е. что присутствует на каждом проводе при каждом режиме. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот примерный скетч, но аппаратный фильтр сообщений, которые будет принимать CAN контроллер, на этой библиотеке не знаю как сделать, поэтому все сообщения будут сыпаться, возможно будут тормоза. Там сделан вывод в сериал-монитор всех сообщений (Не забываем в сериал мониторе скорость 115200 справа внизу выставить), чтоб понять работает ли вообще приём сообщений из CAN.  Если ардуино будет правильно принимать ссобщения из кан шины, то можно из скетча убрать всё, что связано с сериал соединением. 

и ещё, если у вас CAN адаптер, не шилд, а  маленький такой с кварцем на 8 MHZ, то надо кое что поменять, а то не будет работать. 

 

#include <SPI.h>
#include <mcp2515.h>

#define ledPin_4H 5
#define ledPin_4L 6
#define ledPin_4WD_CHECK 7


struct can_frame canMsg;
MCP2515 mcp2515(10);


void setup() {
  Serial.begin(115200);
  SPI.begin();
  
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS);
  mcp2515.setNormalMode();
  
  Serial.println("------- CAN Read ----------");
  Serial.println("ID  DLC   DATA");
 
 pinMode(ledPin_4H,OUTPUT); digitalWrite (ledPin_4H, LOW);
 pinMode(ledPin_4L,OUTPUT); digitalWrite (ledPin_4L, LOW);
 pinMode(ledPin_4WD_CHECK,OUTPUT); digitalWrite (ledPin_4WD_CHECK, LOW);

}

void loop() {
  
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
     if (canMsg.can_id==0x3E8) {

         //все выходы ардино не активны, если байт 0х00
         if (canMsg.data[0]==0x00) {
                  digitalWrite(ledPin_4H,LOW);
                  digitalWrite(ledPin_4L,LOW);
                  digitalWrite(ledPin_4WD_CHECK,LOW);
         }
         
         //включаем ledPin_4H, если байт 0х01
         if (canMsg.data[0]==0x01) {
                  digitalWrite(ledPin_4H,HIGH);
                  digitalWrite(ledPin_4L,LOW);
                  digitalWrite(ledPin_4WD_CHECK,LOW);
         }

         //включаем ledPin_4L, если байт 0х02
         if (canMsg.data[0]==0x02) {
                  digitalWrite(ledPin_4H,LOW);
                  digitalWrite(ledPin_4L,HIGH);
                  digitalWrite(ledPin_4WD_CHECK,LOW);
         }

         //включаем ledPin_4WD_CHECK, если байт 0х04
         if (canMsg.data[0]==0x04) {
                  digitalWrite(ledPin_4H,LOW);
                  digitalWrite(ledPin_4L,LOW);
                  digitalWrite(ledPin_4WD_CHECK,HIGH);
         }
       
    Serial.print(canMsg.can_id, HEX); // print ID
    Serial.print(" "); 
    Serial.print(canMsg.can_dlc, HEX); // print DLC
    Serial.print(" ");
    
    for (int i = 0; i<canMsg.can_dlc; i++)  {  // print the data
        
      Serial.print(canMsg.data[i],HEX);
      Serial.print(" ");

    }

    Serial.println();      
  }}
}

 

yamkin
Offline
Зарегистрирован: 29.08.2017

MaksVV пишет:

yamkin пишет:
Изначально в качесте эксперимента я хотел реализовать что бы поток CAN генерила ардуино.

Не очень понятно, что бы это дало. У вас и так в шине уже летает инфа о режимах раздатки. Ну послали бы вы ещё своё сообщение в CAN. И что? на чем вы собирались увидеть результат? Щиток то ведь по аналогу состояние раздатки получает. 

В общем нарисуйте схему проводов щитка приборов, на которых присутствуют аналоговые сигналы о режимах раздатки. Распишите все режимы - т.е. что присутствует на каждом проводе при каждом режиме. 

Суть в чем, есть раздатка которая работает по CAN

Есть комбинация приборов которая работает по аналогу.

Необходимо все это связать, для того что бы испытать раздатку в дороге.

Для этого в составе автомобиля я хочу принимать CAN сообщения на ардуино от блока раздаточной коробки.

Далее с помощью ардуино зажигать соотвеетствующий светодиод не на самой комбинации приборов а отдельно подключу на проводах.

   

yamkin
Offline
Зарегистрирован: 29.08.2017

Спасибо за проделанную работу!

Скажите откуда такие знания в области ардуино? Можете порекомендовать литературу?

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот ещё один вариант, но уже с прерыванием и аппаратным фильтром только на сообщение с ID 0x3E8

// demo: CAN-BUS Shield, receive data with interrupt mode, and set mask and filter
//
// when in interrupt mode, the data coming can't be too fast, must >20ms, or else you can use check mode
// loovee, 2014-7-8

#include <SPI.h>
#include "mcp_can.h"

// 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;

MCP_CAN CAN(SPI_CS_PIN);                                    // Set CS pin


unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[8];


#define ledPin_4H 5
#define ledPin_4L 6
#define ledPin_4WD_CHECK 7


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

    START_INIT:

    if(CAN_OK == CAN.begin(CAN_500KBPS))                   // init can bus : baudrate = 500k
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(100);
        goto START_INIT;
    }

    attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt

    CAN.init_Filt(0, 0, 0x3E8);// аппаратный фильтр контроллера CAN, будет поступать только сообщение с ID 0x3E8

 pinMode(ledPin_4H,OUTPUT);        digitalWrite (ledPin_4H, LOW);
 pinMode(ledPin_4L,OUTPUT);        digitalWrite (ledPin_4L, LOW);
 pinMode(ledPin_4WD_CHECK,OUTPUT); digitalWrite (ledPin_4WD_CHECK, LOW);

}

void MCP2515_ISR()
{
    flagRecv = 1;
}

void loop()
{
    if(flagRecv)                   // если сообщение из CAN поступило на прерывание
    {

        flagRecv = 0;                // clear flag
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
        Serial.println("\r\n------------------------------------------------------------------");
        Serial.print("Get Data From id: ");
        Serial.println(CAN.getCanId());  // напечатаем ID CAN сообщения 

         for(int i = 0; i<len; i++)    //напечатаем все байты поля данных CAN сообщения 
        {
            Serial.print("0x");
            Serial.print(buf[i], HEX);
            Serial.print("\t");
        }
        Serial.println();

 

if (CAN.getCanId()==0x3E8) { // если поступило CAN сообщение с ID 0x3E8
        
         //все выходы ардино не активны, если байт 0х00
         if (buf[0]==0x00) {
                  digitalWrite(ledPin_4H,LOW);
                  digitalWrite(ledPin_4L,LOW);
                  digitalWrite(ledPin_4WD_CHECK,LOW);
         }
         
         //включаем ledPin_4H, если байт 0х01
         if (buf[0]==0x01) {
                  digitalWrite(ledPin_4H,HIGH);
                  digitalWrite(ledPin_4L,LOW);
                  digitalWrite(ledPin_4WD_CHECK,LOW);
         }

         //включаем ledPin_4L, если байт 0х02
         if (buf[0]==0x02) {
                  digitalWrite(ledPin_4H,LOW);
                  digitalWrite(ledPin_4L,HIGH);
                  digitalWrite(ledPin_4WD_CHECK,LOW);
         }

         //включаем ledPin_4WD_CHECK, если байт 0х04
         if (buf[0]==0x04) {
                  digitalWrite(ledPin_4H,LOW);
                  digitalWrite(ledPin_4L,LOW);
                  digitalWrite(ledPin_4WD_CHECK,HIGH);
         }
                           }

               

    }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

просто похожую задачу с CAN шиной  решаю. Обучался тут на форуме. Поначалу, как и всем, приходилось отмахиваться от ссаных тряпок, котрые тут в новичков всегда кидают)

yamkin
Offline
Зарегистрирован: 29.08.2017

MaksVV пишет:

просто похожую задачу с CAN шиной  решаю. Обучался тут на форуме. Поначалу, как и всем, приходилось отмахиваться от ссаных тряпок, котрые тут в новичков всегда кидают)

Спаибо тебе мужик! Буду разбираться с кодом, а в дальнейшем у меня задумка есть. Хочу реализовать диагностику полностью всего автомобиля. Но для этого еще поднатаскаться нужно в части программирования ардуино. Понять скажем так все нюансы и тонкости.

MaksVV
Offline
Зарегистрирован: 06.08.2015

yamkin пишет:

Суть в чем, есть раздатка которая работает по CAN

Есть комбинация приборов которая работает по аналогу.

Необходимо все это связать, для того что бы испытать раздатку в дороге.

это понятно, но причем здесь щиток приборов? если:

yamkin пишет:
Далее с помощью ардуино зажигать соотвеетствующий светодиод не на самой комбинации приборов а отдельно подключу на проводах.

 

yamkin
Offline
Зарегистрирован: 29.08.2017

MaksVV пишет:

yamkin пишет:

Суть в чем, есть раздатка которая работает по CAN

Есть комбинация приборов которая работает по аналогу.

Необходимо все это связать, для того что бы испытать раздатку в дороге.

это понятно, но причем здесь щиток приборов? если:

yamkin пишет:
Далее с помощью ардуино зажигать соотвеетствующий светодиод не на самой комбинации приборов а отдельно подключу на проводах.

 

Изначально я планировал это сделать на комбинации приборов.

Потом понял, что мне необходимо дополнительно покупать шилд реле.

Решение вывести отлельно диоды на проводах куда проще.

MaksVV
Offline
Зарегистрирован: 06.08.2015

а зачем реле? Может так ? если сигналы слаботочные?