Go Down

Topic: BPM (Beats per Minute) detection program - my version (Read 19834 times) previous topic - next topic

dreggory

Okay so, after many months of study and tinkering, writing and re-writing code I finally made a working(at least with version 22)(see my last post I uploaded the library and my code that works with IDE 1.6)  beat detection program it takes 10 seconds to get a rough beat and then starts honing in after 20 more seconds if I remember correctly... it's been a while since I messed with it. I found a much cooler solution to my problem and no longer need this code, but I put the absolute peak of my focus and effort into it for many months so it seems a waste to not share it.

 be nice to me I'm not a programmer and I only had one class of java in college. but I know enough to know that it's sloppy, not very well documented and downright confusing at some parts. for example, I start using some weird variables like "fruit" or "Fruity" my brain was fried and I needed a variable with a unique name... sorry. Despite all this I'll do my best to answer any questions.

keep in mind that beat detection is hard enough to do for a person and their instincts let alone to define it in an algorithm but this is still fun to see it respond to faster or slower beats even though it might be off a little (it's not as good as we all hope it was.) sometimes its dead on though.

when I started this project I knew nothing of Arduinos or micro controllers for that matter, but after lurking 100% (out of fear of angering grumpy Arduino community members) I learned a lot. in fact I feel that everyone needs to try and figure things out without making things a problem for someone else or at least until you are really stuck.

I still don't feel like I belong posting anything on here cause I don't know very much. but I wanted to contribute this so here it is

oh and this is actually a two Arduino project, one for detecting the BPM and one for controlling animations on an 8X8 RGB LED matrix. if anyone is interested in the animation side of this project I'll post it in the appropriate section and add a link to it in this post.
 I fully intended on cleaning up this code and making it pretty and easy to understand but I am busy with other projects, a three year old, job, new business and life in general so this is what you get, sorry.


some things you'll need besides my code:

SimpleTimer library

you will also need this web site as reference as to how to hook up the MSGEQ7 chip for audio data input:

http://nuewire.com/info-archive/msgeq7-by-j-skoba/


dreggory

#1
Jan 14, 2013, 05:54 am Last Edit: Jan 14, 2013, 06:22 am by dreggory Reason: 1
and finally my sketch:
Code: [Select]
/* Beat Detection Program

this program uses a MSGEQ7 chip to collect sound data,
the chip seperates the audio into 7 bands centered on 63hz, 160hz, 400hz, 1khz,
2.5khz, 6.25khz and 16khz(which from my tests is more like 15khz)

  then it takes the average of however many samples are in 1.25 seconds
and compares it to the current sample. If the current sample is higher
than the average multiplied by C, it counts a beat.

  it takes the average amounts of beats in ten seconds and converts that
to beats per minute.

 It then takes 60 divided by the average beats per minute and multiplies
it by 1000 to convert beats per minute into a delay to use between
animations.


 The animations are done on an eight by eight LED Matrix. I'm using four of the
74hc595 ic shift registers to extend the outputs of the Arduino Uno.
I used common cathode RGB LEDs so if the binary animations seem funny
it may be that you have common anode LEDs.


 

*/


#include <Wire.h>

#include <SimpleTimer.h>
SimpleTimer timer;

                  // these are for the MSGEQ7
int analogPin = 0; // read from multiplexer using analog input 0
int strobePin = 2; // strobe is attached to digital pin 2
int resetPin = 3; // reset is attached to digital pin 3
int spectrumValue=0; // to hold a2d values


const int numReadings2 = 20;
const int numReadings3 = 20;

float readings2[numReadings2];       // the readings from the analog input
float readings3[numReadings3];
int index2 = 0;                  // the index of the current reading
int index3 = 0;
float total2 = 0.0;                  // the running total
float total3 = 0.0;
int average = 0;                // the average
float cycles2 = 0.0;
float cycles3 = 0.0;
float cyclesS2 = 0.0;
float cyclesS3 = 0.0;
float cyclesV = 0.0;
float cyclesV3 = 0.0;
float sumBPM2 = 0.0;
float sumBPM3 = 0.0;
//  int BperM2 = 0;      
float spectrumSum2 = 0.0;
float spectrumSum3 = 0.0;
 float average2 = 0.0; //using
 float average3 = 0.0;
//  int average4 = 0;
//  int average5 = 0;  // not using these, I was thinking it would be cool to work in the different frequencies later.
//  int average6 = 0;
//  int average7 = 0;
 int holdValue1 = 0;   // this is for later if I want to do more with different frequencies.    frequency of 63 Hz
 int holdValue2 = 0;   // I'm currently using this one which is assigned the frequency of 160 Hz
 int holdValue3 = 0;   // not using frequency of 400 Hz
 int holdValue4 = 0;   // not using this one either    frequency of 1 KHz
 int holdValue5 = 0;   // or this    frequency of 2.5 KHz
 int holdValue6 = 0;   //or this    frequency of 6.25 KHz
 int holdValue7 = 0;   // or this frequency of 16 Hz (seems more like 15 KHz)
 int averageBPM1 = 0;  // not using
float aveBPM2 = 0.0;  // I'm using this
float aveBPM3 = 0.0;  // and this
 int holdBeat2 = 0;
 int holdBeat3 = 0;
 int beat2 = 0;
 int beat3 = 0;
unsigned long lastCycle ;
 int saveBPM2 = 0;
unsigned long saveAverage = 0;
 int b = 0;
unsigned long timesAround = 0;
float aveBPerM = 0.0;
float aveBPerM3 = 0.0;
int Fruit = 0;
int Fruit3 = 0;
float variance = 0;
float variance3 = 0;
float C = 0;
float C3 = 0;
float averageVariance = 0;
float averageVariance3 = 0;
float greatestAverageVariance;
float greatestVariance = 0;
unsigned long varianceSum = 0;
unsigned long varianceSum3 = 0;
int holdBPMDelay = 0;
double BPMDelay = 0.0;
int trigger2 = 0;
int trigger3 = 0;
int greg2 = 0;
int greg3 = 0;
int byteSending = 1;
//int toTransfer = 32767;
int Shift = BPMDelay;
int mask = 0xFF;
unsigned char toSend = 0;
int twenty2 = 0;
int twenty3 = 0;


void setup()
{
 Serial.begin(9600);
 Wire.begin(0x52); // Start I2C Bus as slave
 Wire.onRequest(requestInt);
 Serial.print("new Session");
 pinMode(analogPin, INPUT);
 pinMode(strobePin, OUTPUT);
 pinMode(resetPin, OUTPUT);
 analogReference(DEFAULT);
 digitalWrite(resetPin, LOW);
 digitalWrite(strobePin, HIGH);
 delayMicroseconds(36);
 timer.setInterval(1250, BPM2);
 timer.setInterval(1250, BPM3);
 timer.setInterval(1250, ResetSec);
//  timer.setInterval(11250, AverageBPM2);
//  timer.setInterval(11250, AverageBPM3);
//  timer.setInterval(11250, ResetTenSec);  
 timer.setInterval(11250, Fruity); // ran out of ideas for names so I chose Fruity all it does is switch a boolean statement
 for (int thisReading2 = 0; thisReading2 < numReadings2; thisReading2++)
 {
   readings2[thisReading2] = 0;
 }
 for (int thisReading3 = 0; thisReading3 < numReadings3; thisReading3++)
 {
   readings3[thisReading3] = 0;
 }
}







dreggory

Code: [Select]
void requestInt()
{
  delay(8);
  if (byteSending == 1) //send packet 1
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 2;
  }
  else if (byteSending == 2) //send packet 2
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 3;
  }
  else if (byteSending == 3) //send packet 3
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 4;
  }
  else if (byteSending == 4) //send packet 4
  {
    toSend = Shift & mask;
    Shift = Shift >> 8;
    Wire.send(toSend);
    byteSending = 1;
    //initialization for next turn
    Shift = BPMDelay;
    mask = 0xFF;
    toSend = 0;
  }

}



int Strobe()
{
  digitalWrite(resetPin, HIGH);
  delay(33);
  digitalWrite(resetPin, LOW);
             
            for(int b=0; b < 7; b++)
              {                 
                digitalWrite(strobePin, HIGH);
                delayMicroseconds(18);
                if (b==0)
                  {
                    digitalWrite(strobePin, LOW);
                    delayMicroseconds(36);
                    analogRead(analogPin);
                    spectrumValue = analogRead(analogPin);
//                    Serial.print(" s1=");
//                    Serial.print(spectrumValue);
//                    Spacing();
                    holdValue1 = spectrumValue;
                   
                  }                                   
                if (b==1)
                  {
                    digitalWrite(strobePin, LOW);
                    delayMicroseconds(36);
                    analogRead(analogPin);
                    spectrumValue = analogRead(analogPin);
//                    Serial.print(" s2=");
//                    Serial.print(spectrumValue);
//                    Spacing();
                    holdValue2 = spectrumValue;
                   
                  }
                if (b==2)
                  {
                    digitalWrite(strobePin, LOW);
                    delayMicroseconds(36);
                    analogRead(analogPin);
                    spectrumValue = analogRead(analogPin);
//                    Serial.print(" s3=");
//                    Serial.print(spectrumValue);
//                    Spacing();
                    holdValue3 = spectrumValue;
                                       
                  }
                 if (b==3)
                  {
                    digitalWrite(strobePin, LOW);
                    delayMicroseconds(36);
                    analogRead(analogPin);
                    spectrumValue = analogRead(analogPin);
//                    Serial.print(" s4=");
//                    Serial.print(spectrumValue);
//                    Spacing();
                    holdValue4 = spectrumValue;
                   
                  }
                 if (b==4)
                  {
                    digitalWrite(strobePin, LOW);
                    delayMicroseconds(36);
                    analogRead(analogPin);
                    spectrumValue = analogRead(analogPin);
//                    Serial.print(" s5=");
//                    Serial.print(spectrumValue);
//                    Spacing();
                    holdValue5 = spectrumValue;
                   
                  }
                 if (b==5)
                  {
                    digitalWrite(strobePin, LOW);
                    delayMicroseconds(36);
                    analogRead(analogPin);
                    spectrumValue = analogRead(analogPin);
//                    Serial.print(" s6=");
//                    Serial.print(spectrumValue);
//                    Spacing();
                    holdValue6 = spectrumValue;
                   
                  }
                 if (b==6)
                  {
                    digitalWrite(strobePin, LOW);
                    delayMicroseconds(36);
                    analogRead(analogPin);
                    spectrumValue = analogRead(analogPin);
//                    Serial.print(" s7=");
//                    Serial.print(spectrumValue);
//                    Spacing();
                    holdValue7 = spectrumValue;
                   
                  }       
               
              }
//              Serial.println();

}
         
         


