Pages: 1 2 [3]   Go Down
Author Topic: ATtiny85 + TLC5940  (Read 5653 times)
0 Members and 1 Guest are viewing this topic.
Camisano Vicentino (VI), Italy
Offline Offline
God Member
*****
Karma: 5
Posts: 956
ƎR like no other.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Whoa ƎR, are those 2pin rgb fade leds or are those 4 pin rgb terminated leds?  They look to only have 2 pins.
they are RGB LEDs with common anode, 4 pins, they are controlled by 3 TLC's

about the tiny84, i'm trying it, but i think there is a problem with the port mapping, because in the tiny85 you set the pin PB0, PB1 and and PB2 but in attiny84 should be PA6 PA5 and PA4, do you agree with me? or am i wrong?

i modified this part and it compiles:
Code:
#if defined (__AVR_ATtiny85__) || (__AVR_ATtiny84__)
/*------------------------------------------------------------------------
  Configuration
------------------------------------------------------------------------*/
// How many TLC chips are attached. Each chip needs 32 bytes of RAM.
// The ATtiny85 only has 512 bytes of RAM and you need some left over
// for the rest of your program. Do the math...
#ifndef NUM_TLC5940s
#define NUM_TLC5940s 3
#endif

/*------------------------------------------------------------------------
  Pin assignments
------------------------------------------------------------------------*/
// You could move the BLANK_XLAT_PIN if you wanted to
// but the USI pins are fixed.
#if defined (__AVR_ATtiny85__)
#define BLANK_XLAT_PIN PB0
#define USI_OUT_PIN PB1
#define USI_CLK_PIN PB2
#else
#define BLANK_XLAT_PIN PA6
#define USI_OUT_PIN PA5
#define USI_CLK_PIN PA4
#endif
after i'll try the hardware, but i think that with those modifications that library can be called "Tiny_TLC5940" smiley
what do you think about? am i wrong?
Logged

Riccardo Ertolupi of the Vicenza Thunders Team: http://www.VicenzaThunders.com

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5510
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Whoa ƎR, are those 2pin rgb fade leds or are those 4 pin rgb terminated leds?  They look to only have 2 pins.
they are RGB LEDs with common anode, 4 pins, they are controlled by 3 TLC's

about the tiny84, i'm trying it, but i think there is a problem with the port mapping, because in the tiny85 you set the pin PB0, PB1 and and PB2 but in attiny84 should be PA6 PA5 and PA4, do you agree with me? or am i wrong?

Oh, yes, those pins need to change, too. smiley

PA6 PA5 and PA4 is correct but you'll also have to change all references to PORTB, DDRB and PINB into PORTA, DDRA and PINA.

Maybe you can #define those, too:

Code:
#if defined (__AVR_ATtiny85__)
#define BLANK_XLAT_PIN PB0
#define USI_OUT_PIN PB1
#define USI_CLK_PIN PB2
#define USI_DDR DDRB
#define USI_PORT PORTB
#define USI_PIN PINB
#else
#define BLANK_XLAT_PIN PA6
#define USI_OUT_PIN PA5
#define USI_CLK_PIN PA4
#define USI_DDR DDRA
#define USI_PORT PORTA
#define USI_PIN PINA
#endif


Then use (eg.) "USI_DDR" instead of "DDRB" in the code...

The code then becomes:

Code:
/*------------------------------------------------------------------------
  Bitbang driver for ATtiny85+TLC5940 using only three pins
------------------------------------------------------------------------*/
#ifndef _TEENY5940_H
#define _TEENY5940_H

#if defined (__AVR_ATtiny85__) || (__AVR_ATtiny84__)
/*------------------------------------------------------------------------
  Configuration
------------------------------------------------------------------------*/
// How many TLC chips are attached. Each chip needs 32 bytes of RAM.
// The ATtiny85 only has 512 bytes of RAM and you need some left over
// for the rest of your program. Do the math...
#ifndef NUM_TLC5940s
#define NUM_TLC5940s 1
#endif

/*------------------------------------------------------------------------
  Pin assignments
------------------------------------------------------------------------*/
// You could move the BLANK_XLAT_PIN if you wanted to
// but the USI pins are fixed.
#if defined (__AVR_ATtiny85__)

#define BLANK_XLAT_PIN PB0
#define USI_OUT_PIN PB1
#define USI_CLK_PIN PB2

#define USI_DDR DDRB
#define USI_PORT PORTB
#define USI_PIN PINB

#else

#define BLANK_XLAT_PIN PA6
#define USI_OUT_PIN PA5
#define USI_CLK_PIN PA4

#define USI_DDR DDRA
#define USI_PORT PORTA
#define USI_PIN PINA

#endif

