/*
  El arduino se conecta a un chip 74HC595
  El chip 74HC595 se conecta a varios leds
  El SerialInput ofrece varias formas de encender y apagar los leds
*/
#define TOTAL_CHIPS 3

const int clockPin = 44;
const int latchPin = 42;
const int dataPin = 40;

byte leds[8*TOTAL_CHIPS];
int incomingByte = 0;

const int potenciometerPin = A13;

const int pwmPin = 7;
int pwmValue = 0;
float percentBefore = 0;

void setup() 
{
  pinMode(pwmPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(potenciometerPin, INPUT); 
  for(byte Chip=0; Chip < TOTAL_CHIPS; Chip++)
  {
    leds[Chip] = 0;
    updateShiftRegister(1);
  }
  Serial.begin(115200);
  Serial.println("Introducir:");
  Serial.println("- Numero: Sera interpretado como bit del led a encender");
  Serial.println("- Simbolo menos (-) para apagar todos los bits");
  Serial.println("- Simbolo mas (+) para encender todos los bits");
  Serial.println();
  Serial.println("ATENCION CON EL POTENCIÓMETRO QUE INICIALMENTE PUEDE ESTAR EN VALOR 0");
  Serial.println();
}

void loop() 
{
  if (Serial.available() > 0) 
  {
    String inputString = "";
    int receivedNumber = 0;

    while (Serial.available())
    {
      char inChar = (char)Serial.read();
      if (inChar == '-')
      {
        for (int chip = 0; chip < TOTAL_CHIPS; chip++)
        {
            leds[chip] = 0;
        }
        updateShiftRegister(0);
        Serial.println("Reseteando bits");
        Serial.println();
        return;
      }
      if (inChar == '+')
      {
        for (int chip = 0; chip < TOTAL_CHIPS; chip++)
        {
          for (int bit = 0; bit < 8; bit++)
          {
            bitSet(leds[chip], bit);
          }
        }
        updateShiftRegister(1);
        Serial.println("Activando todos los bits");
        Serial.println();
        return;
      }
      inputString += inChar; // Agrega el carácter a la cadena
      delay(2);
    }

    inputString.trim();
    if (inputString == "") return;
    
    receivedNumber = inputString.toInt();

    Serial.print("Texto recibido: ");
    Serial.println(inputString);

    Serial.print("Convertido a numero: ");
    Serial.println(receivedNumber);

    int chip = receivedNumber / 8;
    int bit = receivedNumber - (chip*8);
    
    //leds[chip] = 0;
    bitSet(leds[chip], bit); /* turn on red led */
    updateShiftRegister(1);
    Serial.println();

  }

  int potenciometerValue = analogRead(potenciometerPin);
  pwmValue = map(potenciometerValue, 0, 1023, 255, 0);  
  float percent = 100.0 - ((100.0/255)*pwmValue);

  if (percent != percentBefore)
  {
    percentBefore = percent;
    analogWrite(pwmPin, pwmValue); 
    Serial.print("Ajustando brillo a ");
    Serial.print(percent);
    Serial.print("% ");
    Serial.println(pwmValue);
  }

  delay(5);
}

bool bitGet(unsigned int registro, int bitPosicion)
{
  return (registro & (1 << bitPosicion)) != 0;
}

void updateShiftRegister(bool printData)
{
  Serial.println("Enviando a chips");
  digitalWrite(latchPin, LOW);
  for (int chip = TOTAL_CHIPS-1; chip>-1; chip--)
  {
    shiftOut(dataPin, clockPin, MSBFIRST, leds[chip]);
    if (printData)
    {
      Serial.print("Chip ");
      Serial.print(chip);
      Serial.print(" -> ");
      Serial.println(leds[chip], BIN);
    }
  }
  digitalWrite(latchPin, HIGH);
  delay(200);
}
74HC595
74HC595
74HC595