My Digital Tachometer - putting it all together

Go To Last Post
192 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To review, I am making a digital tachometer that looks like this:

To drive the 7 segment LEDs, I am using a MAX7219, and for the bar graph around the perimeter, I'm using 5 PCA9922s, which are shift registers similar to 74HC595s but higher power (and different pinouts). There are also three LEDs to backlight the "RPM" nomenclature and are driven by spare outputs of one of the PCA9922s. After experimenting with the AS4 simulator and trying different ideas writing code, I have frozen the hardware design of my tachometer.

|=============================================================================| | | | ATtiny 26 Microcontroller | | | | +----v----+ | | MOSI/PB0 -| 1 20 |- PA0/ADC0 Analog Dimmer Input | | MAX7219 Data Out MISO/PB1 -| 2 19 |- PA1/ADC1 | | Serial Clock SCK/PB2 -| 3 18 |- PA2/ADC2 | | Crank Sensor Input PCINT0/PB3 -| 4 17 |- PA3/AREF Capacitor to ground | | VCC -| 5 16 |- GND | | GND -| 6 15 |- AVCC | | 16 mHz crystal XTAL1/PB4 -| 7 14 |- PA4/ADC3 MAX7219 Select/Latch | | 16 mHz crystal XTAL2/PB5 -| 8 13 |- PA5/ADC4 PCA9922 Select/Latch | | T0/PB6 -| 9 12 |- PA6/ADC5 | | Reset RESET/PB7 -| 10 11 |- PA7/ADC6 PCA9922 data out | | +---------+ | | | ===============================================================================

Through my experimenting I found the USI is the most efficient way to send data to the MAX7219. But the bar graph is another story. Breaking the serial stream into 8 bit (single byte) chunks is quite cumbersome. I need to send 40 bits in series. Since it is a bar graph, there is a series of continuous ones followed by a series of zeros. I'll use a loop to count through the ones then the zeros. This takes more clock cycles that I expected in the loop, but is is way better than breaking the 40 bits into 5 bytes. I'll use the USI clock for the PCA9922 even though the data is output from a different pin than the USI data. The USI clock toggles with one clock cycle while an I/O pin takes two. As discussed in previous threads, on the bar graph, I plan to use software PWM to vary the intensity of the top lit segment to do a kind of 'interpolation' between segments. It is a kind of anti-aliasing for the top segment (if that makes sense). I am using an external analog signal to define the LED intensity for overall dimming at night (just like the way the dimming in a car works). This will be easy with the MAX7219. But since the bar graph top segment uses PWM, I need to make sure the whole program runs fast enough to provide enough granularity so I can do both overall intensity AND top segment PWM. The crank sensor input uses the Pin Change Interrupt to count edges from 40 'holes' (80 edges) in a disk (flywheel). I count these edges for .075 secs. This gives one tenth the RPM (ie. at 2500 RPM = 250 counts). If I want more resolution, I found that I can average, say, ten readings, but NOT divide by ten. In this thread, I will be sharing the step-by-step assembly of the whole project. I have a small machine shop (including CNC) and will be custom building the enclosure, LED diffuser, engraved face, etc. So I'll show all that along with the code development and testing. I have already completed the diffuser and engraved face, so in my next few posts, I'll show the process of fabricating them. Plus, I should have PCBs in a few weeks, so stay tuned.... This forum has been such a great help to my being able to even do this, I think it will be a way for all that helped to see the fruit of their efforts (since this has DEFINITELY been a team effort). It is also a way for me to thank Kartman, clawson, bobgardner, joeymorin, et al.... I don't know if this is the proper forum, so forgive me if it isn't. :wink: Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

Last Edited: Thu. Feb 19, 2015 - 07:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Pins and needles!

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I don't know if this is the proper forum,

You could host it on Atmel Spaces and use your own blog their to document build steps as you go. It ties code, design documents, bug tracker, forum even together in one place for all time. The only proviso Atmel stipulate is that, like SourceForge (on which it is based) it must be an open source project and you effectively give Atmel rights to the design.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sounds pretty cool!

Why all the extra chips? Looks like you could use just an AVR and charlieplex the LEDS.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I count these edges for .075 secs. This gives one tenth the RPM (ie. at 2500 RPM = 250 counts). If I want more resolution, I found that I can average, say, ten readings, but NOT divide by ten.


What works well in many of these situations is to keep a small circular buffer of the last n readings. For example, you could have 10 entries over 0.75 seconds and the total would be your RPM.

You can then make the balance between number of entries and responsiveness.

In any case, with even just a few entries it tends to smooth out readings that are small numbers, and as with other "oversampling" can increase precision. If you have a few bytes of SRAM for the buffer and current index, the processing is minimal (especially if the buffer size is a power of 2, and/or adds up to a magic number as with your sampling rate and a 10-place buffer).

Quote:

Breaking the serial stream into 8 bit (single byte) chunks is quite cumbersome.

Quote:

but is is way better than breaking the 40 bits into 5 bytes.

You've lost me on this one. I'll assume that when all 40 are lit, you are at the redline and that represents a certain RPM. For the sake of discussion, let's say that RPMmax is 4000 and each fully-lit LED represents 100rpm.