/*------------------------------------------------------------------------
  The TLC5940 controller
------------------------------------------------------------------------*/
#define NUM_LEDS (16*NUM_TLC5940s)   /* 16 LEDs per chip */

class Teeny5940 {
  typedef uint8_t byte;
  typedef uint16_t pwm_val;
  pwm_val pwmVals[NUM_LEDS];
public:
  // ----------------------------------------
  // Initialize - call this in your "setup()"
  // ----------------------------------------
  void init() {
    USI_DDR |= _BV(BLANK_XLAT_PIN);    // Set pin as 'output'
    USI_PORT |= _BV(BLANK_XLAT_PIN);   // BLANK pin high (stop the TLC5940, disable all output)
    // Set all PWM values to zero
    clear();
  }
 
  // --------------------------
  // Set all PWM values to zero
  // --------------------------
  void clear() {
    byte *p = (byte*)pwmVals;
    byte *e = p + (NUM_LEDS*sizeof(pwm_val));
    while (p!=e) {
      *p++ = 0;
    }
  }
 
  // ------------------------------------------------------------------------
  // Set the PWM value of one of the PWM channels, 'value' in range [0..4095]
  //
  // eg. "set(2,2048)" sets LED 2 to 50% on, 50% off
  // ------------------------------------------------------------------------
  void set(byte channel, pwm_val value) {
    if ((channel&1)!=0) {
      pwmVals[channel] = value<<4;    // update() expects data for the odd channels to be shifted...
    }
    else {
      pwmVals[channel] = value&0x0fff;
    }
  }

  // ------------------------------------------------------------------------
  // Call this in your main loop to perform one complete PWM cycle
  //
  // With the Tiny85's internal 8mHz clock this takes almost exactly
  // one millisecond to execute :-)
  // ------------------------------------------------------------------------
  void update() const {
    // Set BLANK and XLAT low for the PWM cycle
    USI_PORT &= ~_BV(BLANK_XLAT_PIN);

    // Set up USI (USI drives the TLC5940 clocks and serial data input)
    byte sOut = _BV(USI_CLK_PIN)|_BV(USI_OUT_PIN);
    USI_DDR |= sOut;         // Pins are outputs
    USI_PORT &= ~sOut;       // Outputs are low
    USICR = _BV(USIWM0);     // Three wire mode

// Macros to drive the USI clock
#define tick USICR=_BV(USIWM0)|_BV(USITC)
#define tock USICR=_BV(USIWM0)|_BV(USITC)|_BV(USICLK)
#define clock8()   tick; tock;  tick; tock;  tick; tock;  tick; tock;  tick; tock;  tick; tock;  tick; tock;  tick; tock;

    // We need to send 4096 clock pulses per PWM cycle, ie. 512 bytes of data.
    // There's only 24 bytes of real data per TLC5940 so we send some dummy data first.
    byte dummySize = (512-(24*NUM_TLC5940s))/2;
    while (dummySize != 0) {
      clock8();      // Send clock pulses for dummy data...
      clock8();
      --dummySize;
    }

    // Now send the real PWM data
    // nb. This sequence of instructions is the result of a lot of
    // compiles/disassembles to get the best possible code output
    // from the compiler. Don't change it...
    byte numPairs = 8*NUM_TLC5940s;
    const pwm_val *pwm = pwmVals+NUM_LEDS-2;
    while (numPairs != 0) {
      const pwm_val hi = pwm[1];
      USIDR = hi>>8;
      clock8();
      const pwm_val lo = pwm[0];
      USIDR = hi|(lo>>8);
      clock8();
      USIDR = lo;
      clock8();
      pwm -= 2;
      --numPairs;
    }

    // Set BLANK and XLAT high while you do your updates
    USI_PIN = _BV(BLANK_XLAT_PIN);
  }
};


// A driver for you to use
Teeny5940 tlc5940;


#else
  unsupported_chip;
#endif

#endif /*_TEENY5940_H*/

« Last Edit: January 15, 2013, 02:06:11 pm by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Camisano Vicentino (VI), Italy
Offline Offline
God Member
*****
Karma: 5
Posts: 956
ƎR like no other.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

very well, after i'll try it smiley-wink
Logged

Riccardo Ertolupi of the Vicenza Thunders Team: http://www.VicenzaThunders.com

Camisano Vicentino (VI), Italy
Offline Offline
God Member
*****
Karma: 5
Posts: 956
ƎR like no other.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i just tried and it works with attiny84 too smiley-wink
Logged

Riccardo Ertolupi of the Vicenza Thunders Team: http://www.VicenzaThunders.com

Wisconsin
Offline Offline
Edison Member
*
Karma: 4
Posts: 1001
I LOVE THIS STUFF!!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is going to sound really newbish but how do you guys program your ATtinys?  I have tried the High Low Tech tutorial numerous times and it doesn't work.  Also I have a hard time finding ATtiny85 cores. 
Any help?
Logged

