Cint no funciona como se esperaba en .NET MF
-
26-10-2019 - |
Pregunta
Tengo algo bastante nota para feder el color de un LED RGB y tengo problemas para obtener los valores deseados.
He despojado este ejemplo hasta un mínimo pero Start
, End
y Steps
todos serán variables ...
Este debería incremento linealmente R
(Uint) de 0 a 255 en 100 pasos. No estoy demasiado preocupado por la precisión aquí, así que realmente no me importa si redondea correctamente o simplemente hace un 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
Esto sale:
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
Como puede ver, la variable TEMP es bastante correcta, lo que permite una ligera imprecisión, pero no puedo ver cuál es la correlación con R
.
Es posible que Cuint simplemente esté leyendo los bits para temperatura y tratando el Double
como un UInt
- Pero si es así, ¿cómo hago que lo convierta correctamente?
(Por cierto, esto se está ejecutando en un netduino), .NET Micro Framework 4.2
Editar: pruebas solicitadas a continuación:
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
Usando el siguiente código ...
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
Me entiendo (en el Dim Temp
línea):
An unhandled exception of type 'System.Exception' occurred in Netduino_VBTest.exe
No hay una excepción interna, pero justo encima de ella en la salida es una excepción de primera oportunidad que supongo que es la causa raíz:
A first chance exception of type 'System.NotImplementedException' occurred in Microsoft.SPOT.Native.dll
Solución
Intente usar convert.touInt32, descritos aquí: http://msdn.microsoft.com/en-us/library/y3569ft9.aspx
En mi .NET 4.0 (no micro) en Windows 7 64bit no estoy viendo lo que está viendo con Cint/Cuint (el mío se convierte correctamente). Este puede ser un error de implementación en NetDuino/Micro Framework ... si lo tuviera, probaría lo anterior para usted.
Otros consejos
Lo que sea que esté sucediendo, le aconsejaría que evite UINTS tanto como pueda (he estado allí). Escribiría el código así:
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
No puedo intentarlo porque no tengo el compilador VB.NET disponible y he escrito el código directamente en entonces, por favor, perdóname si hay algún error de compilación.
Otro enfoque completamente diferente. Como el problema parece ser con dobles y conversiones, podríamos evitar que los dobles solo se resten:
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
Rápido y sucio pero funciona.
Qué tal si
Debug.Print(Test.ToString().Split("."c)(0))
No he resuelto ningún caso de borde, pero esto funcionó en un par de ejemplos que probé. No recomendaría esta solución si esto tendrá que realizarse en un bucle, ya que no funcionará bien, pero podría ser un vacío hasta que pueda encontrar algo mejor.