Arduino вместо джойстика Денди: ковыряния
Подготовив стенд, я начал ковырять трансляцию нажатий джойстика Сеги на Денди.
Сначала сделал схему с двумя прерываниями, для Latch и Clock, и записью данных через digitalWrite. В принципе оно как-то даже заработало, но со сдвигом на бит. И что бы я не делал, оно, во-первых, работало неправильно, а во-вторых, нестабильно.
Я подумал, что не хватает скорости digitalWrite и переделал на прямую работу с портом. Стало очень значительно хуже! Если раньше работало хоть как-то почти адекватно, теперь оно стало как будто едва нажиматься. Почему — я так и не понял.
Я предположил, что не хватает скорости реакции на прерывание от линии Clock. Сделал трюк: по срабатыванию прерывания Latch начинается глухой цикл на 8 итераций с ожиданием импульсов Clock через while и таймаутом на случай, что что-то пойдёт не так.
Это сработало! Но… не очень стабильно. Раз в секунду или около того последовательность бит как бы сбивалась, и если танк в Battle City ехал вверх, он на один кадр дёргался вниз. Сколько бы я не бился, и не улучшал этот код, решить проблему я не смог. Удалось добиться почти стабильной работы, когда этот сбой случается редко, но осталось это самое почти. А мне нужен идеально надёжный результат.
До этого я искал готовые решения, но почему-то не нашёл. Обычно решается противоположная задача: подключают джойстик к Ардуино. Нашёл только схему, где используется сдвиговый регистр CD4021, как в реальном джойстике, что обходит проблему на аппаратном уровне. Но это же глупо, иметь мощь Ардуины, и добавлять ещё какой-то регистр.
Пока не понимаю, почему что-то идёт не так. Цикл чтения одного бита около 12 микросекунд. Это даёт частоту около 83 килогерц, порядка 192 тактов Arduino на один бит — должно хватать. Но по ощущениям, я упираюсь именно в скорость, её совсем чуть-чуть не хватает, чтобы вовремя выставить состояние, или что-то такое. К сожалению, мой осциллограф простенький одноканальный, а подходящий есть только на работе, куда я всё это Денди-безобразие, конечно не потащу.
Для дальнейших действий есть максимально простая идея: попробовать взять Ардуину помощнее, благо, их есть у меня. Также есть вариант задействовать SPI для обмена с консолью.