• Welcome to LusoRobótica - Robótica em Português.
 

3 register's 595 (codigo)

Started by Donvan, 27 de July de 2012, 20:02

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Donvan

Pessoal, aqui está um codigo que tive de fazer para os meus registers, por causa de alguns reles muito sensiveis ao "multiplex".
Dessa forma não existe "multiplex", e os reles funcionam bem.

  /*
    * Cesário Pereira
    *
    * Para 3 595's
    *
    * Para des/activar portas, escrever o numero da porta seguido de um "a"
    * Ex.: 01a (activa ou des. a porta 1)
    *    : 16a (activa ou des. a porta 16)
    *
    * Jesus é o Caminho
    */
   
   int c = 0;
   int dato = 0;

   int latchPin = 8;  //Pino conectado ao pino 12 do 74HC595 (Latch).
   int dataPin = 11;  //Pino conectado ao pino 14 do 74HC595 (Data).
   int clockPin = 12; //Pino conectado ao pino 11 do 74HC595 (Clock).
   
   int b1=0,b2=0,b3=0;
   
   int o1=0,o2=0,o3=0,o4=0,o5=0,o6=0,o7=0,o8=0,o9=0,o10=0,o11=0,o12=0,o13=0,
       o14=0,o15=0,o16=0,o17=0,o18=0,o19=0,o20=0,o21=0,o22=0,o23=0,o24=0;

   char buffer[3];
   int received;

    void setup(){
   
      Serial.begin(9600);
      pinMode(latchPin,OUTPUT);
      pinMode(dataPin,OUTPUT);
      pinMode(clockPin,OUTPUT);
      received = 0;
      }
     
    void loop () {
     
  if(Serial.available()){
    char c = Serial.read();
    if(c == 97){
      int dato = atoi(buffer);
      received = 0;
   
  if (o1==0 && dato==1){o1=1;Serial.print("o1:");Serial.println(o1);dato=0;}
  if (o1==1 && dato==1){o1=0;Serial.print("o1:");Serial.println(o1);dato=0;}
  if (o2==0 && dato==2){o2=2;Serial.print("o2:");Serial.println(o2);dato=0;}
  if (o2==2 && dato==2){o2=0;Serial.print("o2:");Serial.println(o2);dato=0;}
  if (o3==0 && dato==3){o3=4;Serial.print("o3:");Serial.println(o3);dato=0;}
  if (o3==4 && dato==3){o3=0;Serial.print("o3:");Serial.println(o3);dato=0;}
  if (o4==0 && dato==4){o4=8;Serial.print("o4:");Serial.println(o4);dato=0;}
  if (o4==8 && dato==4){o4=0;Serial.print("o4:");Serial.println(o4);dato=0;}
  if (o5==0 && dato==5){o5=16;Serial.print("o5:");Serial.println(o5);dato=0;}
  if (o5==16 && dato==5){o5=0;Serial.print("o5:");Serial.println(o5);dato=0;}
  if (o6==0 && dato==6){o6=32;Serial.print("o6:");Serial.println(o6);dato=0;}
  if (o6==32 && dato==6){o6=0;Serial.print("o6:");Serial.println(o6);dato=0;}
  if (o7==0 && dato==7){o7=64;Serial.print("o7:");Serial.println(o7);dato=0;}
  if (o7==64 && dato==7){o7=0;Serial.print("o7:");Serial.println(o7);dato=0;}
  if (o8==0 && dato==8){o8=128;Serial.print("o8:");Serial.println(o8);dato=0;}
  if (o8==128 && dato==8){o8=0;Serial.print("o8:");Serial.println(o8);dato=0;}
  if (o9==0 && dato==9){o9=1;Serial.print("o9:");Serial.println(o9);dato=0;}
  if (o9==1 && dato==9){o9=0;Serial.print("o9:");Serial.println(o9);dato=0;}
  if (o10==0 && dato==10){o10=2;Serial.print("o10:");Serial.println(o10);dato=0;}
  if (o10==2 && dato==10){o10=0;Serial.print("o10:");Serial.println(o10);dato=0;}
  if (o11==0 && dato==11){o11=4;Serial.print("o11:");Serial.println(o11);dato=0;}
  if (o11==4 && dato==11){o11=0;Serial.print("o11:");Serial.println(o11);dato=0;}
  if (o12==0 && dato==12){o12=8;Serial.print("o12:");Serial.println(o12);dato=0;}
  if (o12==8 && dato==12){o12=0;Serial.print("o12:");Serial.println(o12);dato=0;}
  if (o13==0 && dato==13){o13=16;Serial.print("o13:");Serial.println(o13);dato=0;}
  if (o13==16 && dato==13){o13=0;Serial.print("o13:");Serial.println(o13);dato=0;}
  if (o14==0 && dato==14){o14=32;Serial.print("o14:");Serial.println(o14);dato=0;}
  if (o14==32 && dato==14){o14=0;Serial.print("o14:");Serial.println(o14);dato=0;}
  if (o15==0 && dato==15){o15=64;Serial.print("o15:");Serial.println(o15);dato=0;}
  if (o15==64 && dato==15){o15=0;Serial.print("o15:");Serial.println(o15);dato=0;}
  if (o16==0 && dato==16){o16=128;Serial.print("o16:");Serial.println(o16);dato=0;}
  if (o16==128 && dato==16){o16=0;Serial.print("o16:");Serial.println(o16);dato=0;}
  if (o17==0 && dato==17){o17=1;Serial.print("o17:");Serial.println(o17);dato=0;}
  if (o17==1 && dato==17){o17=0;Serial.print("o17:");Serial.println(o17);dato=0;}
  if (o18==0 && dato==18){o18=2;Serial.print("o18:");Serial.println(o18);dato=0;}
  if (o18==2 && dato==18){o18=0;Serial.print("o18:");Serial.println(o18);dato=0;}
  if (o19==0 && dato==19){o19=4;Serial.print("o19:");Serial.println(o19);dato=0;}
  if (o19==4 && dato==19){o19=0;Serial.print("o19:");Serial.println(o19);dato=0;}
  if (o20==0 && dato==20){o20=8;Serial.print("o20:");Serial.println(o20);dato=0;}
  if (o20==8 && dato==20){o20=0;Serial.print("o20:");Serial.println(o20);dato=0;}
  if (o21==0 && dato==21){o21=16;Serial.print("o21:");Serial.println(o21);dato=0;}
  if (o21==16 && dato==21){o21=0;Serial.print("o21:");Serial.println(o21);dato=0;}
  if (o22==0 && dato==22){o22=32;Serial.print("o22:");Serial.println(o22);dato=0;}
  if (o22==32 && dato==22){o22=0;Serial.print("o22:");Serial.println(o22);dato=0;}
  if (o23==0 && dato==23){o23=64;Serial.print("o23:");Serial.println(o23);dato=0;}
  if (o23==64 && dato==23){o23=0;Serial.print("o23:");Serial.println(o23);dato=0;}
  if (o24==0 && dato==24){o24=128;Serial.print("o24:");Serial.println(o24);dato=0;}
  if (o24==128 && dato==24){o24=0;Serial.print("o24:");Serial.println(o24);dato=0;}

}
   
      if(c != 97){
      buffer[received++] = c;
    }
    Serial.flush();
  }
 
   
     b1=o1+o2+o3+o4+o5+o6+o7+o8;            // Primeiro register
     b2=o9+o10+o11+o12+o13+o14+o15+o16;     // Segundo register
     b3=o17+o18+o19+o20+o21+o22+o23+o24;    // Terceiro register
     
     
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, b3);  // 3º register
    shiftOut(dataPin, clockPin, MSBFIRST, b2);  // 2º register
    shiftOut(dataPin, clockPin, MSBFIRST, b1);  // 1º register
    digitalWrite(latchPin, HIGH);
} 

