Maker Pro
Maker Pro

Trouble with tribbles.. erm, timers.

kpatz

Feb 24, 2014
334
Joined
Feb 24, 2014
Messages
334
That won't work either. On an 8-bit processor, bitfields that don't fit in the byte end up in another byte, so three :5 fields ends up taking 3 bytes on an 8-bit processor.

Here's a way around it, and in C++ you can encapsulate it in a class so it's transparent to the rest of the code. What I did was split the 2nd 5-bit field (the "green" one I named G) into 3 bits and 2 so that the first 3 bits fit in the 1st byte and the remaining 2 in a 2nd byte. Then the access functions split and combine the field and gets/sets its value.

Code:
// Class stores 3 5-bit values and a boolean into 16 bits (2 bytes).
class RGBValue {

 private:
   unsigned pBCR  :5;     // Red (5-bits)
   unsigned pBCG1 :3;    // Green (upper 3-bits, shares byte with Red)
   unsigned pBCG2 :2;    // Green (bottom 2-bits, shares byte with Blue and Pressed)
   unsigned pBCB  :5;     // Blue (5-bits)
   unsigned pPressed :1;  // Pressed flag (1 bit)

 public:
  //Access functions declarations
  unsigned char getR(void);
  unsigned char getG(void);
  unsigned char getB(void);
  bool getPressed(void);
  void setR(unsigned char);
  void setG(unsigned char);
  void setB(unsigned char);
  void setPressed(bool);

};

// Access functions implementation
unsigned char RGBValue::getR(void) {
  return pBCR;
}

unsigned char RGBValue::getG(void) {
  return pBCG1 << 2 | pBCG2;
}

unsigned char RGBValue::getB(void) {
  return pBCB;
}

bool RGBValue::getPressed(void) {
  return pPressed;
}

void RGBValue::setR(unsigned char Value) {
  pBCR = Value;
}

void RGBValue::setG(unsigned char Value) {
  pBCG1 = (Value >> 2) & 0x07;
  pBCG2 = (Value & 0x03);
}

void RGBValue::setB(unsigned char Value) {
  pBCB = Value;
}

void RGBValue::setPressed(bool Value) {
  pPressed = Value;
}

If you want to access the three values as an array, create get and set functions for that as well:

