Управление винтажными дисководами

После того, как я нашел решение проблемы, которую хотел решить, я надеюсь, что третья публикация будет удачной. :)

Я хочу использовать Arduino для управления винтажным дисководом. Я хочу использовать его как тестовую платформу, чтобы сначала убедиться, что все базовые функции (вращение двигателя, заход и выход, возврат на дорожку 0) работают, а в качестве бонуса хотелось бы иметь возможность протестировать запись и чтение данных. Надеюсь, что с помощью Arduino у меня будет больше контроля над функциями, вместо того чтобы подключать его к системе и пытаться выполнить команды «dir» или «copy» в надежде, что всё будет работать правильно.

В ходе своего исследования я нашёл статью 2014 года (Управление дисководом с помощью Arduino) и ещё одну статью 2017 года Простое чтение и запись на дискету. В первой статье так и не удалось реализовать базовые функции, а вторая статья (основанная на первой) пропустила основные функции и сразу перешла к чтению/записи.

Первый выпуск плаката был -

Я ожидаю, что индекс будет пульсировать при вращении двигателя диска, а дорожка 0 будет меняться, когда я нахожусь снаружи диска, но оба значения всегда НИЗКИЕ. Я что-то упускаю?

Они не говорят об этом конкретно, но и не подтверждают, что степпинг работает.

Я использую код непосредственно из первой статьи с предложенным @geometrikal изменением:

//https://arduino.stackexchange.com/questions/3702/controlling-floppy-disk-drive-with-arduino
//
//константы
static const int IN = LOW;
static const int OUT = HIGH;
static const int pulseDelayTime = 6;

//пины
int indexPin = 2; //8 на диске INDEX
int track0Pin = 3; //26 на диске. TRACK 0
int dirPin = 6; //18 на диске. НАПРАВЛЕНИЕ
int stepPin = 7; //20 на диске. STEP
int motorEnableBPin = 9; //16 на приводе. MOTOR ENABLE B

unsigned long motorSpinTime = 1000UL; //в мс


void setup() {

  //начальная задержка
  delay(3000);

  //настройка последовательного монитора
  Serial.begin(9600);      

  //настройка пинов.
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(motorEnableBPin, OUTPUT);
  //pinMode(indexPin, INPUT); - Оригинальный код от @jeffctown
  //pinMode(track0Pin, INPUT); - Оригинальный код от @jeffctown
  //Код предложен @geometrikal в https://arduino.stackexchange.com/a/3706/106869
  pinMode(indexPin, INPUT_PULLUP); 
  pinMode(track0Pin, INPUT_PULLUP);
  //сначала выключите двигатель
  digitalWrite(motorEnableBPin, HIGH);

  //вывести состояние здесь.
  printState("Setup done.");

  // немного покрутим диск.
  printState("Begin to spin motor");
  spinMotorForThisManyMs(motorSpinTime);
  spinMotorForThisManyMs(motorSpinTime);
  printState("Done spinning motor");

  //вставляем головку чтения/записи полностью внутрь.
  stepAllTheWayIn();

  //раскручиваем диск еще немного.
  printState("Begin to spin motor");
  spinMotorForThisManyMs(motorSpinTime);
  spinMotorForThisManyMs(motorSpinTime);
  printState("Done spinning motor");

  //выдвигаем головку чтения/записи полностью наружу.
  stepAllTheWayOut();

  //раскручиваем диск еще сильнее.
  printState("Begin to spin motor");
  spinMotorForThisManyMs(motorSpinTime);
  spinMotorForThisManyMs(motorSpinTime);
  printState("Done spinning motor");

  //никогда не завершается.
  waitForIndex();
}

void loop() {
}

//вращает дисковый двигатель в течение определенного количества мс и выводит состояние
void spinMotorForThisManyMs(unsigned long msToSpin) {

  //начать вращение
  digitalWrite(motorEnableBPin,LOW);

  //задержка.. продолжаем печатать состояние
  unsigned long maxTimeMs = millis() + msToSpin;  
  while(millis() < maxTimeMs ) {
    printState("Spinning");    
  }

  //остановить вращение
  digitalWrite(motorEnableBPin,HIGH);
}



//перемещаем головку чтения/записи полностью в центр
void stepAllTheWayIn() {
  for(int i=0;i<100;i++) {
    printState("Stepping In");
    stepInALittle();
  }
}

//выводим головку чтения/записи полностью наружу
void stepAllTheWayOut() {
  for(int i=0;i<100;i++) {
    printState("Stepping Out");
    stepOutALittle();
  }
}

//вывести состояние индекса и трека
void printState(const char* charPrint) {
  Serial.print(" Index:");
  Serial.print(digitalRead(indexPin));
  Serial.print(" Track:");
  Serial.print(digitalRead(track0Pin));
  Serial.print(" ");
  Serial.println(charPrint);
}

//слегка смещаем голову наружу
void stepOutALittle() {
  digitalWrite(dirPin,HIGH);
  stepPulse();
}

//смещаем голову немного к центру
void stepInALittle() {
  digitalWrite(dirPin,LOW);
  stepPulse();
}

// импульс на шаговый штифт
void stepPulse() {
  digitalWrite(stepPin,LOW);
  delay(pulseDelayTime);
  digitalWrite(stepPin,HIGH);
}

