CAN адаптер для рулевых кнопок VW Polo Sedan
-
bratec_bober
- Первый раз сказал Мяу!
- Сообщения: 23
- Зарегистрирован: Ср сен 26, 2012 18:25:30
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Попробовал твой код запихать в прогу - не работает(( И если оставлять часть с while(1) из цикла не выходит.
Раскопал еще инфу, получается как то так. B9 - адрес, 46B9 - инвертированный адрес + адрес. в двоичном виде выглядит как
0b100011010111001
а передается в посылке
0b100111010110001 (вся портянка младшим битом вперед)
с кодами команд то же самое.
Раскопал еще инфу, получается как то так. B9 - адрес, 46B9 - инвертированный адрес + адрес. в двоичном виде выглядит как
0b100011010111001
а передается в посылке
0b100111010110001 (вся портянка младшим битом вперед)
с кодами команд то же самое.
- Реклама
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
а точно! инвертированый адрес.
ну так прога это пример кода, а вот задержки надо выставлять опытным путем, мои задержки подогнаны под тини 13а подгонял с лог анализатором.
мой пример только показывает программный способ передачи
цикл да бесконечный в многоточии подразумевается основной код программы
Но есть одно но во время передачи надо контролировать прерывания иначе задержки могут уплыть, у меня задержки подогнаны при условии работы АЦП изза чего и расходятся расчетные задержки с реальными.
как пример что будет если во время передачи нека прийдет прерывание от кана?
ну так прога это пример кода, а вот задержки надо выставлять опытным путем, мои задержки подогнаны под тини 13а подгонял с лог анализатором.
мой пример только показывает программный способ передачи
цикл да бесконечный в многоточии подразумевается основной код программы
Но есть одно но во время передачи надо контролировать прерывания иначе задержки могут уплыть, у меня задержки подогнаны при условии работы АЦП изза чего и расходятся расчетные задержки с реальными.
как пример что будет если во время передачи нека прийдет прерывание от кана?
-
bratec_bober
- Первый раз сказал Мяу!
- Сообщения: 23
- Зарегистрирован: Ср сен 26, 2012 18:25:30
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Мне кажется, ничего не будет, по крайней мере в ардуино коде. Там смысл такой, что пока сообщение окончательно не обработается (не будет отпрален ИК-код), следующее сообщение не будет получено. В качестве примера из прошлого сообщения с листингом кан пакетов, при нажатии кнопки прилетает подряд 4 пакета, а если вставить на прием пакета с определенной датой отправку ИК, то их них успевает обрабатываться 2 (один раз проскочило 3).
Еще поясни пожалуйста, с помощью строки
if ((necc&(1<<i))!=0)
осуществляется перебор с первого бита или с последнего? Я пока не силен в побитовых операциях(
Насчет задержек это да, находил на ардуину скетч похожий, там чутка другие тайминги. Ну это дело поправимое, главное посылку правильно собрать.
Еще поясни пожалуйста, с помощью строки
if ((necc&(1<<i))!=0)
осуществляется перебор с первого бита или с последнего? Я пока не силен в побитовых операциях(
Насчет задержек это да, находил на ардуину скетч похожий, там чутка другие тайминги. Ну это дело поправимое, главное посылку правильно собрать.
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
проверка i бита на неравенство 0, мы же передаем число в виде битов вот и читаем последовательно каждый бит если 0 передаем 0, если не ноль передаем еденичку. 1<<0 есть нулевой бит, 1<<7 седьмой (последний) бит
по поводу перебора смотреть выше оператор for, как там идет счет? i++ значит с 0 бита по 7
надо для начала разобраться с битовыми операциями, с ними можно такого наворотить.....считай это основа при работе как с портами так и с переменными и их конвертирование в иной вид.....
по поводу перебора смотреть выше оператор for, как там идет счет? i++ значит с 0 бита по 7
надо для начала разобраться с битовыми операциями, с ними можно такого наворотить.....считай это основа при работе как с портами так и с переменными и их конвертирование в иной вид.....
-
bratec_bober
- Первый раз сказал Мяу!
- Сообщения: 23
- Зарегистрирован: Ср сен 26, 2012 18:25:30
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Ок, спасибо)
- Реклама
-
bratec_bober
- Первый раз сказал Мяу!
- Сообщения: 23
- Зарегистрирован: Ср сен 26, 2012 18:25:30
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
В общем, еще одна победа! Can и Kenwood теперь разговаривают)
Вот такой вот скетч
#include <SPI.h>
#include "mcp_can.h"
#define outputPin 4
unsigned int VOL_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int VOL_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int MUTE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0};
unsigned int SOURCE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,0};
unsigned int SEEK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int ANSWER[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0};
// 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;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
void setup()
{
Serial.begin(115200);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH);
Serial.println("start");
START_INIT:
if(CAN_OK == CAN.begin(CAN_100KBPS)) // init can bus : baudrate = 100k
{
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;
}
}
boolean send(unsigned int *command)
{
digitalWrite(outputPin, LOW);
delay(10);
digitalWrite(outputPin, HIGH);
delayMicroseconds(4500);
for (int x = 0; x < 49; x++)
{
if (command[x] == 0)
{
digitalWrite(outputPin, LOW);
}
else
{
digitalWrite(outputPin, HIGH);
}
delayMicroseconds(1000);
digitalWrite(outputPin, HIGH);
delayMicroseconds(200);
}
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
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 = 0x5C1)&&(len=4)&&(buf[1]==0)&&(buf[2]==0)&&(buf[3]==0x20)) //((buf[0]==0x06)||(buf[0]==0x07)||(buf[0]==0x02)||(buf[0]==0x03)||(buf[0]==0x1A)||(buf[0]==0x2B))&&
{
switch (buf[0])
{
case 0x06: // Vol_Up
Serial.println("Volume UP");
send(VOL_UP); //отправка кода(адрес, команда)
break;
case 0x07: // Vol_Down
Serial.println("Volume Down");
send(VOL_DN); //отправка кода(адрес, команда)
break;
case 0x1A: // Phone
Serial.println("Phone Btn");
send(SOURCE); //отправка кода(адрес, команда)
break;
case 0x02: // UP (0x22)
Serial.println("Track UP");
send(TRK_UP); //отправка кода(адрес, команда)
break;
case 0x03: // Down (0x23)
Serial.println("Track Down");
send(TRK_DN); //отправка кода(адрес, команда)
break;
case 0x2B: //Mute
Serial.println("Mute");
send(MUTE); //отправка кода(адрес, команда)
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
}
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
Хрен знает, что за коды сигналов, и почему там 49 бит, но тут все немного иначе, чем при отправке IR-кода, хотя бы потому, что по умолчанию на линии высокий уровень. Кстати, работает даже без подключения к массе авто/магнитолы, то есть по одному проводу.
Код отправки честно скопипастчен отсюда http://custombaggerforum.com/forum/show ... acks/page3
Но не все так гладко, есть загвоздка. Как мы уже знаем, при нажатии клавиши ардуино обрабатывает 4 кан-пакета. Если вставить обработчик ИК, то по кану успевает обрабатываться 2 (а иногда 3), точнее даже наверное они остаются в буфере mcp. Соответственно, при нажатии кнопки громкость увеличивается на 2 пункта, треки переключаются через 1)). Нужно припилить сюда обработчик, который бы считал одинаковые пакеты в течение определенного времени и считал их за один пакет, либо ничего не делал при всех получениях, кроме первого.
А еще накопал пакеты с данными о включении задней передачи, и можно сюда запилить отправку ATT при ее включении и еще раз ATT при выключении.
Работа идет..)) Не прошло и 3 года..))
Вот такой вот скетч
Спойлер
// Version 1.0, фильтр CAN с последующей передачей IR-кода#include <SPI.h>
#include "mcp_can.h"
#define outputPin 4
unsigned int VOL_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int VOL_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int MUTE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0};
unsigned int SOURCE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,0};
unsigned int SEEK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int ANSWER[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0};
// 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;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
void setup()
{
Serial.begin(115200);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH);
Serial.println("start");
START_INIT:
if(CAN_OK == CAN.begin(CAN_100KBPS)) // init can bus : baudrate = 100k
{
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;
}
}
boolean send(unsigned int *command)
{
digitalWrite(outputPin, LOW);
delay(10);
digitalWrite(outputPin, HIGH);
delayMicroseconds(4500);
for (int x = 0; x < 49; x++)
{
if (command[x] == 0)
{
digitalWrite(outputPin, LOW);
}
else
{
digitalWrite(outputPin, HIGH);
}
delayMicroseconds(1000);
digitalWrite(outputPin, HIGH);
delayMicroseconds(200);
}
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
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 = 0x5C1)&&(len=4)&&(buf[1]==0)&&(buf[2]==0)&&(buf[3]==0x20)) //((buf[0]==0x06)||(buf[0]==0x07)||(buf[0]==0x02)||(buf[0]==0x03)||(buf[0]==0x1A)||(buf[0]==0x2B))&&
{
switch (buf[0])
{
case 0x06: // Vol_Up
Serial.println("Volume UP");
send(VOL_UP); //отправка кода(адрес, команда)
break;
case 0x07: // Vol_Down
Serial.println("Volume Down");
send(VOL_DN); //отправка кода(адрес, команда)
break;
case 0x1A: // Phone
Serial.println("Phone Btn");
send(SOURCE); //отправка кода(адрес, команда)
break;
case 0x02: // UP (0x22)
Serial.println("Track UP");
send(TRK_UP); //отправка кода(адрес, команда)
break;
case 0x03: // Down (0x23)
Serial.println("Track Down");
send(TRK_DN); //отправка кода(адрес, команда)
break;
case 0x2B: //Mute
Serial.println("Mute");
send(MUTE); //отправка кода(адрес, команда)
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
}
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
Код отправки честно скопипастчен отсюда http://custombaggerforum.com/forum/show ... acks/page3
Но не все так гладко, есть загвоздка. Как мы уже знаем, при нажатии клавиши ардуино обрабатывает 4 кан-пакета. Если вставить обработчик ИК, то по кану успевает обрабатываться 2 (а иногда 3), точнее даже наверное они остаются в буфере mcp. Соответственно, при нажатии кнопки громкость увеличивается на 2 пункта, треки переключаются через 1)). Нужно припилить сюда обработчик, который бы считал одинаковые пакеты в течение определенного времени и считал их за один пакет, либо ничего не делал при всех получениях, кроме первого.
А еще накопал пакеты с данными о включении задней передачи, и можно сюда запилить отправку ATT при ее включении и еще раз ATT при выключении.
Работа идет..)) Не прошло и 3 года..))
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
ну вот, осталось разукрасить и мона пользоваться
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
bratec_bober, как у тебя дела с проектом? У меня задачка попроще чем у тебя, нужно управлять мафаном с резистивных кнопок руля. Управление тоже кенвудом, и тоже по одному проводу. Не могу разобраться с аппаратной частью. может проблема с пониманием протокола. Из описания протокола понял. что пауза это отсутствие напряжения, что я и использовал. Но мне советовали использовать транзистор, для инвертирования сигнала. Ты как сделал? Транзистора под рукой нет, не могу проветрить предложенный вариант. Ещё есть подозрения, что из-за задержек, связанными с выполнением других функций в программе, не выдерживаются необходимые временные задержки для соблюдения протокола NEC
-
bratec_bober
- Первый раз сказал Мяу!
- Сообщения: 23
- Зарегистрирован: Ср сен 26, 2012 18:25:30
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Пауза - это высокий уровень. По умолчанию на линии - высокий уровень. Импульс - низкий уровень. На практике вышло так. По описанию - да, все как ты говоришь, и Mishany говорил, и wheelremote пишет. Короче, все так, как в описании, но уровни надо инвертировать))) я не знаю, как проще сказать)) Схема подключения кана в скетче, на 4-ю ногу ардуины повесил вывод на remote_cont, все работает. Сегодня как раз пришла последняя запчасть - can-модуль от китайцев, подружу его с pro-mini и l7805 и будет готовое устройство) как будет готово - выложу.
Скетч полностью готов к употреблению, реализована функция ATT при включении задней передачи.
#include <SPI.h>
#include "mcp_can.h"
#define outputPin 4 // remote_cont
unsigned int VOL_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int VOL_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int MUTE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0};
unsigned int SOURCE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,0};
unsigned int SEEK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int ANSWER[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0};
int reverse = 0;
unsigned long last_time;
// 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;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
void setup()
{
Serial.begin(115200);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH);
Serial.println("start");
START_INIT:
if(CAN_OK == CAN.begin(CAN_100KBPS)) // init can bus : baudrate = 100k
{
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;
}
}
boolean send(unsigned int *command)
{
digitalWrite(outputPin, LOW);
delay(10);
digitalWrite(outputPin, HIGH);
delayMicroseconds(4500);
for (int x = 0; x < 49; x++)
{
if (command[x] == 0)
{
digitalWrite(outputPin, LOW);
}
else
{
digitalWrite(outputPin, HIGH);
}
delayMicroseconds(1000);
digitalWrite(outputPin, HIGH);
delayMicroseconds(200);
}
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
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 = 0x5C1)&&(len=4)&&(buf[1]==0)&&(buf[2]==0)&&(buf[3]==0x20)) //((buf[0]==0x06)||(buf[0]==0x07)||(buf[0]==0x02)||(buf[0]==0x03)||(buf[0]==0x1A)||(buf[0]==0x2B))&&
{
if(last_time<millis())
{
switch (buf[0])
{
case 0x06: // Vol_Up
Serial.println("Volume UP");
send(VOL_UP); //отправка кода(адрес, команда)
break;
case 0x07: // Vol_Down
Serial.println("Volume Down");
send(VOL_DN); //отправка кода(адрес, команда)
break;
case 0x1A: // Phone
Serial.println("Phone Btn");
send(SOURCE); //отправка кода(адрес, команда)
break;
case 0x02: // UP (0x22)
Serial.println("Track UP");
send(TRK_UP); //отправка кода(адрес, команда)
break;
case 0x03: // Down (0x23)
Serial.println("Track Down");
send(TRK_DN); //отправка кода(адрес, команда)
break;
case 0x2B: //Mute
Serial.println("Mute");
send(MUTE); //отправка кода(адрес, команда)
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
last_time=millis()+40;
}
}
if((canId = 0x470)&&(len=8)&&(buf[3]==0x46)&&(buf[4]==0)&&(buf[5]==0)&&(buf[6]==0)&&(buf[7]==0x1F)) //Включение задней передачи
{
/*for(int i=0; i<8; i++)
{
Serial.print(buf, HEX);
Serial.print('\t');
}
Serial.println("");*/
if(((buf[0]==0xC0)||(buf[0]==0x40))&&(reverse==1)) //задняя не включена и предыдущее значение 1
{
reverse=0;
Serial.println("Reverse Disabled");
send(MUTE);
}
if(((buf[0]==0xE0)||(buf[0]==0x60))&&(reverse==0))
{
reverse=1;
Serial.println("Reverse Enabled");
send(MUTE);
}
}
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
Скетч полностью готов к употреблению, реализована функция ATT при включении задней передачи.
Спойлер
// Version 1.0, фильтр CAN с последующей передачей IR-кода#include <SPI.h>
#include "mcp_can.h"
#define outputPin 4 // remote_cont
unsigned int VOL_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int VOL_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0};
unsigned int MUTE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0};
unsigned int SOURCE[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,1,0};
unsigned int SEEK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int TRK_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_UP[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int DISC_DN[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0};
unsigned int ANSWER[49] = {0,1,0,0,0,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0};
int reverse = 0;
unsigned long last_time;
// 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;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
void setup()
{
Serial.begin(115200);
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH);
Serial.println("start");
START_INIT:
if(CAN_OK == CAN.begin(CAN_100KBPS)) // init can bus : baudrate = 100k
{
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;
}
}
boolean send(unsigned int *command)
{
digitalWrite(outputPin, LOW);
delay(10);
digitalWrite(outputPin, HIGH);
delayMicroseconds(4500);
for (int x = 0; x < 49; x++)
{
if (command[x] == 0)
{
digitalWrite(outputPin, LOW);
}
else
{
digitalWrite(outputPin, HIGH);
}
delayMicroseconds(1000);
digitalWrite(outputPin, HIGH);
delayMicroseconds(200);
}
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
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 = 0x5C1)&&(len=4)&&(buf[1]==0)&&(buf[2]==0)&&(buf[3]==0x20)) //((buf[0]==0x06)||(buf[0]==0x07)||(buf[0]==0x02)||(buf[0]==0x03)||(buf[0]==0x1A)||(buf[0]==0x2B))&&
{
if(last_time<millis())
{
switch (buf[0])
{
case 0x06: // Vol_Up
Serial.println("Volume UP");
send(VOL_UP); //отправка кода(адрес, команда)
break;
case 0x07: // Vol_Down
Serial.println("Volume Down");
send(VOL_DN); //отправка кода(адрес, команда)
break;
case 0x1A: // Phone
Serial.println("Phone Btn");
send(SOURCE); //отправка кода(адрес, команда)
break;
case 0x02: // UP (0x22)
Serial.println("Track UP");
send(TRK_UP); //отправка кода(адрес, команда)
break;
case 0x03: // Down (0x23)
Serial.println("Track Down");
send(TRK_DN); //отправка кода(адрес, команда)
break;
case 0x2B: //Mute
Serial.println("Mute");
send(MUTE); //отправка кода(адрес, команда)
break;
default:
// if nothing else matches, do the default
// default is optional
break;
}
last_time=millis()+40;
}
}
if((canId = 0x470)&&(len=8)&&(buf[3]==0x46)&&(buf[4]==0)&&(buf[5]==0)&&(buf[6]==0)&&(buf[7]==0x1F)) //Включение задней передачи
{
/*for(int i=0; i<8; i++)
{
Serial.print(buf, HEX);
Serial.print('\t');
}
Serial.println("");*/
if(((buf[0]==0xC0)||(buf[0]==0x40))&&(reverse==1)) //задняя не включена и предыдущее значение 1
{
reverse=0;
Serial.println("Reverse Disabled");
send(MUTE);
}
if(((buf[0]==0xE0)||(buf[0]==0x60))&&(reverse==0))
{
reverse=1;
Serial.println("Reverse Enabled");
send(MUTE);
}
}
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
- Mishany
- Электрический кот
- Сообщения: 1031
- Зарегистрирован: Чт июн 20, 2013 00:00:58
- Откуда: москва, м.Сходненская
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
при передачи, функцию передачи могут только прерывания прерывать.
при передачи запрещать прерывания! и все будет норм, задержки подбирать опытным путем по логическому анализатору.
при передачи запрещать прерывания! и все будет норм, задержки подбирать опытным путем по логическому анализатору.
-
bratec_bober
- Первый раз сказал Мяу!
- Сообщения: 23
- Зарегистрирован: Ср сен 26, 2012 18:25:30
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Вот готовое устройство. Чуть уть оптимизировал код (закомментировал все Serial.println которые были нужны для отладки), иначе было занято 95% памяти переменных ProMini и выполнялось только первые 2-3- команды, а дальше срач в сериал кракозябрами.
А также опытным путем выяснено, что MCP2515 c 8mhz кварцем не работает с mcp с 16mhz кварцем (делал can-сеть из 2-х плат). С тачкой работает только 16 mhz, поэтому китайская плата не заработала, после замены кваца все поперло. Завтра видос выложу, может интересно кому будет, как из кармана под магнитолой поло торчит кусок витухи с коннектором rj-45. Не обессутьте, работаю в телекоме, чем богаты, тем и рады)))
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Добрый день.
Наткнулся на эту тему, и появился ряд вопросов...
Тоже хочу разобраться с CAN в Polo sedan, но мне нужны будут концевики дверей, ручник и состояние двигла. Имею китайскую платку синюю ( как на фото постом выше) и ардуинку, цепляться буду к КЭН шине на магнитоле... (UPDATE: в комфортлайне нету КЭН шины возле магнитолы - буду брать с приборки)
я так понимаю битрейт CAN шины 100кбит? и что платка китайская пахать не хочет, если в ней не поменять кварц на 16мгц?
p.s. нет ли у вас готового скетча для снифа сообщений шины?
Наткнулся на эту тему, и появился ряд вопросов...
Тоже хочу разобраться с CAN в Polo sedan, но мне нужны будут концевики дверей, ручник и состояние двигла. Имею китайскую платку синюю ( как на фото постом выше) и ардуинку, цепляться буду к КЭН шине на магнитоле... (UPDATE: в комфортлайне нету КЭН шины возле магнитолы - буду брать с приборки)
я так понимаю битрейт CAN шины 100кбит? и что платка китайская пахать не хочет, если в ней не поменять кварц на 16мгц?
p.s. нет ли у вас готового скетча для снифа сообщений шины?
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Для сканирования шины CAN, собери CANHacker, в сети все для этого есть и будет нужный инструмент под рукой.Fighter писал(а):Добрый день.
p.s. нет ли у вас готового скетча для снифа сообщений шины?
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Ща задам самый тупой вопрос в этой теме
CAN-шина двухпроводная (L/H). Требуется ли соединять земли автомобиля и своего девайса?
Вопрос возник в связи с тем, что например у этой штуки земля не выведена:

CAN-шина двухпроводная (L/H). Требуется ли соединять земли автомобиля и своего девайса?
Вопрос возник в связи с тем, что например у этой штуки земля не выведена:

Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Ещё один вопросик по Can.
Есть ли какая-то обратная связь по шине? В смысле, должен ли отправлять в пустоту Tx посылки или есть какая-то синхронизация через Rx? Вчера написал тест, который в бесконечном цикле шлёт посылки на шину, в итоге отправляется как я понимаю только arbitration field и передатчик вываливается по таймауту
Есть ли какая-то обратная связь по шине? В смысле, должен ли отправлять в пустоту Tx посылки или есть какая-то синхронизация через Rx? Вчера написал тест, который в бесконечном цикле шлёт посылки на шину, в итоге отправляется как я понимаю только arbitration field и передатчик вываливается по таймауту
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Конечно есть! иначе как бы разруливались приорритеты, нулевой id имеет высший приорритет.
Поэтому передавая каждый бит id все устройства в шине одновременно стартуют и проверяют линию, если оно передает еденицу а получает в линии ноль то просто останавливает передачу, и ждет начало следующей передачи, так как в шине более важное сообщение. Вот как то так, не знаю понятно ли разъяснил, вроде все просто.
Поэтому передавая каждый бит id все устройства в шине одновременно стартуют и проверяют линию, если оно передает еденицу а получает в линии ноль то просто останавливает передачу, и ждет начало следующей передачи, так как в шине более важное сообщение. Вот как то так, не знаю понятно ли разъяснил, вроде все просто.
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Да, спасибо, всё понятно!
Почему-то сам не подумал про приоритеты.
Буду юзать Loop back mode
Почему-то сам не подумал про приоритеты.
Буду юзать Loop back mode
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
Поясните, если не сложно такой ламерский вопрос, для чего используют микруху sja1000 при создании устройств для работы с CAN шиной, что мешает микроконтроллеру напрямую работать с CAN трансивером tja1050 ?
Re: CAN адаптер для рулевых кнопок VW Polo Sedan
1) sja1000 используют в том случае, если у применяемого контроллера нет в наличии аппаратного CAN, и can это не тот интерфейс который легко создается программно.
2) В целях экономии, допустим атмега16м1 с аппаратным can стоит значительно дороже, нежели атмега16+sja1000
Конечно на сегодняшний день STM32 имеет несравненное преимущество и по цене и по периферии, но есть такая категория которой сложно покинуть AVR, думаю вряд ли вы встретите проект STM32+SJA1000
2) В целях экономии, допустим атмега16м1 с аппаратным can стоит значительно дороже, нежели атмега16+sja1000
Конечно на сегодняшний день STM32 имеет несравненное преимущество и по цене и по периферии, но есть такая категория которой сложно покинуть AVR, думаю вряд ли вы встретите проект STM32+SJA1000