Tive de alterar uns numeros que estavam mal.

Donvan


senso

Podias poupar muita RAM ao usar simplesmente uma variavel de 8bits para cada shift-register e usar operadores lógicos, tipo |= e &= para limpar ou definir bits.
Avr fanboy

Donvan

Quote from: senso on 28 de July de 2012, 15:54
Podias poupar muita RAM ao usar simplesmente uma variavel de 8bits para cada shift-register e usar operadores lógicos, tipo |= e &= para limpar ou definir bits.

Pois. fiz como sabia, vou aprendendo uma coisa e outra, certamente essa será a proxima a aprender.

se quiser dar um exemplo disso...pa eu ver mais ou menos como é isso.

Obrigado!

outra coisa, como os reles são sensiveis ao multiplex, não pude fazer PWM em um led RGB, mas penso que é possivel fafer o multiplex só no led e nos reles continuar sem mudar estado do pin... isso ainda é para eu testar mais para a frente...

iyahdub

Espero que ajude...Da-te varias opcoes... Inluindo mais SR 595's
Codigo pelo meu amigo Nick Gammon

// Example of setting, clearing, rotating LEDs connected to a 74HC595 shift register
// Author: Nick Gammon
// Date: 3rd May 2012

/*

For more information see:

http://www.gammon.com.au/forum/?id=11518

Baud rate: 115200

Commands you can type in the serial monitor (can be upper or lower case):

nnnX   where nnn is a number (1 or more digits) and X is a command

Spaces are ignored. Carriage-return or linefeed terminates the current command and resets ready for a new one.

nnn C  --> Clear LED nnn. If nnn is omitted, or zero, all LEDs are cleared.
nnn S  --> Set LED nnn. If nnn is omitted, or zero, all LEDs are set.
nnn I  --> Invert LED nnn. If nnn is omitted, or zero, all LEDs are inverted.  (if on, turned off, or vice-versa)

nnn R  --> Rotate all LEDs to the right nnn positions. If nnn is omitted, default to rotate one position right.
nnn L  --> Rotate all LEDs to the left nnn positions. If nnn is omitted, default to rotate one position left.

nnn D  --> Set delay amount. The delay (default 100 mS) is done after each command. Can be zero for doing things quickly.
nnn P  --> Pause for nnn milliseconds. If nnn is zero, pause for the delay amount.

Examples:

5s  --> turn LED 5 on
s   --> turn all LEDs on
7s8s9s  --> turn on LEDs 7, 8, 9
30c --> clear LED number 30
c   --> clear (turn off) all LEDs
44i --> invert LED number 44 (turn on if off, or off if on)
i   --> invert all LEDs
R   --> rotate pattern 1 to the right (if LED 1 was on, LED 2 will be on now and so on)
10r --> rotate pattern 10 positions to the right
L   --> rotate pattern 1 to the left (if LED 2 was on, LED 1 will be on now and so on)
4L  --> rorate pattern 4 positions to the left

1000D --> do a delay of 1000 mS (1 second) after every command
P   --> pause the current delay amount
50P --> pause for 50 mS


Change "numberOfChips" below to reflect how many 74HC595 shift registers you have connected together.

Wiring:
D10 (SS) to ST_CP (pin 12) of all 74HC595 chips
D11 (MOSI) to DS (pin 14) of the first 74HC595 chip
D13 (SCK) to SH_CP (pin 11) of all 74HC595 chips

If you want to use a different SS (LATCH) pin on the processor change the LATCH constant below.       
*/



