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

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

  1. ser24alm

    ser24alm Нерд

    А можно примерную схему и полный код? Заранее спасибо
     
  2. ser24alm

    ser24alm Нерд

    Всем большое спасибо за ответы. Буду пробовать
     
  3. ser24alm

    ser24alm Нерд

    А что за таймеры?)
     
  4. geher

    geher Гуру

    О которых писал acos.
    Первый, который задает несущую ИК сигнала.
    Он в коде от acos инициализируется следующими строками.
    Timer1.initialize(MAN_FREQ); // 72000 Hz, 14 microseconds, 36 kHz*2
    Timer1.attachInterrupt( timerIsr ); // attach the service routine here
    Также для него нужна библиотека TimerOne (#include <TimerOne.h>)
    и функция прерывания (timerIsr).

    Второй, который можно использовать для тактирования самого сигнала (судя по величинам импульсов, он должен иметь частоту в 600 мкс).

    Без второго можно обойтись, если использовать решение "в лоб". Недостаток такого решения ("в лоб") в том, что во время передачи команды ардуино ничего больше делать не будет.
    С дополнительным таймером можно организовать "фоновую" передачу.
     
  5. ser24alm

    ser24alm Нерд

    Тоесть, его нужно просто инициилизировать?
     
  6. ser24alm

    ser24alm Нерд

    @geher
    Проверил код - не работает(

    Код (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 36000
    #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);
      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);
      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&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);
              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
    }
     
  7. geher

    geher Гуру

    Можно попробовать инвертировать импульсы (в смысле LOW и HIGH на 12-й пин поменять), я так понимаю, это может от схемы включения диода зависеть.
    Можно попробовать еще расставить "собак" (в смысле вывод отладочной информации в Serial, который, судя по коду, свободен) и смотреть монитором порта, что, где и как в программе происходит.
    Можно осциллографом (это, возможно, чрезмерное требование, искать осциллограф всего лишь для проверки данного проекта) попробовать посмотреть, что на светодиоде творится.
    Кроме того, вопрос с правильностью подключения ИК светодиода.
    Я так понимаю, в вашем случае он между пятым и двенадцатым пинами подключен?

    Следует, естественно, учитывать, что я исключительно теоретизирую. Могу где-то ошибаться без возможности проверить на практике.
     
  8. ser24alm

    ser24alm Нерд

    @geher
    Блин. Я его просто между 12 пном и землей поставил. А как должно быть? Где плюс и минус должны быть?
     
  9. geher

    geher Гуру

    Это к acos, Я могу только предполагать.
    Если исходить из этого:
    "Инфракрасный светодиод с резистором можно просто поставить между двух ножек микроконтроллера - TX и 5. Главное, чтобы он с резистором ел меньше 40 мА"
    то, поскольку вместо TX задействован 12-й пин, то как-то между 12-м и 5-м пинами, наверное.
     
  10. ser24alm

    ser24alm Нерд

    @geher
    Где 5 - минус?
     
  11. acos

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

    Тут как бы всего два варианта - если не работает так, то попробуйте вот так)
    Судя по коду, у вас передача должна идти при высоком уровне на 12-й ноге, значит светодиод подключаем анодом к 12 пину, а катодом к 5.
     

    Вложения:

  12. ser24alm

    ser24alm Нерд

    @acos
    От кнопок ничего не меняется?
     
  13. ser24alm

    ser24alm Нерд

    @acos
    Это снова я. Проверил, не работает((( Я думаю, что с кодом что-то не так или с подключением. Подскажите пожалуйста
     
  14. acos

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

    Приёмник на сколько кГц? Код на 36 рассчитан, а по факту ваш приёмник на сколько?
    Если смотреть на ик-светодиод в процессе работы через видео-камеру - светодиод горит?
    Если смотреть на ик-светодиод в процессе работы через видео-камеру - Светодиод горит всегда и гаснет при отправке или всегда потушен и горит при отправке?
     
  15. ser24alm

    ser24alm Нерд

    @acos
    1) Приемник расчитан расчитан на частоту от 36. Меняется в настройках.
    2)Обычный светодиод горит в пол силы. А ИК - нет.
    3)Светодиод в процессе отправки моргает. ИК - нет.
    И если у вас есть скайп то добавьте меня, пожалуйста(almaev.s).
     
  16. acos

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

    1. это что за приёмник такой?
    2. ик-свет не видно. видно только если смотреть на него через видеокамеру. Мобильник подойдёт.
     
  17. ser24alm

    ser24alm Нерд

    @acos
    1)TSOP 4856(ошибся)
    2)Смотрел в камеру. Свечения нет. А обычный светодиод горит в пол силы
     
    Последнее редактирование: 18 авг 2014
  18. ser24alm

    ser24alm Нерд

    @acos
    Вот мой код. Он будет работать?

    Код (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 36000
    #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);
      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
    }
     
  19. acos

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

    1. Отсюда ясно следует, что ваш приёмник работает на частоте 56 кГц. Стало быть надо писать
    #define FREQ 56000. И любой гугл вам это подтвердит:)
    2. Вы хоть видео запишите, чтоль. Как подключены светодиоды? катодом куда? а инфракрасный так же? Какой стоит ограничительный резистор? Есть уверенность, что ИК-светодиод рабочий? Моргание светодиода похоже на то, что вы от него ожидаете? Он горит в пол силы все все все рабочее время или только тогда, когда нужно передавать? Если конструкция и код правильный, то светодиод должен всё рабочее время не гореть, и загораться (в пол силы, помаргивая при этом) только при передаче. Если это не так - переверните светодиод и тогда всё станет именно так.
     
  20. ser24alm

    ser24alm Нерд

    @acos
    1) Код изменю
    2)Ик диод точно рабочий. Причем если подключить + к 12 пину, а - к земле, то он работает(тоесть моргает). Но когда подключаю как Вы сказали, то ничего не работает.