int Spacing()
{
  if (spectrumValue < 10)
    {
      Serial.print("    ");                   
    }
  else if (spectrumValue < 100 )
    {
      Serial.print("   ");                   
    }
  else
    {
      Serial.print("  ");                   
    }
}

int AverageSpectrum2And3()

  cyclesS2++;
  cyclesS3++;
 
  spectrumSum2 += holdValue2;
  spectrumSum3 += holdValue3;
  average2 = ((spectrumSum2)/(cyclesS2));
  average3 = ((spectrumSum3)/(cyclesS3));
//  Serial.print(" spectrum ave1=");
//  Serial.print(average2);
//  Serial.print(" add it up=");
//  Serial.print(cycles1);
//  Serial.print(" Spectrum Sum =");
//  Serial.print(spectrumSum1);
//  if (cycles1 - lastCycle > 4)    //count to four make a new line
// {
//
//   Serial.println();                //  make sure to un-comment
//   lastCycle = cycles1;
//   
// }
}

void DynamicC()
{
  cyclesV++;
  if (holdValue2 > average2)
  {
    variance = ((holdValue2)-(average2));
  }
  if (average2 > holdValue2)
  {
    variance = ((average2)-(holdValue2));
  }
//  Serial.print(" variance =");
//  Serial.print(variance);
//  if (variance > greatestVariance)
//       {
//         greatestVariance = variance;
//         Serial.print(" GreatestVariance=");
//         Serial.print(greatestVariance);
//       }

  varianceSum += variance;
//  Serial.print(" varianceSum =");
//  Serial.print(varianceSum);
//  Serial.println();
  averageVariance = ((varianceSum)/(cyclesV));
//  Serial.print(" aveVariance =");
//  Serial.print(averageVariance);
//  Serial.println();
//  if (averageVariance > greatestAverageVariance)
//  {
//    greatestAverageVariance = averageVariance;
//    Serial.print(" greatest Average Variance =");
//    Serial.print(greatestAverageVariance);
//    Serial.println();
//  }
 
  C = (((0.00125)*(averageVariance))+(1));
//  Serial.print(" C =");
//  Serial.print(C);
//  Serial.println();
}