#include <SPI.h>

const byte LATCH = 10;

const byte numberOfChips = 4;
const byte maxLEDs = numberOfChips * 8;

byte LEDdata [numberOfChips] = {
  0 };  // initial pattern

unsigned long delayAmount = 100;

void refreshLEDs ()
{
  digitalWrite (LATCH, LOW);
  for (int i = numberOfChips - 1; i >= 0; i--)
    SPI.transfer (LEDdata [i]);
  digitalWrite (LATCH, HIGH);
} // end of refreshLEDs

void setup ()
{
  SPI.begin ();   
  Serial.begin (115200);
  Serial.println ("Starting ...");
  refreshLEDs ();  // clear all LEDs
} // end of setup

// turn an LED number into the position in the array, and a bit mask
boolean getChipAndBit (unsigned int led, int & chip, byte & mask)
{
  if (led > maxLEDs)
  {
    Serial.print ("LED ");
    Serial.print (led);
    Serial.println (" too high.");
    return true;  // error
  } // end of too high

  led--;  // make zero relative

  // divide by 8 to work out which chip
  chip = led / 8;  // which chip

  // remainder is bit number
  mask = 1 << (led % 8);

  return false;  // no error
}  // end of getChipAndBit

// clear LED n (or all if zero)
void clearLED (const long n)
{
  // zero means all
  if (n == 0)
  {
    for (int i = 0; i < numberOfChips; i++)
      LEDdata [i] = 0;
    return;
  }  // end of if zero

  int chip;
  byte mask;
  if (getChipAndBit (n, chip, mask))
    return;  // bad number

  LEDdata [chip] &= ~ mask;
}  // end of clearLED