Accelerate to 88 miles per hour.

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5510
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is going to sound really newbish but how do you guys program your ATtinys?

I use an ISP programmer I bought on eBay

eg.: http://www.ebay.com/sch/i.html?_nkw=arduino+isp+programmer

When I started out I just poked wires into the cable (see photos at the start of this thread).

Now I use a little board I made, see here:

http://arduino.cc/forum/index.php/topic,134673.0.html

As an experiment I've designed/ordered some little PCBs for an ATtiny85 version of that (nb. they didn't arrive yet...)

I have tried the High Low Tech tutorial numerous times and it doesn't work.  Also I have a hard time finding ATtiny85 cores.  
Any help?

I think that was the page I used when I started out but I admit I never did "Arduino as ISP", I bought an ISP programmer.

I usually don't bother with cores any more. The chips are very easy to program directly and writing the code is part of the fun!

The real problem would be in using other libraries that rely on having SPI, etc. Adapting code that needs those things would be a challenge. I don't use other code much though (it rarely fits exactly) and I can always use a Mega328 if I really need to...


PS: This is my PCB for the Tiny85duino... smiley


* Tiny85duino.png (22.78 KB, 205x130 - viewed 37 times.)
« Last Edit: January 16, 2013, 09:03:20 am by fungus » Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Camisano Vicentino (VI), Italy
Offline Offline
God Member
*****
Karma: 5
Posts: 956
ƎR like no other.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i use an arduino as ISP programmer and with this core: http://code.google.com/p/arduino-tiny/
Logged

Riccardo Ertolupi of the Vicenza Thunders Team: http://www.VicenzaThunders.com

Denmark
Offline Offline
Edison Member
*
Karma: 35
Posts: 1072
Happy Hobbyist
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote

I have made a litlle step by step using this core . http://www.ernstc.dk/arduino/attiny85.html

And i recommend using Coding Badly's TinyISP. It gives you all the debug benefits you are used to from the Arduino
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5510
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

And i recommend using Coding Badly's TinyISP. It gives you all the debug benefits you are used to from the Arduino

Serial comms? The problem with that is the Tiny85 has very limited pins. Dedicating some of them to debug output is difficult.

PS: This is why I do most of my Tiny85 coding on a Tiny84... they're similar enough that the code can run on both chips without much effort and the Tiny84 has enough pins left over to use for debugging.

( I use LEDs and a little screen for debug output...you can see my development environment here: http://arduino.cc/forum/index.php/topic,139345.0.html  )

Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Denmark
Offline Offline
Edison Member
*
Karma: 35
Posts: 1072
Happy Hobbyist
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When using the TinyISP you use the MISO pin to communicate, so it is not dedicated to debug output.

Anyway it is a nice little programming board you have made.
Any link to the display ?
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 146
Posts: 5510
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When using the TinyISP you use the MISO pin to communicate, so it is not dedicated to debug output.

It's still a pin not being used to light up LEDs... smiley-sad

Anyway it is a nice little programming board you have made.
Any link to the display ?

This is the one I bought: http://www.ebay.com/itm/170842973484

(also available from other sellers...)
http://www.ebay.com/itm/170929165280
http://www.ebay.com/itm/160889283903
http://www.ebay.com/itm/250986036479
http://www.ebay.com/itm/180945872898
...

nb. There's some cheaper OLED screens on eBay but those ones run off 5V and have an extra controller chip that can draw text, etc. all by itself - no need for font data or bitmap manipulation code on the Arduino. I definitely think it's worth the extra $5 for that feature (nb. I didn't know this when I bought mine, I got lucky...)
 
Logged

No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

Denmark
Offline Offline
Edison Member
*
Karma: 35
Posts: 1072
Happy Hobbyist
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks fungus, good to know those features i might not be so lucky
Logged

Camisano Vicentino (VI), Italy
Offline Offline
God Member
*****
Karma: 5
Posts: 956
ƎR like no other.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i'm using fungus's library and i want to try to consume less energy.
is there any way to say to the TLC "go to sleep" as we do with atmel microcontrollers?
do you think that just stopping the communication with it could be enough? or usign the method init?
Code:
void init() {
    USI_DDR |= _BV(BLANK_XLAT_PIN);    // Set pin as 'output'
    USI_PORT |= _BV(BLANK_XLAT_PIN);   // BLANK pin high (stop the TLC5940, disable all output)
    // Set all PWM values to zero
    clear();
  }
is the fact that it disable all output useful or not?
thanks in advance! smiley-wink
Logged

Riccardo Ertolupi of the Vicenza Thunders Team: http://www.VicenzaThunders.com

Pages: 1 2 [3]   Go Up
Jump to: