Diagrama de fiação do arduino das luzes de corrida. Executando sinais de volta na fita WS2812 e Arduino

Neste tutorial, continuaremos a trabalhar com LEDs, mas aumentaremos o número de LEDs para 5. E faremos o efeito de um fogo em andamento. Para controlar os LEDs, usaremos a manipulação de portas do Arduino. Vamos gravar dados diretamente nas portas do Arduino. Isso é melhor do que trabalhar com entradas/saídas específicas do controlador. Isso permitirá que você defina os valores dos LEDs com uma única operação.

O Arduino UNO tem 3 portas:
B (E/S digitais 8 a 13)
C (entradas analógicas)
D (E/S Digital 0 a 7)

Cada porta é controlada por 3 registradores. Registrar DDR determina qual perna (pino) será uma entrada ou saída. Com ajuda registrar PORTA você pode definir o pino para HIGH ou LOW. Com ajuda registrar PIN você pode ler o estado das pernas do Arduino quando elas são inseridas.

Usaremos a porta B. Primeiro, devemos definir todos os pinos da porta B como saídas digitais. A porta B tem apenas 6 pinos. Os bits de registro para a porta DDRB B devem ser definidos como 1 se a perna for usada como SAÍDA e em 0 se a perna for usada como ENTRADA. Os bits de porta são numerados de 0 a 7, mas nem sempre contêm todas as 8 pernas. Exemplo:
DDRB = B00111110; // define os pinos da porta B 1 a 5 como saídas e 0 como entrada.

Observe que nos microcontroladores Microchip, o oposto é verdadeiro. 0 bit - a perna funciona como saída e 1 - como entrada.

Em nosso projeto de corrida de fogo, usaremos 5 saídas:
DDRB = B00011111; // define os pinos da porta B de 0 a 4 como saídas

Para escrever valores na porta B, você deve usar o registro PORTB. Você pode acender o primeiro LED com o comando:
PORTB=B00000001;
primeiro e quarto:
PORTB=B00001001;

Agora você vê como é fácil ligar e desligar os LEDs. Agora vamos falar sobre os operadores de turno

Existem 2 operadores de deslocamento binário: o operador de deslocamento à esquerda >. O operador de deslocamento à esquerda > desloca os bits para a direita.

Exemplo:
varA = 1; // 00000001
varA = 1 varA = 1 varA = 1

Agora de volta ao nosso programa, que é mostrado abaixo. Precisamos introduzir 2 variáveis: a primeira cima baixo conterá o valor de onde mover - para cima ou para baixo, e o segundo cylon quais LEDs acender.

Em função configurar() definimos quais pernas devem funcionar como saídas.

No programa main loop(), os LEDs acendem um a um incrementando a variável cylon, e quando atinge o mais alto, a variável upDown é setada em 0 e os LEDs acendem por sua vez.

/* Correndo fogo. 5 LEDs */ unsigned char upDown=1; // começa a subir unsigned char cylon=0; // determina a ordem do LED void setup() ( DDRB = B00011111; // configura a porta B 0 para 4 como saídas ) void loop() ( if(upDown==1)( // se subirmos, então cylon++; if ( cylon>=4) upDown=0; // quando o número de LED mais alto for alcançado, então no próximo loop desça ) else ( cylon--; if(cylon==0) upDown=1; // quando o menor O número do LED é atingido, então no próximo ciclo subimos) PORTB = 1

Neste experimento, fazemos uma luz correr ao longo de uma escala de LED.

LISTA DE PEÇAS PARA O EXPERIMENTO

- 1 placa Arduino Uno;

- 1 placa de ensaio sem solda;

- 1 escala de LED;

- 10 resistores com valor nominal de 220 Ohm;

- 11 fios macho-macho.

DIAGRAMA PRINCIPAL

DIAGRAMA NA Breadboard

RETRATO FALADO