// set LED n (or all if zero)
void setLED (const long n)
{
  // zero means all
  if (n == 0)
  {
    for (int i = 0; i < numberOfChips; i++)
      LEDdata [i] = 0xFF;
    return;
  }  // end of if zero

  int chip;
  byte mask;
  if (getChipAndBit (n, chip, mask))
    return;  // bad number

  LEDdata [chip] |= mask;
}  // end of setLED

// invert LED n (or all if zero)
void invertLED (const long n)
{
  // zero means all
  if (n == 0)
  {
    for (int i = 0; i < numberOfChips; i++)
      LEDdata [i] ^= 0xFF;
    return;
  } // end of if zero

  int chip;
  byte mask;
  if (getChipAndBit (n, chip, mask))
    return;  // bad number

  LEDdata [chip] ^= mask;
}  // end of invertLED

// set the current delay amount to n
void setDelay (const long n)
{
  delayAmount = n; 
}  // end of setDelay

// rotate pattern right (up) n positions
void rotateRight (unsigned int n)
{
  if (n >= maxLEDs)
  {
    Serial.print ("Rotation right amount ");
    Serial.print (n);
    Serial.println (" too high.");
    return;  // error
  }  // end of if too high an amount

  // assume rotate at least once
  if (n == 0)
    n = 1;

  // first do whole bytes
  while (n >= 8)
  {
    byte temp = LEDdata [numberOfChips - 1];
    memmove (&LEDdata [1], &LEDdata [0], numberOfChips - 1);
    LEDdata [0] = temp;
    n -= 8;
  }  // end of more than a byte 

  while (n-- > 0)
  {
    // each time we carry forwards the high order bit
    // the very first time we take that bit from the highest byte
    byte oldCarry = (LEDdata [numberOfChips - 1] & 0x80) ? 1 : 0;

    for (int thisChip = 0; thisChip < numberOfChips; thisChip++)
    {
      byte newCarry = (LEDdata [thisChip] & 0x80) ? 1 : 0;
      LEDdata [thisChip] <<= 1; 
      LEDdata [thisChip] |= oldCarry;
      oldCarry = newCarry;
    } // end of for
  }  // end of doing each bit

}  // end of rotateRight

// rotate pattern left (down) n positions
void rotateLeft (unsigned int n)
{
  if (n >= maxLEDs)
  {
    Serial.print ("Rotation left amount ");
    Serial.print (n);
    Serial.println (" too high.");
    return;  // error
  }  // end of if too high an amount

  // assume rotate at least once
  if (n == 0)
    n = 1;

  // first do whole bytes
  while (n >= 8)
  {
    byte temp = LEDdata [0];
    memmove (&LEDdata [0], &LEDdata [1], numberOfChips - 1);
    LEDdata [numberOfChips - 1] = temp;
    n -= 8;
  }  // end of more than a byte 

  while (n-- > 0)
  {
    // each time we carry forwards the low order bit
    // the very first time we take that bit from the lowest byte
    byte oldCarry = (LEDdata [0] & 1) ? 0x80 : 0;

    for (int thisChip = numberOfChips - 1; thisChip >= 0; thisChip--)
    {
      byte newCarry = (LEDdata [thisChip] & 1) ? 0x80 : 0;
      LEDdata [thisChip] >>= 1; 
      LEDdata [thisChip] |= oldCarry;
      oldCarry = newCarry;
    } // end of for
  }  // end of doing each bit

}  // end of rotateLeft

