ATTiny 85 + shift register + ir sensor

5

Tuve el ATTIN trabajando con el registro de cambios, pero cuando agregué el receptor de IR al código, el registro de cambios no funcionó como se desea.

Tengo un registro de desplazamiento conectado a 8 LED y controlado por un ATtiny85. También tengo un botón y un receptor de IR conectado. La idea es controlar los LED con mi control remoto utilizando el espacio mínimo requerido para una ATTIN.

Definitivamente está en el código, ya que estaba trabajando con el código solo para el registro de cambios y todo lo que cambió en el hardware fue la adición de un botón y un sensor IR. El registro de turnos solo enciende todas las luces y eventualmente las apaga todas. Lo que quiero que ocurra es que se muestren patrones en los LED.

Aquí está mi código:

Conexiones de hardware:

74HC595 pin  LED pin   Arduino pin

    1            (QB)      LED 2 +
    2            (QC)      LED 3 +
    3            (QD)      LED 4 +
    4            (QE)      LED 5 +
    5            (QF)      LED 6 +
    6            (QG)      LED 7 +
    7            (QH)      LED 8 +
    8            (GND)     GND

    9            (QH*)
    10           (SRCLR*)  5 V
    11           (SRCLK)   Digital 3
    12           (RCLK)    Digital 4
    13           (OE*)     GND
    14           (SER)     Digital 2
    15           (QA)      LED 1 +
    16           (VCC)     5 V

*/

// Pin definitions:
// The 74HC595 uses a type of serial connection called SPI
// (Serial Peripheral Interface) that requires three pins:

int datapin = 2;
int clockpin = 3;
int latchpin = 4;
int switchpin = 1;

// We'll also declare a global variable for the data we're
// sending to the shift register:

/* Raw IR commander

   This sketch/program uses the Arduno and a PNA4602 to
   decode IR received.  It then attempts to match it to a previously
   recorded IR signal

   Code is public domain, check out www.ladyada.net and adafruit.com
   for more tutorials!
*/

// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
//
//uint8_t IRpin = 2;
//
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN      PINB
#define IRpin          0

// The maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
#define NUMPULSES 50

// What our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing.
#define RESOLUTION 20

// What percent we will allow in variation to match the same code
#define FUZZINESS 20

// We will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[NUMPULSES][4];  // Pair is high and low pulse
uint8_t currentpulse = 0;       // Index for pulses we're storing

#include "ircodes.h"

byte data = 0;
int m = 0;
int paterns = 6;

void setup()
{
    // Set the three SPI pins to be outputs:

    pinMode(datapin, OUTPUT);
    pinMode(clockpin, OUTPUT);
    pinMode(latchpin, OUTPUT);
    digitalWrite(switchpin, HIGH);
}


void loop()
{
    int numberpulses;

    numberpulses = listenForIR();

    if (IRcompare(numberpulses, center,sizeof(center)/4)) {

    }
    if (IRcompare(numberpulses, left,sizeof(left)/4)) {
        if (m>0) {
            m = (m-1);
        }
        else {
            m = paterns;
        }
    }
    if (IRcompare(numberpulses, right,sizeof(right)/4)) {
        m = (m+1)%paterns;
    }

    if (digitalRead(switchpin) == LOW)
    {
        m = (m+1)%paterns;
        delay(800);
    }

    switch (m) {
        case 0:
            oneAfterAnother();  // All on, all off
            break;
        case 1:
            oneOnAtATime();     // Scroll down the line
            break;
        case 2:
            pingPong();         // Like above, but back and forth
            break;
        case 3:
            randomLED();        // Blink random LEDs
            break;
        case 4:
            marquee();          // like an old movie theater
            break;
        case 5:
            binaryCount();      // Bit patterns from 0 to 255
            break;
        }
    }


void shiftWrite(int desiredPin, boolean desiredState)

// This function lets you make the shift register outputs
// HIGH or LOW in exactly the same way that you use digitalWrite().

// Like digitalWrite(), this function takes two parameters:

//    "desiredPin" is the shift register output pin
//    you want to affect (0-7)

//    "desiredState" is whether you want that output
//    to be HIGH or LOW

