Thanks. Tried it out but I guess I'm not that lucky.
I think it has to do with how I'm following the Timing Chart?
Here is the Arduino I'm trying to convert to Basic.
/*Ti 5940 16-port LED driver
= overlapped fade across 16 LEDs at a low background level
* Peter Mackey June 2007 Pratt Digital Arts [email protected]
* direct adressing to PORTB, smooth flickerless fading (thanks to Amp on the Arduino forum)
* additional logic from David Cuartielles's & Marcus Hannerstig's LEDdriver demo
= see the TLC5940 data sheet for the logic behind these pulse sequences
*/
//using the pin codes on the TLC5940NT to name the Arduino ports
#define VPRG 2 //"chip pin 27 to Arduino pin 2"
#define SIN 3
#define SCLK 7
#define XLAT 4
#define BLANK 5
#define DCPRG 6
#define GSCLK 8 //note: but using PORTB method
#define MSINTRVL 0 //could be used to delay updating of incrementFades()
#define FADEMIN 100 //lowest fade level LEDs will reach (min would be 0, max 4065)
#define FADEINCR 64 //determines how many steps it takes to run the desired range (lower=longer)
int fadeLevel[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //stores a level for each of 16 ports
int faderNdx = 0; //counter used in this fading sequence
int fadeState[] = {
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //stores the direction of fading for each port 1,0,-1
//start with first port
int next; //used for limit checking in fading function
float prevMillis; //used for a timing delay
int word[] = {
0,0,0,0,0,0,0,0,0,0,0,0}; //temp storage for reversing bits in a word (for greyscale setting)
void setup() {
pinMode(VPRG, OUTPUT);
pinMode(SIN, OUTPUT);
pinMode(SCLK, OUTPUT);
pinMode(XLAT, OUTPUT);
pinMode(BLANK, OUTPUT);
pinMode(DCPRG, OUTPUT);
pinMode(GSCLK, OUTPUT); //could also set DDRB directly
beginSerial(9600); //in case of debugging
Serial.println("Ready...");
preset(); //input 'Dot Correction' data
}
void loop () {
setGreys();
feedPorts();
if (millis() > (prevMillis+MSINTRVL)){
incrementFades();
prevMillis=millis();
}
}
void incrementFades() {
//a very particular sequence: fade up from LED 0 to 15 then fade down in same direction
//overlaps incoming&outgoing adjacent ports' fade level
for (faderNdx=0; faderNdx<=15; faderNdx++) {
if (fadeState[faderNdx]!=0) { //if the state for this LED is not 0...
if (fadeState[faderNdx]==1) { //then fade up...
next = fadeLevel[faderNdx]+FADEINCR;
if (next<4095) {
fadeLevel[faderNdx] = next; //...by incrementing the value in the fadeLevel array
}
else { //set the state for this LED to fade down
fadeLevel[faderNdx] = 4095; //be sure is at "max level"
fadeState[faderNdx] = -1; //flip my sign
//AND...make next neighbor begin a fade up
if (faderNdx<15) {
fadeState[faderNdx+1] = 1;
}
else {
fadeState[0] = 1;
}
}//------------------------------------------------
} //end fading up
else { //fade down instead...........................
next = fadeLevel[faderNdx]-FADEINCR;
if (next>=FADEMIN) { //-----------------
fadeLevel[faderNdx] = next;
}
else {
//set me to fade down
fadeLevel[faderNdx] = FADEMIN; //be sure at minimum level
fadeState[faderNdx] = 0; //stop fading me until neighbor sets me to fade up
}//------------------------------------------------
}//end fading down
}//end check for state not 0
}// end of cycle thru each port
}
//=======5940 control======================================
void setGreys() {
//data for each port (12 bit word * 16 ports =192 bits in this loop)...
//read the fadeLevel array
for (int i=15; i>=0; i--) { // ports, count DOWN
int datb = fadeLevel[i];
//load fade level bits into the temp array BACKWARDS
for (int j=11; j>=0; j--) {
word[j]=(datb & 1); //& bitwise AND
datb >>= 1; //shift right and assign
// (maybe there's a slicker way to do this!? but this works...)
}
//send the data to the 5940
for (int j=0; j<12; j++) {
digitalWrite(SIN,word[j]);
pulseSCLK();
}
}
digitalWrite(XLAT, HIGH);
digitalWrite(XLAT, LOW);
}
void feedPorts() {
//The actual sequencing of the PWM data into the LEDs, must do constantly...
digitalWrite(BLANK, HIGH);
digitalWrite(BLANK, LOW); //=all outputs ON, start PWM cycle
for (int i=0; i<4096; i++) {
pulseGSCLK();
}
}
//DOT CORRECTION...do once
void preset() {
//Input 'DotCorrex' Data
//16 outputs, 64 posssible levels of adjustment, 6 bits/chan = 96 bits total
//[use if any LEDs in array are physically too bright]
digitalWrite(DCPRG, HIGH); //leaving it H is my arbitrary choice (="write to register not EEPROM")
digitalWrite(VPRG, HIGH); //=inputting data into dot correx register
digitalWrite(BLANK, HIGH); //=all outputs off, when this goes high it resets the greyscale counter
digitalWrite(SIN, LOW); //to start dot correction
digitalWrite(XLAT, LOW);
//begin loading in the dot correx data, most significant bit first...
//but here we are not correcting anything, so LSB is going first!
for (int i=0; i<16; i++) { //16 ports
for (int j=0; j<6; j++) { //6 bits of data for each port
digitalWrite(SIN, HIGH); //for now, 111111 for everybody
pulseSCLK();
digitalWrite(SIN, LOW);
}
}
//----doing the FIRST GREYSCALE SETTING here becuz of the unique 193rd clock pulse
digitalWrite(XLAT, HIGH); //latch the dot data into the dot correx register
digitalWrite(XLAT, LOW);
digitalWrite(VPRG, LOW); //entering greyscale mode
for (int i=0; i<16; i++) { //16 ports
int datb = 4095; //using same fade level for all ports this first time
for (int j=0; j<12; j++) { //data for each port, all the same value to start
digitalWrite(SIN, datb & 01);
pulseSCLK();
datb>>=1;
}
}
digitalWrite(XLAT, HIGH); //latch the greyscale data
digitalWrite(XLAT, LOW);
pulseSCLK(); //193rd clock pulse only need to do the FIRST time after dot correx
digitalWrite(BLANK, LOW); //=all outputs ON, start PWM cycle... moved here
}
//SCLK used in dot correx and greyscale setting
void pulseSCLK() {
digitalWrite(SCLK, HIGH);
digitalWrite(SCLK, LOW);
}
void pulseGSCLK() {
//ultra fast pulse trick, using digitalWrite caused flickering
PORTB=0x01; //bring PORTB0 high (pin 8), other ports go low [0x01 does only pin 8, 0x21 also lifts pin 13]
//16nanosecs is the min pulse width for the 5940, but no pause seems needed here
PORTB=0x20; //keep pin13 high [0x00 would be all low]
}
Bookmarks