Frage

I've got something pretty noddy to cross-fade the colour of an RGB led and I'm having problems getting the desired values.

I've stripped this example down to a bare minimum but Start, End and Steps will all be variable...

This should linearly increment R (UInt) from 0 to 255 in 100 steps. I'm not too worried about precision here so I don't really care if it rounds properly or just does a Floor/Ceiling

    Dim Start As UInteger = 0
    Dim [End] As UInteger = 255
    Dim Steps = 100

    For x = 1 To Steps
        Dim Temp = ([End] - Start) / Steps * x + Start
        Dim R = CUInt(Temp)

        Debug.Print(x.ToString & ": Temp: " & Temp.ToString & ", R:" & R.ToString)
        LedR.SetPulse(255, R)
        Threading.Thread.Sleep(20)
    Next

This Outputs:

1: Temp: 2.5500, R:196608
2: Temp: 5.1000, R:327680
3: Temp: 7.6500, R:524288
4: Temp: 10.2000, R:655360
5: Temp: 12.7499, R:851968
...
95: Temp: 242.2488, R:15859712
96: Temp: 244.7988, R:16056320
97: Temp: 247.3488, R:16187392
98: Temp: 249.8988, R:16384000
99: Temp: 252.4488, R:16515072
100: Temp: 254.9988, R:16711680

As you can see, the Temp variable is pretty-much correct, allowing for some slight imprecision but I can't see what the correlation is with R.

It's possible that CUint is simply reading the bits for Temp and treating the Double as a UInt - but if so, how do I get it to convert it correctly?

(Incidentally, this is running on a netduino), .Net Micro Framework 4.2

Edit: Tests requested below:

    Dim Test As Integer = 2
    Debug.Print(Test.ToString)
    Debug.Print(CInt(Test).ToString)
    Debug.Print(CUInt(Test).ToString)

    2
    2
    2

    Dim Test As Double = 2.5
    Debug.Print(Test.ToString)
    Debug.Print(CInt(Test).ToString)
    Debug.Print(CUInt(Test).ToString)

    2.5000
    131072
    131072

Using the following code...

    For x = 0 To Steps
        Dim Temp As Long = ([End] - Start) \ Steps * x + Start
        Dim R = CType(Temp, UInteger)

        Debug.Print(x.ToString & ": Temp: " & Temp.ToString & ", R:" & R.ToString)
        LedR.SetPulse(255, R)
        Threading.Thread.Sleep(20)
    Next

I get (on the Dim Temp line):

An unhandled exception of type 'System.Exception' occurred in Netduino_VBTest.exe

There's no inner exception but just above it in the output is a first chance exception which I'm guessing is the root cause:

A first chance exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll
War es hilfreich?

Lösung

Try using Convert.ToUInt32, outlined here: http://msdn.microsoft.com/en-us/library/y3569ft9.aspx

On my .Net 4.0(not Micro) on Windows 7 64bit I am not seeing what you are seeing with CInt/CUInt (mine converts properly). This may be an implementation error in netduino/the Micro Framework... If I had it I would test the above for you.

Andere Tipps

Whatever is happening I would advise you to avoid UInts as much as you can (I've been there). I would write the code like this:

Dim Start As Integer = 0
Dim [End] As Integer = 255
Dim Steps As Integer = 100

For x As Integer = 1 To Steps
    Dim Temp As Integer = ([End] - Start) \ Steps * x + Start
    LedR.SetPulse(255, CType(Temp,UInteger))
    Threading.Thread.Sleep(20)
Next

I cannot try it because I have not the Vb.Net compiler available and I've wrote the code directly on SO, please forgive me if there are any compilation errors.

Another approach completely different. As the problem looks to be with doubles and conversions we could avoid doubles doing only subtracts:

Dim Start As Integer = 0
Dim [End] As Integer = 255
Dim Increment As Integer = 3
Dim Current as Integer = Start

While Current < End
    Current = Current + Increment
    LedR.SetPulse(255, CType(Current ,UInteger))
    Threading.Thread.Sleep(20)
End While

Quick & Dirty but it works.

How about

Debug.Print(Test.ToString().Split("."c)(0))

I have not worked out any edge-cases, but this worked on a couple of examples I tried. I would not recommend this solution if this will have to be performed in a loop as it will not perform well, but it might be a stop-gap until you can find something better.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top