Main Content

Circuitos_1

O Circuito hoje apresentado é um circuito construído com 3 Shift Registers - 74HC595.

Este circuito permite controlar até 24 outputs - no caso LEDs e controlá-los independentemente.

Foi usado um CSEduino para controlar os 24 outputs. Atendendo a que apenas foram usados 4 pinos do ATMega328P este micro-controlador poderia ter sido substituído por outro mais pequeno/simples.

Poderia ser usado um micro-controlador da família ATTiny que é parecido com os ATMega mas que são mais baratos/pequenos e têm menos funcionalidades.

O 74HC595 é um integrado muito comum que permite expandir o número de outputs uma vez que implementa uma interface Série para Paralela. Permite com apenas 3 pinos do micro-controlador controlar até oito pinos de output. Adicionalmente permite ser ligado em cascata e dessa forma permitir o controlo de ainda mais outputs mantendo os 3 pinos do micro-controlador.

O modo de operação do 74HC595 é o seguinte:

  1. Baixa-se o sinal do LATCH (também designado por ST_CP ou RCLK)
  2. Envia-se os bits um a um da seguinte forma:
  3. Baixa-se o pino do CLOCK (também designado por SH_CP ou SRCLK)
  4. Envia-se um bit para o pino do DATA (também designado por DS ou SER)
  5. Levanta-se o pino do CLOCK (também designado por SH_CP ou SRCLK)
  6. Nota: Deverão ser enviados tantos grupos de oito bits (bytes) quantos os 74hc595 estiverem ligados
  7. Levantar o sinal do LATCH (também designado por ST_CP ou RCLK)

Adicionalmente pode-se usar o pino OE (também designado por G) do 74HC595 para controlar o brilho dos LEDs, ligando o mesmo a um pino com PWM.

A Cascata é feita ligando também os pinos do CLOCK e do LATCH nos outros integrados e ligando o pino Q7’ do primeiro chip para o DATA do segundo e o Q7’ do segundo chip para o DATA do terceiro chip.

Esquemático

Circuitos_3_Schematics

Nota: No esquemático apenas são apresentadas as ligações entre os 74HC595 e os LEDs.
O circuito para o CSEduino pode ser consultado na página do CSEduino. Pode igualmente ser usado um Arduino.

Componentes (BOM)

  • 3x 74HC595 - 8-bit serial-in, serial or parallel-out shift register with output latches; 3-state (U1, U2 e U3)
  • 24x LED 3mm ou de 5mm (D1-D20)
  • 24x Resistências de 470 Ohms (R1-R20)

Pin-out dos IC

Circuitos_4_Pinout

Para programar o Micro-controlador usou-se o Arduino IDE.

Código

O Sketch usado foi o seguinte:

/*

  Created by Joao Alves on 2015-Jun-8.
  Copyright 2014 - Under creative commons license 4.0:
          Attribution-ShareAlike CC BY-SA
  This software is provided "as is", without technical support, and with no
  warranty, express or implied, as to its usefulness for any purpose.

  Description:
  Circuit with defined 24-Led sequences.

  The circuit:
  * 3 x 74HC595
      - 1st 74HC595 - Pin DATA  - D10
      - 2nd 74HC595 - Pin DATA - 1st 74HC595 Pin Q7'
      - 3rd 74HC595 - Pin DATA - 2st 74HC595 Pin Q7'
      - All 74HC595 - Pin LATCH - D12
      - All 74HC595 - Pin CLOCK - D11
      - All 74HC595 - Pin OE - D9

  Created on 2015-Jun-8
  By Joao Alves <jpralves@gmail.com>

*/
#include <avr/pgmspace.h>

#if defined (__AVR_ATtiny45__)
#define LATCH 1
#define CLOCK 2
#define DATA 3
#define INTENSITY 0
#else
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
    //Code here
#define LATCH 12
#define CLOCK 11
#define DATA 10
#define INTENSITY 9
#endif
#endif

const int patternDelay = 200;

const byte test_pattern[][3] PROGMEM = {
{0,0,0},

{0,0,1},
{0,0,2},
{0,0,4},
{0,0,8},
{0,0,16},
{0,0,32},
{0,0,64},
{0,0,128},

{0,1,0},
{0,2,0},
{0,4,0},
{0,8,0},
{0,16,0},
{0,32,0},
{0,64,0},
{0,128,0},

{1,0,0},
{2,0,0},
{4,0,0},
{8,0,0},
{16,0,0},
{32,0,0},
{64,0,0},
{128,0,0}
};