// pause for supplied mS, or if zero, the current delay amount
void pause (const long mS)
{
  if (mS == 0)
  {
    if (delayAmount)
      delay (delayAmount);
    return;     
  }

  delay (mS);     
}  // end of pause

void processCommand (const byte command, const long n)
{
  switch (command)
  {
  case 'C':
    clearLED    (n);   
    break;   // Clear LED(s)
  case 'S':
    setLED      (n);   
    break;   // Set LED(s)
  case 'I':
    invertLED   (n);   
    break;   // Invert LED(s)
  case 'D':
    setDelay    (n);   
    break;   // Delay amount (mS)
  case 'P':
    pause       (n);   
    break;   // Pause for some mS
  case 'R':
    rotateRight (n);   
    break;   // Rotate right n positions
  case 'L':
    rotateLeft  (n);   
    break;   // Rotate left n positions

  default:
    Serial.print ("Unknown command: ");   
    Serial.println (command);
    return;

  }  // end of switch on command

  // push the new pattern out to the chips
  refreshLEDs ();

  // do optional delay between commands
  if (delayAmount)
    delay (delayAmount);

}  // end of processCommand

void processInput ()
{
  static long receivedNumber = 0;

  byte c = Serial.read ();

  switch (c)
  {

    // accumulate digits
  case '0' ... '9':
    receivedNumber *= 10;
    receivedNumber += c - '0';
    break;

  default:
    Serial.print ("Unexpected input: ");   
    Serial.println (c);

    // fall through to start new number

    // carriage-return or line-feed starts new number
  case '\r':
  case '\n':
    receivedNumber = 0;
    break;

  case 'A' ... 'Z':
  case 'a' ... 'z':
    processCommand (toupper (c), receivedNumber);
    receivedNumber = 0;
    break;

    // ignore spaces
  case ' ':
    break;
  } // end of switch on received character
}  // end of processInput

void loop ()
{

  if (Serial.available ())
    processInput ();

  // do other stuff here
} // end of loop

ps-Desculpen a falta de pontuacao, mas vivo no estrangeiro e os teclados sao xenofobos !!

Donvan

Quote from: iyahdub on 28 de July de 2012, 18:03
Espero que ajude...Da-te varias opcoes... Inluindo mais SR 595's
Codigo pelo meu amigo Nick Gammon

// Example of setting, clearing, rotating LEDs connected to a 74HC595 shift register
// Author: Nick Gammon
// Date: 3rd May 2012

/*

For more information see:

http://www.gammon.com.au/forum/?id=11518

Baud rate: 115200

Commands you can type in the serial monitor (can be upper or lower case):

nnnX   where nnn is a number (1 or more digits) and X is a command

Spaces are ignored. Carriage-return or linefeed terminates the current command and resets ready for a new one.

nnn C  --> Clear LED nnn. If nnn is omitted, or zero, all LEDs are cleared.
nnn S  --> Set LED nnn. If nnn is omitted, or zero, all LEDs are set.
nnn I  --> Invert LED nnn. If nnn is omitted, or zero, all LEDs are inverted.  (if on, turned off, or vice-versa)

nnn R  --> Rotate all LEDs to the right nnn positions. If nnn is omitted, default to rotate one position right.
nnn L  --> Rotate all LEDs to the left nnn positions. If nnn is omitted, default to rotate one position left.

nnn D  --> Set delay amount. The delay (default 100 mS) is done after each command. Can be zero for doing things quickly.
nnn P  --> Pause for nnn milliseconds. If nnn is zero, pause for the delay amount.

Examples:

5s  --> turn LED 5 on
s   --> turn all LEDs on
7s8s9s  --> turn on LEDs 7, 8, 9
30c --> clear LED number 30
c   --> clear (turn off) all LEDs
44i --> invert LED number 44 (turn on if off, or off if on)
i   --> invert all LEDs
R   --> rotate pattern 1 to the right (if LED 1 was on, LED 2 will be on now and so on)
10r --> rotate pattern 10 positions to the right
L   --> rotate pattern 1 to the left (if LED 2 was on, LED 1 will be on now and so on)
4L  --> rorate pattern 4 positions to the left

1000D --> do a delay of 1000 mS (1 second) after every command
P   --> pause the current delay amount
50P --> pause for 50 mS


Change "numberOfChips" below to reflect how many 74HC595 shift registers you have connected together.

Wiring:
D10 (SS) to ST_CP (pin 12) of all 74HC595 chips
D11 (MOSI) to DS (pin 14) of the first 74HC595 chip
D13 (SCK) to SH_CP (pin 11) of all 74HC595 chips

If you want to use a different SS (LATCH) pin on the processor change the LATCH constant below.       
*/