baixar sketch para Arduino IDE
// a escala de LED está conectada a um grupo de pinos localizados // em uma linha. Dando nomes amigáveis ​​ao primeiro e último pinos #define FIRST_LED_PIN 2 #define LAST_LED_PIN 11 void setup() ( // existem 10 LEDs na escala. Poderíamos escrever pinMode 10 // vezes: para cada um dos pinos, mas isso seria inchar o código e // tornou mais problemático alterá-lo. // Portanto, é melhor usar um loop. Realizamos // pinMode for (eng. for) cada pino (variável pin) // desde o primeiro (= FIRST_LED_PIN) até o último inclusivo // ​​(<= LAST_LED_PIN), всякий раз продвигаясь к следующему // (++pin увеличивает значение pin на единицу) // Так все пины от 2-го по 11-й друг за другом станут выходами for (int pin = FIRST_LED_PIN; pin <= LAST_LED_PIN; ++pin) pinMode(pin, OUTPUT); } void loop() { // получаем время в миллисекундах, прошедшее с момента // включения микроконтроллера unsigned int ms = millis(); // нехитрой арифметикой вычисляем, какой светодиод // должен гореть именно сейчас. Смена будет происходить // каждые 120 миллисекунд. Y % X — это остаток от // деления Y на X; плюс, минус, скобки — как в алгебре. int pin = FIRST_LED_PIN + (ms / 120) % 10; // включаем нужный светодиод на 10 миллисекунд, затем — // выключаем. На следующем проходе цикла он снова включится, // если гореть его черёд, и мы вообще не заметим отключения digitalWrite(pin, HIGH); delay(10); digitalWrite(pin, LOW); }

EXPLICAÇÕES DO CÓDIGO

  • Usando a expressão por nós organizamos laço com contador . Neste caso, para configurar portas para saída. Para fazer esse ciclo, você precisa:
    • Inicialize a variável do contador com seu valor inicial. No nosso caso: pino int = FIRST_LED_ ALFINETE ;
    • Especifique a condição até a qual o loop será repetido. No nosso caso: alfinete<= LAST_LED_ ALFINETE ;
    • Determine a regra pela qual o contador será alterado. No nosso caso ++pin(veja abaixo para operador ++ ).
  • Por exemplo, você pode fazer um loop for (int i = 10; i > 0; i = i - 1). Nesse caso:
    • A variável i recebe um valor 10 ;
    • Este valor satisfaz a condição eu > 0 ;
    • Portanto, o bloco de código colocado no loop é executado na primeira vez;
    • Significado eu diminui em um, de acordo com a regra dada, e assume o valor 9 ;
    • O bloco de código é executado uma segunda vez;
    • Tudo se repete várias vezes até que o significado eu igual 0 ;
    • Quando eu torna-se igual a 0 , doença eu > 0 não será executado e a execução do loop terminará;
    • O controlador pulará para o código seguindo o loop por ;
  • Coloque o código que você deseja fazer um loop entre um par de chaves {} se contiver mais de uma instrução;
  • Variável de contador declarada na instrução por, pode ser usado dentro de um loop. Por exemplo, neste experimento alfinete sequencialmente assume valores de 2 a 11 e, sendo transferido para pinMode, permite configurar 10 portas com uma linha colocada em loop;
  • As variáveis ​​do contador são visíveis apenas dentro do loop. Aqueles. se você recorrer alfinete antes ou depois do loop, o compilador lançará um erro sobre uma variável não declarada;
  • Projeto e = e - 1 na explicação acima não é uma equação! Usamos o operador de atribuição = para colocar em uma variável eu colocar valor igual ao valor atual eu, reduzido por 1 ;
  • Expressão ++pin- este é o chamado. operador incremento , aplicado a uma variável alfinete. Esta instrução dará o mesmo resultado que pin = pin + 1 ;
  • O operador funciona de forma semelhante ao incremento diminuir - - Diminuindo o valor em um. Mais sobre isso no artigo sobre operações aritméticas;
  • Tipo de dados não assinado usado para armazenar inteiros sem sinal, ou seja, só não negativo . Devido ao bit extra, que agora não é usado para armazenar o sinal, podemos armazenar valores de até 65 535 ;
  • Função milissegundos retorna o número de milissegundos que se passaram desde que o microcontrolador foi ligado ou reiniciado. Aqui nós o usamos para cronometrar o tempo entre as alternâncias de LED;
  • Usando a expressão (ms / 120) % 10 determinamos qual dos 10 LEDs deve estar aceso agora. Parafraseando, determinamos qual segmento de 120 ms é agora e qual é o seu número dentro dos dez atuais. Adicionamos o número de sequência do segmento ao número da porta que aparece primeiro no conjunto atual;
  • O fato de desligarmos o LED com digitalWrite(pino, BAIXO) apenas 10 ms após ligar, não é perceptível aos olhos, porque muito em breve será recalculado qual dos LEDs acender, e ele será aceso - apenas apagado ou o próximo.

