Не могу сделать второй 74HC595, чтобы начать отсчет

Я делаю свой первый проект с Arduino, однако я попал в тупик и не могу понять, что я делаю не так.

Этот проект "прост". Это Стена той Странной Штуки.

Тем не менее, я хочу использовать 74HC595, чтобы оставить контакты свободными на arduino, чтобы, возможно, расширить и сделать что-то еще с этим, поэтому я попробовал выполнить учебник по arduino (https://www.arduino.cc/en/Tutorial/Foundations/ShiftOut)

Итак, моя текущая схема приведена ниже

Однако мой код - это своего рода франкенштейн. Я использовал shiftOut из учебников, однако должен признаться, я не знаю, как это работает (и я думаю, что именно в этом может заключаться ошибка). Я знаю VBA и Python, но я ничего не знаю о C (или о том, что это за язык).

    //Вывод, подключенный к ST_CP 74HC595
#define latchPin 5
//Контакт, подключенный к SH_CP 74HC595
#define clockPin 7
////Контакт, подключенный к DS 74HC595
#define dataPin 6
String text;                                                    //Variável do tipo string que receberá o texto
void setup() {
  Serial.begin(9600);                                           //Скорость связи
  for (int i = 2; i < 7; i++) {
    pinMode(i, OUTPUT);                                   //Declarando o pino como saída
  }
  Serial.println("Iniciando");
  inicializationEffect();                                       //Chamada da Função responsável pelo efeito inicial
  //Базовый тест();
}
void loop() {
  

  receiveText();                                               //Chamada da função responsável por receber o texto digitado
}
//Função que recebe o texto diitado
void receiveText() {
  while (Serial.available() > 0) {                              //Verifica se existe alguma informação na Serial
    char c = Serial.read();                                     //atribui cada caractere a variável c que é do tipo char
    if (c != '\n') text.concat(c) ;                              //verifica se a variável do tipo char recebeu uma quebra de linha que indica o fim da palavra ou frase e concatena todos os caracteres na String text
    delay(10);                                                  //aguarda 10 milissegundos
  }
  if (text.length() > 0) {                                      //проверка текста строки тем tamanho maior que 0
    text.toUpperCase();                                       //transforma tudo que estiver na string text para maiúsculo
    if (text[0] == '#'){
      waveEffect();
    }else {
      executeEffect(text);                                        //chama a função executeEffect передает строковый текст с параметрами
    }
  }
  text = "";                                                    //лимпа строковый текст
}
//Função responsável por ativar linha que recebe como parâmetro o número da linha
void lineActivation(int line, int keepalive) {
  if (keepalive == 0) {
    for (int i = 2; i <= 4; i++) {
      digitalWrite(i, LOW);
    }
  }
    digitalWrite(line+1, HIGH);                               //coloca a linha 1 em estado lógico alto
}

void activateLetter(char letter, int on, int off) {
  int lt;
  lt = (((int)letter - 64) % 9);
  if (((int)letter - 64) > 8) {
    lt = lt + 1;
  }
  if (on) {
    callCol(1<<lt-1);
    delay(on);                                                //mantém o pino em nível lógico alto durante o tempo que foi determinado no parâmetro da função
  }
  if (off) {
    callCol(0);
    delay(off);                                               //mantém o pino em nível lógico baixo durante o tempo que foi determinado no parâmetro da função
  }

}

void callCol(int col){
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, col);
  digitalWrite(latchPin, HIGH);

}
void executeEffect(String text) {
  for (int i = 0; i < text.length(); i++) {
    if (text[i] == ' ') {
      delay(1000);
    } else if ((int)text[i] < 65 or (int)text[i] > 90) {
    } else {
      lineActivation(int(((int)text[i] - 64) / 9) + 1, 0);
      activateLetter(text[i], 1000, 200);
    }
  }
}

void inicializationEffect() {
  for (int i = 1; i < 27; i++) {
    lineActivation(int(i / 9) + 1, 0);                          //ativa a linha
    activateLetter(char(64 + i), 1000, 10);                   //ativa a letra
  }
}
void waveEffect() {
  for (int i = 1; i < 4; i++) {
    lineActivation(i, 1);                          //ativa a linha
  }
  for (int i = 1; i < 10; i++) {
    activateLetter(char(72 + i), 100, 0);
  }

  for (int i = 1; i < 10; i++) {
    activateLetter(char(72 + i), 0, 100);
  }
  for (int i = 1; i < 4; i++) {
    lineActivation(i, 1);                          //ativa a linha
  }
}

void basicTest() {
  lineActivation(2,1);
    for (int i = 0; 1 < 500; i++) {
    callCol(255-i);
    delay(100);
    }
    
  
}


void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// Это сначала смещает 8 бит из MSB,
// на переднем фронте тактового сигнала,
// часы работают на холостом ходу
//настройка внутренней функции
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//очистите все на всякий случай, чтобы
// подготовить регистр сдвига для сдвига битов
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//для каждого бита в байте myDataOut&#xFFFD;
//ОБРАТИТЕ ВНИМАНИЕ, ЧТО МЫ ВЕДЕМ ОБРАТНЫЙ ОТСЧЕТ в нашем цикле for
//Это означает, что %00000001 или "1" будут проходить через такие
//что загорается именно контакт Q0.
for (i=7; i>=0; i--)  {
digitalWrite(myClockPin, 0);
//если значение, переданное в myDataOut, и результат битовой маски
// тогда это правда... итак, если мы находимся в i = 6 и наше значение равно
// %11010100 было бы, если бы код сравнивал его с %01000000
// и переходит к установке pinState равным 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Устанавливает вывод на ВЫСОКИЙ или НИЗКИЙ в зависимости от pinState
digitalWrite(myDataPin, pinState);
//регистр сдвигает биты при движении вверх тактового вывода
digitalWrite(myClockPin, 1);
// обнуляйте вывод данных после сдвига, чтобы предотвратить утечку через
digitalWrite(myDataPin, 0);
}
//остановить сдвиг
digitalWrite(myClockPin, 0);
}

Если я правильно понял (чего я, возможно, не понимаю), теоретически, когда я отправляю значение больше 255, оно должно "переполниться" до следующего 74HC595, который будет использоваться для освещения девятой колонки.

, 👍2

Обсуждение

почему shiftOut(dataPin, clockPin, 0);?, @Juraj

Однако, чтобы убедиться в его ясности, я удалил эту строку для решения, которое я опубликовал, @Feeds

откуда у тебя взялась эта идея?, @Juraj

Я имею в виду, что я был неправ. Но смысл был в том, чтобы всегда устанавливать двоичное значение равным 0, прежде чем устанавливать для него правильное значение. Просто как безотказный вариант, однако чем больше я занимаюсь этим, тем меньше понимаю. Для этого не нужна защита от сбоев, верно?, @Feeds


1 ответ


3

Решаемая с помощью https://arduino.stackexchange.com/a/17093/37827

Удалив пользовательскую функцию shiftOut и изменив мой

shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, col);

с

shiftOut(dataPin, clockPin, MSBFIRST, highByte(col));  
shiftOut(dataPin, clockPin, MSBFIRST, lowByte(col));  

Работает как заклинание

PS: Не стесняйтесь предлагать что-то еще, но таким образом это решило мою проблему

,