// Inside the Arduino, numbers are stored as arrays of "bits",
// each of which is a single 1 or 0 value. Because a "byte" type
// is also eight bits, we'll use a byte (which we named "data"
// at the top of this sketch) to send data to the shift register.
// If a bit in the byte is "1", the output will be HIGH. If the bit
// is "0", the output will be LOW.

// To turn the individual bits in "data" on and off, we'll use
// a new Arduino commands called bitWrite(), which can make
// individual bits in a number 1 or 0.
{
    // First we'll alter the global variable "data", changing the
    // desired bit to 1 or 0:

    bitWrite(data,desiredPin,desiredState);

    // Now we'll actually send that data to the shift register.
    // The shiftOut() function does all the hard work of
    // manipulating the data and clock pins to move the data
    // into the shift register:

    shiftOut(datapin, clockpin, MSBFIRST, data);

    // Once the data is in the shift register, we still need to
    // make it appear at the outputs. We'll toggle the state of
    // the latchPin, which will signal the shift register to "latch"
    // the data to the outputs. (Latch activates on the high-to
    // -low transition).

    digitalWrite(latchpin, HIGH);
    digitalWrite(latchpin, LOW);
}


/*
oneAfterAnother()

This function will light one LED, delay for delayTime, then light
the next LED, and repeat until all the LEDs are on. It will then
turn them off in the reverse order.
*/

void oneAfterAnother()
{
    int index;
    int delayTime = 100; // Time (milliseconds) to pause between LEDs
                         // Make this smaller for faster switching

    // Turn all the LEDs on:

    // This for() loop will step index from 0 to 7
    // (putting "++" after a variable means add one to it)
    // and will then use digitalWrite() to turn that LED on.

    for(index = 0; index <= 7; index++)
    {
        shiftWrite(index, HIGH);
        delay(delayTime);
    }

    // Turn all the LEDs off:

    // This for() loop will step index from 7 to 0
    // (putting "--" after a variable means subtract one from it)
    // and will then use digitalWrite() to turn that LED off.

    for(index = 7; index >= 0; index--)
    {
        shiftWrite(index, LOW);
        delay(delayTime);
    }
}


/*
oneOnAtATime()

  This function will step through the LEDs, lighting one at at time.
*/

void oneOnAtATime()
{
    int index;
    int delayTime = 100; // Time (milliseconds) to pause between LEDs
                         // Make this smaller for faster switching

    // step through the LEDs, from 0 to 7

    for(index = 0; index <= 7; index++)
    {
        shiftWrite(index, HIGH);  // Turn LED on
        delay(delayTime);         // Pause to slow down the sequence
        shiftWrite(index, LOW);   // Turn LED off
    }
}


/*
pingPong()

  This function will step through the LEDs, lighting one at at time,
  in both directions.
*/

void pingPong()
{
    int index;
    int delayTime = 100; // Time (milliseconds) to pause between LEDs
                         // make this smaller for faster switching.

    // Step through the LEDs, from 0 to 7

    for(index = 0; index <= 7; index++)
    {
        shiftWrite(index, HIGH);  // Turn LED on
        delay(delayTime);         // Pause to slow down the sequence
        shiftWrite(index, LOW);   // Turn LED off
    }

    // Step through the LEDs, from 7 to 0

    for(index = 7; index >= 0; index--)
    {
        shiftWrite(index, HIGH);  // Turn LED on
        delay(delayTime);         // Pause to slow down the sequence
        shiftWrite(index, LOW);   // Turn LED off
    }
}


/*
randomLED()

  This function will turn on random LEDs. Can you modify it so it
  also lights them for random times?
*/

void randomLED()
{
    int index;
    int delayTime = 100; // Time (milliseconds) to pause between LEDs
                         // make this smaller for faster switching.

    // The random() function will return a semi-random number each
    // time it is called. See http://arduino.cc/en/Reference/Random
    // for tips on how to make random() more random.

    index = random(8);   // Pick a random number between 0 and 7

    shiftWrite(index, HIGH);  // Turn LED on
    delay(delayTime);         // Pause to slow down the sequence
    shiftWrite(index, LOW);   // Turn LED off
}


/*
marquee()

  This function will mimic "chase lights" like those around signs.
*/