void DynamicC3()
{
  cyclesV3++;
  if (holdValue3 > average3)
  {
    variance3 = ((holdValue3)-(average3));
  }
  if (average3 > holdValue3)
  {
    variance3 = ((average3)-(holdValue3));
  }
//  Serial.print(" variance =");
//  Serial.print(variance);
//  if (variance > greatestVariance)
//       {
//         greatestVariance = variance;
//         Serial.print(" GreatestVariance=");
//         Serial.print(greatestVariance);
//       }

  varianceSum3 += variance3;
//  Serial.print(" varianceSum =");
//  Serial.print(varianceSum);
//  Serial.println();
  averageVariance3 = ((varianceSum3)/(cyclesV3));
//  Serial.print(" aveVariance =");
//  Serial.print(averageVariance);
//  Serial.println();
//  if (averageVariance > greatestAverageVariance)
//  {
//    greatestAverageVariance = averageVariance;
//    Serial.print(" greatest Average Variance =");
//    Serial.print(greatestAverageVariance);
//    Serial.println();
//  }
 
  C3 = (((0.00125)*(averageVariance3))+(1));
//  Serial.print(" C =");
//  Serial.print(C);
//  Serial.println();
}




dreggory

Code: [Select]
void Beat2()
{
  if(trigger2 == 0)
    {
    if((holdValue2) > ((average2)*(C)))
      {
   
        beat2++;
   
        trigger2 = 1;
      }     
    }
  if((holdValue2) < ((average2)*(C)))
    {
      trigger2 = 0;
    }
 
}


void Beat3()
{
  if(trigger3 == 0)
    {
    if((holdValue3) > ((average3)*(C3)))
      {
   
        beat3++;
   
        trigger3 = 1;
      }     
    }
  if((holdValue3) < ((average3)*(C3)))
    {
      trigger3 = 0;
    }
 
}


void BPM2()
{
//  // subtract the last reading:
//  total2 -= readings2[index2];       
  // read the beats 
  readings2[index2] = beat2;
  // add the reading to the total:
  for (int i2 = 0; i2 < 19; ++i2)
    {
      total2 += readings2[i2];
     
    } 
Serial.print(" TOTAL 2=");
Serial.print(total2);
Serial.println();
  // advance to the next position in the array: 
  index2++;
   

  // if at the end of the array...
  if (index2 >= numReadings2)

    // ...wrap around to the beginning:
    index2 = 0;
}


//  holdBeat2 = beat2;

 
  Serial.print(" **** BPS 2 ****=");
  Serial.print(beat2);
  Serial.println();
 
   
  greg2 = 2;
 
}



void BPM3()
{
 

//  // subtract the last reading:
//  total3 -= readings3[index3];

                   

  // read the beats 
  readings3[index3] = beat3;
  // add the reading to the total:
  for (int i3 = 0; i3 < 19; ++i3) 
    {
//      if(i3 == 0)
//      {
//        Serial.print("yaaaaaaaaaaaaahhhoooooooooo");
//      }
      total3 += readings3[i3];
    }
    Serial.print(" TOTAL 3=");
    Serial.print(total3);
    Serial.println();
   
// advance to the next position in the array: 
  index3++;   
 
  // if at the end of the array...
  if (index3 >= numReadings3)

    // ...wrap around to the beginning:
    index3 = 0;
}   

//  holdBeat3 = beat3;

 
  Serial.print(" **** BPS 3 ****=");
  Serial.print(beat3);
  Serial.println();
 
 
       greg3 = 2;
 
}




void AverageBPM2()
{
  if(cycles2 < 20)
{
cycles2++;

}
  Serial.print("cycles2=");
  Serial.print(cycles2);
  Serial.println();

   aveBPM2 = ((total2)/(cycles2));
   aveBPerM = (aveBPM2 * 48);
   delay(100);
   if (aveBPerM < 30)
   {
     aveBPerM = 30;
   }
   if (aveBPerM > 500)
   {
     aveBPerM = 500;
   }
   
    total2 = 0;   
       
     greg2 = 0; 
     
}



dreggory

