User Tag List

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

Тема: ROM-плеер на ардуино

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    Регистрация
    06.02.2018
    Адрес
    г. Волгоград
    Сообщений
    1,065
    Спасибо Благодарностей отдано 
    582
    Спасибо Благодарностей получено 
    471
    Поблагодарили
    253 сообщений
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Двигаемся дальше, теперь нужно добавить запись... Вот что я думаю: запись нужно делать полностью, со всеми заголовками, синхроимпульсами и прочей служебной информацией -- это даст возможность писать в любом формате, не только ROM, но и бейсика/монитора/ретекса и т.д. И вывод, соответственно, должен быть идентичен вводу.

    Потом, при захвате сигнала принимаем за аксиому, что во всех форматах Вектора вывод начинается с группы нулей. (Это ведь так?) Это избавляет от необходимости поиска синхроимпульса и инвертирования сигнала "на лету".

    И вот первый пробный вариант:

    Test_InputROM

    Сигнал в цифровом виде подаётся на вход D2 ардуино. Никаких дополнительных библиотек скетчу не нужно.
    Код:
    #define InputPIN 2
    
    volatile unsigned long PPeriod = 0;     // текущее значение полупериода
    volatile unsigned int PPeriod_sred = 0; // среднее значение границы длинны полупериода
    unsigned int Tpp = 0;                   // расчётное значение полупериода для вывода
    volatile unsigned long iMicros_old = 0; // предыдущее значение микросекунд
    volatile boolean Pik = false;           // есть изменение сигнала
    volatile boolean Plong = false;         // "длинный" полупериод
    
    byte BUFF[512];       // буфер данных
    unsigned int CWB = 0; // индекс записи в буфер
    byte bBit = 14;       // индекс записываемого полубита
    byte A = 0;           // записываемый байт
    byte B = 0;           // записываемый бит
    int i0 = 0;           // счётчик циклов без сигнала
    //unsigned int j;
    
    void setup() //процедура setup
    {
      pinMode(InputPIN, INPUT); //объявляем пин как вход
      pinMode(13, OUTPUT);      // объявляем пин как выход
      attachInterrupt(0, TakeTime, CHANGE); // включаем обработку внешнего прерывания
      Serial.begin(9600);
    }
    
    void loop() //процедура loop
    {
      if (Pik) {          // Произошло изменение сигнала
        Pik = false;
        i0 = 0;
    
        if (Plong) {      // получен длинный полупериод
          B ^= 1;         // инвертируем бит
          A = (A<<1)+B;   // заносим бит
          bBit--;         // уменьшаем счётчик полубитов
        }
        else {            // получен короткий полупериод
          if (bBit & 1) { // нечётный полубит
            A = (A<<1)+B; // заносим бит
          }
        }
        // ===================================
        if (bBit > 1) {
          bBit--;         // счётчик -1
        }
        else {
          if (CWB < 512) BUFF[CWB] = A;
          CWB++;
          A = 0;
          bBit += 15;
        }
        // ====================================
        digitalWrite(13, HIGH); // зажигаем светодиод -- сигнал есть
      } 
      else{               // изменения сигнала не было
        if (i0 < 9) {     // считаем 10 раз
          i0++;
        }
        if (i0 == 8) {    // на восьмой раз выводим тестовую инфу
          digitalWrite(13, LOW); // гасим светодиод -- сигнала нет
          Serial.println("--------");
          for (int j = 0; j<=511; j++) {
            Serial.print(BUFF[j], HEX);
            Serial.print('-');
            if (((j+1)%16) == 0) Serial.println('-');
          }
          Serial.println("--------");
          Serial.println(PPeriod_sred); // граница короткий/длинный полупериод
          if (((PPeriod_sred/3*2)%8) < 4) { // полупериод для последующего вывода...
            Tpp = (PPeriod_sred/12)*8;    // округление до кратного 8 в меньшую сторону
          }
          else {
            Tpp = ((PPeriod_sred/12)+1)*8;// округление до кратного 8 в большую сторону
          }
          Serial.println(Tpp); // расчётное значение длинны полупериода для вывода
          // сбрасываем счётчики -- сигнала слишьком долго нет
          CWB = 0; 
          A = 0;
          B = 0;
          bBit = 14;
          delay(100);
        }
      }
      delayMicroseconds(128); // задержка...
    }
    
    void TakeTime()
    {
      PPeriod = micros() - iMicros_old;
      iMicros_old += PPeriod;
      if (PPeriod < 1000) { // началось...
        if (PPeriod_sred != 0) {
          if (!Plong) { 
            if (PPeriod > PPeriod_sred) Plong = true;  // тек. полупериод стал длинный
          }
          else {
            if (PPeriod < PPeriod_sred) Plong = false; // тек. полупериод стал короткий
          }
          // если ни то, ни другое -- они равны, т.е. Plong без изменений
          if (!Plong) { // если полупериод короткий, пересчитываем среднее значение
            PPeriod_sred = (PPeriod_sred + PPeriod/2*3)/2;
          }
        }
        else {
          PPeriod_sred = PPeriod/2*3; // если ещё нет статистики, берём текущее значение
        }
        Pik = true; // есть сигнал
      }
      else { // был перерыв в сигнале
        if (PPeriod_sred != 0) {
          PPeriod_sred = 0;           // обнуляем среднее значение
          Plong = false;              // и считаем, что будет короткий полупериод
        }
      }
    }
    [свернуть]

    В этом варианте решил попробовать сделать захват сигнала через внешнее прерывание, которое на большинстве ардуин работает на порту D2. (Может у кого будут идеи по-лучше?)

    До записи на карту пока не дошёл, скетч пока только определяет наличие сигнала, захватывает первые 512 байт в буфер и по завершении вываливает всё это в терминал, плюс в конце выводит размер полупериода входного сигнала в микросекундах. На живом Векторе пока не проверял, но две ардуины между собой уже передают информацию вполне уверенно.

    Вот этот скетч в архиве: Test_InputROM.7z

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

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

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

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

Похожие темы

  1. Портативный AY плеер.
    от Руслан в разделе Звук
    Ответов: 1
    Последнее: 16.04.2014, 08:46
  2. Service rom + 128 basic rom
    от VELESOFT в разделе Оси
    Ответов: 1
    Последнее: 24.03.2013, 04:48
  3. Плеер для pt 3
    от Руслан в разделе Музыка
    Ответов: 25
    Последнее: 14.08.2012, 19:25
  4. Advanced ROM Manager (ROM Switvcher + Prof. ROM)
    от Alex_NEMO в разделе Память
    Ответов: 4
    Последнее: 04.10.2010, 11:43
  5. AY плеер
    от newart в разделе Звук
    Ответов: 19
    Последнее: 20.07.2006, 00:03

Метки этой темы

Ваши права

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