So you calculate that you are at 2550 rpm. Divide that by 100 and you get 25 with a remainder of 50. So 25 get fully lit, and you fuss with the remainder.

"value" is now 25
LOOPon:
  Is "value" >= 8?  
  If so, 
    -- output a 11111111 byte
    -- subtract 8  from value
    -- goto LOOPon

  If not,
    -- output the partial byte 1/0 combination
    -- calculate how many off bytes
    -- use that to jump into the 5-place table below (Duff's device? ;) 

LOOPoff5:
  Output 00000000 byte
LOOPoff4:
  Output 00000000 byte
LOOPoff3:
  Output 00000000 byte
LOOPoff2:
  Output 00000000 byte
LOOPoff1:
  Output 00000000 byte
  

I don't know where you fuss with the remainder. The first 0 bit in the combination byte?

Just one way to approach it. I'd tend to call it "tricky" rather than "cumbersome", but it is fun to do such programming challenges IME.

The painful /100 can be made much less painful with a judicious choice of RPMmax so that "value" is just a mask or shift/mask.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
You could host it on Atmel Spaces
...[snip] ...
you effectively give Atmel rights to the design.
Thanks. :wink: I'm not ready to do that right now.
Torby wrote:
Why all the extra chips? Looks like you could use just an AVR and charlieplex the LEDS.
Yes, that would work. At this point though, I don't see a significant advantage in saving three 50 cent chips. So starting over with hardware redesign (along with PCB layout) isn't in the cards at this time. I'll keep it in mind in the future. :wink:
theusch wrote:
What works well in many of these situations is to keep a small circular buffer of the last n readings.
Yes, exactly my plan. I just didn't know how to put in words as well as you did. :wink:
theusch wrote:
I'd tend to call it "tricky" rather than "cumbersome", but it is fun to do such programming challenges IME.
I did essentially what you suggest and ran it through the simulator. It took three times as many clock cycles as the loop I wrote. So this is why I used the word cumbersome.
    1. I set the data line high 2. toggle the clock on/off 25 times
    3. pull data line low
    4. toggle clock on/off for the remaining bits
DONE! It seems way too simple to ignore. :wink:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

Last Edited: Thu. Sep 5, 2013 - 11:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IME you might have trouble getting balanced brightness with the different-coloured LEDs if all driven with the same current.

That said, it may not matter. Looking at your design, if the orange and/or yellow are a bit brighter than the green it may not matter. If the yellow and red on the ends are brighter--so much the better.

Looking at the picture, my "RPMmax" is 7000? (I only see 36 LEDs in the picture, with an extra yellow at the low end and otherwise 5 per (I assume) 1000rpm? So it is really 200rpm for one LED and an extra at the bottom?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
IME you might have trouble getting balanced brightness with the different-coloured LEDs if all driven with the same current.
I have LEDs that are similar brightness. But you are right, it may not matter.
theusch wrote:
Looking at the picture, my "RPMmax" is 7000?
You were right the first time, 4000 max rpm. I don't see a need to have LEDs for 100-400 RPM. The bottom segment is for 500 RPM. The engine won't be running below that.

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

You were right the first time, 4000 max rpm.

So it then ends up to be one LED for each 100rpm over a threshold.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
So it then ends up to be one LED for each 100rpm over a threshold.
Yep! You got it. :wink:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I made solid models of the gauge to get a sense of how everything goes together (the back cover is aluminum but I show it as transparent to allow for viewing what's inside):

One of the challenges of this gauge is diffusing the LEDs. Through hole LEDs are molded with a lens/diffuser, but it seems the SMT LEDs rarely are. I ran into this problem with a project for a customer and solved it after some experimentation. It now works quite well.

Each segment (LED) needs to be optically isolated so the light doesn't 'bleed' from one to another. So each segment needs to be a separate piece of acrylic with something opaque between them. With a bar graph, you want minimal space between the segments. Since the bar graph is an arc, each segment is a trapezoidal shape.

To make the diffuser, I knew it would be easiest to use my CNC mill.

I began with 1/2" translucent white acrylic sheet that is used for back lit signs. I found that an eighth inch thickness will diffuse the LED to minimize the 'hot' spot and not absorb too much light. The idea is that the CNC would cut a series of trapezoids in an arc and opaque epoxy would be cast around them. Since the desire is to have minimal space between segments, the cutter would need to be really skinny - unless something different could be devised. I cut every other trapezoid so there was a larger space between them, and made two pieces like this:

Then sandwiched them together like this.

The four holes in the corners are pinned to keep everything aligned. Epoxy is poured into the larger hole on the left and allowed to cure. The pins are removed and most of the plastic is machined away to leave this:

It is important to have a light barrier between segments and with only .014" (.36mm) between segments, it is doubtful the epoxy will be sufficient. I didn't want to use black epoxy because I wanted to REFLECT the light rather than absorb it. So I got an aluminized mylar granola bar wrapper and cut strips that I could insert between the trapezoids before sandwiching and epoxying. You can see the darker lines from these strips in the photo above.

The 7 segment displays will poke through the rectangular hole and the RPM nomenclature is illuminated by the smaller rectangular section below it. It will then be covered by the engraved face below:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very cool.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Holy [phneep]!

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been working on the code and getting a little discouraged. :? It looks like being able to control the bar graph intensity with my current approach won't work. :(

Running at 16mHz, with a refresh rate of 80 Hz, a 3 bit PWM for the top lit bar graph segment, and 3 bit PWM for bar graph dimming, the program loop has 3,125 clock cycles to do its job. So far it uses about 2,300 cycles. Since I still have to incorporate the PWM functions, it looks like I could easily bust the budget. :shock: (Plus, it would be nice to have the option to go to 4 or more bit PWM).

So I am looking at a different strategy. To control the bar graph dimming, I am looking into using the ATtiny26's hardware PWM connected to the chip enable pins of the PCA9922s (shift registers). This changes the rules enough that there is plenty of margin and there is no longer any concern about having enough time. Plus, increasing PWM from 3 to 4 bits (or more) is no problem. However, doing this requires re-arranging the furniture somewhat. :wink:

I am assuming that the PWM will use the resources of timer1 so I will need to use timer0 for the RPM timing. Timer0 does not have a compare feature so I'll have to deal with that.

Question:
Is it possible to preload a non-zero value in the timer register and count overflow interrupts?

Also, the PWM output pin is currently used for the Pin Change interrupt from the crank sensor. Because of the limitations of the tiny26's PCINT, it is problematic to use it on a different pin. BUT, I discovered the external interrupt INT0 has a mode to detect any change as well as either edge. :wink: So I'll connect the crank sensor to INT0 instead. Here are the pinouts with these changes:

|=============================================================================|
|                                                                             |
|                          ATtiny 26 Microcontroller                          |
|                                                                             |
|                                 +----v----+                                 |
|                       MOSI/PB0 -| 1    20 |- PA0/ADC0  Analog Dimmer Input  |
|   MAX7219 Data Out    MISO/PB1 -| 2    19 |- PA1/ADC1                       |
|       Serial Clock     SCK/PB2 -| 3    18 |- PA2/ADC2                       |
|   BarGraph Dim Out  PCINT0/PB3 -| 4    17 |- PA3/AREF  Capacitor to ground  |
|                            VCC -| 5    16 |- GND                            |
|                            GND -| 6    15 |- AVCC                           |
|     16 mHz crystal   XTAL1/PB4 -| 7    14 |- PA4/ADC3  MAX7219 Select/Latch |
|     16 mHz crystal   XTAL2/PB5 -| 8    13 |- PA5/ADC4  PCA9922 Select/Latch |
| Crank Sensor Input    INT0/PB6 -| 9    12 |- PA6/ADC5                       |
|              Reset   RESET/PB7 -| 10   11 |- PA7/ADC6  PCA9922 data out     |
|                                 +---------+                                 |
|                                                                             |
===============================================================================

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not to derail your thread, but that's not a "Waiex" in your avatar? Oh, no. The canopy and nose are completely different.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Torby wrote:
that's not a "Waiex" in your avatar?
No, it's my own design... I call it aeroHAWK. :wink:

It is single place and powered by a converted Corvair engine. Currently it is inside my computer - I'm trying to figure out how to get it out! :shock:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Where does one obtain a Corvair engine?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
Where does one obtain a Corvair engine?
Just monitor Craig's list, they pop up from time to time. The 'best' engines for aircraft are generally the ones that the Corvair collectors do not want.

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Currently it is inside my computer - I'm trying to figure out how to get it out!

Open the hangar doors and just fly it out?

Place the computer on a good piece of Styrofoam, put that stack in some water and hope it believes it is an aircraft carrier? (The CD tray could be ejected to resemble one of those aircraft lifts they have..)

Put pontoons on your aeroHAWK and let Jeckson fly it out?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Open the hangar doors and just fly it out?
:lol: LOL! :lol: Thanks for the laugh!

I can talk about airplanes 24/7, but that is another forum. :wink: For this forum however, I still have a question.

I want to switch from timer1 to timer0 for the RPM timer. The challenge is that I'm using the output compare feature of timer1, but timer0 doesn't have that feature.

The F_CPU is 16mHz, and the prescaler is 1/1024. Timer1 compares the counter to 194 to get a period of .0125 Sec. My thinking is to pre-load the register (TCNT0) with 61 after each overflow (in the ISR) so there are 194 counts left before it overflows.

Is this feasible?

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK wrote:
The F_CPU is 16mHz, and the prescaler is 1/1024. Timer1 compares the counter to 194 to get a period of .0125 Sec. My thinking is to pre-load the register (TCNT0) with 61 after each overflow (in the ISR) so there are 194 counts left before it overflows.

Is this feasible?

Yes, but if there's too much delay between timer0 overflowing, and your code reloading the timer, the timer0 period will be long. You have around 1024 instruction cycles to play with, that should be plenty, unless you're doing a lot of work with interrupts disabled.

Hmmm... What setup are you planning for timer1? You might be able to use timer1 for both PWM dimming and RPM counting - use OCR1B for the PWM dimming, OCR1C for setting the period, and the TOV1 interrupt for the RPM count.

- S

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mnehpets wrote:
You have around 1024 instruction cycles to play with, that should be plenty
Okay, great, that was my thinking also.
mnehpets wrote:
You might be able to use timer1 for both PWM dimming and RPM counting
After reading more about the PWM, I looked into that. I want the PWM frequency to be several hundred hertz, so it seems a lot easier if I can separate the PWM and RPM timing.

THANKS! :wink:

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK wrote:
I want the PWM frequency to be several hundred hertz, so it seems a lot easier if I can separate the PWM and RPM timing.

It's not too difficult to run both functions on the same timer. Hmmmm.. Is the 80Hz used for RPM measurement? What you could do is to set timer1 to run at 400Hz, and use OCR1B for PWM. For the RPM timing, you simply need to do the RPM measurement every 5 timer overflows.

- S

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mnehpets wrote:
It's not too difficult to run both functions on the same timer.
Thanks, I see what you're saying. :wink:

Is there a compelling reason to use only one timer?

There are two timers in the micro, it appears to also be quite easy to use both timers. So which way is better?

It looks like six of one - half dozen of the other. :wink: So now I have to pick....

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, debugging is apt to be a bit easier if you use separate Timer/Counters for separate functions.

But that only applies to those of us who have to occasionally debug some code...

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Code errors? You guys don't make THOSE, do you?

Why count revolutions, 'stead of timing them and dividing?

In the 70s, I wanted to make a CMOS optical tach for model airplanes. I couldn't figure out how to divide. Well, duh, I knew how to program 2708 eproms, just program one so you could look up the RPM based on the time. These days? Just divide.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Torby wrote:
Why count revolutions, 'stead of timing them and dividing?
Why NOT?

There is more than one way to do it. Is there a compelling reason to do one or the other? Six of one - half dozen of the other.... :wink:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK wrote:
mnehpets wrote:
It's not too difficult to run both functions on the same timer.

Is there a compelling reason to use only one timer?

There are two timers in the micro, it appears to also be quite easy to use both timers. So which way is better?

It looks like six of one - half dozen of the other. :wink: So now I have to pick....

No, there's no compelling reason for either choice. If you use two separate timers, it's easier to have the two functions completely independent. On the other hand, with the two timer approach, you get a timing constraint on the reloading of the timer value.

- S

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK,

This is a very cool, ambitious project, your machining skills are awesome!

Where do all of the shift registers and other digit driving ICs go in the 3D models you have shown?

It seems like you are trying to achieve PWM of the bar graph by using a successive shift register loading technique. Wherein you load the shift registers for 1,2,3 or 4 "time slots" within a certain 4-slot PWM period to achieve four levels of overall brightness. Is that sort of correct?

Do you have brightness control over the whole bar-graph, plus an additional "level" of brightness control for the top segment? Or, is it only the top segment that has the 4-level brightness control?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK wrote:
So I am looking at a different strategy. To control the bar graph dimming, I am looking into using the ATtiny26's hardware PWM connected to the chip enable pins of the PCA9922s (shift registers). This changes the rules enough that there is plenty of margin and there is no longer any concern about having enough time. Plus, increasing PWM from 3 to 4 bits (or more) is no problem. However, doing this requires re-arranging the furniture somewhat. :wink:
Just remember that if you're mixing two PWM signals to drive one display element, you must be mindful of 'beating'. Specifically (as discussed in some of your other threads), the display will beat with a frequency equal to:
    modulo
This is fine, so long as the beat frequency is faster than POV, say 60 Hz.

If the beat frequency is zero, you must still take care that the two PWM are in phase.

The advantage of doing both PWM on the AVR is you have control over both.

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Just remember that if you're mixing two PWM signals to drive one display element, you must be mindful of 'beating'. Specifically (as discussed in some of your other threads), the display will beat with a frequency equal to:
    modulo
This is fine, so long as the beat frequency is faster than POV, say 60 Hz.
Thanks for keeping me on top of this JJ. When this was discussed in my other thread, I googled 'beating' and 'aliasing' and I found the same formula, as well as this:
    beat freq. = abs (freq1 - freq2)
:wink: Yes, I am aware, and yes I am taking it into account. :wink: :wink: I plan to use a fairly high frequency... say between 1kHz and 4kHz.

Using different timers as discussed above makes it easier to make adjustment to this if needed. :wink:

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck-Rowst wrote:
Where do all of the shift registers and other digit driving ICs go in the 3D models you have shown?
It isn't very clear in the images, but there are two PCBs stacked. The shift registers are on the back side of the front board (close to the LEDs they drive). The 20 pin SOIC package that is easily seen, is the MAX7219 that drives the seven segment displays.
Chuck-Rowst wrote:
It seems like you are trying to achieve PWM of the bar graph by using a successive shift register loading technique. Wherein you load the shift registers for 1,2,3 or 4 "time slots" within a certain 4-slot PWM period to achieve four levels of overall brightness. Is that sort of correct?
Yes, exactly. I plan to use eight levels of brightness.
Chuck-Rowst wrote:
Do you have brightness control over the whole bar-graph, plus an additional "level" of brightness control for the top segment?
Yes. The shift registers have a 'chip eneble' pin that I will drive with a PWM. This is the subject of the last few posts (i.e. which timer to use for what).

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK,

The PCA9922's have a configurable current drive (15 - 60 mA). What current drive value are you using?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck-Rowst wrote:
The PCA9922's have a configurable current drive (15 - 60 mA). What current drive value are you using?
I will do some experimenting, but expect to be between 15 mA and 20 mA.

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK,

It seems from your descriptions of the Bar Graph section of your instrument that you are connecting 5 PCA9922's serially into one long 40 bit shift register. Correct?

If so, I think you should consider NOT taking this approach. Instead, drive the 9922's as five parallel 8-bit shift registers - that is with 5 separate data lines, one common clock and one common load line. I believe this approach will offer you a number of advantages. However, before I launch into an elaborate discussion of these benefits, please tell me if you have enough I/O lines on your processor to accomodate this "5 wide" approach.

Also, do you have any FPGA experience?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck-Rowst wrote:
you are connecting 5 PCA9922's serially into one long 40 bit shift register. Correct?
Correct
Chuck-Rowst wrote:
tell me if you have enough I/O lines on your processor to accomodate this "5 wide" approach.
Barely. I have 4 lines left, but I'd have to use the data-in of the USI. This should be okay, since I don't use the USI for any input. This is what I have currently.
|=============================================================================|
|                                                                             |
|                          ATtiny 26 Microcontroller                          |
|                                                                             |
|                                 +----v----+                                 |
|                       MOSI/PB0 -| 1    20 |- PA0/ADC0  Analog Dimmer Input  |
|   MAX7219 Data Out    MISO/PB1 -| 2    19 |- PA1/ADC1                       |
|       Serial Clock     SCK/PB2 -| 3    18 |- PA2/ADC2                       |
|   BarGraph Dim Out  PCINT0/PB3 -| 4    17 |- PA3/AREF  Capacitor to ground  |
|                            VCC -| 5    16 |- GND                            |
|                            GND -| 6    15 |- AVCC                           |
|     16 mHz crystal   XTAL1/PB4 -| 7    14 |- PA4/ADC3  MAX7219 Select/Latch |
|     16 mHz crystal   XTAL2/PB5 -| 8    13 |- PA5/ADC4  PCA9922 Select/Latch |
| Crank Sensor Input    INT0/PB6 -| 9    12 |- PA6/ADC5                       |
|              Reset   RESET/PB7 -| 10   11 |- PA7/ADC6  PCA9922 data out     |
|                                 +---------+                                 |
|                                                                             |
===============================================================================

Chuck-Rowst wrote:
Also, do you have any FPGA experience?
None (I had to google it to know what it was).

In case you missed earlier threads... I am a mechanical engineer / toolmaker / moldmaker. My knowledge in electronics is only adequate (self taught), but I do seem to pick things up very quickly. :wink:

FYI - I have the PCB layout finished. I don't know what you have in mind, but anything more than changing a few traces will need to provide significant advantages to warrant a redesign.... :wink:

Can you put the advantages into a concise sentence?

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We EE's are not known for our conciseness!!!

Here's what I'm thinking:
The bar graph (as you pointed out) has only a few basic display modes (40 I think) which are basically a bunch of 1's (lit LEDs) followed by 40-a bunch of 0s. The uppermost lit LED will do something special.

My idea is to only load four of the 9922's once, but load the fifth 9922 (the one with that topmost modulated last LED) repetitively to achieve the desired dimming of the topmost LED. You only reload the other four 9922's as you need to update the overall "value" of the Bar Graph. The advantage is you can write to the one active 9522 at a nominal 5 times rate that you would do with the 40 bit shift register approach.

Also, with the 5-wide shift register approach you can "broadside" load the 40 bits in approximately one-fifth the time it would take you to serially load the 40bit long register. There's a special software technique for doing this, but it relies on having the N-wide shift register to begin with.

Yes, I realize your main background is as a machinist/mechanical designer. But you are apparently a Lifelong Learner with few excuses. I thought you may have had some FPGA exposure along the way. I was going to suggest a possible FPGA alternative to the 9922's. But no big deal. We all have different approaches to our projects, these approaches are always inherently rooted in our acquired skill and knowledge sets. In other words, you use what you have and you run with it! I think you've figured this out already on your own.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck-Rowst wrote:
My idea is to only load four of the 9922's once, but load the fifth 9922 (the one with that topmost modulated last LED) repetitively to achieve the desired dimming of the topmost LED.
First, let me say thank you for your interest in my project!

I like your idea, and I have some concerns.

When I was working on a purely software solution to the overall dimming (in conjunction with the top lit segment), I tried many things in the simulator to speed things up. One thing I found was that it was cumbersome to separate the 40 bits into 5 bytes. Overall, it was faster to just spit out 40 bits in a loop, even though the loop adds 4 clock cycles each pass to monitor the count.

Your suggestion would also require converting 40 bits to 5 bytes.

By going to the ATtiny26's hardware PWM for the overall dimming, speed is no longer a factor. Unless I am missing something, I understand that your suggestion is an attempt to make things faster.

However, is also sounds like you are familiar with some coding trick that may make the 40 bit to 5 byte conversion more efficient, which piques my interest (as a Lifelong Learner :wink: ).

Chuck-Rowst wrote:
you use what you have and you run with it!
Yeah... to a hammer, everything looks like a nail. :wink:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, my scheme would still use the ATTiny's PWM to control overall brightness via the Output Enable inputs of the 9922's.

In your scheme how would you get that "special" dimming for the topmost lit LED you described? I got the idea you would have to reload the complete 40 bits of the shift register continuously with the same pattern except for the topmost LED bit which would be 0 or 1 in a sequence that would give you the desired brightness of that topmost LED.

In my scheme I would not "calculate" the bit pattern(S) to be shifted into the 9922's. Instead, I would create a "hard-wired" table containing all possible patterns that could be shifted to the 9922's. You figure out the contents of this table during the design process and it is stored as part of the program in the ATTiny's Flash. When you load the 9922's, you simply read successive table entries and transfer them to the GPIO data lines and "click" the common 9922 clock line for each transfer.

The table is created in C-language a similar way that you make a normal N x M array. E.g. "unsigned char Table[n][m];" Except ypou include the keyword "const" in the declaration and assign the desired "hard" values to the array in the same statement. This is how we make a "look-up table" ("LUT") in C. Here's an example:

( "TableX" is the name I've chosen for this example, you would pick your own name like you do with any variable declaration.)

const unsigned char TableX[3][4]=
{
{0,1,2,3},
{10,11,12,13},
{20,21,22,23}
};

I've used decimal values in the example, but for bit patterns like you would need for your application you would probably use hex or binary bit-field values for ease of composition and debugging. Your table would probably be considerably longer - probably 40 rows at least.

To speed things up a litle faster you would choose 5 GPIO bits in the same output port for the data lines. That way you simply read a value from the table and write it directly to that GPIO port as a single byte value.

By the way this is a standard programming trick in many languages. To pick up a speed advantage where you have some type of limited or repetitive calculation or bit manipulation, you devise some sort of clever look-up table which holds all possible "answers" and merely "pop" them out of the table according to the same parameters you would have used to calculate them in the CPU. I've used this technique in countless programs, for various reasons - speed advantage being the main one.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck-Rowst wrote:
I got the idea you would have to reload the complete 40 bits of the shift register continuously with the same pattern except for the topmost LED bit which would be 0 or 1 in a sequence that would give you the desired brightness of that topmost LED.
Yes, this is what I planned.
Chuck-Rowst wrote:
In my scheme I would not "calculate" the bit pattern(S) to be shifted into the 9922's. Instead, I would create a "hard-wired" table containing all possible patterns that could be shifted to the 9922's.
AHA! I love it! :wink: :shock:

Some time ago (my memory is vague), I had a project where I considered solving a problem in a similar way (without a micro) using a 27C256 EPROM.

Chuck-Rowst wrote:
You figure out the contents of this table during the design process and it is stored as part of the program in the ATTiny's Flash.
In this case (as I attempted to point out above), I don't need the extra speed. On the other hand, many of the choices made in this design were made because it would teach me something new. So I am interested in learning this. :) I think this will be useful for many things.
Chuck-Rowst wrote:
To speed things up a little faster you would choose 5 GPIO bits in the same output port for the data lines. That way you simply read a value from the table and write it directly to that GPIO port as a single byte value.
This might be a little tricky since the ATtiny26 has limitations as to what pins are used for some functions. But as I see it, this is only a minor inconvenience.
Chuck-Rowst wrote:
By the way this is a standard programming trick
Yes, now that you tell me about it, I am familiar with it. But because of my inexperience with C (and probably other reasons), it never dawned on me. Besides, I wouldn't have known how to implement it without your brief tutorial above. :wink: I will be studying it to make sure I get it all. :wink:

Cris

P.S. Sorry for taking so long to respond, I had to attend to things that took me away from my computer.

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay... I have changed to the following pinout to incorporate the look up table method that Chuck proposed:

//==============================================================================
//                                                                             |
//                          ATtiny 26 Microcontroller                          |
//                                                                             |
//                                 +----v----+                                 |
//        MAX7219 Load   MOSI/PB0 -| 1    20 |- PA0/ADC0  Analog Dimmer Input  |
//    MAX7219 Data Out   MISO/PB1 -| 2    19 |- PA1/ADC1  PCA9922 Load         |
//        Serial Clock    SCK/PB2 -| 3    18 |- PA2/ADC2  PCA9922 Data Out A   |
//    BarGraph Dim Out   OC1B/PB3 -| 4    17 |- PA3/AREF  Capacitor to ground  |
//                            VCC -| 5    16 |- GND                            |
//                            GND -| 6    15 |- AVCC                           |
//      16 mHz crystal  XTAL1/PB4 -| 7    14 |- PA4/ADC3  PCA9922 Data Out B   |
//      16 mHz crystal  XTAL2/PB5 -| 8    13 |- PA5/ADC4  PCA9922 Data Out C   |
//  Crank Sensor Input   INT0/PB6 -| 9    12 |- PA6/ADC5  PCA9922 Data Out D   |
//               Reset  RESET/PB7 -| 10   11 |- PA7/ADC6  PCA9922 Data Out E   |
//                                 +---------+                                 |
//                                                                             |
//==============================================================================

The PCB layout is also updated. I put together the look up table, too. It took some head scratching since I had not done anything like this before, so I had to restart the thought process a few times. :?

Plus, since I'm using ImageCraft, the syntax of Chuck's example needed a little tweak but here is my table:

__flash unsigned char TablePORTA[37][8]=
{
  {0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80},

  {0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80},
  {0x04, 0x04, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80},
  {0x04, 0x04, 0x04, 0x00, 0x00, 0x80, 0x80, 0x80},
  {0x04, 0x04, 0x04, 0x04, 0x00, 0x80, 0x80, 0x80},
  {0x04, 0x04, 0x04, 0x04, 0x04, 0x80, 0x80, 0x80},
  {0x04, 0x04, 0x04, 0x04, 0x04, 0x84, 0x80, 0x80},
  {0x04, 0x04, 0x04, 0x04, 0x04, 0x84, 0x84, 0x80},
  {0x04, 0x04, 0x04, 0x04, 0x04, 0x84, 0x84, 0x84},

  {0x14, 0x04, 0x04, 0x04, 0x04, 0x84, 0x84, 0x84},
  {0x14, 0x14, 0x04, 0x04, 0x04, 0x84, 0x84, 0x84},
  {0x14, 0x14, 0x14, 0x04, 0x04, 0x84, 0x84, 0x84},
  {0x14, 0x14, 0x14, 0x14, 0x04, 0x84, 0x84, 0x84},
  {0x14, 0x14, 0x14, 0x14, 0x14, 0x84, 0x84, 0x84},
  {0x14, 0x14, 0x14, 0x14, 0x14, 0x94, 0x84, 0x84},
  {0x14, 0x14, 0x14, 0x14, 0x14, 0x94, 0x94, 0x84},
  {0x14, 0x14, 0x14, 0x14, 0x14, 0x94, 0x94, 0x94},

  {0x34, 0x14, 0x14, 0x14, 0x14, 0x94, 0x94, 0x94},
  {0x34, 0x34, 0x14, 0x14, 0x14, 0x94, 0x94, 0x94},
  {0x34, 0x34, 0x34, 0x14, 0x14, 0x94, 0x94, 0x94},
  {0x34, 0x34, 0x34, 0x34, 0x14, 0x94, 0x94, 0x94},
  {0x34, 0x34, 0x34, 0x34, 0x34, 0x94, 0x94, 0x94},
  {0x34, 0x34, 0x34, 0x34, 0x34, 0xb4, 0x94, 0x94},
  {0x34, 0x34, 0x34, 0x34, 0x34, 0xb4, 0xb4, 0x94},
  {0x34, 0x34, 0x34, 0x34, 0x34, 0xb4, 0xb4, 0xb4},

  {0x74, 0x34, 0x34, 0x34, 0x34, 0xb4, 0xb4, 0xb4},
  {0x74, 0x74, 0x34, 0x34, 0x34, 0xb4, 0xb4, 0xb4},
  {0x74, 0x74, 0x74, 0x34, 0x34, 0xb4, 0xb4, 0xb4},
  {0x74, 0x74, 0x74, 0x74, 0x34, 0xb4, 0xb4, 0xb4},
  {0x74, 0x74, 0x74, 0x74, 0x74, 0xb4, 0xb4, 0xb4},
  {0x74, 0x74, 0x74, 0x74, 0x74, 0xf4, 0xb4, 0xb4},
  {0x74, 0x74, 0x74, 0x74, 0x74, 0xf4, 0xf4, 0xb4},
  {0x74, 0x74, 0x74, 0x74, 0x74, 0xf4, 0xf4, 0xf4},

  {0xf4, 0x74, 0x74, 0x74, 0x74, 0xf4, 0xf4, 0xf4},
  {0xf4, 0xf4, 0x74, 0x74, 0x74, 0xf4, 0xf4, 0xf4},
  {0xf4, 0xf4, 0xf4, 0x74, 0x74, 0xf4, 0xf4, 0xf4},
  {0xf4, 0xf4, 0xf4, 0xf4, 0x74, 0xf4, 0xf4, 0xf4},
}; 

The PCA9922 shift registers are used to drive the 36 bar code segments plus three LEDs used to illuminate the "RPM" nomenclature. So the top three outputs of the last shift register are always on (and one output isn't used).

Chuck-Rowst wrote:
My idea is to only load four of the 9922's once, but load the fifth 9922 (the one with that topmost modulated last LED) repetitively to achieve the desired dimming of the topmost LED. You only reload the other four 9922's as you need to update the overall "value" of the Bar Graph.
With the "5 wide" approach, isn't it just as fast to load all 5 since it is done in parallel?

Plus, wouldn't it be faster because you don't have to figure out which four to avoid or if they should be avoided?

EDIT: Oh, I also just realized:

Chuck-Rowst wrote:
drive the 9922's as five parallel 8-bit shift registers - that is with 5 separate data lines, one common clock and one common load line.
With the common load line, I couldn't do one at a time if I wanted.... :shock:

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
With the common load line, I couldn't do one at a time if I wanted....

Do you care the rest just get the same data over and over again.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sparrow2 wrote:
Do you care the rest just get the same data over and over again.
Since the program will need to be able to load all shift registers at once anyway (because there will be times the data won't be the same), it turns out to be easier. :wink: So no, don't care....

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK,

You are correct, with the parallel load topology there is no advantage to loading just one 9922. My original fuzzy thinking involved some sort of individual 9922 enabling function - this is NOT needed, nor is it beneficial.

Next issue: Do you envision some sort of "interference" between the overall PWM dimming applied to the Output Enables of the 9922's? Don't you have to synchronize the loading of the top-most 9922 with the PWM so that the special top-most PWMing occurs while the 9522 are actually driving the LEDs? If you load the top-most 9522 while the chain is in it "dark time" (i.e. PWM is off) you will never see the augmentive dimming action on the topmost LED, or you will see it in some "choppy" manner. I think this would have been the case with your original 40-bit serial version as well. Have you thought about this?

The solution would be to somehow co-ordinate the 9522 loading with the PWM dimming signal. You would probably do that using one of the interrupts associated with the ATTiny counter that generates the dimming PWM.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lets say you want to do 4 brightnesses, so need to redraw the led tower 280Hz, every 3.5ms, and the top bit is a 1 for 0,1,2, or 3 passes depending on brightness.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck-Rowst wrote:
Do you envision some sort of "interference" between the overall PWM dimming applied to the Output Enables of the 9922's? Don't you have to synchronize the loading of the top-most 9922 with the PWM so that the special top-most PWMing occurs while the 9522 are actually driving the LEDs?
Although I have never used PCA9922s, I am assuming Output Enable is independent of the input (as it is in every other chip I have used). The data sheet doesn't call it a Chip Enable, so the only interference I expect is due to aliasing of the two PWM frequencies. Also there is a special sequence of toggling /OE, LE, and CLK to enter an 'error detection' mode that will need to be avoided.

If my assumption is wrong and the output enable has an effect on the input, I'll switch to a different chip. On Semiconductor has the CAT4008 with the same pinout and no 'error detection' mode, and the data sheet is clearer that the /OE doesn't effect input.

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
Lets say you want to do 4 brightnesses, so need to redraw the led tower 280Hz, every 3.5ms, and the top bit is a 1 for 0,1,2, or 3 passes depending on brightness.
Yes, just what I plan. With the only difference being, I will have 8 brightnesses with a refresh freq of 640 Hz. :wink:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK,

The "interference" I refer to is what you are calling "aliasing", not any logical loading/clocking mechanism within the 9922s. (I have never used these either.)

What is the frequency/period and duty cycle range of the overall PWM brightness signal you will be applying to the 9922 Output Enables?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck-Rowst wrote:
What is the frequency/period and duty cycle range of the overall PWM brightness signal you will be applying to the 9922 Output Enables?
1kHz PWM, 30% - 100% duty cycle.

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK,

When your 1KHz PWM is running at less than 100% duty cycle you will have a "beat frequency" effect between it ( the PWM dimming control) and the rate (640Hz) at which you update the topmost segment of the bar graph. I can't say exactly what visual effect you will see when this happens. The nominal beat freqency is 360Hz which is well beyond the flicker frequency detection of human vision. Still, I have had visible effects caused by various secondary effects in similar types of stroboscopic situations as what you are doing here with the bar graph PWMing. E.g. beating of harmonics of the fundamental switching frequencies.

When you get the bar graph working, you should slowly adjust the PWM through its entire range of 30% to 99% (100% is not an issue because it represents a steady-on case). If you see any ill effects, there are a few software remedies which will likely correct the sitauation. Flicker effects are typically most visible in low-light situations.

By the way, in my experience PWMing a LED at 30% does not have much of a visual dimming effect. I'm not sure what you expected lighting conditions are with this instrument. However, in "dark room" conditions (e.g. an office with the ceiling lights turned off, but light coming from other instruments, desk lamps, etc.), I have found that PWMs above around 10% have a tendency to "blind" your vision because of their perceived brightness. So, you may find in your situation that you really need to run the PWM down into that 10% range for a "comfortable" display. I'd imagine that would occur during night flying in your case, but again I don't know your expected operational situations.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aeroHAWK wrote:
1kHz PWM, 30% - 100% duty cycle.
Chuck-Rowst wrote:
I have had visible effects caused by various secondary effects in similar types of stroboscopic situations
Chuck-Rowst wrote:
you may find in your situation that you really need to run the PWM down into that 10% range for a "comfortable" display
Thanks Chuck! Since I have not done this before, I plan to experiment to find the best solution. I merely guessed at what I thought would be a starting place. Thank you for your additional input, it is very helpful. :wink:

If I run into flicker problems, my plan has been to increase the PWM frequency (say... to maybe 4kHz). But if there are still issues... as you say, I will likely need to synchronize the two PWMs.

I will receive the PCBs on Monday. So right now, I'm stuck at calculating the current-set resistors for the PCA9922s. I've scoured the datasheet and cannot find ANYTHING! :shock: It's not a very good data sheet. :?

I have been working on the mechanical parts. I have finished the lens/window and am starting to CNC the bezel (I've got the programming done).

Next week I should have more pictures as the parts come together. :D

Cris

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. Antoine de Saint-Exupery (1900 - 1944)

Pages