Code: [Select]
void AverageBPM3()
{
 
  if(cycles3 < 20)
{
cycles3++;
}
  Serial.print("cycles3=");
  Serial.print(cycles3);
  Serial.println();
   aveBPM3 = ((total3)/(cycles3));
   aveBPerM3 = (aveBPM3 * 48);
   delay(100);
   if (aveBPerM3 < 30)
   {
     aveBPerM3 = 30;
   }
   if (aveBPerM3 > 500)
   {
     aveBPerM3 = 500;
   }
   
       total3 = 0;
       
       greg3 = 0;
     
}



void ResetSec()  //ran every second
{
// delay(10);
  lastCycle = 0;
//  holdBeat2 = beat2;
//  holdBeat3 = beat3;
  beat2 = 0;
  beat3 = 0;
  variance = 0;
  variance3 = 0;
  varianceSum = 0;
  varianceSum3 = 0;
  averageVariance = 0;
  averageVariance3 = 0;
  cyclesV = 0;
  cyclesV3 = 0;
 
}



void ResetTenSec2()  //was used to run every ten seconds
{
  delay(15);
  spectrumSum2 = 0;

  cycles2 = 0;

  sumBPM2 = 0;

  cyclesS2 = 0;
 
  for (int thisReading2 = 0; thisReading2 < numReadings2; thisReading2++)
   {
     readings2[thisReading2] = 0;
   }

 
}

void ResetTenSec3()  //was used to run every ten seconds
{
  delay(15);

  spectrumSum3 = 0;

  cycles3 = 0;

  sumBPM3 = 0;
  cyclesS3 = 0;
 

  for (int thisReading3 = 0; thisReading3 < numReadings3; thisReading3++)
   {
     readings3[thisReading3] = 0;
   }
 
}



void Fruity()
{
  delay(20);
  Fruit3 = 0;
}

void FruityOs()
{
  Fruit = 0;
}


void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile ("  jmp 0");
}   



void loop()
{

Strobe();
if (holdValue2 > 130)
{
  Fruit = 0;
  delay(10);
  do
    { 
      Strobe();
      AverageSpectrum2And3();
      DynamicC();
      Beat2();
      timer.run();
      if (greg2 == 2)
       {         
         AverageBPM2();
         if (aveBPerM > 35)
           {
             BPMDelay = (((60)/(aveBPerM))*(1000));
             delay(50);
//             Serial.print("^^^^BPMDelay in 2^^^^=");
//             Serial.print(BPMDelay);
//             Serial.print("****BPMDelay is set in 2****");
           }
         
         Serial.print("      ******* Average BPM 2 *******= ");
         Serial.print(aveBPerM);
         Serial.print("      BPMDelay =");
         Serial.print(BPMDelay);
         Serial.println();
       }

 
      if ((holdValue2< 100) || (aveBPerM == 30))
        {
          ResetTenSec2();
          Serial.print("holdValue2 =");
          Serial.print(holdValue2);         
          Fruit = 2;
          Fruit3 = 2;
        }
 
    }while(Fruit == 0);   
}

if ((holdValue3 > 130)&&(Fruit3 == 2))         //detect third spectrum if fail to run spectrum 2
            {

              delay(10);
              do
                { 
                  Strobe();
                  AverageSpectrum2And3();
                  DynamicC3();
                  Beat3();
                  timer.run();
                  if(greg3 == 2)
                   {                     
                    AverageBPM3();
                    if (aveBPerM3 > 35)
                     {
                       BPMDelay = (((60)/(aveBPerM3))*(1000));
                       delay(50);
                       Serial.print("BPMDelay is set in 3");
                     }
                     
                     Serial.print("      ******* Average BPM 3 *******= ");
                     Serial.print(aveBPerM3);
                     Serial.print("      BPMDelay =");
                     Serial.print(BPMDelay);
                     Serial.println(); 

                   
                   }
     

                  if ((holdValue3< 100) || (aveBPerM3 == 30))
                   {
                     ResetTenSec3();
                     
                     Fruit3 = 0;                     
                   }
 
                }while(Fruit3 == 2);
            }


else
{
  Serial.print("Waiting...");
  Serial.println();
  BPMDelay = 115;
}
 
 
//
//if(Fruit == 2)
//{
//  if (aveBPerM < 35)
//    {
//      Fruit = 0;
//    }
//  delay(100);
//  ResetSec();
////  ResetTenSec();
//}


 
}

