Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 06.04.2019, 03:25  
GrafGrigorio
Частый гость
 
Регистрация: 13.08.2018
Адрес: Краснодар
Сообщений: 25
Сказал спасибо: 14
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GrafGrigorio на пути к лучшему
По умолчанию Декодирование Манчестера на ардуинке.

Всем привет,
Пытаюсь декодировать rfid метку по данной статье https://habr.com/ru/post/330710/ и делаю это через ардуино
Наскрябал код:
Нажмите, чтобы открыть спойлер
Код:
#include ‹Arduino.h›
#include ‹TimerOne.h›

boolean skan = true; // Переключение между сканированием и выводом
int x0[200];         //храним время между перепадами
int x1[200];         //храним физический бит с
int fiz_ukaz = 0;
int ty = 0; //отвечает за запуск каждую секунду
byte data[6];

boolean data_binar[200]; //по извращенски храним биты

void setup()
{
  Serial.begin(115200);
  pinMode(11, OUTPUT);
  Timer1.initialize(8); // делитель частоты 1Мгц/8=125Кгц, 8us = 125KHz
  Timer1.pwm(9, 512);   // Шим на 9м пине
  // Timer1.attachInterrupt(Timer1_action);//выполнение действия(функции) каждый цикл счетчика
  ACSR = bit(ACIE); //Обозначение компаратора на 6м и 7м пине
}