#include <SPI.h>

const byte LATCH = 10;

const byte numberOfChips = 4;
const byte maxLEDs = numberOfChips * 8;

byte LEDdata [numberOfChips] = {
  0 };  // initial pattern

unsigned long delayAmount = 100;

void refreshLEDs ()
{
  digitalWrite (LATCH, LOW);
  for (int i = numberOfChips - 1; i >= 0; i--)
    SPI.transfer (LEDdata [i]);
  digitalWrite (LATCH, HIGH);
} // end of refreshLEDs

void setup ()
{
  SPI.begin ();   
  Serial.begin (115200);
  Serial.println ("Starting ...");
  refreshLEDs ();  // clear all LEDs
} // end of setup

// turn an LED number into the position in the array, and a bit mask
boolean getChipAndBit (unsigned int led, int & chip, byte & mask)
{
  if (led > maxLEDs)
  {
    Serial.print ("LED ");
    Serial.print (led);
    Serial.println (" too high.");
    return true;  // error
  } // end of too high

  led--;  // make zero relative

  // divide by 8 to work out which chip
  chip = led / 8;  // which chip

  // remainder is bit number
  mask = 1 << (led % 8);

  return false;  // no error
}  // end of getChipAndBit

// clear LED n (or all if zero)
void clearLED (const long n)
{
  // zero means all
  if (n == 0)
  {
    for (int i = 0; i < numberOfChips; i++)
      LEDdata [i] = 0;
    return;
  }  // end of if zero

  int chip;
  byte mask;
  if (getChipAndBit (n, chip, mask))
    return;  // bad number

  LEDdata [chip] &= ~ mask;
}  // end of clearLED

// set LED n (or all if zero)
void setLED (const long n)
{
  // zero means all
  if (n == 0)
  {
    for (int i = 0; i < numberOfChips; i++)
      LEDdata [i] = 0xFF;
    return;
  }  // end of if zero

  int chip;
  byte mask;
  if (getChipAndBit (n, chip, mask))
    return;  // bad number

  LEDdata [chip] |= mask;
}  // end of setLED

// invert LED n (or all if zero)
void invertLED (const long n)
{
  // zero means all
  if (n == 0)
  {
    for (int i = 0; i < numberOfChips; i++)
      LEDdata [i] ^= 0xFF;
    return;
  } // end of if zero

  int chip;
  byte mask;
  if (getChipAndBit (n, chip, mask))
    return;  // bad number

  LEDdata [chip] ^= mask;
}  // end of invertLED

// set the current delay amount to n
void setDelay (const long n)
{
  delayAmount = n; 
}  // end of setDelay

