Pages: 1 2 [3]   Go Down
Author Topic: Optimization of code for maximum speed, very specific project.  (Read 3799 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your sketch can't keep up,   you could always try moving to a country with 50 Hz electricity.    Like, for example,  New Zealand.    Or one half of Japan ( I forget which half ).

That is thinking outside the box. smiley
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
 tickCounter += TIMER_CYCLE_COUNT;
You are chasing a wrong direction here, I think.   You should want to redefined a "tick" so that tick = CycleTime/BrightnessLevels (or, for 8.3ms and 256 brightness levels, about 32 us.)  That means that the clock always ticks by 1 in your ISR.   The actual clock or instruction rate of the cpu ought to be irrelevant.  Sure, at some level it's the limiting factor, but you want to have your code running in a way that it's so much faster than the problem, that there's no actual dependency...

Looking at the code generated when tick and powerDelay are both uint8_t, it looks to be about 480 instructions.  32 us is about 512 instructions.  Now, every ISR execution doesn't execute all the instructions, and all the instructions are not one cycle, so it's hard to tell whether this would actually be fast enough.  It does indicate (to me) a couple of things:
1) It would be pretty close; certainly close enough to worry about.
2) wider math (32bit tick and powerDelay) probably isn't going to work at all. (1100 instructions!  (odd that it isn't more.))
3) going to, say, 100 ticks/halfcycle instead of 256 ticks/halfcycle, would probably give you all the breathing room you need.

I see what you are getting at now, thanks.  I didn't understand how you expected me to put values of 256 or more into a byte.  I'll have to see what I can to rearrange this.  The latest code is attached.

* XmasLightControllerForVixenSSRs.ino (55.83 KB - downloaded 11 times.)
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Similarly, since serial messages are only occasional and not more than every 50ms, while AC cycles happen every 1/120 s (8.3ms),
get rid your calculations of powerDelay[] in ZeroCrossDetected and move them into the serial receive code.

Done. I only update the powerDelay values after I have read in a new set of channel values, see the updatePowerDelayValues() in the code.  I'm turning the interrupts off during this process and I'm not sure if that is a good or bad idea.

I asked this next question earlier and I think I've seen to conflicting "answers" can someone give me the straight poop (I've changed the code this is no longer true but I would like to know)?  "Given that the powerDelay array is only assigned values inside one of the ISRs and only read from the other ISR and the ISRs are not nested:  Can I remove the volatile attribute from the declaration?  That should give me a few extra cycles in speed shouldn't it?"

Quote
You can.  You shouldn't.  It won't make any difference...

In each ISR each element of powerDelay is accessed just once (read in one ISR; written in the other).  Removing volatile only helps when there are multiple accesses.  Removing volatile eliminates redundant loads from memory but there aren't any.

and

Quote
This would get better if powerDelay isn't volatile, and if it's smaller, but it still doesn't need to happen every half-cycle.
Or you could look at making the copy into a memcpy() call, which would "short circuit" the (correct) volatile declarations.

Maybe I'm just reading more into the second one than is really there.

 
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay, random mode, reading data from Vixen, zero cross detection and setting the powerDelay values all work as long as I set the prescaler to 8 and TIMER_CYCLE_COUNT to 100. However in Vixen mode the channels don't turn on until the channel values reach about 128 out of the 255 possible.  I had a lot of really stupid bugs in there.  Working on this stuff when I'm very tired has proven to be a bad choice, lol.

Now I just have to figure out why the light don't come on until around 128 and they don't seem to change intensity.  Attached is the latest code.

* XmasLightControllerForVixenSSRs.ino (54.73 KB - downloaded 9 times.)
« Last Edit: April 05, 2013, 08:41:13 pm by zparticle » Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay the code is now working! Thanks for the help everyone.  Boy was I going about this the wrong way.  Code is attached.

* XmasLightControllerForVixenSSRs.ino (33.53 KB - downloaded 17 times.)
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 137
Posts: 6805
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Working?!  Already!   Excellent!

I was fun to help with a well-defined, well-expressed problem with existing well-commented code, and someone who was responsive to the suggestions made.  MUCH better than all the "Is a MEGA too slow to handle 32 channels of dimming?  Do I need a Due?" questions that result in an extended "discussion" of 8 vs 32 bit cpus, during which the original poster disappears...
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Working?!  Already!   Excellent!

I was fun to help with a well-defined, well-expressed problem with existing well-commented code, and someone who was responsive to the suggestions made.  MUCH better than all the "Is a MEGA too slow to handle 32 channels of dimming?  Do I need a Due?" questions that result in an extended "discussion" of 8 vs 32 bit cpus, during which the original poster disappears...


LOL, yeah that kind of topic can be a bummer.  smiley
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is a new video. It may take a little while for youtube to process it and make it live. This shows the project basically completed and running through some effects fed to it by Vixen. Finding some interesting side effects of the relay boards. Most interesting is that they seem to be leaking enough power to dimly light a string of LEDs. It isn't a code problem, there is definitely power leaking through the relays. You don't notice it until you connect a string of LEDs, incandescent lights don't have the issue. I wonder if replacing the relays with random cross relays is showing a flaw in the sainsmart board design.

More likely there are resistors on the boards that aren't large enough to keep the power from leaking or the photo decouplers are getting triggered somehow. I've also found an interesting issue with Vixen that I didn't run into before. If none of the channel values change from one frame to the next frame, no data is sent. So my suggestion is to use one of the channels to make sure something always changes so all of the channel data will get sent every frame.

http://youtu.be/AGeSo57uV1I
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 227
Posts: 6639
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Most interesting is that they seem to be leaking enough power to dimly light a string of LEDs. It isn't a code problem, there is definitely power leaking through the relays. You don't notice it until you connect a string of LEDs, incandescent lights don't have the issue. I wonder if replacing the relays with random cross relays is showing a flaw in the sainsmart board design.

SSRs leak a small amount of current, you will find how much on the datasheet for the SSR. For switching low currents (0.9A or less), there are power opto triacs available with virtually no leakage.

btw if you ever want to increase the number of channels or get more levels of brightness, there is a way to make the critical code (in particular the ISR) faster. Use two arrays of (channel, ticks) pairs. Each entry in the array says which channel should be turned on next, and how many ticks to wait since the last channel. So the ISR only needs to consider one or a few channels each time, except when you have a large number of channels set to the same brightness. The reason for having 2 arrays is that the code in loop() can be setting up one of them while the ISR works from the other.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Newbie
*
Karma: 1
Posts: 41
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, okay. Thanks I didn't realize that.  It gives me an idea for how to "fix" it though.
Logged

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