Code:
unsigned char RGBValue::getColor(unsigned char index) {
  switch(index) {
    case 0:
      return getR();
    case 1:
      return getG();
    case 2:
      return getB();
    default:
      return 0;
}

void RGBValue::setColor(unsigned char index, unsigned char value) {
  switch(index) {
    case 0:
      setR(value);
      break;
    case 1:
      setR(value);
      break;
    case 2:
      setR(value);
      break;
}
 
Last edited:

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
You intend to have 20 different brightness levels for each LED, right? I guess you will be using PWM, as well as multiplexed drive? Have you considered the speed requirements? It may impact your choice of language and/or micro!

So you have 107 tri-colour LEDs, right? That's 321 control signals? Say you multiplex them in 16 groups of 20 or 21. To avoid flicker, your multiplex cycle needs to complete in, say, 16 ms. That's 1 ms per group. If you want 20 brightness levels, you'll need to calculate 21 ON/OFF states every 50 µs. Typically, that's done inside a timer interrupt handler. That's in addition to the other logic you need to perform.

That may be feasible. You might also be able to merge the brightness and multiplexing behaviours in some way to reduce the maximum update rate. I can't think of any good way, but you might.

If you were planning to drive the LEDs using shift registers, instead of multiplexing them, you might be able to reduce the overhead, especially if your micro has an SPI peripheral built in.

I'm concerned about the amount of overhead involved in bit-shifting. kpatz has already made the excellent suggestion of allocating bits carefully to minimise the amount of bit-shifting required. I suspect that it might be worthwhile writing the relevant methods in assembler though, where you can use tricks that the compiler can't. I could be wrong. It depends how good the compiler is at handling bitfields.

The 8-bit AVR is not very well suited to compiled languages. It's a lot better suited than the PIC, but that's not saying much! There are other options that are a lot more efficient. I've used the MSP430 devices in plain old C, and they're very good, though not blazingly fast. There's also the many ARM variants, which I know little about, but which would be up to the job I'm sure.

I think you should be considering these practical issues before you get too far into the details of the hardware and firmware design.

It would be quite helpful if you could post a schematic of what you're planning.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
That won't work either. On an 8-bit processor, bitfields that don't fit in the byte end up in another byte, so three :5 fields ends up taking 3 bytes on an 8-bit processor.

Here's a way around it, and in C++ you can encapsulate it in a class so it's transparent to the rest of the code. What I did was split the 2nd 5-bit field (the "green" one I named G) into 3 bits and 2 so that the first 3 bits fit in the 1st byte and the remaining 2 in a 2nd byte. Then the access functions split and combine the field and gets/sets its value.

Code:
// Class stores 3 5-bit values and a boolean into 16 bits (2 bytes).
class RGBValue {

 private:
   unsigned pBCR  :5;     // Red (5-bits)
   unsigned pBCG1 :3;    // Green (upper 3-bits, shares byte with Red)
   unsigned pBCG2 :2;    // Green (bottom 2-bits, shares byte with Blue and Pressed)
   unsigned pBCB  :5;     // Blue (5-bits)
   unsigned pPressed :1;  // Pressed flag (1 bit)

 public:
  //Access functions declarations
  unsigned char getR(void);
  unsigned char getG(void);
  unsigned char getB(void);
  bool getPressed(void);
  void setR(unsigned char);
  void setG(unsigned char);
  void setB(unsigned char);
  void setPressed(bool);

};

// Access functions implementation
unsigned char RGBValue::getR(void) {
  return pBCR;
}

unsigned char RGBValue::getG(void) {
  return pBCG1 << 2 | pBCG2;
}

unsigned char RGBValue::getB(void) {
  return pBCB;
}

bool RGBValue::getPressed(void) {
  return pPressed;
}

void RGBValue::setR(unsigned char Value) {
  pBCR = Value;
}

void RGBValue::setG(unsigned char Value) {
  pBCG1 = (Value >> 2) & 0x07;
  pBCG2 = (Value & 0x03);
}

void RGBValue::setB(unsigned char Value) {
  pBCB = Value;
}

void RGBValue::setPressed(bool Value) {
  pPressed = Value;
}

If you want to access the three values as an array, create get and set functions for that as well:

Code:
unsigned char RGBValue::getColor(unsigned char index) {
  switch(index) {
    case 0:
      return getR();
    case 1:
      return getG();
    case 2:
      return getB();
    default:
      return 0;
}

void RGBValue::setColor(unsigned char index, unsigned char value) {
  switch(index) {
    case 0:
      setR(value);
      break;
    case 1:
      setR(value);
      break;
    case 2:
      setR(value);
      break;
}
Wow! That's a lot of thought you put into this. I thank you so much, seriously. Everyone here has been incredibly helpful! I think that what Kris said is correct though. I've got to worry about processing speed at this point, and it's not worth it to me to add this level of complexity to save two bytes of space per key. With the BC and BPC variables taking up 3 bytes each, and the DutyCycle and Fader variables taking up 3 bytes per color per key I'll still only be using 1605 bytes compared to about 1391 bytes. I don't feel the memory benefit is that worth it in this case. This is, however, a very good thing to keep in mind for future programming since if I run into a problem with memory on a less complex project that's running less at once this seems like it can be very beneficial. As a token of my gratitude I'll put your name down on the circuit board I've designed for this project, and post a picture once I do so from the computer design, and of the circuit board once it's shipped to me. What do you want on it?

You intend to have 20 different brightness levels for each LED, right? I guess you will be using PWM, as well as multiplexed drive? Have you considered the speed requirements? It may impact your choice of language and/or micro!

So you have 107 tri-colour LEDs, right? That's 321 control signals? Say you multiplex them in 16 groups of 20 or 21. To avoid flicker, your multiplex cycle needs to complete in, say, 16 ms. That's 1 ms per group. If you want 20 brightness levels, you'll need to calculate 21 ON/OFF states every 50 µs. Typically, that's done inside a timer interrupt handler. That's in addition to the other logic you need to perform.

That may be feasible. You might also be able to merge the brightness and multiplexing behaviours in some way to reduce the maximum update rate. I can't think of any good way, but you might.

If you were planning to drive the LEDs using shift registers, instead of multiplexing them, you might be able to reduce the overhead, especially if your micro has an SPI peripheral built in.

I'm concerned about the amount of overhead involved in bit-shifting. kpatz has already made the excellent suggestion of allocating bits carefully to minimise the amount of bit-shifting required. I suspect that it might be worthwhile writing the relevant methods in assembler though, where you can use tricks that the compiler can't. I could be wrong. It depends how good the compiler is at handling bitfields.

The 8-bit AVR is not very well suited to compiled languages. It's a lot better suited than the PIC, but that's not saying much! There are other options that are a lot more efficient. I've used the MSP430 devices in plain old C, and they're very good, though not blazingly fast. There's also the many ARM variants, which I know little about, but which would be up to the job I'm sure.

I think you should be considering these practical issues before you get too far into the details of the hardware and firmware design.

It would be quite helpful if you could post a schematic of what you're planning.

Changes to the physical layout.. are just not going to happen. Even if I have to use multiple microcontrollers it will take less time to design that, than to redesign the circuit board. The board is designed using 6 74HC595 chips, 3 ULN2803, a 10x11 matrix for key presses (directly to microcontroller), and 18x18 matrix for all the LEDs. 3 74HC595 in series connected to 3 ULN2803, and 3 in series for positive voltage. I'll give you as much as I can as far as it's setup, but you'll have to extrapolate information as I made these pictures when I was still just learning. ; ) Not that I'm not now.. lol

Why would an SPI pin be more helpful (not entirely sure what you were referring to tbh)? Is there already a setup as far as the 3 pin serial connection to the 74HC595 chips?

The one that I obviously did not create is for better illustration purposes as far as the matrix setup for the LEDs.
keyboard.png

kbledmatrix.png

LEDM88RGBCC_Circuit.gif
 

gorgon

Jun 6, 2011
603
Joined
Jun 6, 2011
Messages
603
Just a comment on the driver structure of the matrix. You use ULN2803 to sink the columns, and the 74HC595 to source one LED. That is a bit on the low side, if you want some light out of the LEDs. You will need to make a source driver. A 74hc595 will only source(and sink) around 6mA, and still keep the output voltage around 3.5-4V.
If you divide 6mA with a dutycycle of 1/18 you end up with an effective max current of 0.33mA. If your LEDs are efficient, you may see a glow. And then you PWM down 20 steps from there.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Just a comment on the driver structure of the matrix. You use ULN2803 to sink the columns, and the 74HC595 to source one LED. That is a bit on the low side, if you want some light out of the LEDs. You will need to make a source driver. A 74hc595 will only source(and sink) around 6mA, and still keep the output voltage around 3.5-4V.
If you divide 6mA with a dutycycle of 1/18 you end up with an effective max current of 0.33mA. If your LEDs are efficient, you may see a glow. And then you PWM down 20 steps from there.

Yes, I've measured that on my breadboard with 74HC595 and ULN2803. To be honest, these LEDs I'm using are REALLY bright. At max brightness they seem uncomfortably bright as something you'd want to look at commonly like a keyboard. Although the entire assembly isn't done I think that the reduced power source on them may actually be helpful, though, I haven't seen their effect after the PWM dimming. You're likely to be right, but it needs investigation.

I have however measured some oddities with power supply though. There seems to be a DRASTIC increase in available amperage without a resistor in the LED assembly. I don't know if it will cause any problems with the chips, but for the green without a resistor I measured [email protected]! That's almost perfectly in line with the LEDs spec sheet for continuous current. The green has a rating of 3.2V@20mA with maximum being 3.4V@100mA (I saw it listed somewhere as the 1/10 duty cycle allowable current). So, it appears that I can just run without resistors for the Blue, and Green LEDs to get full brightness. Likely, I'll need a much smaller resistor for the Red LED. However, if I do want to use the 100mA current for the LEDs to make them brighter I'll have to find another solution.

I've got to double check to make sure that if I load all 8 pins of a 74HC595 with LEDs the Voltages and Currents stay the same. Do you have any suggestions as far as replacements for the 74HC595? Perhaps it has a big brother in the shift register family you know of?
 
Last edited:

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Just did some manipulating of tiny things, and the voltage seems to be roughly a stable [email protected] or very close to it on all the Green/Blue LEDs. I don't particularly want to find appropriate resistors for the Red ones at the moment, but those are running at [email protected] with the resistors I did have handy (100Ohm 1/4th watt). That setup had 1.86V across just the LED when there rated is 1.8V@20mA. I don't think it's safe to run the Red direct from the chip.

It also looks like the electrical is about 4.68V between unconnected pins of the 74HC595 and ULN2803 with about 44mA measuring out.. 0.o So.. odd. When I had those same 100 Ohm resistors in series with the Green/Blue LEDs they were getting about 6mA like you said.. Why are these readings all over the place?

test.jpg
 
Last edited:

gorgon

Jun 6, 2011
603
Joined
Jun 6, 2011
Messages
603
What is the update frequency and the dutycycle for the current setup? If the output is continuous, you can't really see the effect of multiplexing on the light.

The reason for the high current is that you short the output(s) of the 595. The current is only limited by the output driver transistor and the LEDs Vfwd. When you load the output this way you can't go below Vcc/2. This voltage is where you get the 'absolute max' current of 35mA as stated in the datasheet. This is also why you need the current limiting resistor on the red LED. If you use a DIP package you can dissipate 750mW, but only up to 65degC then you derate 100mW/10degC above 65degC. The SOIC and TSSOP packages are much lower in power.

Ok, if you want to use the high current, you should at least test the long term thermal effect of this in a real box and at ambient temp.
If you want to get the same current in the red LEDs, you may use a resistor around 60ohm. (3.1V @ 22mA)

With a dutycycle of 1/18 you still only get an average current of 1mA+ when multiplexing the matrix.
 

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
I'm pretty confused by your second and third diagrams in post #63. The second diagram shows a matrix of circles, which I guess are LEDs, and squares connecting the 74HC595 outputs to the outputs from buck regulators. What do these symbols mean?

I'm also concerned that you seem to be planning to drive the LEDs from fixed-voltage power supples. LEDs are current-controlled and their forward voltage (for a given current) varies somewhat with temperature and manufacturing tolerances. Even if all your RGB LEDs are from the same batch they won't be identical. That could mean that brightnesses and colours won't match on adjacent keys. Exactly what is the best way to drive them... I'm not sure. An array of 107 (or is it 110?) tri-colour LEDs is not exactly simple to deal with! I would like to see a full schematic of what you're planning to do. It's not important to show all of the LEDs; just show one row or column (presumably, one ULN2803 output and all the LEDs whose cathodes are connected to it, and all the circuitry that drives the anodes).

The second diagram is of an 8x8 matrix which is not what you're using. I guess you've included it just to show us the general idea? I would much rather see an actual schematic.

Re shift registers with open-collector or open-drain drivers, yes there are some of these. Have a look at http://www.digikey.com/product-detail/en/TLC59282DBQR/296-28098-2-ND/2509793. There are other types as well; look on Digikey. I'm not sure which category they're under. That one I linked to is under ICs --> PMIC - LED drivers, but check other categories under the ICs heading as well; I don't think they're all in the PMIC - LED Drivers category.

Edit: The ULN2803 is not well-suited to this application because the transistors are all Darlingtons and they won't pull down hard to 0V. Even with slight current flow into the collector, the collector voltage will be greater than 0.5V, possibly as high as 1V. This will also cause different LEDs on the same common cathode bus to affect each other; when one turns ON, others that were already ON will become dimmer. I would use small MOSFETs. These are available singly or in pairs. Digikey's cheapest option is http://www.digikey.com/product-detail/en/DMG5802LFX-7/DMG5802LFX-7DICT-ND/2639350 a dual N-channel MOSFET with Rds(on) = 15 milliohms but in a no-lead package - hard to assemble by hand. Next best option: http://www.digikey.com/product-detail/en/DMG9926USD-13/DMG9926USD-13DICT-ND/2179796 dual N-channel MOSFET 24 milliohm SO-8 package.
 
Last edited:

gorgon

Jun 6, 2011
603
Joined
Jun 6, 2011
Messages
603
For shiftregisters with drivers, I've used UCN5818EPF from Allegro. This is a 32bit wide SPI shiftregister with source drivers. I don't know if this family is still alive but there were several variants with different bit lengths.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
What is the update frequency and the dutycycle for the current setup? If the output is continuous, you can't really see the effect of multiplexing on the light.

The reason for the high current is that you short the output(s) of the 595. The current is only limited by the output driver transistor and the LEDs Vfwd. When you load the output this way you can't go below Vcc/2. This voltage is where you get the 'absolute max' current of 35mA as stated in the datasheet. This is also why you need the current limiting resistor on the red LED. If you use a DIP package you can dissipate 750mW, but only up to 65degC then you derate 100mW/10degC above 65degC. The SOIC and TSSOP packages are much lower in power.

Ok, if you want to use the high current, you should at least test the long term thermal effect of this in a real box and at ambient temp.
If you want to get the same current in the red LEDs, you may use a resistor around 60ohm. (3.1V @ 22mA)

With a dutycycle of 1/18 you still only get an average current of 1mA+ when multiplexing the matrix.
Well, it's a 50Hz per full duty cycle divided by 20 for the 20 LED steps and divided again by 18 from the matrix brings the update frequency to once every 18Khz.

The long term thermal effect at 100mA was only 5x the normal 20mA for a 1/10 duty cycle should have been measured in the factory, and I've seen many other LEDs with similar ratings. I trust it. Plus, these LEDs don't really have a box. They're more or less exposed to open air being that they'll only have a keycap above them that will provide airflow when struck.

I'm pretty confused by your second and third diagrams in post #63. The second diagram shows a matrix of circles, which I guess are LEDs, and squares connecting the 74HC595 outputs to the outputs from buck regulators. What do these symbols mean?

I'm also concerned that you seem to be planning to drive the LEDs from fixed-voltage power supples. LEDs are current-controlled and their forward voltage (for a given current) varies somewhat with temperature and manufacturing tolerances. Even if all your RGB LEDs are from the same batch they won't be identical. That could mean that brightnesses and colours won't match on adjacent keys. Exactly what is the best way to drive them... I'm not sure. An array of 107 (or is it 110?) tri-colour LEDs is not exactly simple to deal with! I would like to see a full schematic of what you're planning to do. It's not important to show all of the LEDs; just show one row or column (presumably, one ULN2803 output and all the LEDs whose cathodes are connected to it, and all the circuitry that drives the anodes).

The second diagram is of an 8x8 matrix which is not what you're using. I guess you've included it just to show us the general idea? I would much rather see an actual schematic.

Re shift registers with open-collector or open-drain drivers, yes there are some of these. Have a look at http://www.digikey.com/product-detail/en/TLC59282DBQR/296-28098-2-ND/2509793. There are other types as well; look on Digikey. I'm not sure which category they're under. That one I linked to is under ICs --> PMIC - LED drivers, but check other categories under the ICs heading as well; I don't think they're all in the PMIC - LED Drivers category.

Edit: The ULN2803 is not well-suited to this application because the transistors are all Darlingtons and they won't pull down hard to 0V. Even with slight current flow into the collector, the collector voltage will be greater than 0.5V, possibly as high as 1V. This will also cause different LEDs on the same common cathode bus to affect each other; when one turns ON, others that were already ON will become dimmer. I would use small MOSFETs. These are available singly or in pairs. Digikey's cheapest option is http://www.digikey.com/product-detail/en/DMG5802LFX-7/DMG5802LFX-7DICT-ND/2639350 a dual N-channel MOSFET with Rds(on) = 15 milliohms but in a no-lead package - hard to assemble by hand. Next best option: http://www.digikey.com/product-detail/en/DMG9926USD-13/DMG9926USD-13DICT-ND/2179796 dual N-channel MOSFET 24 milliohm SO-8 package.
I apologize about my lack of visual information. I haven't drawn up a legitimate schematic, and the one I've made in Eagle with the circuit board doesn't exactly help as I've used quite a few buses since there were so many connections. They were meant as a "general idea" sort of thing, and your guesses were spot on. I was missing 3 keys worth of LEDs on that.. thing I drew. The squares were meant to indicate transistors that were activated by the 74HC595, but I've realized since then that the transistors placed there would pass the 5V from the shift registers into the LED circuit instead of just the buck circuit voltages. I'm no longer using the buck converters anyways, so it's a moot point. As for all the other arguments.. they had been taken into account, and I decided to drive them that way regardless as they had minimal effect from what I was seeing. There were some things I was hoping to add to the LED array using the buck converters, but realized that I wouldn't be able to make them happen without more work than it is worth so I went back to the resistor (or none) idea. I did quite a lot of work to get them in the circuit board, so it's a shame I had to remove them. Ces't la vie. Anyways, I'll be looking into these other options assuming that when I order the smaller shift registers they don't put out what I was hoping.

Hmm, that's so odd.. on the current setup I've got I haven't noticed any changes in brightness with the LEDs, or even any current flow with activation/deactivation of various LEDs. I suppose that finding better chips for the LEDs on both cathode, and anode is in order then.
For shiftregisters with drivers, I've used UCN5818EPF from Allegro. This is a 32bit wide SPI shiftregister with source drivers. I don't know if this family is still alive but there were several variants with different bit lengths.
As you can see space is limited on the board. I need 8 bit shift registers/source/drivers that I can get in small form factors that I can spread across the board easier.

Thanks again for the help guys! It's time for more homework on this, so I'm going to be back in a couple days or so with more! If I could ask for one more thing? What's a good programmer to use on the cheap for my ATTINY861? I want to purchase a Dragon debugger eventually, but don't have the funding atm.
 
Last edited:

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Also, I've been looking into VUSB.. but it says that it's only USB 1.1!? Is there any benefit, or negative side to using/not using USB 2.0 HID? I'm not sure if there's even a difference to be honest. My Google Fu seems weak today.. It looks like the Teensy boards use something similar, but I think they achieve hi-speed USB. Perhaps using their code instead of V-USB is a better option..
 
Last edited:

gorgon

Jun 6, 2011
603
Joined
Jun 6, 2011
Messages
603
Well, it's a 50Hz per full duty cycle divided by 20 for the 20 LED steps and divided again by 18 from the matrix brings the update frequency to once every 18Khz.

You still need an update frequency of 24x20x18x50 = 432000bps to achieve this, not including the single step column driver pulses. That's a fast SPI.

You'll need 1080 bytes to store 1 frame of data(3x20x18)

If you reduce the number of colour from 8000 to 512 = 8 steps, you'll gain a lot of processing time, reducing the update frequency to 172800bps.

With a small microcontroller you'll need a lot of assembler tweeking to get that speed.
 
Last edited:

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
Sorry, I can't help with recommendations for an ATtiny861 programmer. I suggest you make sure that an 8-bit AVR will be up to the task first - using an emulator, perhaps - before you buy a programmer.

Also I can't help re VUSB etc.
 

Solidus

Jun 19, 2011
349
Joined
Jun 19, 2011
Messages
349
The Hammer said:
I apologize about my lack of visual information. I haven't drawn up a legitimate schematic, and the one I've made in Eagle with the circuit board doesn't exactly help as I've used quite a few buses since there were so many connections. They were meant as a "general idea" sort of thing, and your guesses were spot on. I was missing 3 keys worth of LEDs on that.. thing I drew. The squares were meant to indicate transistors that were activated by the 74HC595, but I've realized since then that the transistors placed there would pass the 5V from the shift registers into the LED circuit instead of just the buck circuit voltages. I'm no longer using the buck converters anyways, so it's a moot point. As for all the other arguments.. they had been taken into account, and I decided to drive them that way regardless as they had minimal effect from what I was seeing. There were some things I was hoping to add to the LED array using the buck converters, but realized that I wouldn't be able to make them happen without more work than it is worth so I went back to the resistor (or none) idea. I did quite a lot of work to get them in the circuit board, so it's a shame I had to remove them. Ces't la vie. Anyways, I'll be looking into these other options assuming that when I order the smaller shift registers they don't put out what I was hoping.

Hmm, that's so odd.. on the current setup I've got I haven't noticed any changes in brightness with the LEDs, or even any current flow with activation/deactivation of various LEDs. I suppose that finding better chips for the LEDs on both cathode, and anode is in order then.

Find a way to get me the .sch file and I'll work to figure it out.

I haven't bothered to read through all 8 pages, so I've only done the past 3 or so for relevancy; I'm perplexed as to why you want to use an ATtiny, a LPC (low-pin-count) device, to attempt to control so much GPIO real estate. With a larger AVR, perhaps an ATmega, you could have a smaller or negligibly-larger footprint IC that could exert control over much more IO with more ease.

I'm not condoning that decision, I'm just curious. It's been awhile since I worked to lay the groundwork with you, so a lot of it may have to be dug up again. The other issue is that being a small device, the ATtiny861 doesn't have access to serial lines that are capable of matching the speed of a USB HID upstream connection. This isn't necessarily a bad thing, but it's best to try to eliminate speed bottlenecks if at all possible.

As for the programmer - programmers typically run the gamut from full-end JTAGIce3s (JTAG programmer and simulator capable of working with the newer AVR32s as well) to small serial/parallel-port-based devices that do little more than pin connections and sometimes level-shifting, allowing software to figure out the specific protocols. For ATtiny devices, it is possible to use an Arduino to program them by proxy - this will somewhat curb your ability to do verification on the result, but it certainly is a handy solution.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
You still need an update frequency of 24x20x18x50 = 432000bps to achieve this, not including the single step column driver pulses. That's a fast SPI.

You'll need 1080 bytes to store 1 frame of data(3x20x18)

If you reduce the number of colour from 8000 to 512 = 8 steps, you'll gain a lot of processing time, reducing the update frequency to 172800bps.

With a small microcontroller you'll need a lot of assembler tweeking to get that speed.
I'm not sure where all those numbers are coming from to be honest?
Sorry, I can't help with recommendations for an ATtiny861 programmer. I suggest you make sure that an 8-bit AVR will be up to the task first - using an emulator, perhaps - before you buy a programmer.

Also I can't help re VUSB etc.
Hmm, I'll look into emulators in a second.
Find a way to get me the .sch file and I'll work to figure it out.

I haven't bothered to read through all 8 pages, so I've only done the past 3 or so for relevancy; I'm perplexed as to why you want to use an ATtiny, a LPC (low-pin-count) device, to attempt to control so much GPIO real estate. With a larger AVR, perhaps an ATmega, you could have a smaller or negligibly-larger footprint IC that could exert control over much more IO with more ease.

I'm not condoning that decision, I'm just curious. It's been awhile since I worked to lay the groundwork with you, so a lot of it may have to be dug up again. The other issue is that being a small device, the ATtiny861 doesn't have access to serial lines that are capable of matching the speed of a USB HID upstream connection. This isn't necessarily a bad thing, but it's best to try to eliminate speed bottlenecks if at all possible.

As for the programmer - programmers typically run the gamut from full-end JTAGIce3s (JTAG programmer and simulator capable of working with the newer AVR32s as well) to small serial/parallel-port-based devices that do little more than pin connections and sometimes level-shifting, allowing software to figure out the specific protocols. For ATtiny devices, it is possible to use an Arduino to program them by proxy - this will somewhat curb your ability to do verification on the result, but it certainly is a handy solution.
The ATTINY861 is just something I bought for use with another project that code was already written by someone else. I am using it to test my current code in a scaled down variety. It's only got the pins to do the LEDs, and 20 buttons with no USB or other communications support on the 861 I've got. I have been looking at other MCU for the final product as I would like something that's not pins, and is QFP to use in the project.
 

gorgon

Jun 6, 2011
603
Joined
Jun 6, 2011
Messages
603
I'm not sure where all those numbers are coming from to be honest?

Well you should be since you want to do this display system. I'll break it down.

24x20x18x50 = 432000bps:

SPI controllers always send whole bytes so 18 bits is expanded to 24 bit for the 18 rows.

You want to have a colour depth of 20, so you need to repeat the above 20 times for each column. (here you can save some updates if you make the algorithm intelligent, but this is worst case(20))

You have 18 columns. This makes one complete frame.

You want to update the display 50 times each second, or 50 frames/second
this makes the necessary minimum bandwidth(clock speed) for the SPI to be 432000bps.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Oh! Gotcha. I was not sure where the 24 came from, and although I recognized the rest of the numbers I wasn't sure if that's what I was looking at. Makes sense now. I hadn't had time to look into that since there's been so much going on. I'm also not entirely sure that I need to use an SPI though? I know it was suggested, but I would like to see if it's necessary since it seems like kinda a waste if it doesn't need to be added in.
 

Solidus

Jun 19, 2011
349
Joined
Jun 19, 2011
Messages
349
I'm not sure where all those numbers are coming from to be honest?

Hmm, I'll look into emulators in a second.

The ATTINY861 is just something I bought for use with another project that code was already written by someone else. I am using it to test my current code in a scaled down variety. It's only got the pins to do the LEDs, and 20 buttons with no USB or other communications support on the 861 I've got. I have been looking at other MCU for the final product as I would like something that's not pins, and is QFP to use in the project.

Oh okay. SMT versus DIP.

If you're really pressing for "exact" timing than you may want to use inline assembly. At this point I can't really be bothered to do a writeup on it, but basically in a nutshell, there are methods in C/C++ that can be used to force the compiler to use specific assembly conventions. It affords you use of standard programming conventions elsewhere but in specific portions of your code, you can be positive that your timing is occurring exactly as you intend it to, and not left to the compiler to make (or not make...) certain optimizations. For example, calling an inline shift would assure you that the shift is occurring in one cycle only and not left to the whim of the compilation stages.

If you're interested, I'll do some homework on it and help you figure it out. I've never exactly worked much with it - when I work in assembly, I tend to do it all in assembly, so inlining is a bit of a new thing to me. I have had to do it in programming for large, multi-cored CPUs where timing is VERY critical, however.

I'd also look at pushing the uC of choice to its Fmax (its maximum operant frequency) - most ATMegas can be pushed to 20MHz over the nominal 16 that Arduinos use. There are certain timing things (with the timer modules, that is) that get going, but when you're pushed for speed, it may be in your favor to amp up and you may get some good leeway on an extra 4MHz.

Just some things to chew on.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Yeah, definitely want SMT. I don't have enough room for a DIP package. Inline assembly sounds quite interesting, and I'd like to look into it. That's for another time though. I need to test what I HAVE done, and see if it works. I need to get a programmer asap so I can test, and select a chip, but I'm looking into USB communication in more depth before I decide on a chip. Any suggestions would be appreciated, but I am starting to investigate ARM Atmel chips as it appears that's what the Teensy uses. Not to mention apparently the only serious changes between the 32bit and ARM chips seems to be their speed as far as my uses are concerned.

Thanks for looking into that stuff! Mayhaps you can let me know when you've looked into it as far as it's usefulness. I've actually considered going to Assembly after hearing it's benefits.
 

Solidus

Jun 19, 2011
349
Joined
Jun 19, 2011
Messages
349
Yeah, definitely want SMT. I don't have enough room for a DIP package. Inline assembly sounds quite interesting, and I'd like to look into it. That's for another time though. I need to test what I HAVE done, and see if it works. I need to get a programmer asap so I can test, and select a chip, but I'm looking into USB communication in more depth before I decide on a chip. Any suggestions would be appreciated, but I am starting to investigate ARM Atmel chips as it appears that's what the Teensy uses. Not to mention apparently the only serious changes between the 32bit and ARM chips seems to be their speed as far as my uses are concerned.

Thanks for looking into that stuff! Mayhaps you can let me know when you've looked into it as far as it's usefulness. I've actually considered going to Assembly after hearing it's benefits.

Only transition into full ASM if you want a headache, IMO - for this purpose, it's a null thing. I used to write assembly for MIPS processors; coding encryption algorithms which could be processed in 100 lines of C++ would turn into multi-thousand line operations in assembly, because the CPU doesn't understand anything but numeric shifts, arithmetic operations and branchings.

For a project like this, which will almost certainly involve a good amount of interrupt service routines and timing, as well as USB throughput, I'd say at your current level of understanding of this stuff (programming) would be a death wish to try and do in ASM thoroughbred. Writing in a high-level like C++ or even C will introduce you to concepts you will almost certainly use, no matter what language you prefer to call your "workhorse" language.

As to chips; I'd go the way of ARM. They're faster than the AVR32s as of late (84MHz typical as to 66, although that's not a tremendous consideration). More important is that the development of toolings for the Atmel ARMs seems to be more matured; AVR32s will be a lot of API lookups and stuff that if you're new, you'd preferably avoid. That, and they are a separate architecture - they're not just a 32-bit extension of the AVR architecture - so they will handle differently anyways.

I've always been very excited about the AVR32s, but very let down in that their development seems to be sidelined to the ARM cores. There is a development board out there (open source) called Aery32 which I've been interested in for a good while but never convinced myself to pull the trigger on and purchase. I'm not sure if it'll be of any use for this project, but if you want to start experimenting with things of more "horsepower" than the standard AVRs, I'll be a friend and companion you can work with on it.

As for the inline assembly, here's a taste:
Code:
int someFunction(int someArg) {
    int output;
    asm volatile ( "addi %1, $0;" // immediate add of input ref call (%1) to contents of reg $0,
                          "mov $0, %0;" // move contents of reg $0 to output ref call (%0)
                           : "=r" (output)
                           : "r" (someArg)
                         )
    return output;
}

That may seem convoluted, and I had to google that to do a writeup. It's 'pseudocode' so the conventions may not be kosher to any specific architecture. Some specific things going on here:

1. asm () gives a codespace for the assembly.

2. Suffixing "volatile" to the assembly codespace specifies that the compiler is to accept the code and execute literally, and not attempt to make any optimizations such as moving it out of a loop or otherwise branching or reworking your code. In other words, "volatile" is telling the compiler chain to accept your code as the literal word of the Programming Gods.

3. The %0 and %1 are conventions for tying in high-level operands (e.g. int input, int output) into your assembly. The key term "r" tells GCC (the compiler chain, which I believe Atmel Studio, Arduino Framework, et. al. use a subset of) to be free to use whatever register it wants to store those operands.

4. The final two line declarations map the operand references to the high-level (C++ level) integers themselves.

Again, this isn't specific - it's generic code designed to help you get the idea. You'll need to Google and look into Arduino inlining of assembly to get a better picture. Hope this helps.

Eli
 
Top