// rotate pattern right (up) n positions
void rotateRight (unsigned int n)
{
  if (n >= maxLEDs)
  {
    Serial.print ("Rotation right amount ");
    Serial.print (n);
    Serial.println (" too high.");
    return;  // error
  }  // end of if too high an amount

  // assume rotate at least once
  if (n == 0)
    n = 1;

  // first do whole bytes
  while (n >= 8)
  {
    byte temp = LEDdata [numberOfChips - 1];
    memmove (&LEDdata [1], &LEDdata [0], numberOfChips - 1);
    LEDdata [0] = temp;
    n -= 8;
  }  // end of more than a byte 

  while (n-- > 0)
  {
    // each time we carry forwards the high order bit
    // the very first time we take that bit from the highest byte
    byte oldCarry = (LEDdata [numberOfChips - 1] & 0x80) ? 1 : 0;

    for (int thisChip = 0; thisChip < numberOfChips; thisChip++)
    {
      byte newCarry = (LEDdata [thisChip] & 0x80) ? 1 : 0;
      LEDdata [thisChip] <<= 1; 
      LEDdata [thisChip] |= oldCarry;
      oldCarry = newCarry;
    } // end of for
  }  // end of doing each bit

}  // end of rotateRight

// rotate pattern left (down) n positions
void rotateLeft (unsigned int n)
{
  if (n >= maxLEDs)
  {
    Serial.print ("Rotation left amount ");
    Serial.print (n);
    Serial.println (" too high.");
    return;  // error
  }  // end of if too high an amount

  // assume rotate at least once
  if (n == 0)
    n = 1;

  // first do whole bytes
  while (n >= 8)
  {
    byte temp = LEDdata [0];
    memmove (&LEDdata [0], &LEDdata [1], numberOfChips - 1);
    LEDdata [numberOfChips - 1] = temp;
    n -= 8;
  }  // end of more than a byte 

  while (n-- > 0)
  {
    // each time we carry forwards the low order bit
    // the very first time we take that bit from the lowest byte
    byte oldCarry = (LEDdata [0] & 1) ? 0x80 : 0;

    for (int thisChip = numberOfChips - 1; thisChip >= 0; thisChip--)
    {
      byte newCarry = (LEDdata [thisChip] & 1) ? 0x80 : 0;
      LEDdata [thisChip] >>= 1; 
      LEDdata [thisChip] |= oldCarry;
      oldCarry = newCarry;
    } // end of for
  }  // end of doing each bit

}  // end of rotateLeft

// pause for supplied mS, or if zero, the current delay amount
void pause (const long mS)
{
  if (mS == 0)
  {
    if (delayAmount)
      delay (delayAmount);
    return;     
  }

  delay (mS);     
}  // end of pause

void processCommand (const byte command, const long n)
{
  switch (command)
  {
  case 'C':
    clearLED    (n);   
    break;   // Clear LED(s)
  case 'S':
    setLED      (n);   
    break;   // Set LED(s)
  case 'I':
    invertLED   (n);   
    break;   // Invert LED(s)
  case 'D':
    setDelay    (n);   
    break;   // Delay amount (mS)
  case 'P':
    pause       (n);   
    break;   // Pause for some mS
  case 'R':
    rotateRight (n);   
    break;   // Rotate right n positions
  case 'L':
    rotateLeft  (n);   
    break;   // Rotate left n positions

  default:
    Serial.print ("Unknown command: ");   
    Serial.println (command);
    return;

  }  // end of switch on command

  // push the new pattern out to the chips
  refreshLEDs ();

  // do optional delay between commands
  if (delayAmount)
    delay (delayAmount);

}  // end of processCommand

void processInput ()
{
  static long receivedNumber = 0;

  byte c = Serial.read ();

  switch (c)
  {

    // accumulate digits
  case '0' ... '9':
    receivedNumber *= 10;
    receivedNumber += c - '0';
    break;

  default:
    Serial.print ("Unexpected input: ");   
    Serial.println (c);

    // fall through to start new number

    // carriage-return or line-feed starts new number
  case '\r':
  case '\n':
    receivedNumber = 0;
    break;

  case 'A' ... 'Z':
  case 'a' ... 'z':
    processCommand (toupper (c), receivedNumber);
    receivedNumber = 0;
    break;

    // ignore spaces
  case ' ':
    break;
  } // end of switch on received character
}  // end of processInput

void loop ()
{

  if (Serial.available ())
    processInput ();

  // do other stuff here
} // end of loop



