Davide Rosa Hack
Piccolo esempio per controllare un striscia led RGB via USB, utilizzando la scheda DigiSpark.
In questo esempio vado a rappresentare sulla striscia LED lo stato degli HD , della CPU, della LAN e della batteria del mio NoteBook.
Questo pregetto avra una parte di codice scritta in Arduino e una in Visual Studio Visual Basic.
Materiale usato :
Galleria :
Codice lato DigiUSB:
#define USB_CFG_DEVICE_NAME 'H','D','D','L','e','d'
#define USB_CFG_DEVICE_NAME_LEN 6
#include <DigiUSB.h>
#include <WS2811.h>
#define MAX_LED 20
DEFINE_WS2811_FN(WS2811RGB, PORTB, 1)
RGB_t rgb[MAX_LED]; //1 for 1 pixel
byte byteCNT = 0;
byte byteLID = 0;
byte byteVAR = 0;
byte byteVAG = 0;
byte byteVAB = 0;
void erasePixel(){
for (byte i=0;i<MAX_LED;i++) {
setPixel(i+1,0,0,0);
}
}
void setPixel(byte i, byte r, byte g, byte b){
rgb[i - 1].r=r;
rgb[i - 1].g=g;
rgb[i - 1].b=b;
}
void updatePixels(){
WS2811RGB(rgb, ARRAYLEN(rgb));
}
void setup() {
DigiUSB.begin();
pinMode(1, OUTPUT); //LED on Model A or Pro
erasePixel();
}
void loop() {
if (DigiUSB.available()) {
boolean toComplete = false;
byte lr = DigiUSB.read();
DigiUSB.write(lr);
switch (byteCNT){
case 0:
byteLID = lr;
if (byteLID == 0 || byteLID > MAX_LED) {
erasePixel();
toComplete = true;
} else {
byteCNT ++;
}
break;
case 1:
byteVAR = lr;
byteCNT ++;
break;
case 2:
byteVAG = lr;
byteCNT ++;
break;
case 3:
byteVAB = lr;
setPixel(byteLID, byteVAR, byteVAG, byteVAB);
toComplete = true;
break;
}
if(toComplete){
updatePixels();
byteCNT = 0;
byteLID = 0;
byteVAR = 0;
byteVAG = 0;
byteVAB = 0;
}
} else {
DigiUSB.delay(10);
}
}
Codice lato Visual Studio (sorgenti):
Imports System
Imports LibUsbDotNet
Imports LibUsbDotNet.Info
Imports LibUsbDotNet.Main
Imports System.Collections.ObjectModel
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.ComponentModel
Public Class frmMain
Dim MyUsbDevice As UsbDevice = Nothing
Public Class clsDriver
Dim PerformanceCounterLetturaSec As PerformanceCounter
Dim PerformanceCounterScritturaSec As PerformanceCounter
Public Leggi As Boolean = False
Public Scrivi As Boolean = False
Public Lettura As Single = 0
Public Scrittura As Single = 0
Public IName As String = String.Empty
Public Control As urcLed = Nothing
Public Tipo As enmTipo = enmTipo.none
Public Enum enmTipo
none
Drive
Lan
CPU
Battery
End Enum
Public Sub New(strIName As String, entTipo As enmTipo)
IName = strIName
Tipo = entTipo
Select Case Tipo
Case enmTipo.Battery
'
Case Else
PerformanceCounterLetturaSec = New PerformanceCounter()
CType(PerformanceCounterLetturaSec, ISupportInitialize).BeginInit()
Select Case Tipo
Case enmTipo.Drive
PerformanceCounterLetturaSec.CategoryName = "Disco logico"
PerformanceCounterLetturaSec.CounterName = "Letture disco/sec"
Case enmTipo.Lan
PerformanceCounterLetturaSec.CategoryName = "Interfaccia di rete"
PerformanceCounterLetturaSec.CounterName = "Byte ricevuti/sec"
Case enmTipo.CPU
PerformanceCounterLetturaSec.CategoryName = "Processore"
PerformanceCounterLetturaSec.CounterName = "% Tempo processore"
End Select
PerformanceCounterLetturaSec.MachineName = "."
PerformanceCounterLetturaSec.InstanceName = IName
CType(PerformanceCounterLetturaSec, ISupportInitialize).EndInit()
PerformanceCounterScritturaSec = New PerformanceCounter()
CType(PerformanceCounterScritturaSec, ISupportInitialize).BeginInit()
Select Case Tipo
Case enmTipo.Drive
PerformanceCounterScritturaSec.CategoryName = "Disco logico"
PerformanceCounterScritturaSec.CounterName = "Scritture disco/sec"
Case enmTipo.Lan
PerformanceCounterScritturaSec.CategoryName = "Interfaccia di rete"
PerformanceCounterScritturaSec.CounterName = "Byte inviati/sec"
Case enmTipo.CPU
PerformanceCounterScritturaSec.CategoryName = "Processore"
PerformanceCounterScritturaSec.CounterName = "% Tempo processore" ' "% Tempo inattività "
End Select
PerformanceCounterScritturaSec.MachineName = "."
PerformanceCounterScritturaSec.InstanceName = IName
CType(PerformanceCounterScritturaSec, ISupportInitialize).EndInit()
End Select
End Sub
Public Sub update()
Try
Select Case Tipo
Case enmTipo.Battery
Lettura = 0
Scrittura = 0
If SystemInformation.PowerStatus.PowerLineStatus = PowerLineStatus.Online Then
Lettura = SystemInformation.PowerStatus.BatteryLifePercent * 100
ElseIf SystemInformation.PowerStatus.PowerLineStatus = PowerLineStatus.Offline Then
Scrittura = SystemInformation.PowerStatus.BatteryLifePercent * 100
End If
Case Else
Lettura = CSng(Math.Round(Math.Max(Lettura, PerformanceCounterLetturaSec.NextValue), 1))
Scrittura = CSng(Math.Round(Math.Max(Scrittura, PerformanceCounterScritturaSec.NextValue), 1))
End Select
Catch ex As Exception
Throw
End Try
Leggi = Leggi OrElse Lettura > 0
Scrivi = Scrivi OrElse Scrittura > 0
End Sub
Public Sub show(Luminosita As Integer)
Control.SuspendLayout()
Control.LabelCaption.SuspendLayout()
Control.LabelLeggi.SuspendLayout()
Control.LabelScrivi.SuspendLayout()
Control.BackColor = Color.FromArgb(255, If(Not Leggi AndAlso Scrivi, Luminosita, 0), If(Leggi AndAlso Not Scrivi, Luminosita, 0), If(Leggi AndAlso Scrivi, Luminosita, 0))
Control.LabelCaption.Text = IName
Dim strLeggi As String = String.Empty
Dim strScrivi As String = String.Empty
Select Case Tipo
Case enmTipo.Drive
strLeggi = "L : " & Lettura.ToString
strScrivi = "S : " & Scrittura.ToString
Case enmTipo.Lan
strLeggi = "D : " & Lettura.ToString
strScrivi = "U : " & Scrittura.ToString
Case enmTipo.CPU
strLeggi = Lettura.ToString & " %"
Dim l As Integer = CInt((Luminosita * Lettura) / 100)
Control.BackColor = Color.FromArgb(255, l, l, l)
Control.LabelCaption.Text = "CPU"
Case enmTipo.Battery
If Lettura Then
strLeggi = Lettura.ToString & " %"
End If
If Scrivi Then
strLeggi = Scrittura.ToString & " %"
End If
End Select
Control.LabelCaption.ForeColor = ColorInverter(Control.BackColor)
Control.LabelCaption.BackColor = Control.BackColor
Control.LabelLeggi.ForeColor = ColorInverter(Control.BackColor)
Control.LabelLeggi.BackColor = Control.BackColor
Control.LabelScrivi.ForeColor = ColorInverter(Control.BackColor)
Control.LabelScrivi.BackColor = Control.BackColor
Control.LabelLeggi.Text = strLeggi
Control.LabelScrivi.Text = strScrivi
Control.LabelScrivi.ResumeLayout()
Control.LabelLeggi.ResumeLayout()
Control.LabelCaption.ResumeLayout()
Control.ResumeLayout()
Control.Refresh()
My.Application.DoEvents()
End Sub
Public Sub reset()
Leggi = False
Scrivi = False
Lettura = 0
Scrittura = 0
End Sub
Private Function ColorInverter(ColorX As Color) As Color
Dim clrX As Color = Color.FromArgb(ColorX.A, InCo(ColorX.R), InCo(ColorX.G), InCo(ColorX.B))
If Math.Max(clrX.ToArgb(), ColorX.ToArgb()) - Math.Min(clrX.ToArgb(), ColorX.ToArgb()) < 197380 Then
clrX = Color.Black
End If
Return clrX
End Function
Private Function InCo(ByVal intX As Integer) As Integer
Return 127 + (128 - intX)
End Function
Public Overrides Function Equals(obj As Object) As Boolean
If obj Is Nothing OrElse Not Me.GetType().Equals(obj.GetType()) Then
Return False
Else
Return IName.Equals(DirectCast(obj, clsDriver).IName)
End If
End Function
End Class
Dim lstDrivers As List(Of clsDriver)
Private Sub TimerLeggiValori_Tick(sender As Object, e As EventArgs) Handles TimerLeggiValori.Tick
For intX As Integer = 0 To lstDrivers.Count - 1
Try
lstDrivers(intX).update()
Catch ex As Exception
addListi("Removed " & lstDrivers(intX).IName & " " & ex.Message)
If lstDrivers(intX).Tipo = clsDriver.enmTipo.Lan Then
lstLan.Add(lstDrivers(intX).IName)
End If
FlowLayoutPanelLeds.Controls.Remove(lstDrivers(intX).Control)
lstDrivers.RemoveAt(intX)
Exit For
End Try
Next
End Sub
Dim drcW As Integer = 80
Dim drcH As Integer = drcW
Private Sub Me_Load(sender As Object, e As EventArgs) Handles Me.Load
TrackBarLuminosita.Width = 0
FlowLayoutPanelLeds.Width = 0
FlowLayoutPanelLeds.Height = 0
ListBoxLog.Width = 0
ListBoxLog.Height = 0
ListBoxLog.Items.Clear()
TrackBarLeggi.Value = My.Settings.Leggi
TrackBarScrivi.Value = My.Settings.Scrivi
TrackBarLuminosita.Value = My.Settings.Luminosita
TrackBarLeggi_Scroll(TrackBarLeggi, New EventArgs)
TrackBarScrivi_Scroll(TrackBarScrivi, New EventArgs)
TrackBarLuminosita_Scroll(TrackBarLuminosita, New EventArgs)
lstDrivers = New List(Of clsDriver) From {
New clsDriver("_Total", clsDriver.enmTipo.CPU) With {.Control = New urcLed() With {.BorderStyle = BorderStyle.FixedSingle, .Width = drcW, .Height = drcH}},
New clsDriver("Battery", clsDriver.enmTipo.Battery) With {.Control = New urcLed() With {.BorderStyle = BorderStyle.FixedSingle, .Width = drcW, .Height = drcH}}
}
TimerDriver_Tick(TimerDriver, New EventArgs)
ConnettiUsbDevice()
TimerLeggiValori.Interval = TrackBarLeggi.Value
TimerLeggiValori.Enabled = True
TimerDriver.Enabled = True
End Sub
Public Sub ConnettiUsbDevice()
Try
DisconnettiUsbDevice()
MyUsbDevice = UsbDevice.OpenUsbDevice(New UsbDeviceFinder(&H16C0, &H5DF))
If MyUsbDevice Is Nothing Then
addListi("Device Not Found.")
MyUsbDevice = Nothing
Else
addListi("Device Found.")
If MyUsbDevice.Open() Then
addListi("Device Open.")
TimerScriviValori.Interval = TrackBarScrivi.Value
TimerScriviValori.Enabled = True
Else
addListi("Device Not Open.")
MyUsbDevice = Nothing
End If
End If
Catch ex As Exception
addListi(ex.Message)
End Try
End Sub
Public Sub DisconnettiUsbDevice()
If MyUsbDevice IsNot Nothing Then
If MyUsbDevice.IsOpen Then
MyUsbDevice.Close()
addListi("Device Close.")
End If
'MyUsbDevice = Nothing
UsbDevice.[Exit]()
End If
End Sub
Public Sub addListi(testo As String)
For Each strX As String In testo.Replace(vbLf, String.Empty).Split(Chr(13))
ListBoxLog.SelectedIndex = ListBoxLog.Items.Add(strX)
Next
Do While ListBoxLog.Items.Count > 10
ListBoxLog.Items.RemoveAt(0)
Loop
End Sub
Private Sub Me_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
My.Settings.Leggi = TrackBarLeggi.Value
My.Settings.Scrivi = TrackBarScrivi.Value
My.Settings.Luminosita = TrackBarLuminosita.Value
My.Settings.Save()
TimerDriver.Enabled = False
TimerLeggiValori.Enabled = False
TimerScriviValori.Enabled = False
sendUsbDevice(0, 0, 0, 0)
sendUsbDevice(0, 0, 0, 0)
DisconnettiUsbDevice()
End Sub
Dim PacchettiFalliti As Integer = 0
Private Sub sendUsbDevice(intI As Byte, intR As Byte, intG As Byte, intB As Byte)
If MyUsbDevice IsNot Nothing Then
Dim blnSend As Boolean = False
Dim intCntS As Integer = 0
blnSend = blnSend Or Not sendByteUsbDevice(intI)
If blnSend Then
intCntS += 1
End If
blnSend = blnSend Or Not sendByteUsbDevice(intR)
If blnSend Then
intCntS += 1
End If
blnSend = blnSend Or Not sendByteUsbDevice(intG)
If blnSend Then
intCntS += 1
End If
blnSend = blnSend Or Not sendByteUsbDevice(intB)
If blnSend Then
intCntS += 1
End If
If blnSend Then
addListi($"{Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} Error {intCntS.ToString}.{PacchettiFalliti.ToString} send : L {intI.ToString} - RGB {intR.ToString},{intG.ToString},{intB.ToString}")
If intCntS >= 4 Then
PacchettiFalliti += 1
If PacchettiFalliti > 5 Then
PacchettiFalliti = 0
ConnettiUsbDevice()
End If
End If
Else
PacchettiFalliti = 0
End If
Else
PacchettiFalliti = 0
ConnettiUsbDevice()
End If
End Sub
Private Function sendByteUsbDevice(byteX As Byte) As Boolean
If MyUsbDevice IsNot Nothing Then
Dim intS As Integer = 5
Threading.Thread.Sleep(intS)
Dim numBytesTransferred As Integer = 0
Try
MyUsbDevice.ControlTransfer(New UsbSetupPacket(
UsbCtrlFlags.RequestType_Class Or UsbCtrlFlags.Recipient_Device Or UsbCtrlFlags.Direction_Out,
&H9, &H300, byteX, 0), Nothing, 0, numBytesTransferred)
Catch ex As Exception
Return False
End Try
Dim byteR() As Byte = {If(byteX = Byte.MaxValue, 0, byteX + 1)}
Dim tmrStart As Date = Now.AddMilliseconds(intS * 4)
Do
My.Application.DoEvents()
Threading.Thread.Sleep(intS)
Try
MyUsbDevice.ControlTransfer(New UsbSetupPacket(
UsbCtrlFlags.RequestType_Class Or UsbCtrlFlags.Recipient_Device Or UsbCtrlFlags.Direction_In,
&H1, &H300, 0, 1), byteR, 1, numBytesTransferred)
If byteX = byteR(0) Then
Return True
End If
If tmrStart < Now Then
Return False
End If
Catch ex As Exception
Return False
End Try
Loop
End If
Return False
End Function
<System.Runtime.InteropServices.DllImportAttribute("user32.dll")>
Private Shared Function DestroyIcon(ByVal handle As IntPtr) As Boolean
End Function
Private Sub TimerScriviValori_Tick(sender As Object, e As EventArgs) Handles TimerScriviValori.Tick
TimerScriviValori.Enabled = False
Dim myBitmap As Bitmap = Me.Icon.ToBitmap
Dim grpX As Graphics = Graphics.FromImage(myBitmap)
' grpX.Clear(Color.Black)
For intX As Integer = 0 To lstDrivers.Count - 1
Try
lstDrivers(intX).show(TrackBarLuminosita.Value)
If Not FlowLayoutPanelLeds.Controls.Contains(lstDrivers(intX).Control) Then
FlowLayoutPanelLeds.Controls.Add(lstDrivers(intX).Control)
End If
Dim clrX As Color = lstDrivers(intX).Control.BackColor
sendUsbDevice(CByte(intX + 1), clrX.R, clrX.G, clrX.B)
grpX.FillRectangle(New SolidBrush(clrX), CSng(intX * (myBitmap.Width / lstDrivers.Count)), 0, CSng(myBitmap.Width / lstDrivers.Count), myBitmap.Height)
grpX.DrawLine(New Pen(Color.White, 1), CSng(intX * (myBitmap.Width / lstDrivers.Count)), 0, CSng(intX * (myBitmap.Width / lstDrivers.Count)), myBitmap.Height)
lstDrivers(intX).reset()
Catch ex As Exception
'
End Try
Next
grpX.DrawRectangle(New Pen(Color.White, 1), 0, 0, myBitmap.Width - 1, myBitmap.Height - 1)
DestroyIcon(Me.Icon.Handle)
Me.Icon = Icon.FromHandle(myBitmap.GetHicon())
TimerScriviValori.Enabled = True
End Sub
Private Sub TrackBarLeggi_Scroll(sender As Object, e As EventArgs) Handles TrackBarLeggi.Scroll
TimerLeggiValori.Interval = TrackBarLeggi.Value
Me.ToolTipMain.SetToolTip(Me.TrackBarLeggi, $"{TrackBarLeggi.Value.ToString} su {TrackBarLeggi.Maximum.ToString} (Ogni {Math.Round(TrackBarLeggi.Value / 1000D, 2).ToString("0.00")} sec, {Math.Round(1000D / TrackBarLeggi.Value, 2).ToString("0.00")} volte al sec)")
End Sub
Private Sub TrackBarScrivi_Scroll(sender As Object, e As EventArgs) Handles TrackBarScrivi.Scroll
TimerScriviValori.Interval = TrackBarScrivi.Value
Me.ToolTipMain.SetToolTip(Me.TrackBarScrivi, $"{TrackBarScrivi.Value.ToString} su {TrackBarScrivi.Maximum.ToString} (Ogni {Math.Round(TrackBarScrivi.Value / 1000D, 2).ToString("0.00")} sec, {Math.Round(1000D / TrackBarScrivi.Value, 2).ToString("0.00")} volte al sec)")
End Sub
Private Sub TrackBarLuminosita_Scroll(sender As Object, e As EventArgs) Handles TrackBarLuminosita.Scroll
Me.ToolTipMain.SetToolTip(Me.TrackBarLuminosita, $"{TrackBarLuminosita.Value} su 255 ({((TrackBarLuminosita.Value * 100) / 255).ToString("0.00")}%)")
End Sub
Dim lstLan As New List(Of String)
Private Sub TimerDriver_Tick(sender As Object, e As EventArgs) Handles TimerDriver.Tick
For Each drive As IO.DriveInfo In My.Computer.FileSystem.Drives
If drive.DriveType = IO.DriveType.Fixed OrElse drive.DriveType = IO.DriveType.Removable Then
Dim x As New clsDriver(drive.Name.Substring(0, 2), clsDriver.enmTipo.Drive) With {.Control = New urcLed() With {.BorderStyle = BorderStyle.FixedSingle, .Width = drcW, .Height = drcH}}
If Not lstDrivers.Contains(x) Then
addListi("Found Driver " & drive.Name & " " & drive.DriveType.ToString & " " & If(drive.DriveType = IO.DriveType.Fixed OrElse drive.DriveType = IO.DriveType.Removable, String.Empty, "IGNORED"))
lstDrivers.Add(x)
End If
End If
Next
For Each adapter As Net.NetworkInformation.NetworkInterface In Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
Dim properties As Net.NetworkInformation.IPInterfaceProperties = adapter.GetIPProperties()
If adapter.OperationalStatus = Net.NetworkInformation.OperationalStatus.Up AndAlso Not adapter.NetworkInterfaceType = Net.NetworkInformation.NetworkInterfaceType.Loopback Then
Dim x As New clsDriver(adapter.Description.Replace("(", "[").Replace(")", "]"), clsDriver.enmTipo.Lan) With {.Control = New urcLed() With {.BorderStyle = BorderStyle.FixedSingle, .Width = drcW, .Height = drcH}}
If Not lstDrivers.Contains(x) AndAlso Not lstLan.Contains(adapter.Description) Then
addListi("Found Network " & adapter.Description & " " & adapter.OperationalStatus.ToString)
lstDrivers.Add(x)
End If
End If
Next
End Sub
End Class