int man_bit(int posled, int bitv)
{
  if (posled ‹= 3) //200
  {
    if (bitv == 1)
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
  //*-*-*-*-*-*-*-*
  if (posled › 3) //400
  {
    if (bitv == 1)
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
}

void decoding(int time[], int bit[]) //декодируем в массив data
{
  int edinicki = 0; //счетчик едениц стартового блока
  boolean start_block_fined = false;
  boolean read_data = false;
  int wr_byte = 7;
  int wr_block = 0;
  int niible = 0;
  int chetnost = 0;
  for (int t = 0; t ‹ 200; ++t)
  {
    int posle = (time[t + 1] - time[t]) / 100;
    int pered = (time[t] - time[t - 1]) / 100;
    //==================================================  ================
    if (bit[t] == 1 && pered › 3 && posle ‹= 3 && !start_block_fined) //если стартовый бит еще не был найден
    {
      start_block_fined = true;
    }
    //==================================================  ================
    if (start_block_fined) //если стартовый бит найден
    {

      if (posle ‹= 3 && bit[t] == 1) //проверяем время после указателя
      {
        ++edinicki;
        ++t;
      }
      else //если вреня не соответствует еденице
      {

        edinicki = 0;
        start_block_fined = false;
      }
      if (edinicki == 8)
      {
        Serial.println("edinicki");
        read_data = true;          //запускам процесс записи данных
        start_block_fined = false; // прекращаем поиск стартового блока
      }
    }
    //==================================================  ================
    if (read_data)
    {
      if (niible ‹ 4) //если 4 бита наиббла
      {
        if (posle ‹= 3) //если задержка между битами
          ++t;
        if (man_bit(posle, x1[t]) == 1)
        {
          ++chetnost;
          data[wr_block] += pow(2, wr_byte);
          --wr_byte;
        }
        else
        {
          --wr_byte;
        }
      }
      else //если бит четности
      {
        if (posle ‹= 3) //если задержка между битами
          ++t;
        if ((chetnost % 2) == man_bit(posle, x1[t]))
        {
          Serial.println(" + ");
        }
      }
    }
    //==================================================  ================
    if (wr_byte == -1)
    {
      wr_byte = 7;
      ++wr_block;
    }
    if (wr_block == 6)
    {
      break;
    }
    //==================================================  ================
  } //for
}

void loop() // int p= pow(2, 0);
{
  if (ty ‹ (int)millis() / 1000) //Запуск раз в секунду
  {
    Serial.println("Start!==-=--=-=-=-==-=-");
    if (!skan) //если компаратор не занят заполнением массива
    {
      decoding(x0, x1);           //декодируем в массив data
      for (int y = 0; y ‹ 6; ++y) // выводим результат
      {
        Serial.println(data[y], HEX);
      }
      skan = true; //отправляем считывать данные
    }
  }
  ty = millis() / 1000;
}
int kol = 0; //указатель массива
//Вызов при изменении выхода компаратора с 0 на 1 и обратно
ISR(ANALOG_COMP_vect) //внутренний компаратор, выполнение при изменеии сигнала
{
  boolean by = ACSR & bit(ACO);       //текуще положение компаратора
  digitalWrite(11, !digitalRead(11)); //инвертируем сигнал для проверки работоспособности осцилографом
  if (skan)
  {
    if (by) //Если сигнал +
    {
      x1[kol] = 1;
      x0[kol] = micros(); //фиксируем время единички
    }
    else //если сигнал 0
    {
      x1[kol] = 0;
      x0[kol] = micros(); //фиксируем время нолика
    }
    ++kol;
    if (kol ›= 200) //считаем биты и даем разрешение на чтение массива с битами
    {
      skan = false;
      kol = 0;
    }
  }
}

Проблема в том что получаю каждый раз разные значения
Нажмите, чтобы открыть спойлер
Цитата:
Start!==-=--=-=-=-==-=-
edinicki
AF
A6
1E
B9
55
68
Start!==-=--=-=-=-==-=-
edinicki
5A
79
99
8D
4C
60

Делаю все по принципу
Жду пока компаратор переключится 200 раз, походу дела заполняя массивы временем и положением компаратора далее получив массивы х0, х1 разбираю данные по принципу, если за указателем время 0.2-0.3мс то передвигаем указатель на 2 если больше 0.3мс тогда указатель двигаю на 1, если кому не сложно направьте меня на истинный путь, а то я совсем заплутал, или может у кого есть уже написанный для ардуинки код считывателя.

Будь адекватная отладка для ардуинки(кроме терминала) было-бы куда проще.
Реклама:
GrafGrigorio вне форума  
Непрочитано 06.04.2019, 12:08  
ForcePoint
Почётный гражданин KAZUS.RU
 
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 7,018
Сказал спасибо: 3,026
Сказали Спасибо 3,200 раз(а) в 2,171 сообщении(ях)
ForcePoint на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Сам с манчестером не возился, но, может, App. note помогут? Например:
https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en591471 - RC5 IR Remote Control Receiver on tinyAVR and megaAVR devices
https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en591226 - Secure Rolling Code Algorithm for Wireless Link on tinyAVR and megaAVR devices
__________________
Экзорцист 40-го уровня.
ForcePoint вне форума  
Сказали "Спасибо" ForcePoint
GrafGrigorio (06.04.2019)
Непрочитано 06.04.2019, 14:30  
mike-y-k
Модератор
 
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,257
Сказал спасибо: 11,170
Сказали Спасибо 3,858 раз(а) в 2,928 сообщении(ях)
mike-y-k на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Таки имеем 125kHz посылку, берём в 4 раза большую частоту и нормальный формирователь логического уровня на входе. По таймеру с этой частотой пишем тетрады состояния для входа и потом их переводим в битовый поток для выходных 64бит посылки.
Во втором варианте можно сразу битовый поток принимать, настроив пин на прерывание по смене статуса и анализируя интервал в таймере от предыдущего.
Таблица состояний для Манчестера не столь уж сложна в обработке: 10, 01, 11, 00 - всего четыре варианта для разбора.

На тему отладки - тут придётся дополнительно программатор-отладчик приобрести или сделать, тогда станет легче.

PS А та статья на хабре душу согревает - не только отсюда ссылки на него, но и наоборот присутствуют (RECTO, BolyshoyK)
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…

Последний раз редактировалось mike-y-k; 08.04.2019 в 17:47.
mike-y-k вне форума  
Сказали "Спасибо" mike-y-k
GrafGrigorio (06.04.2019)
Непрочитано 06.04.2019, 18:08  
GrafGrigorio
Частый гость
 
Регистрация: 13.08.2018
Адрес: Краснодар
Сообщений: 25
Сказал спасибо: 14
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GrafGrigorio на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Сообщение от mike-y-k Посмотреть сообщение
Таблица состояний для Манчестера не столь уж сложна в обработке: 10, 01, 11, 00 - всего четыре варианта для разбора.
Тут хотелось бы по подробнее откуда и как получаются 10, 01, 11, 00, при использовании 2го варианта
Сообщение от mike-y-k Посмотреть сообщение
На тему отладки - тут придётся дополнительно программатор-отладчик приобрести или сделать, тогда станет легче.
Есть какие либо рекомендации на эту тему, и у меня есть логический анализатор, вариант как-то его использовать?
GrafGrigorio вне форума  
Непрочитано 06.04.2019, 18:24  
akegor
Гуру портала
 
Аватар для akegor
 
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,057
Сказал спасибо: 2,563
Сказали Спасибо 11,890 раз(а) в 5,964 сообщении(ях)
akegor на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Сообщение от mike-y-k Посмотреть сообщение
На тему отладки - тут придётся дополнительно программатор-отладчик приобрести или сделать, тогда станет легче.
Для
Сообщение от GrafGrigorio Посмотреть сообщение
Будь адекватная отладка для ардуинки(кроме терминала) было-бы куда проще.
предлагаете?
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
akegor на форуме  
Непрочитано 06.04.2019, 19:46  
GrafGrigorio
Частый гость
 
Регистрация: 13.08.2018
Адрес: Краснодар
Сообщений: 25
Сказал спасибо: 14
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GrafGrigorio на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Сообщение от akegor Посмотреть сообщение
Для
Сообщение от akegor Посмотреть сообщение
предлагаете?
Эмм, чта?...
GrafGrigorio вне форума  
Непрочитано 06.04.2019, 19:56  
scorpi_0n
Прописка
 
Регистрация: 10.03.2016
Сообщений: 114
Сказал спасибо: 14
Сказали Спасибо 46 раз(а) в 41 сообщении(ях)
scorpi_0n на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Сообщение от GrafGrigorio Посмотреть сообщение
Пытаюсь декодировать rfid метку по данной статье
Смотрим, что там.
Цитата:
Возьмём аналоговую часть такого копировщика у RECTO
Не самый лучший случай, но ладно.
Цитата:
Метод расшифровки манчестерского кодирования и код для этого я взял у Shads.
А вот к этому я бы уже отнёсся с настороженностью. Этому неадекватному клоуну на двух (а может даже и на 3-4-ех) форумах долго талдычили что к чему и не факт что он всё понял и что всё сделал как надо.
scorpi_0n вне форума  
Непрочитано 06.04.2019, 20:19  
akegor
Гуру портала
 
Аватар для akegor
 
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,057
Сказал спасибо: 2,563
Сказали Спасибо 11,890 раз(а) в 5,964 сообщении(ях)
akegor на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Сообщение от GrafGrigorio Посмотреть сообщение
Эмм, чта?...
Мал-мал не то процитировал. Это -
Сообщение от GrafGrigorio Посмотреть сообщение
делаю это через ардуино
точнее.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
akegor на форуме  
Непрочитано 06.04.2019, 20:24  
GrafGrigorio
Частый гость
 
Регистрация: 13.08.2018
Адрес: Краснодар
Сообщений: 25
Сказал спасибо: 14
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GrafGrigorio на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Сообщение от scorpi_0n Посмотреть сообщение
Не самый лучший случай, но ладно.
Сообщение от scorpi_0n Посмотреть сообщение
А вот к этому я бы уже отнёсся с настороженностью. Этому неадекватному клоуну на двух (а может даже и на 3-4-ех) форумах долго талдычили что к чему и не факт что он всё понял и что всё сделал как надо.
Это конечно все хорошо, но если бы я решил не глядя скопировать я бы это сделал, у recto хорошая схема, а в статье на форуме базовые принципы работы более менее понятно описаны, так как хорошего примера нигде нету вот я и пытаюсь сам во все вникнуть и понять, чтобы потом поделиться результатом.
Кстати свой говнокод уже более менее привел к рабочему варианту, работает как надо только проверка четности что то пролетает в некоторых случаях.
Нажмите, чтобы открыть спойлер
Код:
#include ‹Arduino.h›
#include ‹TimerOne.h›

boolean skan = true; // Переключение между сканиноварием и выводом
int x0[200];         //храним время между перепадами
int x1[200];         //храним физический бит с
int fiz_ukaz = 0;
int ty = 0; //отвечает за запуск каждую секунду
int data[6];

boolean data_binar[200]; //по извращенски храним биты

void setup()
{
  Serial.begin(115200);
  pinMode(11, OUTPUT);
  Timer1.initialize(8); // делитель частоты 1Мгц/8=125Кгц, 8us = 125KHz
  Timer1.pwm(9, 512);   // Шим на 9м пине
  // Timer1.attachInterrupt(Timer1_action);//выполнение действия(функции) каждый цикл счетчика
  ACSR = bit(ACIE); //Обозначение копаратора на 6м и 7м пине
}

int man_bit(int posled, int bitv)
{
  if (posled ‹= 3) //200
  {
    if (bitv == 1)
    {
      return 1;
    }
    if (bitv == 0)
    {
      return 0;
    }
  }
  //*-*-*-*-*-*-*-*
  if (posled › 3) //400
  {
    if (bitv == 1)
    {
      return 1;
    }
    if (bitv == 0)
    {
      return 0;
    }
  }
}

void cleaning(boolean b) //очистка массивов
{
  if (b)
  {
    for (int ia = 0; ia ‹ 6; ++ia)
    {
      data[ia] = 0;
    }
  }
  else
  {
    for (int s = 0; s ‹ 201; ++s)
    {
      x0[s]; //храним время между перепадами
      x1[s];
    }
  }
}

void decoding(int time[], int bit[]) //декодируем в массив data
{
  int edinicki = 0; //счетчик едениц стартового блока
  boolean start_block_fined = false;
  boolean read_data = false;
  boolean glob = true;
  int wr_byte = 7;
  int wr_block = 0;
  int niible = 0;
  int chetnost = 0;
  cleaning(true); //чистим массив с ключем
  for (int t = 0; t ‹ 200; ++t)
  {
    int posle = (time[t + 1] - time[t]) / 100;
    int pered = (time[t] - time[t - 1]) / 100;
    //==================================================  ================
    if (glob)
    {
      if (bit[t] == 1 && pered › 3 && posle ‹= 3 && !start_block_fined) //если стартовый бит еще не был найден
      {
        start_block_fined = true;
      }
      //==================================================  ================
      if (start_block_fined) //если стартовый бит найден
      {
        if (edinicki == 8)
        {
          Serial.println("edinicki");
          read_data = true;          //запускам процесс записи данных
          start_block_fined = false; // прекращаем поиск стартового блока
          glob = false;
        }
        if (posle ‹= 3 && bit[t] == 1) //проверяем время после указателя
        {
          ++edinicki;
          //++t;
        }
        else //если вреня не соответствует еденице
        {
          edinicki = 0;
          start_block_fined = false;
        }
      }
    }
    //==================================================  ================
    if (read_data)
    {
      if (niible ‹ 4) //если 4 бита наиббла
      {

        if (man_bit(posle, x1[t]) == 1)
        {
          ++chetnost;
          data[wr_block] += pow(2, wr_byte);
          Serial.print(wr_block);
          Serial.print(":");
          Serial.print(wr_byte);
          Serial.print(":");
          --wr_byte;
          ++niible;
          Serial.print(1);
          Serial.print(" ");
        }
        else
        {
          Serial.print(wr_block);
          Serial.print(":");
          Serial.print(wr_byte);
          Serial.print(":");
          ++niible;
          --wr_byte;
          Serial.print(0);
          Serial.print(" ");
        }
      }
      else //если бит четности
      {
        // Serial.print(2222);
        // Serial.print(" ");
        niible = 0;

        if ((chetnost % 2) == man_bit(posle, x1[t]))
        {
          Serial.print(" + ");
          Serial.print(" ");
          Serial.print(man_bit(posle, x1[t]));
          Serial.print(" ");
          Serial.print(chetnost);
          Serial.print(" ");
          Serial.println(chetnost % 2);
        }
        else
        {
          Serial.print(" - ");
          Serial.print(" ");
          Serial.print(man_bit(posle, x1[t]));
          Serial.print(" ");
          Serial.print(chetnost);
          Serial.print(" ");
          Serial.println(chetnost % 2);
        }
        chetnost = 0;
      }
      // if (posle ‹= 3) //если задержка между битами
      //   ++t;
    }
    //==================================================  ================
    if (wr_byte == -1)
    {
      wr_byte = 7;
      ++wr_block;
    }
    if (wr_block ›= 5 && wr_byte ›= 4)
    {

      break;
    }
    //==================================================  ================
    if (posle ‹= 3) //если задержка между битами
      ++t;
  } //for
}

void loop() // int p= pow(2, 0);
{
  if (ty ‹ (int)millis() / 1000) //Запуск раз в секунду
  {
    Serial.println("Start!==-=--=-=-=-==-=-");
    if (!skan) //если компаратор не занят заполнением массива
    {
      decoding(x0, x1);           //декодируем в массив data
      for (int y = 0; y ‹ 6; ++y) // выводим результат
      {
        if (y == 0)
          Serial.println("");
        Serial.print(y);
        Serial.print(" ");
        Serial.println(data[y], HEX);
      }
      cleaning(false); //чистим массив перед чтением
      skan = true;     //отправляем считывать данные
    }
  }
  ty = millis() / 1000;
}
int kol = 0; //указатель массива
//Вызов при изменении выхода компаратора с 0 на 1 и обратно
ISR(ANALOG_COMP_vect) //внутренний компаратор, выполнение при изменеии сигнала
{
  boolean by = ACSR & bit(ACO);       //текуще положение компаратора
  digitalWrite(11, !digitalRead(11)); //инвертируем сигнал для проверки работоспособности осцилографом
  if (skan)
  {
    if (by) //Если сигнал +
    {
      x1[kol] = 1;
      x0[kol] = micros(); //фиксируем время единички
    }
    else //если сигнал 0
    {
      x1[kol] = 0;
      x0[kol] = micros(); //фиксируем время нолика
    }
    ++kol;
    if (kol ›= 200) //считаем биты и даем разрешение на чтение массива с битами
    {
      skan = false;
      kol = 0;
    }
  }
}

Вывод программы
Нажмите, чтобы открыть спойлер
Цитата:
Start!==-=--=-=-=-==-=-
edinicki
0:7:1 0:6:0 0:5:1 0:4:0 - 1 2 0
0:3:0 0:2:0 0:1:1 0:0:1 + 0 2 0
1:7:0 1:6:0 1:5:1 1:4:0 + 1 1 1
1:3:0 1:2:1 1:1:0 1:0:1 + 0 2 0
2:7:0 2:6:0 2:5:0 2:4:1 + 1 1 1
2:3:0 2:2:0 2:1:1 2:0:1 - 1 2 0
3:7:1 3:6:1 3:5:0 3:4:0 + 0 2 0
3:3:1 3:2:0 3:1:1 3:0:1 - 0 3 1
4:7:0 4:6:1 4:5:1 4:4:0 + 0 2 0
4:3:0 4:2:0 4:1:1 4:0:1
0 A1
1 24
2 12
3 C9
4 61
5 0
Где - там провал проверки четности

Последний раз редактировалось GrafGrigorio; 06.04.2019 в 20:26.
GrafGrigorio вне форума  
Непрочитано 08.04.2019, 07:33  
GrafGrigorio
Частый гость
 
Регистрация: 13.08.2018
Адрес: Краснодар
Сообщений: 25
Сказал спасибо: 14
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
GrafGrigorio на пути к лучшему
По умолчанию Re: Декодирование Манчестера на ардуинке.

Завершил, все работает как надо, постарался прокомментировал весь код, кому интересно пользуйтесь.
Всем спасибо за помощь.
Нажмите, чтобы открыть спойлер
Код:
/*
*Ниббл - половина байта.
Внимание ОЧЕНЬ радиокативный гавнокод=)
Используется atmega328p (NANO)
125кГц RFID
Используется библиотека TimerOne.h для генерации шима 125кГц на 9м пине далее используя схему от RECTO https://habr.com/ru/post/330710/
получаем сигнал на входе встроенного компаратора 6 и 7, на выход 11 подаем уже чистый сигнал с ключа, для внешней отладки.

Используя прерывания компаратора определяем уровень сигнала и время между перепадами, собираем эти данные в массивы.

С помощью внешней отладки получаем сведения о периоде 0.4-0.5 мс., так как каждая передача заканчивается нулевым стоп билом нужно искать 0 с 1
1 в манчестере это _-Б а 0 -_, то-есть ищем сигнал вида _|_-| длиной 1.5 периода, !перед положительным перепадом должно пройти 0.4мс.
Далее ищим только единички получается для начала декодирования мы должны найти _|_-|_-|_-|_-|_-|_-|_-|_-|_-| 9 единичек,
затем идут 10 нибблов и сразу на нибблом 1 бит четности, за ними идет ниббл четности для всех столбцов ключа.
Получаем массив байт содержащий ключ, проверям вдоль и поперек, и радуемся=)

Код старался максимально закомментировать.
**Автор GrafGrigoio, для свободного использования**
*/

#include ‹Arduino.h›//Если используете не IDE Arduino/
#include ‹TimerOne.h›

boolean skan = true; // Переключение между сканиноварием и выводом
int x0[200];         //храним время между перепадами
int x1[200];         //храним физический бит с
int ty = 0; //отвечает за запуск каждую секунду
byte data[6];

boolean data_binar[200]; //по извращенски храним биты

void setup()
{
  Serial.begin(115200);
  pinMode(11, OUTPUT);
  Timer1.initialize(8); // делитель частоты 1Мгц/8=125Кгц, 8us = 125KHz
  Timer1.pwm(9, 512);   // Шим на 9м пине
  // Timer1.attachInterrupt(Timer1_action);//выполнение действия(функции) каждый цикл счетчика
  ACSR = bit(ACIE); //Обозначение копаратора на 6м и 7м пине
}

void check_summ(byte tram[]) //tram массив с байтами, проверка четности сболблов нибблов байта
{
  const byte mask[] = {0x80, 0x40, 0x20, 0x10,
                       0x08, 0x04, 0x02, 0x01};//маска по которой проверяем
  int op[4] = {0, 0, 0, 0};//тут хранится сумма 
  for (int o = 0; o ‹ 5; ++o) //по очередно проверяем 5 байт
  {
    for (int gi = 0; gi ‹ 4; ++gi)//по очередно проверяем по 2 ниббла сразу
    {
      byte buf1 = tram[o] & mask[gi];//если оператор & выдал маску значит 1
      byte buf2 = tram[o] & mask[gi + 4];//тоже самое для второго ниббла

      if (buf1 == mask[gi])//если оператор & выдал маску значит 1
        ++op[gi];
      if (buf2 == mask[gi + 4])//тоже самое для второго ниббла
        ++op[gi];
    }
  }
  Serial.println();
  for (int pk = 0; pk ‹ 4; ++pk)//выводим результат
  {
    Serial.print(op[pk] % 2);
    Serial.print(" ");
  }
  Serial.println();
}

int man_bit(int posled, int bitv)//возвращаем бит в зависимости от физического бита и времени после ^
{
  if (posled ‹= 3) // ^ 200
  {
    if (bitv == 1)
      return 1;
    if (bitv == 0)
      return 0;
  }
  //*-*-*-*-*-*-*-*
  if (posled › 3) // ^ 400
  {
    if (bitv == 1)
      return 1;
    if (bitv == 0)
      return 0;
  }
}

void cleaning(boolean b) //очистка массивов
{
  if (b)//чистим массив байт
    for (int ia = 0; ia ‹ 6; ++ia)
      data[ia] = 0;
  else//чистим физические данные
  {
    for (int s = 0; s ‹ 201; ++s)
    {
      x0[s] = 0; //храним время между перепадами
      x1[s] = 0; //храним физический бит
    }
  }
}

void decoding(int time[], int bit[]) //декодируем в массив data
{
  int edinicki = 0;                  //счетчик едениц стартового блока
  boolean start_block_fined = false; //если найден старновый блок [400 ^ 200]
  boolean read_data = false;         //разрешение на чтение ключа
  boolean glob = true;               //разрешение на поиск стартовой точки
  int wr_block = 0;                  //указатель массива байт
  int chetnost = 0;                  //счетчик чктности
  int wr_byte = 7;                   //указатель бита в байте
  int niible = 0;                    //указатель ниббла

  cleaning(true); //чистим массив с ключем

  for (int t = 0; t ‹ 200; ++t) //стартуем
  {
    int posle = (time[t + 1] - time[t]) / 100; //время после указателя
    int pered = (time[t] - time[t - 1]) / 100; //время до указателя
    //==================================================  ================
    if (glob)
    {
      if (bit[t] == 1 && pered › 3 && posle ‹= 3 && !start_block_fined) //если стартовый бит еще не был найден
      {
        start_block_fined = true;
      }
      //==================================================  ================
      if (start_block_fined) //если стартовый бит найден
      {
        if (edinicki == 8)
        {
          read_data = true;          //запускам процесс записи данных
          start_block_fined = false; // прекращаем поиск стартового блока
          glob = false;              //завершаем подготовку и идем работать с данными
          if (posle ‹= 3)            //если задержка между битами
          {
            ++t;
            ++t;
          }
          else
            ++t;
        }
        if (posle ‹= 3 && bit[t] == 1) //проверяем время после указателя
        {
          ++edinicki; //двигаемся дальше
          //++t;
        }
        else //если вреня не соответствует еденице
        {
          start_block_fined = false; //обижаемся
          edinicki = 0;              //идем в начало
        }
      }
    }
    //==================================================  ================
    if (read_data)
    {
      if (niible ‹ 4) //если 4 бита наиббла
      {

        if (man_bit(posle, x1[t]) == 1) //если по манчестеру словили единичку
        {
          ++chetnost;                       //считаем единички
          data[wr_block] |= (1 ‹‹ wr_byte); //+= pow(2, wr_byte);
          --wr_byte;                        //смещаем указатель байта в право
          ++niible;                         //смещаем указатель ниббла в право
          Serial.print(1);
          Serial.print(" ");
        }
        else
        {
          --wr_byte; //смещаем указатель байта в право
          ++niible;  //смещаем указатель ниббла в право
          Serial.print(0);
          Serial.print(" ");
        }
      }
      else //if (niible ›= 4) //если бит четности
      {
        if (wr_block == 5 && man_bit(posle, x1[t]) == 0) //радуемся что нашли стоп бит =) и идем чифирить
        {
          Serial.print("+0+");
          Serial.println(" ");
          break; //чифир тут
        }
        if ((chetnost % 2) == man_bit(posle, x1[t])) //Если успешная проверка четности
        {
          Serial.print(" + ");
          Serial.println();
        }
        else // если чтото пошло не так
        {
          Serial.print(" - ");
          Serial.println();
        }
        //--wr_byte;
        niible = 0;   //указатель ниббла
        chetnost = 0; //счетчик четности
      }

      // if (posle ‹= 3) //если задержка между битами
      //   ++t;
    }
    //==================================================  ================
    if (wr_byte == -1) //ведем переговоры с указателем байта
    {
      wr_byte = 7;
      ++wr_block;
    }
    if (wr_block › 5) //по сути оно тут не нужно но пуст будет=)
    {
      Serial.println(" ");
      break;
    }
    //==================================================  ================
    if (posle ‹= 3) //толкаем указатель если задержка пол периона
      ++t;
  } //for
}

void loop() // int p= pow(2, 0);
{
  if (ty ‹ (int)millis() / 1000) //Запуск раз в секунду
  {
    Serial.println("Start!==-=--=-=-=-==-=-");
    if (!skan) //если компаратор не занят заполнением массива
    {

      decoding(x0, x1);           //декодируем в массив data -=-=-=--=
      check_summ(data);           //проверка столбцов на корректность
      for (int y = 0; y ‹ 6; ++y) // выводим результат
      {
        if (y == 0) //чистая строка для красоты=)
          Serial.println();
        Serial.println(data[y], HEX);
      }
      cleaning(false); //чистим массив перед чтением
      skan = true;     //отправляем считывать данные
    }
  }
  ty = millis() / 1000; //для запуска каждую секунду
}
int kol = 0; //указатель массива
//Вызов при изменении выхода компаратора с 0 на 1 и обратно
ISR(ANALOG_COMP_vect) //внутренний компаратор, выполнение при изменеии сигнала
{
  boolean by = ACSR & bit(ACO);       //текуще положение компаратора
  digitalWrite(11, !digitalRead(11)); //инвертируем сигнал для проверки работоспособности осцилографом
  if (skan)                           //если с массивами никто не планирует работать
  {
    if (by) //Если сигнал +
    {
      x1[kol] = 1;        //фиксируем физическую 1
      x0[kol] = micros(); //фиксируем время единички
    }
    else //если сигнал 0
    {
      x1[kol] = 0;        // фиксируем нулиг
      x0[kol] = micros(); //фиксируем время нолика
    }
    ++kol;          //толкаем указатель
    if (kol ›= 200) //считаем биты и даем разрешение на чтение массива с битами
    {
      skan = false; //даем разрешение на работу с массивами
      kol = 0;      //переносим указатель в начало
    }
  }
}
//**Автор GrafGrigoio, для свободного использования**
П.С. Нормально так хапанул экспы на этом=)
GrafGrigorio вне форума  
 

Закладки
Опции темы

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

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

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Декодирование NEC протокола Gosha_006 AVR 78 19.10.2015 23:54
Декодирование DTMF на PIC16F628 vovik_t PIC 64 29.07.2013 22:38
Прием Манчестера 2,5Мбит на универсальном микроконтроллере Vlad_Petr Микроконтроллеры, АЦП, память и т.д 23 08.12.2011 11:13
декодирование сигналов пульта ДУ PIRAT7777 Автоматика и аппаратура связи 12 19.06.2008 17:22
Декодирование команд RC5 R_V_A Микроконтроллеры, АЦП, память и т.д 10 20.12.2006 19:52


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


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot