Отправка пакета через ИК

Тема в разделе "Проводная и беспроводная связь", создана пользователем ser24alm, 4 авг 2014.

  1. ser24alm

    ser24alm Нерд

    @acos
    Я вот так подключаю(обычный светодиод горит в пол силы всегда, ИК - негорит вообще). Если сменить строны, то не работает вообще.[​IMG]
     
  2. acos

    acos Официальный гик Администратор

    Код для Arduino Uno? Это важно, если работаешь напрямую с регистрами.
    Похоже вы не настроили модулирующую ножку на выход?

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

    Код (C):
    #include <TimerOne.h>

    #define L_PIN 12
    #define RESP1_PIN 7
    #define RESP2_PIN 6
    #define KILL1_PIN 10
    #define KILL2_PIN 11
    #define FREQ 56000
    #define MAN_FREQ (1000000.0/(FREQ*2))

    boolean bwu = true;
    boolean le = false;
    // описываем пакет, задавая байты данных (другие примерно так же)
    unsigned char packKill[3]={0x83,0x00,0xE8};
    unsigned char packResp[3]={0x83,0x05,0xE8};
    int packlen=3;

    void setup()
    {
      Timer1.initialize(MAN_FREQ); // 72000 Hz, 14 microseconds, 36 kHz*2
      Timer1.attachInterrupt( timerIsr );
      pinMode(L_PIN, OUTPUT);
      pinMode(RESP1_PIN, INPUT_PULLUP);
      pinMode(RESP2_PIN, INPUT_PULLUP);
      pinMode(KILL1_PIN, INPUT_PULLUP);
      pinMode(KILL2_PIN, INPUT_PULLUP);

      ///А где настройка модулирующего пина на выход?
      pinMode(5, OUTPUT); //Я вас правильно понял?

    // Serial.begin(9600);
    }

    void loop()
    {
      if(clik(RESP1_PIN))
      {
        //Serial.println("R1_CL");
        SendPack1(packResp, packlen);
      }
      else if(clik(RESP2_PIN))
      {
        //Serial.println("R2_CL");
        SendPack2(packResp, packlen);
      }
      else if(clik(KILL1_PIN))
      {
      // Serial.println("K1_CL");
      SendPack1(packKill, packlen);
      }
      else if(clik(KILL2_PIN))
      {
        //Serial.println("K2_CL");
        SendPack2(packKill, packlen);
      }
      else
      {
      }
    }



    //SendPack(pack,packlen); //Где-то в коде посылаем наш пакет

    void SendPack1 (unsigned char* pack, int pasklen)
    {
      //сброс линии перед импульсом
      digitalWrite(12,LOW);
    //  Serial.println(0);
      delayMicroseconds(600);
      //импульс
      digitalWrite(12,HIGH);
    //  Serial.println(1);
      delayMicroseconds(2400);
      digitalWrite(12,LOW);
    //  Serial.println(0);
      delayMicroseconds(600);
      for (int i=0;i<packlen;++i)
      {
          unsigned char b=pack[i];
          for (int j=0;j<8;j++)
          {
              digitalWrite(12,HIGH);
    //          Serial.println(1);
              delayMicroseconds((b&1)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              b=b>>1;
              // Это сделано в предположении, что байт передается младшим битом вперед.
              // Поскольку из описания протокола не совсем ясно, как оно должно быть,
              // то в случае передачи старшим битом вперед две строки выше данного блока комментариев
              // надо заменить на две строки ниже, не забыв раскомментировать их
              // delayMicroseconds(b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              // b=b<<1; // ставим старшим битом следующий    
              digitalWrite(12,LOW);
    //        Serial.println(0);
              delayMicroseconds(600); // пауза между битами
          }
      }
    }
    void SendPack2(unsigned char* pack, int pasklen) // функция посылки пакета
    {
      //сброс линии перед импульсом
      digitalWrite(12,LOW);
    //  Serial.println(0);
      delayMicroseconds(600);
      //импульс
      digitalWrite(12,HIGH);
    //  Serial.println(1);
      delayMicroseconds(2400);
      digitalWrite(12,LOW);
    //  Serial.println(0);
      delayMicroseconds(600);
      for (int i=0;i<packlen;i++)
      {
          unsigned char b=pack[i];
          for (int j=0;j<8;j++)
          {
              digitalWrite(12,HIGH);
    //        Serial.println(1);
              delayMicroseconds((b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              b=b<<1;
              // Это сделано в предположении, что байт передается младшим битом вперед.
              // Поскольку из описания протокола не совсем ясно, как оно должно быть,
              // то в случае передачи старшим битом вперед две строки выше данного блока комментариев
              // надо заменить на две строки ниже, не забыв раскомментировать их
              // delayMicroseconds(b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              // b=b<<1; // ставим старшим битом следующий    
              digitalWrite(12,LOW);
    //        Serial.println(0);
              delayMicroseconds(600); // пауза между битами
          }
      }
    }

    boolean clik(int pin)
    {
    boolean biu = digitalRead(pin);
    if(bwu && !biu)
    {
    delay(10);
    biu = digitalRead(pin);
    if(!biu)
    {
      return true;
    }
    }
      else{
        return false;
    }




    }
    void timerIsr()
    {
      //работаем быстро - напрямую с портами
      if ((PIND & _BV(5)) == _BV(5))
        PORTD &= ~_BV(5); //pin 5 LOW
      else
        PORTD |= _BV(5); //pin 5 HIGH
    }
     
  3. ser24alm

    ser24alm Нерд

    Да, код действительно на uno))) Огромное Вам спасибо за все! Буду тестить. Сейчас он хотя бы работает как нужно)
     
    Последнее редактирование: 19 авг 2014
  4. ser24alm

    ser24alm Нерд

    @acos
    SOS!!! Не работает опять(((( Я уже не знаю что делать. Может подскажете, что еще мжно опробовать?
     
  5. acos

    acos Официальный гик Администратор

    Я тоже) А что случилось?
     
  6. ser24alm

    ser24alm Нерд

    @acos
    Случилось ничего) Тоесть результата ноль. Видимо что-то неправильно отправляет. А кнопки никак не влияют на это? Или то, что я использую 7 и 6 пин для них?
     
  7. acos

    acos Официальный гик Администратор

    а работало хоть?
     
  8. ser24alm

    ser24alm Нерд

    @acos
    Вроде как все светится, но на устройстве никакого результата.
     
    Последнее редактирование: 26 авг 2014
  9. ser24alm

    ser24alm Нерд

    @acos
    И что значит
    Код (Text):
    INPUT_PULLUP
    ?
     
  10. geher

    geher Гуру

    Включает встроенные в МК подтягивающие (т.е. подключенные к питанию) резисторы.
    Применяется для кнопок и прочего подобного.
    Если кнопка нажимается, то она должна замыкать пин на землю.
    В результате HIGH на пине будет означать выключение (с питания через резистор), а LOW - включение (земля, подключаемая кнопкой к пину).

    Если не ошибаюсь, того же эффекта можно достичь, объявив пин как INPUT и выдав на него digitalWrite со значением HIGH,
     
  11. ser24alm

    ser24alm Нерд

    А я правильно отслеживаю нажатия?
    Код (Text):
    boolean clik(int pin)
    {
    boolean biu = digitalRead(pin);
    if(bwu && !biu)
    {
    delay(10);
    biu = digitalRead(pin);
    if(!biu)
    {
      return true;
    }
    }
      else{
        return false;
    }
    Он должен возвращать true если был клик
     
  12. geher

    geher Гуру

    А где устанавливается значение bwu?
     
  13. ser24alm

    ser24alm Нерд

    В самом начале кода)
    Вот он целиком

    Код (Text):
    #include <TimerOne.h>

    #define L_PIN 12
    #define RESP1_PIN 7
    #define RESP2_PIN 6
    #define KILL1_PIN 10
    #define KILL2_PIN 11
    #define FREQ 56000
    #define MAN_FREQ (1000000.0/(FREQ*2))

    boolean bwu = true;
    boolean le = false;
    // описываем пакет, задавая байты данных (другие примерно так же)
    unsigned char packKill[3]={0x83,0x00,0xE8};
    unsigned char packResp[3]={0x83,0x05,0xE8};
    int packlen=3;

    void setup()
    {
      Timer1.initialize(MAN_FREQ); // 72000 Hz, 14 microseconds, 36 kHz*2
      Timer1.attachInterrupt( timerIsr );
      pinMode(L_PIN, OUTPUT);
      pinMode(RESP1_PIN, INPUT_PULLUP);
      pinMode(RESP2_PIN, INPUT_PULLUP);
      pinMode(KILL1_PIN, INPUT_PULLUP);
      pinMode(KILL2_PIN, INPUT_PULLUP);
      pinMode(5, OUTPUT);
    // Serial.begin(9600);
    }

    void loop()
    {
      if(clik(RESP1_PIN))
      {
        //Serial.println("R1_CL");
        SendPack1(packResp, packlen);
      }
      else if(clik(RESP2_PIN))
      {
        //Serial.println("R2_CL");
        SendPack2(packResp, packlen);
      }
      else if(clik(KILL1_PIN))
      {
      // Serial.println("K1_CL");
      SendPack1(packKill, packlen);
      }
      else if(clik(KILL2_PIN))
      {
        //Serial.println("K2_CL");
        SendPack2(packKill, packlen);
      }
      else
      {
      }
    }



    //SendPack(pack,packlen); //Где-то в коде посылаем наш пакет

    void SendPack1 (unsigned char* pack, int pasklen)
    {
      //сброс линии перед импульсом
      digitalWrite(12,LOW);
     
      delayMicroseconds(600);
      //импульс
      digitalWrite(12,HIGH);
     
      delayMicroseconds(2400);
      digitalWrite(12,LOW);
     
      delayMicroseconds(600);
      for (int i=0;i<packlen;++i)
      {  
          unsigned char b=pack[i];
          for (int j=0;j<8;j++)
          {
              digitalWrite(12,HIGH);
             
              delayMicroseconds((b&1)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              b=b>>1;
              // Это сделано в предположении, что байт передается младшим битом вперед.
              // Поскольку из описания протокола не совсем ясно, как оно должно быть,
              // то в случае передачи старшим битом вперед две строки выше данного блока комментариев
              // надо заменить на две строки ниже, не забыв раскомментировать их
              // delayMicroseconds(b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              // b=b<<1; // ставим старшим битом следующий        
              digitalWrite(12,LOW);
             
              delayMicroseconds(600); // пауза между битами
          }
      }
    }
    void SendPack2(unsigned char* pack, int pasklen) // функция посылки пакета
    {
      //сброс линии перед импульсом
      digitalWrite(12,LOW);
      //Serial.println(0);
      delayMicroseconds(600);
      //импульс
      digitalWrite(12,HIGH);
      // Serial.println(1);
      delayMicroseconds(2400);
      digitalWrite(12,LOW);
      //Serial.println(0);
      delayMicroseconds(600);
      for (int i=0;i<packlen;i++)
      {  
          unsigned char b=pack[i];
          for (int j=0;j<8;j++)
          {
              digitalWrite(12,HIGH);
              //Serial.println(1);
              delayMicroseconds((b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              b=b<<1;
              // Это сделано в предположении, что байт передается младшим битом вперед.
              // Поскольку из описания протокола не совсем ясно, как оно должно быть,
              // то в случае передачи старшим битом вперед две строки выше данного блока комментариев
              // надо заменить на две строки ниже, не забыв раскомментировать их
              // delayMicroseconds(b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              // b=b<<1; // ставим старшим битом следующий        
              digitalWrite(12,LOW);
              //Serial.println(0);
              delayMicroseconds(600); // пауза между битами
          }
      }
    }

    boolean clik(int pin)
    {
    boolean biu = digitalRead(pin);
    if(bwu && !biu)
    {
    delay(10);
    biu = digitalRead(pin);
    if(!biu)
    {
      return true;
    }
    }
      else{
        return false;
    }




    }
    void timerIsr()
    {
      //работаем быстро - напрямую с портами
      if ((PIND & _BV(5)) == _BV(5))
        PORTD &= ~_BV(5); //pin 5 LOW
      else
        PORTD |= _BV(5); //pin 5 HIGH
    }
     
  14. ser24alm

    ser24alm Нерд

    А может в коде должно быть вместо
    Код (Text):
    for (int j=0;j<8;j++)
          {
              digitalWrite(12,HIGH);
              //Serial.println(1);
              delayMicroseconds((b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              b=b<<1;
              // Это сделано в предположении, что байт передается младшим битом вперед.
              // Поскольку из описания протокола не совсем ясно, как оно должно быть,
              // то в случае передачи старшим битом вперед две строки выше данного блока комментариев
              // надо заменить на две строки ниже, не забыв раскомментировать их
              // delayMicroseconds(b&0x80)?1200:600); //время передачи бита 1 -1200 мкс, 0 600 мкс
              // b=b<<1; // ставим старшим битом следующий      
              digitalWrite(12,LOW);
              //Serial.println(0);
              delayMicroseconds(600); // пауза между битами
          }
     
    j<=8?
     
  15. geher

    geher Гуру

    С bwu понятно, бесполезно, но не мешает.
    Впрочем, одна однозначная некорректность в функции clik есть.
    Результат функции не определен, если biu после второго считывания не ноль. Компилятор по идее должен на это выдавать предупреждение.

    А по циклу там однозначно <8.
    В байте 8 бит. Соответственно, должно быть 8 итераций. Первая итерация при j, установленном в 0, последняя при j, установленном в 7.
    Если заходить на следующую итерацию, будет 9-я итерация, лишняя.
     
  16. ser24alm

    ser24alm Нерд

    А все понял. Но все дело в том, что не работает. На устройстве ноль реакций
     
  17. ser24alm

    ser24alm Нерд

    @geher
    Что еще можно попробовать?
     
  18. geher

    geher Гуру

    Честно говоря, уже не знаю. Это лучше к практикам. Я в данном вопросе (обмен через ИК), только теоретик.
     
  19. M.a.x

    M.a.x Нуб

    Вам удалось разобраться?
     
  20. matvey2004

    matvey2004 Нуб

    помогите я решил повторить проект амперки икрепитер ,но собрался делать на ардуино уно заливаю скетч а он пишет ошибку скачивал с гтхаб установил библиотеки но не компилируется .Что делать?
    вот ошибка
    Arduino: 1.7.7 (Windows 7), Плата"Arduino Uno"

    In file included from IR-repeater.ino:2:0:

    IRremote_header.h:2:22: fatal error: IRremote.h: No such file or directory

    #include <IRremote.h>

    ^

    compilation terminated.

    Ошибка компиляции.

    Это сообщение будет содержать больше информации чем
    "Отображать вывод во время компиляции"
    включено в Файл > Настройки