Qualcuno mi spiega cosa fà questo programma ???

serve per pilotare un driver led ma non capisco come facci a comunicare …

 /*
  Nathan Seidle
  SparkFun Electronics 2011
  
  This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
  
  Controlling an LED strip with individually controllable RGB LEDs. This stuff is awesome.
  
  The SparkFun (individually controllable) RGB strip contains a bunch of WS2801 ICs. These
  are controlled over a simple data and clock setup. The WS2801 is really cool! Each IC has its
  own internal clock so that it can do all the PWM for that specific LED for you. Each IC
  requires 24 bits of 'greyscale' data. This means you can have 256 levels of red, 256 of blue,
  and 256 levels of green for each RGB LED. REALLY granular.
 
  To control the strip, you clock in data continually. Each IC automatically passes the data onto
  the next IC. Once you pause for more than 500us, each IC 'posts' or begins to output the color data
  you just clocked in. So, clock in (24bits * 32LEDs = ) 768 bits, then pause for 500us. Then
  repeat if you wish to display something new.
  
  This example code will display bright red, green, and blue, then 'trickle' random colors down 
  the LED strip.
  
  You will need to connect 5V/Gnd from the Arduino (USB power seems to be sufficient).
  
  For the data pins, please pay attention to the arrow printed on the strip. You will need to connect to
  the end that is the begining of the arrows (data connection)--->
  
  If you have a 4-pin connection:
  Blue = 5V
  Red = SDI
  Green = CKI
  Black = GND
  
  If you have a split 5-pin connection:
  2-pin Red+Black = 5V/GND
  Green = CKI
  Red = SDI
 */

int SDI = 2; //Red wire (not the red 5V wire!)
int CKI = 3; //Green wire
int ledPin = 13; //On board LED

#define STRIP_LENGTH 32 //32 LEDs on this strip
long strip_colors[STRIP_LENGTH];

