8x8 led + 74HC595

fff_GODsTBAPb
Offline
Зарегистрирован: 10.01.2019

Добрейщий день, уважаемые.

Прям боюсь что многие закидают камнями прям вот сейчас же, ибо я только учусь но...

Итак, имеем УНО+2 сдвиговых регистра+ led матрица 8х8, 7 герконов (нормальноразомкнутых). Все подключено, все функционирует. 

Описание устройства - планируется индикатор включенной передачи на авто (механика). Герконы установлены, срабатывают в зависимости от ключенной передачи 1-6, + задняя. (итого 7). При включении передачи (допустим 1) - сперва на дисплее выводится анимация из 8 катринок (назовем ее анимация 1) и 9 картинка остается гореть до выключения
\переключения передачи. На нейтрали (ни один геркон не сработал) - просто проигрывается анимация (назовем ее анимация 2). Что сделано - написал код, не не могу заставить его замереть на последней картинке в анимации 1 (на 9ой), он работает по кругу все время + не могу заставить его проигрывать именно анимацию 2 на нейтрали (проигрывается вообще все анимации). Вот часть кода для примера. Чтоб не захламлять оставил тут анимацию 1 из 2х картинок для понятия и анимацию 2 из одной картинки. Если не сложно пошлите меня куда-нить (за инфой) или может кто знает даже как это исправить? С меня - запросто и беплатно внедрю Вам это устройство в Ваш автомобиль. г. Челябинск. Ну или огромный Вам плюс к карме ;)

#define pinC 8
#define pinD 10
#define pinS 9
#define G1 2
#define delays 500

byte G1State = 0;

int P9[] = {0,0,50,126,126,2,0,0};
int P1[] = {255,0,0,0,0,0,0,0,0};
int N[] = {0,0,60,16,8,60,0,0};

unsigned long timer = 0;
void setup() 
{
  pinMode (pinC, OUTPUT);
  pinMode (pinD, OUTPUT);
  pinMode (pinS, OUTPUT);
  pinMode (G1, INPUT);
  digitalWrite(pinS, HIGH);
  timer=millis();
}
void loop() 
{
  G1State = digitalRead (G1);
  
  if (G1State == HIGH)
 {
  while (millis()-timer<delays)
  {
  for(byte i=0; i<8; i++)
   {
    digitalWrite(pinS, LOW);
    shiftOut(pinD,pinC, MSBFIRST, 1<<i);
    shiftOut(pinD,pinC, LSBFIRST, ~P1[i]);
    digitalWrite(pinS,HIGH);
   }
  }
 timer=millis();

  while (millis()-timer<delays)
  {
  for(byte i=0; i<8; i++)
   {
    digitalWrite(pinS, LOW);
    shiftOut(pinD,pinC, MSBFIRST, 1<<i);
    shiftOut(pinD,pinC, LSBFIRST, ~P9[i]);
    digitalWrite(pinS,HIGH);
   }
  }
 timer=millis();
 }
 
 else 
 {
   while (millis()-timer<delays)
  {
  for(byte i=0; i<8; i++)
   {
    digitalWrite(pinS, LOW);
    shiftOut(pinD,pinC, MSBFIRST, 1<<i);
    shiftOut(pinD,pinC, LSBFIRST, ~N[i]);
    digitalWrite(pinS,HIGH);
   }
  }
 timer=millis();
 }
 }

 

b707
Offline
Зарегистрирован: 26.05.2017

Сначала немного о другом - вы неправильно используете миллис. У вас получился блокирующий код, полностью аналогиченый delay из-за того, что вы загнали проверку millis в цикл while

while + millis() = delay()

в результате, если пользователь переключит передачу во время проигрывания анимации - ваша программа заметит это только после порохождения всех картинок, а у вас это порядка 5 сек - огромная задержка для современного авто

 

Что касается основного вопроса - тут все очень просто. Не играйте свою анимацию при каждом обороте ЛУП заново, прогнали один раз- выставите флаг, что больше играть не надо.

 

fff_GODsTBAPb
Offline
Зарегистрирован: 10.01.2019

Огромное спасибо!!! Теперь хоть понятно куда в какую сторону меня послали и куда мне пойти ;) Начну курить с флагов. 

sadman41
Offline
Зарегистрирован: 19.10.2016

fff_GODsTBAPb пишет:

не могу заставить его проигрывать именно анимацию 2 на нейтрали (проигрывается вообще все анимации).

pinMode (G1, INPUT_PULLUP); ?

fff_GODsTBAPb
Offline
Зарегистрирован: 10.01.2019

Да что же за великий Вы человек. Прям Сайтама мира ардуино. Огромное спасибо, тот момент когда одно слово исправило многое за секунду!!! Но как уже написал уважаемый b707 есть проблема с задержкой выполнения. Довольно долго отвечает на нажатие геркона (собсна пока не дойдет до конца, как и написали) И пока еще не вкурил как заставить выполнить анимацию только один раз и остановиться на 9 картинке - зараза так и бегает по кругу ;(

sadman41
Offline
Зарегистрирован: 19.10.2016

В вашей концепции это проблематично, если вообще осуществимо без извращений. Необходимо придумать такой алгоритм, при котором между кадрами опрашиваются все герконы, т.е. спецэффект выдавался бы не блокирующей пачкой, а в каждом проходе лупа показывался один кадр. К сожалению, я не могу сообразить, что визуально выходит из цикла с shiftOut-ом. Задержек там нет, поэтому всё должно отрабатывать быстрее, чем это увидит человеческий глаз. Вероятно тут можно что-то сократить в коде для начала. Потом уже приступать к декомпозиции (раскадровке) анимации. И затем уже будет понятно, как это всё разложить по switch()-у, например.