dreggory

I wish I could have posted it all in one but I had to cut it up, it's a large sketch.


References:
http://www-scf.usc.edu/~ise575/a/projects/mooser/BeatDetector.htm

hmm you know... as I was checking the bookmarks I had used for reference, I noticed this ^ was the only link that wasn't broken. expired web pages sorry.

marco_c

You can attach files to a posting by clicking on the Additional option... At the bottom of the reply/post screen.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

dreggory

Awesome, thanks!

ok here is my sketch in one file

Magician

Error 503 Service Unavailable

Service Unavailable
Guru Meditation:

XID: 1087605664

Varnish cache server

                                          What does it mean???

dreggory

#9
Jan 15, 2013, 08:08 pm Last Edit: Jul 20, 2014, 03:26 am by dreggory Reason: 1
I don't know. Seems it didn't upload the sketch right. I'll upload it again.

EDIT: the link started working and now both links work :)

dreggory


Here's a video of the whole project put together
https://www.youtube.com/watch?v=fA-RN_4i4y4&feature=youtube_gdata_player

zmanpac

I am new to the Arduino Blogs. I converted from Picaxe to Ardunio since they are much more versatile.  I was hoping you have the setup for the RGB posted some where I can look at how you setup the RGB display. You had mentioned it is a Dual Ardunio configuration on generates the BPM and the other displays the graphics. Was wondering what you use the output from ardunio 1 and inputs to the arduino 2 and the pinouts or if you have the code and schematic?




Very Much appreciate and I think you have done an awesome job.

dreggory

#12
Jul 13, 2014, 12:12 am Last Edit: Jul 13, 2014, 12:14 am by dreggory Reason: 1
I will share the whole project with you, no problem.
just one thing... the animation program I used, originated from someone Else's code and I can't remember who I got it from, I adapted it heavily for my use but I still feel it would be rude/plagiarism to not cite who wrote it originally. so instead of posting it for all to see, I will share it over PM. my schematics are terrible, I made them in fritzing and only worked on cleaning up the PCB version(not the schematic.)
later I wanted to use 256 LEDs so I added 4 more shift registers(so the video that is posted is only 64 of the 256 LEDs)
it could be sorted through and cleaned up, but I am too busy to get involved in this.
I can send you the files and all the info you will need; but I can't help much more than that, sorry.

zmanpac

That is fine I was hoping you had something where if I came up with some or a version different I be glad to share it you and all in here. I appreciate anything you can provide even if the schematics are done with pencil and xerox and scanned in is fine so long as they are legible I can create the schematic using DesignSpark tool for schematics.


By the way I make PCB using my CNC machine. If a PCB needs to be proto let me hace the schematic I can cut it on the CNC machine.

dreggory

I'll just post it for all, if the person who wrote the code recognizes it I will just add the recognition.
attached are the files needed

also the animations are written for common cathode LEDs, so if your matrix is common anode, you will have to invert the binary numbers (example: 01000010 will be rewritten as 10111101, and change the methods that look like this:
Code: [Select]

void allRed() //
// turns on all RED
{
  digitalWrite(latchpin, LOW);
  shiftOut(datapin, clockpin, MSBFIRST, 255);
  shiftOut(datapin, clockpin, MSBFIRST, 0);
  shiftOut(datapin, clockpin, MSBFIRST, 0);
  shiftOut(datapin, clockpin, MSBFIRST, 255);// cathodes
  digitalWrite(latchpin, HIGH);
}

need to be changed to this:

void allRed() //
// turns on all RED
{
  digitalWrite(latchpin, LOW);
  shiftOut(datapin, clockpin, MSBFIRST, 0);
  shiftOut(datapin, clockpin, MSBFIRST, 255);
  shiftOut(datapin, clockpin, MSBFIRST, 255);
  shiftOut(datapin, clockpin, MSBFIRST, 0);// cathodes

  digitalWrite(latchpin, HIGH);
}

But you can ignore the code changes if you are using a common cathode matrix.

IMPORTANT!
in order for the whole thing to work you need to use the arduino IDE version 22 or it will not compile. (I didn't feel like porting it over to the new IDE)


and lastly the breadboard/PCB project was made in fritzing which is a free PCB prototyping software.

Go Up