void marquee()
{
    int index;
    int delayTime = 200; // Time (milliseconds) to pause between LEDs.
                         // Make this smaller for faster switching.

    // Step through the first four LEDs
    // (We'll light up one in the lower 4 and one in the upper 4)

    for(index = 0; index <= 3; index++)
    {
        shiftWrite(index, HIGH);    // Turn a LED on.
        shiftWrite(index+4, HIGH);  // Skip four, and turn that LED on.
        delay(delayTime);           // Pause to slow down the sequence.
        shiftWrite(index, LOW);     // Turn both LEDs off.
        shiftWrite(index+4, LOW);
    }
}


/*
binaryCount()

  Numbers are stored internally in the Arduino as arrays of "bits",
  each of which is a 1 or 0. Just like the base-10 numbers we use
  every day, The position of the bit affects the magnitude of its
  contribution to the total number:

  Bit position   Contribution
  0              1
  1              2
  2              4
  3              8
  4              16
  5              32
  6              64
  7              128

  To build any number from 0 to 255 from the above 8 bits, just
  select the contributions you need to make. The bits will then be
  1 if you use that contribution, and 0 if you don't.

  This function will increment the "data" variable from 0 to 255
  and repeat. When we send this value to the shift register and LEDs,
  you can see the on-off pattern of the eight bits that make up the
  byte. See http://www.arduino.cc/playground/Code/BitMath for more
  information on binary numbers.
*/

void binaryCount()
{
    int delayTime = 1000; // Time (milliseconds) to pause between LEDs
                          // Make this smaller for faster switching.

    // Send the data byte to the shift register:

    shiftOut(datapin, clockpin, MSBFIRST, data);

    // Toggle the latch pin to make the data appear at the outputs:

    digitalWrite(latchpin, HIGH);
    digitalWrite(latchpin, LOW);

    // Add one to data, and repeat!
    // (Because a byte type can only store numbers from 0 to 255,
    // if we add more than that, it will "roll around" back to 0
    // and start over).

    data++;

    // Delay so you can see what's going on:

    delay(delayTime);
}

//IR functions

boolean IRcompare(int numpulses, int Signal[], int refsize) {
    int count = min(numpulses,refsize);
    for (int i=0; i< count-1; i++) {
        int oncode = pulses[i][5] * RESOLUTION / 10;
        int offcode = pulses[i+1][0] * RESOLUTION / 10;

        if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
        }
        else {
            return false;
        }

        if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
        }
        else {
            return false;
        }
    }
    return true;
}

int listenForIR(void) {
    currentpulse = 0;

    while (1) {
        uint16_t highpulse, lowpulse;  // Temporary storage timing
        highpulse = lowpulse = 0;      // Start out with no pulse length
        //  while (digitalRead(IRpin)) { // This is too slow!
        while (IRpin_PIN & (1 << IRpin)) {
           // Pin is still HIGH

           // Count off another few microseconds
           highpulse++;
           delayMicroseconds(RESOLUTION);

           // If the pulse is too long, we 'timed out' - either nothing
           // was received or the code is finished, so print what
           // we've grabbed so far, and then reset.

           // KGO: Added check for end of receive buffer
           if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
               return currentpulse;
           }
        }
        // We didn't time out so lets stash the reading
        pulses[currentpulse][0] = highpulse;

        // same as above
        while (! (IRpin_PIN & _BV(IRpin))) {
            // pin is still LOW
            lowpulse++;
            delayMicroseconds(RESOLUTION);
            // KGO: Added check for end of receive buffer
            if (((lowpulse >= MAXPULSE)  && (currentpulse != 0))|| currentpulse == NUMPULSES) {
                return currentpulse;
            }
        }
        pulses[currentpulse][6] = lowpulse;

        // We read one high-low pulse successfully, continue!
        currentpulse++;
    }
}
    
pregunta Skyler Fly

1 respuesta

0
  1. Parece que hay un problema con la configuración del pin AVR. Para leer la entrada del interruptor, el modo de pin debe ser INPUT_PULLUP y el interruptor debe estar conectado entre el pin y la tierra.

    pinMode(switchpin, INPUT_PULLUP);

  2. No veo el centro / izquierda / derecha declarado en el alcance de la función loop() . ¿Eso es intencional? Por favor, compruebe.

respondido por el tEddy

Lea otras preguntas en las etiquetas