Итак, чтоб подключить фары от рестайлового ГС на новый, нужно :

  • arduino nano
  • can shield (можно откровенно китаезный, с SPI)
  • стабилизатор питания для ардуины
  • две фишки для фар 90980-12A92
  • провода для косы
  • изолента, тюбинги
  • терпение и минимальные навыки программирования

CAN-адаптер я взял самый дешманский китаезный TJA1050. Выглядит вот так (на фото кварц на 8 мгц, но бывает на 16. Внимательнее с кодом): minipic

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

minipic

Ардуино запаиваем с кан-шилдом, все провода SPI припаиваем в соответствии с мануалом от ардуины (пины MOSI/MISO/GND/VCC/SS/SCK) :

minipic

Разъемы для фар придется запиновать самостоятельно, так как они идут без пинов конечноже. Подойдут очень даже многие пины от БУ проводки с разборки. Ради пинов можно взять почти любую проводку от тойоты, главное чтоб она была из подкапотного пространства, так как пины должны быть с типом waterproof. Осторожно разбираем тойотвские фишки и пины оттуда перетыкаем в новые разъемы. Схема подключения всего-всего между собой и к нашему адаптеру с ардуиной вот такая :

minipic

Тут все очень несложно. Фары должны быть соединены между собой по плюсу, минусу, одному из 2х канов, одним LIN-ом. В салон требуется протянуть один кан, один провод для включения-выключения AHB, три провода для датчика высоты кузова, провод для сигнала зажигания. Вот и вобщемто все. Кан который протягивается между фарами шунтируется резистором на 60 Ом. После отсоединения штатных фар, бодик будет генерировать ошибку при включении света. Для ее устранения нужно генерировать серию импульсов на его пины RLEW (21) и LLEW (24). Эти пины мы параллелим и сажаем на транзистор, который будет по сигналу ардуины (в коде вывод ардуины BODY_HLFAKE_PIN/3) подтягивать эти выводы на массу автомобиля.

Программирование ардуины

После запаивания и пртягивания, можно закодить ардуинку. Все компоненты я захреначил в термоусадочную пленку, получилось ок. Получать будем пакеты от приборной панели, которая сообщает состояние всех подрулевых органов управления сразу при их изменении. И заодно спамит раз в секунду положение рычажка режима головного света. Для эмуляции штатных фар используем таймер на 5мс (setTimer5HzForStockHeadlightFeedbackEmulation) и вывод 3.

08.826 622      8      12 00 00 00 00 00 00 00 - свет выключен
18.594 622      8      12 00 E8 30 00 00 00 00 - свет в авто, ближний включился
46.506 622      8      12 00 48 10 00 00 00 00 - габариты включены принудительно, свет выключен
18.988 622      8      12 00 88 30 00 00 00 00 - ближний включен принудительно
50.934 622      8      12 00 88 70 00 00 00 00 - дальний включен принудительно
25.601 622      8      12 80 88 70 00 00 00 00 - мограю дальним, первый пакет сразу
25.771 622      8      12 80 88 70 00 00 20 00 - второй пакет
26.261 622      8      12 80 88 30 00 00 00 00 - отпустил флеш дальнего при включенном ближнем
10.863 622      8      12 80 00 70 00 00 20 00 - дальний вкл и быстро сска!

Эти пакеты просто получает ардуиной и в ответ спамим пакет которые понимают наши фары.

Код :

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

//#define __DEBUG

#define BODY_HLFAKE_PIN    3        // тут у нас висит бодик, пин 21, RLEW 
#define LED_PIN         4
#define DEBUG_PIN         9
#define CANBUS_CS_PIN    10

MCP_CAN CAN0(CANBUS_CS_PIN);
char    msgString[128];
unsigned char len = 0;
unsigned char buf[8];
unsigned long int rxId = 0;

void blink(int delay_ms = 200) {
    digitalWrite(LED_PIN, HIGH);  
    delay(delay_ms);              
    digitalWrite(LED_PIN, LOW);   
    delay(delay_ms);
}

// таймер для эмуляции штатных фар, пин 21 и 24 на бодике.
// тут нужно просто шпарить импульсы +12 вольт 5гц пока
// включен свет фар

void Timer1Handler()
{
    digitalWrite(BODY_HLFAKE_PIN, 
        digitalRead(BODY_HLFAKE_PIN) ^ 1);
}

void setTimer5HzForStockHeadlightFeedbackEmulation() {
    Timer1.initialize(50000);
    Timer1.attachInterrupt(Timer1Handler);
}

void initializeCanModule() {
    if (CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK) {
        CAN0.setMode(MCP_NORMAL);
    }
}

void setup() {
#ifdef __DEBUG
    Serial.begin(115200);
#endif
    pinMode(LED_PIN, OUTPUT);
    pinMode(BODY_HLFAKE_PIN, OUTPUT);
    setTimer5HzForStockHeadlightFeedbackEmulation();
    initializeCanModule();
#ifdef __DEBUG
    Serial.println("CAN Driver : Initialized");
#endif
}

void EnableHighBeam() {
    byte data[8] = { 0x70, 0x05, 0x30, 0x15, 0x00, 0x20, 0x00, 0x00 };
    CAN0.sendMsgBuf(0x750, 8, data);
}

void DisableHighBeam() {
    byte data[8] = { 0x70, 0x05, 0x30, 0x15, 0x00, 0x10, 0x00, 0x00 };
    CAN0.sendMsgBuf(0x750, 8, data);
}

void selectRightModeForHeadlights(unsigned char * dataBytes) {
    if (dataBytes[3] == 0x70) {
        EnableHighBeam();
    }
    else if (dataBytes[3] == 0x30) {
        DisableHighBeam();
    }
}


void loop() {

    if (CAN_MSGAVAIL == CAN0.checkReceive()){

        CAN0.readMsgBuf(&rxId, &len, buf);

        if (rxId == 0x622) {

            if (len == 8 && buf[0] == 0x12) {

#ifdef __DEBUG            
                if ((rxId & 0x80000000) == 0x80000000) {
                    sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
                } else {
                    sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
                }

                Serial.print(msgString);
                if ((rxId & 0x40000000) == 0x40000000) {
                    sprintf(msgString, " REMOTE REQUEST FRAME");
                    Serial.print(msgString);
                } else {
                    for (byte i = 0; i<len; i++) {
                        sprintf(msgString, " 0x%.2X", buf[i]);
                        Serial.print(msgString);
                    }
                }

                Serial.println();
#endif
                selectRightModeForHeadlights(buf);

            }
        }
    }
}

Код небольшой и в особых комментариях не нуждается. Скачать весь проект можно тут : http://zatonevkredit.ru/static/hldriver.rar