PERGUNTAS PARA SE VERIFICAR

  1. Por que neste experimento conectamos a escala de LED sem usar um transistor?
  2. Se acendêssemos apenas os LEDs nas portas 5, 6, 7, 8, 9, o que precisaria ser alterado no programa?
  3. Que outra instrução pode ser usada para executar uma ação equivalente a ++pin ?
  4. Qual é a diferença entre as variáveis ​​de tipo int e não assinado ?
  5. O que a função retorna milis() ?
  6. Como calculamos o número da porta na qual queremos ligar o LED neste experimento?

TAREFAS PARA SOLUÇÃO INDEPENDENTE

  1. Altere o código para que os LEDs sejam comutados uma vez por segundo.
  2. Sem desligar as portas, certifique-se de que a luz percorra apenas as quatro divisões intermediárias da escala.
  3. Modifique o programa para que em vez de pino int = FIRST_LED_ ALFINETE + (ms / 120) % 10 o movimento da chama era controlado pelo ciclo por .
  4. Sem trocar os fios, mude o programa para que a luz corra na direção oposta.

Neste tutorial, continuaremos a trabalhar com LEDs, mas aumentaremos o número de LEDs para 5. E faremos o efeito de um fogo em andamento. Para controlar os LEDs, usaremos a manipulação de portas do Arduino. Vamos gravar dados diretamente nas portas do Arduino. Isso é melhor do que trabalhar com entradas/saídas específicas do controlador. Isso permitirá que você defina os valores dos LEDs com uma única operação.

O Arduino UNO tem 3 portas:

  • B (E/S digitais 8 a 13)
  • C (entradas analógicas)
  • D (E/S Digital 0 a 7)

Cada porta é controlada por 3 registradores. O registrador DDR determina se a perna (pino) será uma entrada ou uma saída. O registrador PORT pode ser usado para definir o pino para HIGH ou LOW. Usando o registro PIN, você pode ler o estado das pernas do Arduino quando elas são inseridas.

Usaremos a porta B. Primeiro, devemos definir todos os pinos da porta B como saídas digitais. A porta B tem apenas 6 pinos. Os bits de registro para a porta DDRB B devem ser definidos como 1 se a perna for usada como SAÍDA e em 0 se a perna for usada como ENTRADA. Os bits de porta são numerados de 0 a 7, mas nem sempre contêm todas as 8 pernas.

Exemplo:

DDRB = B00111110; // define os pinos da porta B 1 a 5 como saídas e 0 como entrada.

Observe que nos microcontroladores Microchip, o oposto é verdadeiro. 0 bit - a perna funciona como saída e 1 - como entrada.

Em nosso projeto de corrida de fogo, usaremos 5 saídas:

DDRB = B00011111; // define os pinos da porta B de 0 a 4 como saídas

Para escrever valores na porta B, você deve usar o registro PORTB. Você pode acender o primeiro LED com o comando:

PORTB=B00000001;
primeiro e quarto:
PORTB=B00001001;

Agora você vê como é fácil ligar e desligar os LEDs. Agora vamos falar sobre os operadores de turno

Existem 2 operadores de deslocamento binário: operador de deslocamento à esquerda<< и оператор сдвига вправо >>. Operador de deslocamento à esquerda<< заставляет все биты сдвигаться влево, соответственно оператор сдвига вправо >> desloca os bits para a direita.

Exemplo:

VarA = 1; // 00000001
varA = 1<< 0; // 00000001
varA = 1<< 1; // 00000010
varA = 1<< 2; // 00000100

