PCCar.ru - Ваш автомобильный компьютер

Вернуться   PCCar.ru - Ваш автомобильный компьютер > MP3Car ТехИнфа > Общение с машиной

Ответ
 
Опции темы
Старый 29.10.2017, 10:32   #1
ghans
Пользователь
 
Аватар для ghans
 
Регистрация: 02.07.2012
Регион: 59
Сообщений: 63
ghans is a glorious beacon of lightghans is a glorious beacon of lightghans is a glorious beacon of lightghans is a glorious beacon of lightghans is a glorious beacon of light
По умолчанию Управление климатом Volkswagen Touareg NF

На VW Touareg NF 2010 - 2015 год отсутствуют кнопки включения обогрева руля и лобового стекла. Управление происходит через меню климата на голове. Иногда это не удобно, хотя бы потому, что голова грузится довольно долго и утром лень ждать. С 2015 года кнопки появились, но просто поставить и подключить их не получается, потому что изменился блок управления бортовой сети.
Для решения использовалась ардуино уно и кан шилд от SeedStudio.
Засыпание не реализовано. Ардуинка тупо висит на засыпающем плюсе.
Код сильно не вылизывал. Сейчас переделываю на Leonardo с засыпанием, новый код выложу позже.

PHP код:

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

/* Скетч управления подогревом руля и лобового для WV Touareg 2014-2014
 * тестировано на Arduino UNO и SEEDStudio CAN-BUS Shield v 1.0
 * для версии CAN-BUS Shield v 1.2 поменять порт MCP на 9
 */

const int MCP_PORT         10;                         // Для версии 1.0, для версии 1.2 поменять на 9.
const int Port             0x601;                      // Порт КАН шины для управления 
const int Button_Glass_Pin 4;                          // Пин кнопки стекла 
const int Button_Steer_Pin 6;                          // Пин кнопки руля 
const int LED_Glass_Pin    5;                          // Пин контрольного светодиода стекла 
const int LED_Steer_Pin    7;                          // Пин контрольного светодиода руля 
const int EE_Steer_Address 0;                          // Адрес постоянного хранилища состояния обогрева руля
const int EE_Glass_Address 1;                          // Адрес постоянного хранилища состояния обогрева стекла
boolean EE_Steer           false;                      // Состояние руля    true - вкл, false - выкл
boolean EE_Glass           false;                      // Состояния стекла  true - вкл, false - выкл

MCP_CAN CAN(MCP_PORT);                                   // Инициализация порта CAN шины

unsigned char SteerOff[5]  = {0x200x740x000x000x00};   // КАН строка выключение руля
unsigned char SteerOn [5]  = {0x200x740x000x010x00};   // КАН строка включение руля
unsigned char GlassOff[4] = {0x200x6D0x000x01};          // КАН строка выключение стекла
unsigned char GlassOn [4]  = {0x200x6D0x010x01};         // КАН строка включение стекла
boolean       flagRecv 0;                              // Флаг того, что сработало прерывание - получен сигнал по шине.    
unsigned char len 0;                                   // Длина полученной строки
unsigned char buf[8];                                    // Буфер КАН шины

struct BUTTON                                             // структура кнопка
      
{
        
boolean on;                                       // нажатие было
        
boolean longpress;                                // нажатие было длинным
      
};

void setup()
{
    
Serial.begin(115200);                                 // Инициализация ком порта для контрольного вывода. В будущем, все строки Serial можно закомментировать

    
while (CAN_OK != CAN.begin(CAN_500KBPS))              // Инициализация КАН шины : 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(Button_Glass_Pin,INPUT);                       // Инициализация кнопки стекла
    
pinMode(LED_Glass_Pin,OUTPUT);                         // Инициализация контрольного светодиода стекла
    
pinMode(Button_Steer_Pin,INPUT);                       // Инициализация кнопки руля
    
pinMode(LED_Steer_Pin,OUTPUT);                         // Инициализация контрольного светодиода руль
    
digitalWrite(Button_Glass_PinHIGH);                  // Включение внутреннего подтягивающего резистора стекло 
    
digitalWrite(Button_Steer_PinHIGH);                  // Включение внутреннего подтягивающего резистора руль 
    
    
EE_Steer EEPROM.read(EE_Steer_Address);              // Чтение из памяти состояние руля
    
EE_Glass EEPROM.read(EE_Glass_Address);              // Чтение из памяти состояние стекла
        
    
Steer ();                                              // Инициализация обогревов из памяти  
    
Glass ();
    
attachInterrupt(0MCP2515_ISRFALLING);              // Инициализация прерывания по чтению из КАН шины 

    
CAN.init_Mask(000x7FF) ;                           // there are 2 mask in mcp2515, you need to set both of them
    
CAN.init_Mask(100x7FF);                            // в оригинале стоит 0x3FF ?
    
CAN.init_Filt(00Port);                             // принимаем сигнал с единственного порта 
}
void MCP2515_ISR()                                         // Обработка прерывания. Не понимаю, как это работает, поэтому сделано строго, как в примере
{
    
flagRecv true;
}

