Variable pwm dimming cycle method? Or something like that?

I’ve been trying to understand this stuff and i can do quite a bit more than i could before, but my code is getting bulky and repeats itself a lot. Like for PWM control of LED dimming, i have 6 different methods (i think thats the word!), 2 each (going up and going down) for 3 different channels. While that works fine, editing the code is more time consuming than it needs to be.

What i started trying to do instead was make one robust method (again, i think this is its name) that can go either up or down, has a specific duration, end, start points that i define when i call it and assigns the right channel of the led driver. However, i am obviously still not quite mentally capable of thinking in code, and what i thought should be simple is not. Everything except picking the channel works…

public static void Ramp(byte start, byte end, sbyte dir, int dur) 
// Here i would like one more field  ..., SomeTypeOfInput color)
     {
          sbyte diff = (sbyte)System.Math.Abs(start - end);
          byte x = start;
          int durStep = (int)((dur * TimeSpan.TicksPerMinute) / (diff * TimeSpan.TicksPerMillisecond)); 
          // Calculate sleep time from dur in minutes / number of steps
          for (; start != end; start = (byte)(start + dir))
          {
               color.Set(5000, x); 
               // SomeTypeOfInput would change this color variable between say blue, red and green
               x = (byte)(x + dir);
               Thread.Sleep(durStep);
          }
     }

Its probably something obvious too, and i’ll feel bad once i read it and see how dumb i must be =D.

I am sorry I read the post twice and I am not sure if you are telling us what is going on or you are asking a question :slight_smile:

Maybe i was doing neither well.

Basically i want to know if there is something i can use to change the color word (in color.Set(5000, x)) to be blue or red or green (or whatever) depending on the way i call that whole deal up, instead of having 3 separate versions of it with red.Set, blue.Set and green.Set already written in the code. I tried having it as a string color, then color.Set() but it would complain that color doesn’t have a .Set or that color doesn’t exist etc.

So yeah, is there something i can use instead of having it hard coded to make color a variable?

@ Gorgok, I think you should show your complete program, that way it might become obvious as to what you are trying to accomplish. Just a suggestion…