Agora de volta ao nosso programa, que é mostrado abaixo. Precisamos introduzir 2 variáveis: a primeira cima baixo conterá o valor de onde mover - para cima ou para baixo, e o segundo cylon quais LEDs acender.

Em função configurar() definimos quais pernas devem funcionar como saídas.

No loop principal do programa ciclo(), os LEDs acendem por sua vez aumentando a variável cylon, e quando atinge o nível mais alto, a variável cima baixoé atribuído 0 e os LEDs acendem-se alternadamente para baixo.

diagrama de circuito

Esquema na placa de ensaio

Nota

    Observe que neste experimento, os resistores são colocados entre os cátodos e o terra, em contraste com o experimento do pulsar.

    Conectamos os LEDs nas portas digitais a partir da porta 2. Podemos usar as portas 0 e 1, mas são canais de dados de porta serial e para cada placa piscando teremos que desligar os dispositivos conectados a elas.

Retrato falado

O tipo de dados unsigned int é usado para armazenar inteiros não assinados, ou seja, só não negativo. Devido ao bit extra, que agora não é usado para armazenar o sinal, podemos armazenar valores de até 65.535 em uma variável desse tipo.

Com a expressão (ms / 120) % 10 determinamos qual dos 10 LEDs deve estar aceso agora. Parafraseando, determinamos qual segmento de 120 ms é agora e qual é o seu número dentro dos dez atuais. Adicionamos o número de sequência do segmento ao número da porta que é a primeira no conjunto atual.

O fato de desligarmos o LED com digitalWrite(pin, LOW) apenas 10 ms depois de ligá-lo não é perceptível aos olhos, porque. muito em breve será recalculado qual dos LEDs acender, e ele será aceso - apenas apagado ou próximo.

Perguntas para testar a si mesmo

    Por que neste experimento conectamos a escala de LED sem usar um transistor?

    Se acendêssemos apenas os LEDs nas portas 5, 6, 7, 8, 9, o que precisaria ser alterado no programa?

    Que outra instrução pode executar o equivalente a ++pin?

    Qual é a diferença entre variáveis ​​do tipo int e unsigned int ?

    O que a função millis() retorna?

    Como calculamos o número da porta na qual queremos ligar o LED neste experimento?

Fazemos luzes de corrida a partir de LEDs no Arduino. Neste caso, é utilizado um Arduino Mega 2560, que é potencialmente capaz de acionar uma esteira de 54 LEDs. Mas o circuito e o programa não vão mudar se você usar outros controladores desse tipo de plataforma Arduino (UNO, Leonardo...)

Diagrama de fiação para LEDs para Arduino Mega 2560.

É assim que o sketch aparece na janela do aplicativo de programação padrão do Arduino.

O texto do programa para a implementação de luzes de corrida na plataforma Arduino.

int primeiro_saída = 11; //primeira saída discreta

int last_out = 13; //última saída discreta

//bloco para inicializar entradas/saídas e outros dados iniciais

last_out = last_out + 1; //adiciona um para uso correto em loops

// define o 11º, 12º e 13º pinos discretos da placa Arduino como saídas

for (i = first_out; i< last_out; i++) { pinMode(i, OUTPUT); }

for (t = first_out; t< last_out; t++) { //перебираем номера дискретных выходов 11,12,13 поочереди

digitalWrite(t, ALTO); // acende o próximo LED

atraso(500); //atraso 500ms

for (i = first_out; i< last_out; i++) { digitalWrite(i, LOW); }//гасим все светодиоды

Para aumentar o número de LEDs controlados em uma guirlanda, o programa simplesmente precisará substituir os valores das variáveis ​​first_out e Último a sair. A primeira variável armazena a saída discreta inicial do controlador e a segunda variável armazena a última de um grupo de saídas consecutivas. Por exemplo, se quisermos conectar 10 LEDs em uma guirlanda, inserimos os seguintes valores: first_out = 4, last_out = 13. E LEDs para pinos em ordem de 4 a 13. E é melhor não tocar no primeiro e segundo pinos de entradas-saídas discretas, pois a porta usb conectada ao computador interfere neles.