void testLeds() {
    for (int numberToDisplay = 0; numberToDisplay < sizeof(test_pattern)/3; numberToDisplay++) {
    digitalWrite(LATCH, LOW);
    // shift out the bits:
    shiftOut(DATA, CLOCK, MSBFIRST, pgm_read_byte(&(test_pattern[numberToDisplay][0])));
    shiftOut(DATA, CLOCK, MSBFIRST, pgm_read_byte(&(test_pattern[numberToDisplay][1])));
    shiftOut(DATA, CLOCK, MSBFIRST, pgm_read_byte(&(test_pattern[numberToDisplay][2])));
    //take the latch pin high so the LEDs will light up:
    digitalWrite(LATCH, HIGH);
    delay(100);
    }
}

void setup() {
  //set pins to output so you can control the shift register
  pinMode(LATCH, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(INTENSITY, OUTPUT);
  digitalWrite(INTENSITY, LOW);  // Funciona ao contrário
  testLeds();
}

const byte pattern[][3] PROGMEM = {
{1,0,0},
{1,1,0},
{1,1,1},
{2,1,1},
{2,2,1},
{2,2,2},
{4,2,2},
{4,4,2},
{4,4,4},
{8,4,4},
{8,8,4},
{8,8,8},
{16,8,8},
{16,16,8},
{16,16,16},
{32,16,16},
{32,32,16},
{32,32,32},
{64,32,32},
{64,64,32},
{64,64,64},
{128,64,64},
{128,128,64},
{128,128,128},
{0,0,0},
{1,0,0},
{1,1,0},
{1,1,1},
{3,1,1},
{3,3,1},
{3,3,3},
{7,3,3},
{7,7,3},
{7,7,7},
{15,7,7},
{15,15,7},
{15,15,15},
{31,15,15},
{31,31,15},
{31,31,31},
{63,31,31},
{63,63,31},
{63,63,63},
{127,63,63},
{127,127,63},
{127,127,127},
{255,127,127},
{255,255,127},
{255,255,255},
{0,0,0},

{128,0,1},
{64,0,2},
{32,0,4},
{16,0,8},
{8,0,16},
{4,0,32},
{2,0,64},
{1,0,128},
{0,1+128,0},
{0,2+64,0},
{0,4+32,0},
{0,8+16,0},
{0,4+32,0},
{0,2+64,0},
{0,1+128,0},
{1,0,128},
{2,0,64},
{4,0,32},
{8,0,16},
{16,0,8},
{32,0,4},
{64,0,2},
{128,0,1}
};

void loop()
{
    for (int numberToDisplay = 0; numberToDisplay < sizeof(pattern)/3; numberToDisplay++) {
      digitalWrite(LATCH, LOW);
      // shift out the bits:
      shiftOut(DATA, CLOCK, MSBFIRST, pgm_read_byte(&(pattern[numberToDisplay][0])));
      shiftOut(DATA, CLOCK, MSBFIRST, pgm_read_byte(&(pattern[numberToDisplay][1])));
      shiftOut(DATA, CLOCK, MSBFIRST, pgm_read_byte(&(pattern[numberToDisplay][2])));
      //take the latch pin high so the LEDs will light up:
      digitalWrite(LATCH, HIGH);
      delay(patternDelay);
    }
}

// Sketch uses 1,646 bytes (5%) of program storage space. Maximum is 32,256 bytes.
// Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes.

Este sketch está preparado para funcionar com o Atmega328P assim como com micro-controladores mais simples.

O Sketch acima apresenta uma forma simples de guardar dados na flash. Este método envolve alguns aspectos:

  • Deverá ser incluído o ficheiro de header <avr/pgmspace.h>
  • Referenciar na declaração das variáveis a definição PROGMEM
  • Aceder às variáveis através de funções especiais designadas por pgm_read_byte ou por pgm_read_word
  • As variáveis têm que ser declaradas como const (uma vez que não podem ser alteradas).

Este circuito foi usado para criar uma estrela de Natal animada.

Circuitos_4