RobG 1,892 Posted August 15, 2012 Share Posted August 15, 2012 Are you powering your LEDs from LP? What is the output current set to (Rext)? I am testing with 8 LEDs, 16 LEDs might be too much for LP's LDO, try lowering output current. Quote Link to post Share on other sites
spreng37 4 Posted August 15, 2012 Author Share Posted August 15, 2012 Everything is on a breadboard. LEDs are powered by 3.3V from my PSU, Rext is 560ohm. It works great with your original pattern or using my original (non-PWM) code. If I change the pattern to the one I posted all LEDs either on constant, on but dim, or not on at all (changes each time I reset the MSP). Here's a video showing the breadboard and my original pattern: http://www.youtube.com/embed/KGCC3TQcBeo Quote Link to post Share on other sites
RobG 1,892 Posted August 15, 2012 Share Posted August 15, 2012 I just pasted your pattern.h and it works. Quote Link to post Share on other sites
spreng37 4 Posted August 15, 2012 Author Share Posted August 15, 2012 Weird. I'll try a different MSP... edit: Tried a new MSP430G2231 and still no dice. How strange... I'm using two cascaded TLC5916s if it matters. Quote Link to post Share on other sites
RobG 1,892 Posted August 15, 2012 Share Posted August 15, 2012 OK, I got rid of _delay_cycles() and now pattern counter is handled in the ISR, giving you more accurate control. I am using TPIC6B595, I will have my 5916s in few days. main.c pattern.h Quote Link to post Share on other sites
spreng37 4 Posted August 16, 2012 Author Share Posted August 16, 2012 Thanks again Rob! Same result, unfortunately With your pattern it works great but if I change lines 2,4,6 for full brightness it does not work. I can get it to work with only line 2 at full brightness only using one TLC (if I connect the second, it freaks out and just starts flashing). edit: I'm not using the external crystal on my breadboard. Could that have anything to do with it? Quote Link to post Share on other sites
RobG 1,892 Posted August 16, 2012 Share Posted August 16, 2012 Sounds like hardware/supply problem. Set all LEDs to 100% on both TLCs and check your 3.3V supply. With 560ohm Rext, the output current is 33mA per LED, 16 LEDs will draw >500mA. Switching them on and off could be affecting your supply and cause resets. Add bypass and decoupling capacitors. One 100uF and three 0.1uF next to each chip's supply pin. Also, 33mA might be a bit too much for your LEDs at 100% duty cycle. Try changing Rext to something like 820ohm or 1k (this could also be a good way to see if the supply is the problem here, use 1k-1.8k resistor and see if that makes the difference.) Quote Link to post Share on other sites
spreng37 4 Posted August 16, 2012 Author Share Posted August 16, 2012 LEDs have a typical 70mA rating (Lumiled SuperFlux) I have 15, drawing 390mA total. I was able to get it working reliably using a pot set to ~1.7k ohms. I do not have the capacitors on my breadboard because all I have are SMT. I'll desolder the M-M headers from my LP and put the M-F ones on tomorrow and then use the MSP from the LP to see if anything changes. Also pick up some through-hole capacitors Quote Link to post Share on other sites
spreng37 4 Posted August 16, 2012 Author Share Posted August 16, 2012 Looks like the caps did the trick. Everything works as it should now. Those 0.1uF caps are more important than I realized!!! Thanks again Rob, you da man. By the way, where do you have your PCBs manufactured? Quote Link to post Share on other sites
RobG 1,892 Posted August 16, 2012 Share Posted August 16, 2012 I make my boards at Seeed, but cross check with iTeadStudio, depending on color, size, you may get a better deal at one or the other. BTW, my LED/shift register board will be available through 43oh store in couple of weeks. It will be sold as a full kit with 3 chips, LEDs, sockets, headers, resistors, etc., all under $10. Quote Link to post Share on other sites
spreng37 4 Posted August 16, 2012 Author Share Posted August 16, 2012 Next question (I just won't stop, will I?): Now that I have it working on my breadboard, I've been making the pattern to how I'd like but I can't seem to figure out how to make it behave the way I had before. In my original design the first five steps were executed with a for () loop "for (CurStep = 0; CurStep < 6; CurStep++)" then the remaining steps were executed repeatedly with a while (1) and a nested for () "for (CurStep = 6; CurStep < 15; CurStep++)". I see in your code where the magic happens with the 'if' condition in the interrupt. How could I change this to behave the same as my original, executing the first few steps only once then moving on to the remaining steps? I've tried substituting a loop sequence similar to my original but to no avail. Appreciate all the help! :thumbup: Quote Link to post Share on other sites
RobG 1,892 Posted August 17, 2012 Share Posted August 17, 2012 Here it is. Use patternCounter to count steps, patternIndex to select patterns. Put your logic in the while loop. #include "msp430G2231.h" #include "pattern.h" #define SDI BIT5 #define CLK BIT4 #define LE BIT0 // 16 levels of brightness const char lut[16] = { 0, 3, 6, 10, 20, 30, 40, 60, 80, 100, 120, 150, 180, 210, 240, 255 }; char pwmCounter = 0; char patternIndex = 0; char patternCounter = 0; int patternDelay = 0; void main(void) { WDTCTL = WDTPW + WDTHOLD; DCOCTL |= DCO0 + DCO1; // DCO = 15.25MHz BCSCTL1 |= RSEL0 + RSEL1 + RSEL2 + RSEL3; // as above P1OUT = 0; P1DIR |= (SDI + CLK + LE); // setup timer CCR0 = 1200; // TACTL = TASSEL_2 + MC_1 + ID_0; // SMCLK, up mode, 1:1 CCTL0 = CCIE; // CCR0 interrupt enabled _bis_SR_register(GIE); while (1) { // logic goes here // patternIndex is used for pattern selection // patternCounter is used for timeline if(patternCounter < 6) { patternIndex++; patternCounter++; } else { patternIndex--; patternCounter++; } // don't change _bis_SR_register(LPM0_bits); // go to sleep and wait }; } #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A0(void) { patternIndex &= 0x0F; // mask patternCounter to get 0-15 range pwmCounter++; pwmCounter++; // increase again to get 128 pwm steps instead of 256 char i; char pwm; for (i = 0; i < 16; i++) { pwm = lut[pattern[patternIndex][i]]; if (pwm > pwmCounter) { P1OUT |= SDI; } else { P1OUT &= ~SDI; } P1OUT |= CLK; P1OUT &= ~CLK; } P1OUT |= LE; P1OUT &= ~LE; patternDelay++; if (patternDelay == 500) { // animation speed patternDelay = 0; _bic_SR_register_on_exit(LPM0_bits); // ready for next pattern, wake up after ISR } } Quote Link to post Share on other sites
spreng37 4 Posted August 17, 2012 Author Share Posted August 17, 2012 Thanks again Rob. I'm still having a helluva time with the pattern though. Rather than a single while loop, I need to use a for loop that only gets executed once then a while loop for the rest of the pattern. Example: for (patternIndex = 0; patternIndex < 7;) { patternIndex++; patternCounter++; } while (1) { for (patternIndex = 7; patternIndex < 14;) { patternIndex++; patternCounter++; } }; I tried using those loops instead of the if else but it did not work. I tried quite a few things, actually. What am I doing wrong? Quote Link to post Share on other sites
RobG 1,892 Posted August 17, 2012 Share Posted August 17, 2012 In your case (very simple sequence,) you could get rid of patternCounter and just use patternIndex. while (1) { // logic goes here // patternIndex is used for pattern selection // patternCounter is used for timeline patternIndex++; patternCounter++; if(patternCounter == 14) { patternIndex = 6; patternCounter = 6; } // don't change _bis_SR_register(LPM0_bits); // go to sleep and wait }; Quote Link to post Share on other sites
spreng37 4 Posted August 17, 2012 Author Share Posted August 17, 2012 That did the trick! Is there a RobG fund I can donate to? :clap: Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.