Trust me, my complete program would make things much less clear =D. Many of the solutions to problems i have are the first ones i found and then just kept because it worked, and some i ‘improved’ but it might have only have convoluted the issue more. But i can try and add a little more of relevant code…

        static void Check_Time()
        {
            long startHB = 23 * TimeSpan.TicksPerHour;
            long startMB = 20 * TimeSpan.TicksPerMinute;
            long startTimeBlue = TimeSpan.TicksPerDay - startHB - startMB;
            long startHW = 23 * TimeSpan.TicksPerHour;
            long startMW = 25 * TimeSpan.TicksPerMinute;
            long startTimeWhite = TimeSpan.TicksPerDay - startHW - startMW;
            DateTime midnight = new DateTime(2011, 9, 1, 0, 0, 0);
            bool doneBlueUp = false;
            bool doneWhiteUp = false;
            while (true)
            {
                DateTime currentTime = DateTime.Now;
                long ticksToGo = midnight.Ticks - currentTime.Ticks;
                for (; ticksToGo <= 0; ticksToGo = ticksToGo + TimeSpan.TicksPerDay) // Amazingly this works so well i forgot that it was here (and that the start date for midnight is 9/1)...
                {
                    midnight = midnight.AddDays(1);
                    //Debug.Print(TimeSpan.FromTicks(ticksToGo).ToString());
                    doneBlueUp = false;
                    doneWhiteUp = false;
                }                      
                if (ticksToGo <= startTimeBlue && ticksToGo > endTimeBlue + blueDurr && ticksToGo > 0 && doneBlueUp == false)
                {
                    //Debug.Print(TimeSpan.FromTicks(TimeSpan.TicksPerDay - ticksToGo).ToString() + " Ramping up blue.");
                    Thread RampUpBlue = new Thread(Ramp_Up_Blue);
                    RampUpBlue.Start();
                    doneBlueUp = true;
                }
                if (ticksToGo <= startTimeWhite && ticksToGo > endTimeWhite + whiteDurr && ticksToGo > 0 && doneWhiteUp == false)
                {
                    //Debug.Print(TimeSpan.FromTicks(TimeSpan.TicksPerDay - ticksToGo).ToString() + " Ramping up white.");
                    Thread RampUpWhite = new Thread(Ramp_Up_White);
                    RampUpWhite.Start();
                    doneWhiteUp = true;
                }

This is one of my main threads to keep track of time and then turn on/off the lights with individual ramp cycles. It starts new threads for the actual cycles, but each of those is its own separate part in the program, instead of the one generic one i am trying to make. With 3 different colors and 2 directions that makes 6 sets of practically identical code (or even 3 since the code in this post seems to work up or down just fine) but its still more cumbersome than 1 code block… These are the current setups:


        public static void Ramp_Up_Blue()
        {
            int durr = (int) (blueDurr / (TimeSpan.TicksPerMillisecond * maxBlue));
            Debug.Print(durr.ToString());
            for (byte b = 0; b < maxBlue; b++)
            {
                blue.Set(5000, b);
                Thread.Sleep(durr);
            }
        }
        public static void Ramp_Up_White()
        {
            int durr = (int)(whiteDurr / (TimeSpan.TicksPerMillisecond * maxWhite));
            for (byte w = 0; w < maxWhite; w++)
            {
                white.Set(5000, w);
                Thread.Sleep(durr);
            }
        }

Its a simpler style of writing it, but still annoying to have multiple versions which just change the color or direction… Copy and pasting every change i make 6 times is annoying. If its still confusing i can try again…

I think i may have gotten a clue as to which way i am supposed to be going from another source. But i haven’t quite nailed it yet.

Instead of that long code that i gave previously, much of which is useless for this problem, i made a separate program just to solve this issue. This stripped down code is without any of the timing things or temp probes and such (which i know work just fine). Here is all i think you would need to run this pwm cycle. As it sits it should just run from 55% to 0% output in 2 minutes, then quit.


    public class Program
    {
        static PWM blue1 = new PWM((PWM.Pin)FEZ_Pin.PWM.Di10);
        static PWM blue2 = new PWM((PWM.Pin)FEZ_Pin.PWM.Di9);
        static PWM white = new PWM((PWM.Pin)FEZ_Pin.PWM.Di8);
        static object[] color = { blue1, blue2, white };
        static sbyte Up = 1;
        static sbyte Down = -1;

        public static void Main()
        {
            Thread rampy = new Thread(() => Ramp(55, 0, Down, 2, 0));
            rampy.Start();
        }

        static void Ramp(byte start, byte end, sbyte dir, int dur, byte c)
        {
            sbyte diff = (sbyte)System.Math.Abs(start - end);
            byte x = start;
            int durStep = (int)((dur * TimeSpan.TicksPerMinute) / (diff * TimeSpan.TicksPerMillisecond)); 
            for (; start != end; start = (byte)(start + dir))
            {
                color[c].Set(5000, x);
                x = (byte)(x + dir);
                Thread.Sleep(durStep);
            }
        }
    }

But that still throws an error:
Error 1 ‘object’ does not contain a definition for ‘Set’ and no extension method ‘Set’ accepting a first argument of type ‘object’ could be found (are you missing a using directive or an assembly reference?)

Am i even going in the right direction? Hopefully this lightened version gets you guys some better clue as to what i am trying to do =D. I know reading other peoples jibba jabba is difficult enough if you sorta know what it should do…

color is an array of objects not PWM. object does not have a Set method.

change this:

static object[] color = { blue1, blue2, white };

to this:

static PWM[] color = { blue1, blue2, white };

See i knew it would make me feel stupid once it was pointed out :-[. The same source had another way to code this, so instead of having to remember which index the color in question was i could write the actual color as i call the code up. It changed just:

     Thread rampy = new Thread(() => Ramp(55, 5, Down, 2, white));
     ...
     static void Ramp(byte start, byte end, sbyte dir, int dur, PWM color)
     ...
     color.Set(5000, x);

Yay. Thanks. Now i need to code some more until i hit the next brain fart. ;D