//ждет срабатывания индекса. Это никогда не завершится.
void waitForIndex() {

  printState("beginning to wait for index pin to pulse");

  //начать вращение
  digitalWrite(motorEnableBPin,LOW);

  //ждите импульса
  while(digitalRead(indexPin));
  //ждем окончания импульса 0
  while(!digitalRead(indexPin));

  printState("end of waiting for index pin to pulse");

  //остановить вращение
  digitalWrite(motorEnableBPin,HIGH);
}

И точно такая же распиновка из первой статьи.

На этой схеме макетная плата представляет собой разъём IDC, подключенный к дисководу.

Для трек-степпинга сначала устанавливается

pinMode(stepPin, OUTPUT);

и позже делает -

digitalWrite(dirPin,HIGH);
// Пошаговая рутина
digitalWrite(stepPin,LOW);
delay(pulseDelayTime);
digitalWrite(stepPin,HIGH);

Он должен выйти, а если установить dirPin в значение LOW, то он должен войти. Похоже, ни одна из этих функций не работает в моей конфигурации. Я проверил проводку полдюжины раз и пересмотрел код, но безуспешно.

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

Я проверил закрепление и код, и не нашел ничего, что могло бы вызывать проблемы.

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

Спасибо, Тук

, 👍-2

Обсуждение

Вы говорите, что не понимаете, в чём причина проблемы. В чём проблема? Вы никогда не говорите, что именно пытаетесь сделать или что сделать, или что идёт не так. Вы пытаетесь записать файлы на дискету?, @Delta_G

Интересно, нашел ли кто-нибудь решение этой проблемы. Это чат, подходящий для форума, но этот сайт не является форумом... здесь требуется задать вопрос о проблеме., @jsotola

Добро пожаловать в SE/Arduino! Вы прошли [экскурсию], что случается редко. Отлично! Теперь вам, возможно, будет интересно прочитать раздел «[спросить]» и другие страницы [помощи]. Это не форум для обсуждения. Этот сайт собирает вопросы и ответы., @the busybee

Если вы [отредактируете] своё сообщение и сделаете его вопросом по теме, оно будет открыто снова. Пожалуйста, внимательно ознакомьтесь с причиной закрытия и способами решения проблемы., @the busybee

Пожалуйста, доведите фрагменты кода до минимального, полного и воспроизводимого эскиза. Также добавьте схему вашего оборудования., @the busybee

Чтение и запись данных, вероятно, невозможны. 5-дюймовые дисководы двойной плотности требовали байт данных каждые 12 мкс, и я предполагаю, что 3,5-дюймовые дисководы будут быстрее. Обычно требуется аппаратное обеспечение DMA., @kiwiron

@kiwiron Это верно, но только если вы хотите читать и писать в том же формате, что и стандартные системы. Можно использовать любой другой последовательный протокол. В восьмидесятых некоторые самодельные компьютеры использовали распространённые асинхронные последовательные сигналы. Так что, в принципе, чтение и запись возможны., @the busybee

@kiwiron — полностью понимаю. Это нужно для проверки работоспособности рига. Это не для хранения чего-либо. В конечном счёте, я просто хочу убедиться, что базовые и, возможно, расширенные функции работают на диске, прежде чем подключать его к хост-системе. Опять же, я не использую его для хранения данных, а просто для проверки базовых функций функции диска., @Tuc

@thebusybee - это будет открыто снова?, @Tuc

Вероятно, вопрос требует нескольких голосов. Моё уже получено., @the busybee

Чем это проще, чем просто подключить диск к компьютеру и протестировать его?, @Delta_G

@Delta_G — У меня есть лучший контроль над приводом, чем просто набрать DIR :3 и надеяться., @Tuc

А ты? Сейчас ты ничего не контролируешь., @Delta_G


1 ответ


0

Теперь, когда мы видим полный источник ошибки, причина кажется очевидной. Вы вообще не включаете диск. Проверить это можно по светодиоду активности на передней панели диска.

Каждый дисковод имеет сигнал «выбора дисковода». Согласно странице Википедии об интерфейсе дисководов, у него есть два контакта: DRVSA и DRVSB — 14 и 12 соответственно.

Вам необходимо выбрать диск, соответствующий используемому вами «разрешению двигателя», то есть DRVSB на выводе 12. Убедитесь, что ваш диск подключен перемычкой к диску B. В противном случае используйте выводы с маркировкой «A».

Для первого эксперимента я бы сократил скетч до простого «мигания» сигнала выбора привода. Только если вы увидите это на передней панели привода, проведите следующий эксперимент, например, включите двигатель.


На самом деле, я экспериментировал со встроенным приводом моего Atari 1040STFM ещё в восьмидесятых. Небольшая ассемблерная программа использовала алгоритм ШИМ для плавной модуляции светодиода привода от выключенного к включенному и обратно. Это было жутко.

,

Поэтому я добавил вывод 10 от Uno к линии DS на моём устройстве. Я установил сигнал HIGH при запуске и LOW при выполнении определённых действий с приводом. Шаговый двигатель работал нормально на Gotek и 5.25, но возникла проблема с 8-дюймовым. 8-дюймовый недавно отремонтировали, так что он должен работать, но не знаю, нужно ли что-то дополнительное, что не нужно Gotek/5.25., @Tuc