void Steer()                                               // Подпрограмма управление рулем
{
  if (
EE_Steer)                                            // Если флаг обогрева установлен
    
{
     
CAN.sendMsgBuf(Port05SteerOn);                  // Посылка команды включения обогрева руля 
     
digitalWrite(LED_Steer_Pin,HIGH);                     // Включение светодиода руля  
     
Serial.println("  руль включен");
    }
  else                                                     
// Иначе - флаг обогрева сброшен
    
{
    
CAN.sendMsgBuf(Port05SteerOff);                  // Посылка команды вкылючения обогрева руля 
    
digitalWrite(LED_Steer_Pin,LOW);                       // Выключение светодиода руля  
    
Serial.println("  руль выключен");
     }
  
delay(200);    

void Glass()                                               // Подпрограмма управление стеклом
{
  if (
EE_Glass)                                            // Если флаг стекла установлен
    
{
    
CAN.sendMsgBuf(Port04GlassOn);                   // Посылка команды включение обогрева стекла
    
digitalWrite(LED_Glass_Pin,HIGH);                      // Включение светодиода стекла  
    
Serial.println("  стекло включено");
    }
  else                                                     
// Иначе - флаг обогрева сброшен
    
{
     
CAN.sendMsgBuf(Port04GlassOff);                 // Посылка команды выключение обогрева стекла
     
digitalWrite(LED_Glass_Pin,LOW);                      // Выключение светодиода стекла  
     
Serial.println("  стекло выключено");
    }
  
delay(200);  
}
void Blink(int pinint nboolean led)                    // Подпрограмма "Моргание светодиодом в подтверждение". Номер пина, количество морганий, статус в котором надо оставить.  
{
     if (
led)                                              // если светодиод уже горит, то выключаем
     
{
      
digitalWrite(pin,LOW);
      
delay (500);
     }
     for (
int i=0i<ni++)
         {                                                 
// n  раз моргнули в подтверждение
          
digitalWrite(pin,HIGH);
          
delay (500);
          
digitalWrite(pin,LOW);
          
delay (500);
         }
     if (
leddigitalWrite(pin,HIGH);                      // Включили светодиод обратно, если надо.  
}
BUTTON Pressing(int pin)                                   // Подпрограмма обработка нажатия кнопки. Pin - номер порта
{
   
int n 0;                                              // Счетчик
   
BUTTON key;                                             // Структура кнопки для возврата
   
while (digitalRead(pin)==LOW && <=100)                // Обрабатывет длинное нажатие, считает тайминги, выход, если превышен таймиг или кнопка отпущена 
     
{
      
n++;                                                 // Увеличение счетчика тайминга
      
delay (20);
     }
  
key.on = (n>0&& n<100);                                  // Установлен флаг короткого нажатия
  
key.longpress = (n>=100);                                // Установлен флаг длинное нажатие  
  
return key;      
}

void KeyDetect()                                           // Подпрограмма чтения кнопки
{
  
BUTTON glass Pressing (Button_Glass_Pin);              // Чтение нажатия кнопки стекла
  
BUTTON steer Pressing (Button_Steer_Pin);              // Чтение нажатия кнопки руля
  
if (steer.longpress)                                     // ОБработка длинного нажатия кнопки руля
     
{
     
EEPROM.write (EE_Steer_Address,EE_Steer);             // Запись текущего состояния в EEPROM
     
Serial.write("запись руль");
     
Blink (LED_Steer_Pin5EE_Steer);                   // Моргнуть 5 раз и оставить в том же положении, что был
     
delay (500);
     }
   if (
glass.longpress)                                    // ОБработка длинного нажатия кнопки стекла
     
{
     
EEPROM.write (EE_Glass_Address,EE_Glass);             // Запись текущего состояния в EEPROM
     
Serial.write("запись руль");
     
Blink (LED_Glass_Pin5EE_Glass);                   // Моргнуть 5 раз и оставить в том же положении, что был  
     
delay(500);
     }               
   if (
steer.on)                                           // ОБработка простого нажатия кнопки руля
     
{    
      
EE_Steer = !EE_Steer;                                // Меняем значение флага обогрева руля на противоположное 
      
Steer ();                                            // Отправляем на обработку с текушщим значением                       
      

    if (
glass.on)                                          // ОБработка простого нажатия кнопки стекла                                               
     
{    
      
EE_Glass = !EE_Glass;                                // Обращаем значение обогрева стекла
      
Glass();                                             // Отправляем на обработку с текушщим значением
     

}
void External_Control()                                    // ОБработка перехвата внешнего воздействия через КАН шину 
{
  
flagRecv=0;
  
boolean steer_on truesteer_off true;               // Инициализация ключей проверки строки  
  
boolean glass_on trueglass_off true;     
  
/* Взято из примера, проверка всего буфера
   * iterate over all pending messages. If either the bus is saturated or the MCU is busy, both RX buffers
   * may be in use and reading a single message does not clear the IRQ conditon.
   */ 
  
while (CAN_MSGAVAIL == CAN.checkReceive())                // Взято из примера, очищение буфера                 
      
{
      
CAN.readMsgBuf(&lenbuf);                           // Чтение данных из буфера КАН.  Данные - len: data length, buf: data buf
      
if (len==5)                                          // Если длина строки == 5, то это руль
        
{
        for(
int i 0i<leni++)
          {
           
steer_on  steer_on  && (buf[i]==SteerOn [i]); // Сравниваем побитово на совпадение со сторокй включения руля
           
steer_off steer_off && (buf[i]==SteerOff[i]); // Сравниваем побитово на совпадение со строкой выключения руля
          
}
        if (
steer_on)                                      // Если перехвачена команда включения руля   
          
{
           
EE_Steer true;                                // Установка флага -подогрев руля включен
           
digitalWrite(LED_Steer_Pin,HIGH);               // Включение светодиода руля  
           
Serial.println("  Обогрев руля включен внешним воздействием");
          }
        else if (
steer_off)                                // Если перехвачена команды выключения руля 
          
{
          
EE_Steer false;                                // Установка флага - подогрев руля выключен 
          
digitalWrite(LED_Steer_Pin,LOW);                 // Выключение светодиода руля  
          
Serial.println("  Обогрев руля выключен внешним воздействием");
          }
        else
          
Serial.println("  неизвестная команда руль");
        }
      else if (
len==4)                                     // Если длина строки == 4, ьо это стекло
        
{
         for(
int i 0i<leni++)
          {
           
glass_on  glass_on  && (buf[i]==GlassOn [i]); // Сравниваем побитово на совпадение со строкой включения стекла 
           
glass_off glass_off && (buf[i]==GlassOff[i]); // Сравниваем побитово на совпадение со строкой вылючения стекла
          
}
        if (
glass_on)                                      // Если перехвачена команда включения стекла
           
{
           
EE_Glass true;                                // Установка флага включения стекла 
           
digitalWrite(LED_Glass_Pin,HIGH);               // Включение светодиода стекла  
           
Serial.println("  стекло включено внешним воздействием");
           }
        else if (
glass_off)                                // Если перехвачена команда включения стекла
           
{
           
EE_Glass false;                               // Установка флага выключения стекла
           
digitalWrite(LED_Glass_Pin,LOW);                // Выключение светодиода стекла  
           
Serial.println("  стекло выключено внешним воздействием");
           }
        else  
           
Serial.println("  неизвестная команда стекло");
        }   
      else
       {
        
Serial.println("  неизвестная управляющая команда ");
       } 
  }                                                        
// Конец цикла чтения из буфера           
}
void loop()                                                // Основной цикл
{    
  if (
flagRecvExternal_Control();                        // Обработка прерывания
  
KeyDetect();                                             // ОБработка нажатия клавиши

ghans вне форума   Ответить с цитированием
Старый 10.12.2017, 23:51   #2
BsdMan
Новый Пользователь
 
Регистрация: 10.12.2017
Регион: 52
Сообщений: 1
BsdMan is on a distinguished road
По умолчанию

Интересная инфа, спасибо!
Известно ли как включить/выключить вебасту (Дополнительный /автономный отопитель) через CAN шину ?
На NFке эбер конечно...

Последний раз редактировалось BsdMan; 11.12.2017 в 09:07. Причина: дополнено
BsdMan вне форума   Ответить с цитированием
Старый 14.12.2017, 12:59   #3
(vS)
Гуру
 
Аватар для (vS)
 
Регистрация: 13.10.2006
Возраст: 40
Город: Санкт-Петербург
Регион: 54
Машина: '98 PRIUS NHW10
Сообщений: 1,982
(vS) will become famous soon enough(vS) will become famous soon enough
По умолчанию

пытаю леонарду, чото глючная она... или только у меня?
ком порт то есть то нету, передернешь есть, еще передернешь нету.... фигня
__________________
маст{ер} c[лов]а и стил<ус>а

мои детки: сивик и геша + а у него названья нет + примус +
грандесла
(vS) вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Часовой пояс GMT +4, время: 09:40.


Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Яндекс.Метрика