void setup() {
  pinMode(SDI, OUTPUT);
  pinMode(CKI, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
  //Clear out the array
  for(int x = 0 ; x < STRIP_LENGTH ; x++)
    strip_colors[x] = 0;
    
  randomSeed(analogRead(0));
  
  //Serial.begin(9600);
  //Serial.println("Hello!");
}

void loop() {
  //Pre-fill the color array with known values
  strip_colors[0] = 0xFF0000; //Bright Red
  strip_colors[1] = 0x00FF00; //Bright Green
  strip_colors[2] = 0x0000FF; //Bright Blue
  strip_colors[3] = 0x010000; //Faint red
  strip_colors[4] = 0x800000; //1/2 red (0x80 = 128 out of 256)
  post_frame(); //Push the current color frame to the strip
  
  delay(2000);

  while(1){ //Do nothing
    addRandom();
    post_frame(); //Push the current color frame to the strip

    digitalWrite(ledPin, HIGH);   // set the LED on
    delay(250);                  // wait for a second
    digitalWrite(ledPin, LOW);    // set the LED off
    delay(250);                  // wait for a second
  }
}

//Throws random colors down the strip array
void addRandom(void) {
  int x;
  
  //First, shuffle all the current colors down one spot on the strip
  for(x = (STRIP_LENGTH - 1) ; x > 0 ; x--)
    strip_colors[x] = strip_colors[x - 1];
    
  //Now form a new RGB color
  long new_color = 0;
  for(x = 0 ; x < 3 ; x++){
    new_color <<= 8;
    new_color |= random(0xFF); //Give me a number from 0 to 0xFF
    //new_color &= 0xFFFFF0; //Force the random number to just the upper brightness levels. It sort of works.
  }
  
  strip_colors[0] = new_color; //Add the new random color to the strip
}

//Takes the current strip color array and pushes it out
void post_frame (void) {
  //Each LED requires 24 bits of data
  //MSB: R7, R6, R5..., G7, G6..., B7, B6... B0 
  //Once the 24 bits have been delivered, the IC immediately relays these bits to its neighbor
  //Pulling the clock low for 500us or more causes the IC to post the data.

  for(int LED_number = 0 ; LED_number < STRIP_LENGTH ; LED_number++) {
    long this_led_color = strip_colors[LED_number]; //24 bits of color data

    for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {
      //Feed color bit 23 first (red data MSB)
      
      digitalWrite(CKI, LOW); //Only change data when clock is low
      
      long mask = 1L << color_bit;
      //The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit.
      
      if(this_led_color & mask) 
        digitalWrite(SDI, HIGH);
      else
        digitalWrite(SDI, LOW);
  
      digitalWrite(CKI, HIGH); //Data is latched when clock goes high
    }
  }

  //Pull clock low to put strip into reset/post mode
  digitalWrite(CKI, LOW);
  delayMicroseconds(5000); //Wait for 500us to go into reset
}

Sostanzialmente il mio problema è che non capisco come faccia a comunicare con il chip esterno…

ho dato uno veloce, comunica tramite 2 fili: int SDI = 2; //Red wire (not the red 5V wire!) int CKI = 3; //Green wire

da quantop ho capito, quando abbassi CKI stai selezionando il prossimo led, dai il comando accendi/spegni attraverso SDI, poi riporti alto CKI per dirgli di eseguire il comando e "chiudere" con questo led il resesto a prima vista serve per scorrere un array, in cui ogni valore rapprenta i led, in pratica nel valore ogni bit corrisponde ad un led, 1 per acceso e 0 per spento. è un metodo un poco scomodo a prima vista, ma permette di risparmiare un sacco di spazio, e ogni combinazione luminosa è rappresentabile in un numero unsigned (il cui valore massimo è rappresentato da 2^numero di led)

ciao

for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {       //Feed color bit 23 first (red data MSB)      
      digitalWrite(CKI, LOW); //Only change data when clock is low      
      long mask = 1L << color_bit;       //The 1'L' forces the 1 to start as a 32 bit number, otherwise it defaults to 16-bit.      
      if(this_led_color & mask)          digitalWrite(SDI, HIGH);
      else          digitalWrite(SDI, LOW);  
       digitalWrite(CKI, HIGH); //Data is latched when clock goes high
    }

Il collegamento é un collegamento seriale con un pin di data e uno di clock dove nel passaggio da l a H del clock viene letto il dato. Potrebbe essere un collegamento SPI dove manca il canale di ritorno.
Il driver per la striscia di led riceve 24 Bit (8bit per colore) e di conseguenza alimenta in PWM i led dei 3 colori della striscia.

for(byte color_bit = 23 ; color_bit != 255 ; color_bit--) {   // Ciclo di 24 ripetizioni
digitalWrite(CKI, LOW); //mette il clock a LOW
long mask = 1L << color_bit;       //definisce la maschera per selezionare un bit dopo l' altro e lo shifta per la posizione del bit ( da 23 a 0 volte)
if(this_led_color & mask)  //  controlla se il bit alla posizione della maschera (n-esimo bit) é HIGH
digitalWrite(SDI, HIGH); // porta l' uscita dati a HIGH
else          digitalWrite(SDI, LOW);   //senó ( controlla se il bit alla posizione della maschera é LOW) porta l' uscita dati a LOW
digitalWrite(CKI, HIGH); //cambnia lo stato del segnale Clock e il dispositivo collegato carica il dato.

Spero di essere stato comprensibile.
Ciao Uwe

Mmmm.... Cercherò di studiarmelo ulteriormente... all oscilloscopio vedo solo un onda quadra che cambia come una seriale lenta.... boh.... mi è poco chiaro il discorso...

ratto93: Cercherò di studiarmelo ulteriormente... all oscilloscopio vedo solo un onda quadra che cambia come una seriale lenta....

Sí ci credo perché é una seriale. che manda 24 bit e un clock di 24 impulsi. Ciao Uwe

Grazie :wink:
permetti un altra domanda …
quindi se volessi mandare all’integrato dei colori specifici fatti da me oppure da un random dovrei fare una variabile che assegna un valore qui ?

long mask = 1L << variabile;

Quella é la maschera una cariabile che ha solo 1 bit messo a high per selezionare il dato da trasmettere.
Il dato che mandi é un mumero da 24 bit dove 8 bit sono per il rosso, 8 per il verde e 8bit per il blu.

È spiegato nel commento del programma.

//Each LED requires 24 bits of data
//MSB: R7, R6, R5…, G7, G6…, B7, B6… B0
//Once the 24 bits have been delivered, the IC immediately relays these bits to its neighbor
//Pulling the clock low for 500us or more causes the IC to post the data.

Questo vale per ogni led della striscia. Ogni led é pilotato da un WS2801. Tutti i WS2801 sono messi in serie.

Ciao Uwe

Cavolo mi era sfuggito.... Grazie Uwe...