Jump to content

C# Usage Questions


mjr

Recommended Posts

i'm wondering if anyone has any advice on the correct way to use DOF at the C# level.  I've been working on building an LEDWiz compatible device with a microcontroller, and I've gotten to the point of testing it with DOF.  It's mostly working, but I'm getting some odd behavior that seems to be on the DOF side.  I'm wondering if I'm just doing something wrong.

 

My basic test program is really simple.  I'm creating a Cabinet object, a Pinball object, and an LedWiz object, using LedWiz.GetLedwizNumbers() to find the unit number to pass to the LedWiz constructor.  I call Cabinet.init() and LedWiz.Init() to initialize the respective instances.  Once this is all set up, I'm just setting the brightness levels for three LEDs by setting the respective LedWiz.Outputs[n].Value properties.  I then call LedWiz.Update() to send the changes to the device.

 

This *kind of* works, but is strangely flaky in a number of respects.  I've done lots of instrumentation on the device side, and as far as I can tell, DOF itself is the source of the flaky behavior.

 

The first problem is that I seem to need to put in a Thread.Sleep() after initializing everything, with a minimum delay of about 250 ms.  If I don't do that, the updates don't happen.  I discovered this by tracing through code in the debugger, and getting different behavior depending on whether I let it run straight through or step through the code manually, which I eventually figured out was due to timing.  Is there a specific requirement to wait for the device worker thread to start up?  I can't find anything in the documentation about this.

 

The second problem is that DOF doesn't always seem to interpret intensity level changes correctly.  If I set my R-G-B outputs to, say, 127 0 0, the device will get a PBA that sets levels to 24 48 48, which are the LEDWiz equivalents of 127 255 255.  If I use strictly 0 and 255 levels, I get the correct PBA.  I think DOF is getting confused about on/off state changes vs intensity state changes.  

 

I've looked at the source code a little but I haven't really puzzled out the conceptual framework by which DOF's ledwiz.cs figures the changes.  I notice that it keeps a separate notion of on/off vs intensity, and that it tries to be smart about calculating dettas to minimize hardware update messages; my working theory is that it conflates intensity 0 with 'off', so it doesn't internally update the intensity of an output that's already marked as 'off' in terms of on/off state when it gets a 0 setting - but it then flushes the intensity state via a PBA, so it sends out the default 48 ("full on") at that point.  This seems consistent with the observed behavior, but I haven't pinpointed the error in the ledwiz.cs code (if there is in fact an error).

 

Or maybe it's my error in how I'm interpreting the PBA/SBA messages.  My read is that a PBA is supposed to be a full state dump, including on/off state, so it replaces a previous SBA.  But maybe the SBA on/off settings are meant to be orthogonal to the PBA intensity levels - i .e., an output that was turned off with SBA is meant to remain off even if set to a non-zero intensity with PBA.  The LEDWiz itself is practically undocumented and I haven't tested this theory against the real thing.

 

Intensity settings that contain no 0 values seem to work properly - e.g., 127 1 1 works, while 127 0 0 doesn't.  Changes that are *only* 0 and 255 values work - e.g., 255 0 0 works.  The problem seems to be with mixing 0 and values from 1-255.

 

Of course, DOF seems to work great in actual games, so I'm wondering if I'm doing the wrong thing by setting the LedWiz.Outputs[n].Value properties directly.  Is there a higher level interface I should be using instead to ensure that the state changes are properly calculated?  Again, the documentation doesn't seem to suggest that there's anything wrong with my approach, but empirically it's not working quite the way it should.

 

Here's my C# program for those who want the gory details.  I trimmed out the error checking to keep it short and simple...

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DirectOutput;
using DirectOutput.Cab;
using DirectOutput.Cab.Out;
using DirectOutput.Cab.Out.LW;
using System.Runtime.InteropServices;
 
namespace DirectOutputTest
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> ledWizList = LedWiz.GetLedwizNumbers();
 
            byte r = 1, g = 1, b = 48;
            if (args.Length >= 3)
            {
                if (!byte.TryParse(args[0], out r) || !byte.TryParse(args[1], out g) || !byte.TryParse(args[2], out g)
                    r = g = b = 1;
            }
 
            Cabinet cab = new Cabinet(ledWizList[0]);
            cab.Init(new Pinball());
            LedWiz lw = new LedWiz(unitNo);
            lw.Init(cab);
            OutputList outs = lw.Outputs;
 
            Thread.Sleep(1000);  // seems necessary to let the worker thread get going
 
            outs[0].Value = r;
            outs[1].Value = g;
            outs[2].Value = b;
 
            lw.Update();
        }
    } 
}
Link to comment
Share on other sites

Okay, main mystery solved!  I experimented with my actual LedWiz, and it turns out that PBA and SBA states are in fact orthogonal.  So it's perfectly reasonable for DOF to treat an Outputs.Value[n] = 0 setting as an SBA off and PBA 48 (full brightness).  I think that accounts for all of the behavior I was seeing with different combinations of brightness levels.

 

I'm still curious about the startup timing issue.  If there's something I'm doing wrong in creating or initializing the objects (e.g., there's some other object I should be creating in addition to or instead of the Cabinet, Pinball, and LedWiz objects), I'd appreciate any pointers to the right setup procedure.  Inserting the Thread.Sleep seems to do the trick, but that's obviously a hack, and it makes me suspicious that there's some deeper problem I need to fix.

Link to comment
Share on other sites

  • Content Provider

Hi

I'm alway surprised how much effort people invest in creating ledwiz compatible devices. If were to create hardware I'd rather go for semthing with more pwm levels and even more important with a si plere command structure.

The ledwiz command structure is one thing which gave me a lot of headaches when developing DOF. The 2 commands of the ledwiz have some specific benefits und downsides:

- SBA exutes fast (approx 1ms) but can only turn the output on or off.

- PWA is much slower (approx 20ms if I remember correctly) but can set pwm intensities from 0-49.

The execution time differences are the reason for the complex update behaviour of DOF. DOF tries to use SBA as much as possible and only uses PWA when really needed. I guess the logic in the code for that is quite ok, but maybe there are still some flaws. The random knocker effect which some users experience might be related to some loophole in the code. Had a look alredy, but disnt find a bug.

The start up timming issue is strange. I'm not aware of anything in the code, which would require a delay, but I'll habe to check again in the source code once I get home in 2 days.

Setting the value property of a output object is the correct way for that. There is no higher interface available. The DOF way of doing things would be to add a toy, likely a rgbatoy in your case to the cab object and then to use that toy object to control the outputs.

All the best

Tom

Link to comment
Share on other sites

I'm alway surprised how much effort people invest in creating ledwiz compatible devices. If were to create hardware I'd rather go for semthing with more pwm levels and even more important with a si plere command structure.

 

Yeah, I could go that route as well, as it looks like DOF is nicely set up for adding new device interfaces.  I only started with the LedWiz command interface because there's so little to it and the PC-side software is already there for it.  (I agree that it's not exactly a straightforward interface, but it actually is pretty simple - just the two commands, as far as I can tell.)

 

And I agree that there's no particular economic incentive to create LedWiz clones given that the real thing is pretty reasonably priced.  In my case it's mostly for fun and education.  This is all a side project - the microcontroller's main job is going to be input, but I figured as long as I have a microcontroller with a USB interface in the system, I might as well see if I can get it to handle some light output duties as well.  I actually do need a handful of extra output ports, so if I can get this function to work properly (which I basically have at this point), it saves me having another USB device in the system.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
  • Create New...