Показано с 1 по 10 из 59

Тема: Arduino и I-BUS

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #2
    Модератор Аватар для XsanderS
    Регистрация
    05.05.2008
    Возраст
    42
    Сообщений
    829
    Вес репутации
    408

    По умолчанию Re: arduino и I-BUS

    Подключение штатных кнопок на руле и не только, по IBUS. перед прошивкой положить библиотеку MsTimer2 в arduino-0017\hardware\libraries

    код для Arduino Mega.

    PHP код:
    #include <MsTimer2.h>

    byte IBUSbyte[6] = {0,0,0,0,0,0}; // массив сообещний
    bool MafonPin false//true - данные идут в комп; false - управляют пинами ардио

    void setup()                    
    {
      
    MsTimer2::set(100ResetPinButton); // Таймер для установки выходов IBUS
      
    Serial.begin(115200);           // открываем порт для передачи в ПК 
      
    Serial1.begin(9600);    // настройка порта IBUS
      
    pinMode(7INPUT); // Вход мафон
      
    pinMode(8OUTPUT); // Громкость +
      
    pinMode(9OUTPUT); // Громкость -
      
    pinMode(10OUTPUT); // Кнопка Next
      
    pinMode(11OUTPUT); // Кнопка Previous
      
    pinMode(12OUTPUT); // Кнопка Dial
      
    pinMode(13OUTPUT); // Кнопка R/T
      
    digitalWrite(8LOW);
      
    digitalWrite(9LOW);
      
    digitalWrite(10LOW);
      
    digitalWrite(11LOW);
      
    digitalWrite(12LOW);
      
    digitalWrite(13LOW);
    }

    void loop()
    {
      
    ReadIBUSmsg();
      
    ReadMAfonPin();
    }

    boolean ReadIBUSmsg()
    {
      while( 
    Serial1.available() > )
      {
        for( 
    int i=1i<6i++ )
          
    IBUSbyte[i-1] = IBUSbyte[i];
        
    IBUSbyte[5] = Serial1.read();
        if( 
    IBUSbyte[0] == 0x50 && IBUSbyte[(IBUSbyte[1]+1)] == CalcXOR(IBUSbyte) )
        {
          if( 
    MafonPin )
            
    Serial.write(IBUSbyte6);
          else
          {
            if( 
    IBUSbyte[3] == 0x32 && IBUSbyte[4] == 0x11 digitalWrite(8HIGH); // Нажал +
            
    else if( IBUSbyte[3] == 0x32 && IBUSbyte[4] == 0x10 digitalWrite(9HIGH); // Нажал -
            
    else if( IBUSbyte[3] == 0x3B && ( IBUSbyte[4] == 0x01 || IBUSbyte[4] == 0x11 ) ) digitalWrite(10HIGH); // Нажата next
            
    else if( IBUSbyte[3] == 0x3B && IBUSbyte[4] == 0x21 digitalWrite(10LOW); // Отпустил next
            
    else if( IBUSbyte[3] == 0x3B && ( IBUSbyte[4] == 0x08 || IBUSbyte[4] == 0x18 ) ) digitalWrite(11HIGH); // Нажата previous
            
    else if( IBUSbyte[3] == 0x3B && IBUSbyte[4] == 0x28 digitalWrite(11LOW); // Отпустил previous
            
    else if( IBUSbyte[3] == 0x3B && ( IBUSbyte[4] == 0x80 || IBUSbyte[4] == 0x90 ) ) digitalWrite(12HIGH); // Нажата dial
            
    else if( IBUSbyte[3] == 0x3B && IBUSbyte[4] == 0xA0 digitalWrite(12LOW); // Отпустил dial
          
    }
          if( 
    IBUSbyte[2] == 0xC8 && IBUSbyte[3] == 0x01 digitalWrite(13HIGH); // Нажата R/T
          
    MsTimer2::start();
          return 
    true;
        }
      }
      return 
    false;
    }

    byte CalcXORbyte IBUSbyte[6] )
    {
      
    byte i;
      
    byte checksum 0;
      
    byte length;
      
    length IBUSbyte[1] + 1;
      for(
    0lengthi++)
      {
        
    checksum ^= IBUSbyte[i];
      }
      return 
    checksum;
    }
    void ResetPinButton()
    {
      
    digitalWrite(8LOW);
      
    digitalWrite(9LOW);
      
    digitalWrite(13LOW);
      
    MsTimer2::stop();
    }

    void ReadMAfonPin()
    {
      if( 
    digitalRead(7) == HIGH )
      {
        
    delay(2);
        if( 
    digitalRead(7) == HIGH MafonPin true;
      }
      else 
    MafonPin false;

    Код предназначен для управления внешним устройством (например не штатная магнитола) и компом одновременно.

    Подключение: сигнал RX c IBUS подключается в Serial1 пины на борту 18tx,19rx (внимание только для Ard Mega для других версий нужно использовать софтовый Serial см ниже)

    Работает след образом: D7 настроен на вход, когда на D7 уровень сигнала LOW то кнопки управляют пинами D8-D13 и данные о нажатиях в комп не идут. когда на D7 HIGH то пины молчат и данные о нажатиях отправляются в ПК (как настроить на эти сигналы на нажатия кнопок клавы см в конце поста)

    примечание: кнопка R/T управляет D13 не зависимо от сигнала на D7, можно использовать для переключения режимов (например на магнитоле CD/AUX/FM)




    Так как многим такие сложности не нужны и большинство использует более компактные версии arduino то решил нарисовать еще один прошивку с использованием библиотеки NewSoftSerial для arduino не имеющих дополнительных Serial портов.

    перед прошивкой положить библиотеку NewSoftSerial в arduino-0017\hardware\libraries

    PHP код:
    #include <NewSoftSerial.h>          // програмный Serial для подключения BMW I-BUS

    // I-BUS
    NewSoftSerial IBUS(78);           // пины для подкл I-BUS (7rx,8tx)
    int IBUSreceiveByte 0;            // считываем байт с I-BUS
    byte IBUSbyte[6] = {0,0,0,0,0,0};   // массив сообещний
    void setup()                    
    {
      
    Serial.begin(115200);               // открываем порт для передачи в ПК 
      
    IBUS.begin(9600);                 // настройка порта IBUS
    }

    void loop()
    {
      
    ReadIBUSmsg();
    }

    boolean ReadIBUSmsg()
    {
      while( 
    IBUS.available() > )
      {
        for( 
    int i=1i<6i++ )
          
    IBUSbyte[i-1] = IBUSbyte[i];
        
    IBUSbyte[5] = IBUS.read();
        if( 
    IBUSbyte[0] == 0x50 && IBUSbyte[(IBUSbyte[1]+1)] == CalcXOR(IBUSbyte) )
        {

            
    Serial.write(IBUSbyte6);  
          {
            if( 
    IBUSbyte[3] == 0x32 && IBUSbyte[4] == 0x11 ); // Нажал +
            
    else if( IBUSbyte[3] == 0x32 && IBUSbyte[4] == 0x10 ) ; // Нажал -
            
    else if( IBUSbyte[3] == 0x3B && ( IBUSbyte[4] == 0x01 || IBUSbyte[4] == 0x11 ) ) ; // Нажата next
            
    else if( IBUSbyte[3] == 0x3B && IBUSbyte[4] == 0x21 ) ; // Отпустил next
            
    else if( IBUSbyte[3] == 0x3B && ( IBUSbyte[4] == 0x08 || IBUSbyte[4] == 0x18 ) ) ; // Нажата previous
            
    else if( IBUSbyte[3] == 0x3B && IBUSbyte[4] == 0x28 ) ; // Отпустил previous
            
    else if( IBUSbyte[3] == 0x3B && ( IBUSbyte[4] == 0x80 || IBUSbyte[4] == 0x90 ) ) ; // Нажата dial
            
    else if( IBUSbyte[3] == 0x3B && IBUSbyte[4] == 0xA0 ) ; // Отпустил dial
            
    else if( IBUSbyte[2] == 0xC8 && IBUSbyte[3] == 0x01 ) ; // Нажата R/T
          
    }
        }
      }
    }
    byte CalcXORbyte IBUSbyte[6] )
    {
      
    byte i;
      
    byte checksum 0;
      
    byte length;
      
    length IBUSbyte[1] + 1;
      for(
    0lengthi++)
      {
        
    checksum ^= IBUSbyte[i];
      }
      return 
    checksum;

    Подключение: к D7rx D8tx (сигнал RX с шины подключается к D7)
    Работает след образом: При нажатии кнопок данные отправляются в ПК (как настроить на эти сигналы на нажатия кнопок клавы см в конце поста)




    Код симулятор посылок с шины дабы не бегать с 5го этажа по морозу на парковку 6 раз чтоб узнать что перепутал Tx и Rx но нужен второй Arduino который будет играть роль шины. D10 настроен на вход, когда на нем уровень HIGH то шлется симулированный сигнал нажатия кнопки руля.

    PHP код:
    byte PLUS_DOWN[8] = {00x500x040x680x320x110x1F}; // + press button
    byte MINUS_DOWN[8] = {00x500x040x680x320x100x1E}; // - press button

    byte NEXT_DOWN[8] = {00x500x040x680x3B0x010x06}; // > press button
    byte NEXT_HOLD[8] = {00x500x040x680x3B0x110x16}; // > hold button
    byte NEXT_REL[8] = {00x500x040x680x3B0x210x26}; // > release button

    byte PREV_DOWN[8] = {00x500x040x680x3B0x080x0F}; // < press button
    byte PREV_HOLD[8] = {00x500x040x680x3B0x180x1F}; // < hold button
    byte PREV_REL[8] = {00x500x040x680x3B0x280x2F}; // < release button

    byte VOICE_DOWN[8] = {00x500x040xC80x3B0x800x27}; // voice press button
    byte VOICE_HOLD[8] = {00x500x040xC80x3B0x900x37}; // voice hold button
    byte VOICE_REL[8] = {00x500x040xC80x3B0xA00x07}; // voice release button

    byte RT_DOWN[8] = {00x500x030xC80x010x9A0x80}; // voice release button

    int ButtonPin 10//кнопка на 10 ноге



    void setup()
    {
      
    Serial.begin(9600);           // открываем порт на скорости 115200 для передачи наружу
      
    pinMode(ButtonPinINPUT);    // Устанавливем 10 пин на вход 
     
    }


    void loop()
    {
      
      if (
    digitalRead(ButtonPin)==1) {
         
        
    //Вывод в стандартный порт байты посылки команды VOL+
        
    for (int i=1<= 6i++){ Serial.write(PLUS_DOWN[i]); } 

        
    //Задержка 1000 милисекунд 1000 м.с. = 1 секунда
        
    delay(1000);
      }

    Подключение: 1пин Tx (стандартный порт на всех моделях) работает соответственно на выход и симулирует Rx сигнал от IBUS.

    для выбора какую команду слать, в этой строке

    for (int i=1; i <= 6; i++){ Serial.write(PLUS_DOWN[i]); }

    PLUS_DOWN

    меняем на то что нужно послать. Например NEXT_DOWN

    byte PLUS_DOWN[8] = {0, 0x50, 0x04, 0x68, 0x32, 0x11, 0x1F}; // + press button
    byte MINUS_DOWN[8] = {0, 0x50, 0x04, 0x68, 0x32, 0x10, 0x1E}; // - press button

    byte NEXT_DOWN[8] = {0, 0x50, 0x04, 0x68, 0x3B, 0x01, 0x06}; // > press button
    byte NEXT_HOLD[8] = {0, 0x50, 0x04, 0x68, 0x3B, 0x11, 0x16}; // > hold button
    byte NEXT_REL[8] = {0, 0x50, 0x04, 0x68, 0x3B, 0x21, 0x26}; // > release button

    byte PREV_DOWN[8] = {0, 0x50, 0x04, 0x68, 0x3B, 0x08, 0x0F}; // < press button
    byte PREV_HOLD[8] = {0, 0x50, 0x04, 0x68, 0x3B, 0x18, 0x1F}; // < hold button
    byte PREV_REL[8] = {0, 0x50, 0x04, 0x68, 0x3B, 0x28, 0x2F}; // < release button

    byte VOICE_DOWN[8] = {0, 0x50, 0x04, 0xC8, 0x3B, 0x80, 0x27}; // voice press button
    byte VOICE_HOLD[8] = {0, 0x50, 0x04, 0xC8, 0x3B, 0x90, 0x37}; // voice hold button
    byte VOICE_REL[8] = {0, 0x50, 0x04, 0xC8, 0x3B, 0xA0, 0x07}; // voice release button

    byte RT_DOWN[8] = {0, 0x50, 0x03, 0xC8, 0x01, 0x9A, 0x80}; // voice

    Для сканирования порта (посмотреть что приходит в ПК) используем Terminal.exe данные должны приходить в таком виде

    next____________________________

    DOWN 50 04 68 3B 01 06

    HOLD 50 04 68 3B 11 16

    RELISE 50 04 68 3B 21 26

    plus____________________________

    50 04 68 32 11 1F

    minus___________________________

    50 04 68 32 10 1E

    prev_____________________________

    DOWN 50 04 68 3B 08 0F

    HOLD 50 04 68 3B 18 1F

    RELISE 50 04 68 3B 28 2F

    R/T______________________________

    50 03 C8 01 9A 80

    Voice____________________________

    DOWN 50 04 C8 3B 80 27

    HOLD 50 04 C8 3B 90 37

    RELISE 50 04 C8 3B A0 07

    Теперь назначаем на принятый сигнал комбинации клавиатуры. сделать это можно с помощью программы IR Kay написанной Chip`ом для проекта "управление любым IR Пультом"

    единственное что файл Config нужно править руками но это не составит труда.

    выглядит он внутри примерно так:

    <50046832111F>Key1=49 />
    <50046832101E>Key1=50 />

    прописываем в ручную коды приходящие от нажатий кнопок руля и код нажатия кнопки.

    PS: Благодарим kostya740 за помощь в написании прошивки для Mega, Также efimomax за очень полезные советы и примеры, Chip за софт и не человеческое терпение
    Вложения Вложения
    Последний раз редактировалось Chip; 08.03.2017 в 03:46.
    хороший модем должен качать пиво!
    Мой проект

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

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