o codigo que fiz, dá para os register's que quizer, é só adicionar linhas...

quanto a esse codigo, ja o tinha visto e quando o fui a testar, funcionou a primeira vez e nunca mais o consegui por a funcionar, não envia nada pelo serial monitor, não sei do que será, porque chegou a funcionar uma vez, não sei se terá a ver com alguma configuração do spi que tenha alterado sem me dar conta...

Sérgio_Sena

Quote from: Donvan on 27 de July de 2012, 20:02
Pessoal, aqui está um codigo que tive de fazer para os meus registers, por causa de alguns reles muito sensiveis ao "multiplex".
Dessa forma não existe "multiplex", e os reles funcionam bem.


Relés sensiveis ao multiplex? ... tens que explicar melhor esta frase.
Posso ser apenas eu que não estou a entender bem. Será que cada vez que transferes informação, sentes os relés a fazer barulho?

Os 74HC595 são SR interessantes porque têem LATCH na saída.
Ou seja, podes transferir a informação para os Flip-flops de entrada, e depois dar um pulso no Clock dos Flip-Flops de saída e só assim é que tens a nova informação disponivel.

Com esta vantagem, podemos transmitir para (quase) infinitos SRs em série, e só no fim com um único pulso de Clock, ligar as saídas com a nova informação.

Cumprimentos,
Sérgio Sena

Electronic Gear for Musicians

Instagram

Donvan

Quote from: asena on 28 de July de 2012, 18:54
Quote from: Donvan on 27 de July de 2012, 20:02
Pessoal, aqui está um codigo que tive de fazer para os meus registers, por causa de alguns reles muito sensiveis ao "multiplex".
Dessa forma não existe "multiplex", e os reles funcionam bem.


Relés sensiveis ao multiplex? ... tens que explicar melhor esta frase.
Posso ser apenas eu que não estou a entender bem. Será que cada vez que transferes informação, sentes os relés a fazer barulho?

Os 74HC595 são SR interessantes porque têem LATCH na saída.
Ou seja, podes transferir a informação para os Flip-flops de entrada, e depois dar um pulso no Clock dos Flip-Flops de saída e só assim é que tens a nova informação disponivel.

Com esta vantagem, podemos transmitir para (quase) infinitos SRs em série, e só no fim com um único pulso de Clock, ligar as saídas com a nova informação.

por muito rapido que seja o PWM, os reles sentem, quando estão 2 ou mais ligados, por exemplo, um display led 4x7 multiplexado para dar um certo numero em um digito e outro diferente em outro digito, o olho não nota que os segmentos ligam e desligam muito rapidamente, mas os reles que tenho, sentem bem isso. certamente que sou eu que não estou a programar bem essa parte, por falta de conhecimento nessa area.

dá-me um exemplo de codigo para essa parte final da tua resposta, pode ser que me seja util para fazer PWM só no led RGB e os reles seguirem ligados sem ter de desligar muito rapidamente, como digo é falta de conhecimento.

Obrigado!

Donvan

he he  8) já consegui fazer pwm só nas saidas que quero sem interferir nos reles

vou criar um topico com o meu projecto, assim ficam a saber o que realmente preciso quando tenho alguma duvida com o meu projecto.

vou testar mais um pouco o codigo que fiz para o pwm e depois posto.  ;)

iyahdub

E capaz de haver algo a intereferir entao, porque como foi dito acima, podes enviar os bits todos, e so depois entao activar a data enviada ( o que evita haver pulsos a sairem em cada pino ate chegar ao pino relevante, que e o caso de outros SR's).
Esse codigo trabalha , e pu-lo ai mais porque era dentro do que querias mais ou menos...E facilmente adaptavel para outros casos similares !
Ja agora, mente o pessoal informado ,mesmo que resolvas o problem, para que alguem que tenha a mesma duvida possa vir a usufruir da solucao, explicada pelo teu ponto de vista !
ps-Desculpen a falta de pontuacao, mas vivo no estrangeiro e os teclados sao xenofobos !!