Just a guess.
Try
I have not read the data sheet or tried your device. But the above works for other shift registers.Code:pulsout XLAT shiftout SER, SCLK, 1, [4000]
Just a guess.
Try
I have not read the data sheet or tried your device. But the above works for other shift registers.Code:pulsout XLAT shiftout SER, SCLK, 1, [4000]
Dave
Always wear safety glasses while programming.
Isn't turning a pin HIGH and then LOW the same as PULSOUT?
I've worked a bunch with other shift registers, but mostly they were binary state (ON or OFF). This is the first time I'm working with a PWM chip so I'm a little confused on how to shift out that much information and in what order it needs to be done..
I think is has more to do with when the latch is made high. I think it needs done just before the data is sent each time.
Like I said, just a guess. Give it a try. Might get lucky.
Dave
Always wear safety glasses while programming.
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]
}
Grayscale values are 12-bits, and you need to send 16 of those values before latching the data, for a total of 192 bits.
The code in the attachment is sending 1,536 bits (16*12*8).
And the method you showed in post #1 would only send 128 (16*8).
And your variable sizes aren't right. fade is a BYTE array, and can't hold 12-bit values. data1 is also a BYTE array, but you're using it like a WORD variable.
I think something like this will work better ...Then you could ...Code:fade var WORD[16] TempW var WORD setGreys: for z = 0 to 15 TempW = fade(z) shiftout ser, sclk, 1, [TempW\12] next z high xlat low xlat returnDot correction values are 6-bits. 16 of those would total 96-bits.Code:RampCount var WORD ChanCount var BYTE RampUP: FOR RampCount = 0 to 4088 STEP 8 FOR ChanCount = 0 to 15 fade(ChanCount) = RampCount NEXT ChanCount GOSUB setGreys PAUSE 50 NEXT RampCount RETURN RampDN: FOR RampCount = 4088 to 0 STEP -8 FOR ChanCount = 0 to 15 fade(ChanCount) = RampCount NEXT ChanCount GOSUB setGreys PAUSE 50 NEXT RampCount RETURN
<br>
DT
Thanks for the help with the variable settings. This definitely helps as I'm sure I'm shifting out the right bits now.
I'm still not getting any response from the TLC5940 though. Now instead of randomly blinking LEDs it's just staying off. I think this is fine because I'm shifting out the right bits, but I'm still confused with the ordering of the LATCH, BLANK, SER.
If you look at the Timing Chart in the spec sheet they show the ordering, but there is this weird thing where they have a separate pulse GSCLK in addition to the main SCLK pulse. I'm not sure why they have this and I don't know how I'm supposed to do both at the same time..
Take a look at this forum topic , maybe it can help you understand the logic of sending data to the chip.
http://www.picaxeforum.co.uk/showthr...?t=8616&page=3
let us know when you succeed.
Bookmarks