burners Posted October 19, 2010 Share Posted October 19, 2010 (edited) OK So this is still a work in progress but works exactly as it is now. I started with the GDI+ functions and then stumbled on some AutoIT clock scripts that really helped with the Trig involved in creating a gauge with a needle.I used a clock script heavily for the code but with a ton of mods.This will read input from any source you can get data from, I have a text file setup so you can see how it works, just comment the Serial Code around lines 392-394 and uncomment around the lines 396 - 401, then create a file called test.txt in the directory and change the values in the text file while saving and you will see the needle update.!! The MAIN needle will not show until the first update !!There are 2 needles, 1 main and 1 peak hold needleIf you use the serial input you will need the .dll file and .au3 file from here http://www.autoitscript.com/forum/index.php?showtopic=45842Go to the last page if you get high CPU usage or cant get it to runIf you want this to run on an Arduino I will include the code, make sure your Serial Port is set correctly in the AIT script.expandcollapse popup;################################################################################################################################ ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ;################################################################################################################################ ; ;Analog Gauge Project ;By: David Orlo ; www.DavidOrlo.com ; ;################################################################################################################################ ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ;################################################################################################################################ #include <GDIPlus.au3> #include <WinAPI.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <CommMG.au3> #Include <File.au3> ; =============================================================================================================================== ; Global variables ; =============================================================================================================================== $WidthHeight = 400 ; Width & Height of Window $iCenter = $WidthHeight /2 ;Center of Window $iDotOpacity = 250 $iOpacity = 128 $nPI = 3.1415926535897932384626433832795 $iRadius = $WidthHeight /2 ;Center of Radius $iLiveNeedleRad = $WidthHeight /2 ;Length of Live Needle $iPeakNeedleRad = 100 ;Length of Peak Needle $iTickLen = 0.02 ;Length of Tick Marks $AC_SRC_ALPHA = 1 $PeakInput = 0 $degin = 2000 ;Set max range of scale HERE !!!!! (Max/2) $deg = ACos(-1) / $degin ;Takes max and divides by ACosine $offset = $degin / 2 ;Offset is how many ticks to offset the starting point, No offset means the 0 point will be 90 degree right angle instead of starting point straight down $radiusM = 200 $radiusP = 360 $R2M = $radiusM * 0.50 $R2P = $radiusP * 0.50 ;********************** COMMENT LINES 46-63 If you are NOT using the SERIAL functions ********************************* ;Internal for the Serial UDF Global $sportSetError = '' ;COM Vars Global $CMPort = 3 ; Port Global $CmBoBaud = 9600 ; Baud Global $CmboDataBits = 8 ; Data Bits Global $CmBoParity = 0 ; Parity Global $CmBoStop = 1 ; Stop Global $setflow = 2 ; Flow ;Start up communication with the Arduino _CommSetPort($CMPort, $sportSetError, $CmBoBaud, $CmboDataBits, $CmBoParity, $CmBoStop, $setflow) Global Enum $eScrDC=0, $eMemDC, $eBitmap, $eWidth, $eHeight, $eGraphic, $ePen, $eCap, $eBrush, $eFormat, $eFamily, $eFont, $eLayout, $eLast Global $hDial, $hDigiGauge, $hNeedle, $hPeak, $hDot, $aGauge, $aLiveNeedle, $aPeakNeedle, $aCurr[3][2], $aLast[3][2] ;################################################################################################################################ ;000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ;################################################################################################################################ ; =============================================================================================================================== ; Main ; =============================================================================================================================== fakeinput() Global $XXM = $iCenter + Cos($PeakInput * $deg) * $R2M Global $YYM = $iCenter + Sin($PeakInput * $deg) * $R2M Global $XXP = $iCenter + Cos($input1 * $deg) * $R2P Global $YYP = $iCenter + Sin($input1 * $deg) * $R2P GaugeInit() DialDraw () Draw () DotDraw () GaugeLoop() GaugeDone() ;################################################################################################################################ ;111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ;################################################################################################################################ ; =============================================================================================================================== ; Loop until user exits ; =============================================================================================================================== Func GaugeLoop() do Draw() until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc ;################################################################################################################################ ;222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 ;################################################################################################################################ ; =============================================================================================================================== ; Initialize Gauge ; =============================================================================================================================== Func GaugeInit() Local $iX, $iY ; Calculate the dial frame caption size $iX = -(_WinAPI_GetSystemMetrics($SM_CXFRAME)) $iY = -(_WinAPI_GetSystemMetrics($SM_CYCAPTION) + _WinAPI_GetSystemMetrics($SM_CYFRAME)) ; Allocate the window resources $hDial = GUICreate("Gauge", $WidthHeight, $WidthHeight, -1, -1, 0, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUISetState() $hDigiGauge = GUICreate("DigiGauge" , $WidthHeight, $WidthHeight, $iX, 240, 0, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $hDial) GUISetState() $hNeedle = GUICreate("Needle" , $WidthHeight, $WidthHeight, $iX, $iY, 0, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $hDial) GUISetState() $hPeak = GUICreate("Peak" , $WidthHeight, $WidthHeight, $iX, $iY, 0, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $hDial) GUISetState() $hDot = GUICreate("Dot" , $WidthHeight, $WidthHeight, $iX, $iY, 0, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $hDial) GUISetState() ; Initialize GDI+ library _GDIPlus_Startup() ; Initialize GDI+ resources DigiGaugeInit() LiveNeedleInit() PeakNeedleInit () ; Hook non client hit test message so we can move the Gauge GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST") EndFunc ; =============================================================================================================================== ; Initialize resources for the digital Gauge ; =============================================================================================================================== Func DigiGaugeInit() $aGauge = ResourceInit($iRadius * 2, $iRadius * 2) $aGauge[$eBrush ] = _GDIPlus_BrushCreateSolid(0xFF008080) $aGauge[$eFormat] = _GDIPlus_StringFormatCreate() $aGauge[$eFamily] = _GDIPlus_FontFamilyCreate("Arial") $aGauge[$eFont ] = _GDIPlus_FontCreate($aGauge[$eFamily], 24, 1) $aGauge[$eLayout] = _GDIPlus_RectFCreate(0, 0, $iRadius * 2, 40) EndFunc ; =============================================================================================================================== ; Initialize resources for the LiveNeedle hand ; =============================================================================================================================== Func LiveNeedleInit() $aLiveNeedle = ResourceInit($iRadius * 2, $iRadius * 2) $aLiveNeedle[$ePen] = _GDIPlus_PenCreate(0xFFFF0000) $aLiveNeedle[$eCap] = _GDIPlus_ArrowCapCreate($iLiveNeedleRad / 2, 8) _GDIPlus_PenSetCustomEndCap($aLiveNeedle[$ePen], $aLiveNeedle[$eCap]) EndFunc ; =============================================================================================================================== ; Initialize resources for the PeakNeedle hand ; =============================================================================================================================== Func PeakNeedleInit() $aPeakNeedle = ResourceInit($iRadius * 2, $iRadius * 2) $aPeakNeedle[$ePen] = _GDIPlus_PenCreate(0xFFFF00FF) $aPeakNeedle[$eCap] = _GDIPlus_ArrowCapCreate($iPeakNeedleRad / 2, 8) _GDIPlus_PenSetCustomEndCap($aPeakNeedle[$ePen], $aPeakNeedle[$eCap]) EndFunc ; =============================================================================================================================== ; Initialize bitmap resources ; =============================================================================================================================== Func ResourceInit($iWidth, $iHeight) Local $aInfo[$eLast + 1] $aInfo[$eScrDC ] = _WinAPI_GetDC(0) $aInfo[$eMemDC ] = _WinAPI_CreateCompatibleDC($aInfo[$eScrDC]) $aInfo[$eBitmap ] = _WinAPI_CreateCompatibleBitmap($aInfo[$eScrDC], $iWidth, $iHeight) _WinAPI_SelectObject($aInfo[$eMemDC], $aInfo[$eBitmap]) $aInfo[$eWidth ] = $iWidth $aInfo[$eHeight ] = $iHeight $aInfo[$eGraphic] = _GDIPlus_GraphicsCreateFromHDC($aInfo[$eMemDC]) _GDIPlus_GraphicsFillRect($aInfo[$eGraphic], 0, 0, $iRadius * 2, $iRadius * 2) Return $aInfo EndFunc ;################################################################################################################################ ;333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 ;################################################################################################################################ ; =============================================================================================================================== ; Draw the Gauge elements ; =============================================================================================================================== Func Draw() ; Calculate current Gauge element position Global $ChangePeak = 0 Global $LastXXP = $XXP Global $LastYYP = $YYP Global $LastXXM = $XXM Global $LastYYM = $YYM If $input1 > $PeakInput Then Global $PeakInput = $input1 Global $ChangePeak = 1 EndIf fakeinput() Global $XXM = $iCenter + Cos($PeakInput * $deg) * $R2M Global $YYM = $iCenter + Sin($PeakInput * $deg) * $R2M Global $XXP = $iCenter + Cos($input1 * $deg) * $R2P Global $YYP = $iCenter + Sin($input1 * $deg) * $R2P ; Draw Gauge elements DigiGaugeDraw() LiveNeedleDraw() PeakNeedleDraw () EndFunc ; =============================================================================================================================== ; Draw the Gauge dial ; =============================================================================================================================== Func DialDraw() Local $aDial, $hPen1, $hPen2, $iI, $iN, $iX1, $iY1, $iX2, $iY2 $aDial = ResourceInit($iRadius * 2, $iRadius * 2) $hPen1 = _GDIPlus_PenCreate() $hPen2 = _GDIPlus_PenCreate(0xFF0000FF, 4) for $iI = 0 to 2 * $nPI Step $nPI / 30 $iX1 = $iCenter + Cos($iI) * ($iRadius * (1.00 - $iTickLen)) $iY1 = $iCenter - Sin($iI) * ($iRadius * (1.00 - $iTickLen)) $iX2 = $iCenter + Cos($iI) * $iRadius $iY2 = $iCenter - Sin($iI) * $iRadius if Mod($iN, 5) = 0 then _GDIPlus_GraphicsDrawLine($aDial[$eGraphic], $iX1, $iY1, $iX2, $iY2, $hPen2) else _GDIPlus_GraphicsDrawLine($aDial[$eGraphic], $iX1, $iY1, $iX2, $iY2, $hPen1) endif $iN += 1 next _GDIPlus_PenDispose($hPen2) _GDIPlus_PenDispose($hPen1) ResourceSet ($hDial, $aDial) ResourceDone($aDial) EndFunc ; =============================================================================================================================== ; Draw the center dot ; =============================================================================================================================== Func DotDraw() Local $aDot $aDot = ResourceInit($iRadius * 2, $iRadius * 2) _GDIPlus_GraphicsFillEllipse($aDot[$eGraphic], $iRadius-10, $iRadius-10, 20, 20) ResourceSet ($hDot, $aDot, $iDotOpacity) ResourceDone($aDot) EndFunc ; =============================================================================================================================== ; Draw the LiveNeedle hand ; =============================================================================================================================== Func LiveNeedleDraw() if ($LastXXP = $XXP) and ($LastYYP = $YYP) then Return LiveNeedleDone() LiveNeedleInit() _GDIPlus_GraphicsDrawLine($aLiveNeedle[$eGraphic], $iCenter, $iCenter, $XXP, $YYP, $aLiveNeedle[$ePen]) ResourceSet($hNeedle, $aLiveNeedle) EndFunc ; =============================================================================================================================== ; Draw the PeakNeedle hand ; =============================================================================================================================== Func PeakNeedleDraw() if $ChangePeak <> 1 then Return PeakNeedleDone() PeakNeedleInit() _GDIPlus_GraphicsFillRect($aPeakNeedle[$eGraphic], 0, 0, $iRadius * 2, $iRadius * 2) _GDIPlus_GraphicsDrawLine($aPeakNeedle[$eGraphic], $iCenter, $iCenter, $XXM, $YYM, $aPeakNeedle[$ePen]) ResourceSet($hPeak, $aPeakNeedle) EndFunc ; =============================================================================================================================== ; Draw the digital Gauge ; =============================================================================================================================== Func DigiGaugeDraw() Local $sString, $aSize if ($LastXXP = $XXP) and ($LastYYP = $YYP) then Return $sString = $input0 $aSize = _GDIPlus_GraphicsMeasureString($aGauge[$eGraphic], $sString, $aGauge[$eFont], $aGauge[$eLayout], $aGauge[$eFormat]) DllStructSetData($aGauge[$eLayout], "X", $iRadius - (DllStructGetData($aSize[0], "Width") / 2)) DllStructSetData($aGauge[$eLayout], "Y", $iRadius / 3) _GDIPlus_GraphicsFillRect($aGauge[$eGraphic], 0, 0, $iRadius * 2, $iRadius * 2) _GDIPlus_GraphicsDrawStringEx($aGauge[$eGraphic], $sString, $aGauge[$eFont], $aGauge[$eLayout], $aGauge[$eFormat], $aGauge[$eBrush]) ResourceSet($hDigiGauge, $aGauge) EndFunc ;################################################################################################################################ ;444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444 ;################################################################################################################################ ; =============================================================================================================================== ; Finalize Gauge ; =============================================================================================================================== Func GaugeDone() ; Finalize GDI+ resources DigiGaugeDone() LiveNeedleDone() PeakNeedleDone () ; Finalize GDI+ library _GDIPlus_Shutdown() EndFunc ; =============================================================================================================================== ; Finalize resources for the LiveNeedle hand ; =============================================================================================================================== Func LiveNeedleDone() _GDIPlus_PenDispose($aLiveNeedle[$ePen]) _GDIPlus_ArrowCapDispose($aLiveNeedle[$eCap]) ResourceDone($aLiveNeedle) EndFunc ; =============================================================================================================================== ; Finalize resources for the PeakNeedle hand ; =============================================================================================================================== Func PeakNeedleDone() _GDIPlus_PenDispose($aPeakNeedle[$ePen]) _GDIPlus_ArrowCapDispose($aPeakNeedle[$eCap]) ResourceDone($aPeakNeedle) EndFunc ; =============================================================================================================================== ; Finalize resources for the digital Gauge ; =============================================================================================================================== Func DigiGaugeDone() _GDIPlus_FontDispose ($aGauge[$eFont ]) _GDIPlus_FontFamilyDispose ($aGauge[$eFamily]) _GDIPlus_StringFormatDispose($aGauge[$eFormat]) _GDIPlus_BrushDispose ($aGauge[$eBrush ]) ResourceDone($aGauge) EndFunc ; =============================================================================================================================== ; Finalize drawing resources ; =============================================================================================================================== Func ResourceDone(ByRef $aInfo) _GDIPlus_GraphicsDispose($aInfo[$eGraphic]) _WinAPI_ReleaseDC (0, $aInfo[$eScrDC]) _WinAPI_DeleteObject($aInfo[$eBitmap]) _WinAPI_DeleteDC ($aInfo[$eMemDC ]) EndFunc ;################################################################################################################################ ;555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555 ;################################################################################################################################ ; =============================================================================================================================== ; Update layered window with resource information ; =============================================================================================================================== Func ResourceSet($hGUI, ByRef $aInfo, $iAlpha=-1) Local $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend if $iAlpha = -1 then $iAlpha = $iOpacity $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize ) DllStructSetData($tSize, "X", $aInfo[$eWidth ]) DllStructSetData($tSize, "Y", $aInfo[$eHeight]) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend ) DllStructSetData($tBlend, "Alpha" , $iAlpha ) DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA) _WinAPI_UpdateLayeredWindow($hGUI, $aInfo[$eScrDC], 0, $pSize, $aInfo[$eMemDC], $pSource, 0, $pBlend, $ULW_ALPHA) EndFunc ;################################################################################################################################ ;666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666 ;################################################################################################################################ Func fakeinput() ;********************************IF using an LCD the code on lines 384-390 will use Regular Expression to filter out characters meant for the LCD ;Do ;sleep(10) ;$serialstringin = _CommGetLine('',0,1000) ;$serialstringout = StringRegExp($serialstringin, "(?<=þ„)....", 2) ;Until @error <> 1 ;Global $input0 = $serialstringout[0] ;Global $input1 = $input0 + $offset $serialstringin = _CommGetLine('',0,1000) Global $input0 = $serialstringin Global $input1 = $input0 + $offset ;********************************Use the code below to test with a file located in script directory ;$file = FileOpen("test.txt", 0) ;$intemp = FileReadLine($file) ;Global $input0 = $intemp ;Global $input1 = $input0 + $offset ;FileClose($file) EndFunc ; =============================================================================================================================== ; Handle the WM_NCHITTEST message so our window can be dragged ; =============================================================================================================================== Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam) if $hWnd = $hDial then Return $HTCAPTION EndFunc Edited October 19, 2010 by burners ~~--Feel Free to Steal my Sigs --~~FLAT LOOK____________________________________ROUNDED LOOK Link to comment Share on other sites More sharing options...
burners Posted October 19, 2010 Author Share Posted October 19, 2010 (edited) AND here is the Arduino code to read the RPM coming in on pin #2 I will be putting diagrams on my site soon to help with wiring the fan and getting it all working /* PC Fan RPM Arduino Script by David Orlo www.DavidOrlo.com*/ int RPMcount; //RPM Input signal variable int Calc; int RPMPIN = 2; //The pin location of the sensor typedef struct{ //Defines the structure for multiple fans and their dividers char fantype; unsigned int fandiv; }fanspec; //Definitions of the fans fanspec fanspace[3]={{0,1},{1,2},{2,8}}; char fan = 1; //select the fan divider, set 1 for unipole hall effect sensor //2 for bipole hall effect sensor void rpm () //This is the function that the interupt calls { RPMcount++; //Each time the interrupt is triggered, 1 is added to RPMcount } void setup() { pinMode(RPMPIN, INPUT); attachInterrupt(0, rpm, RISING); Serial.begin(9600); // Open serial port } void loop () { RPMcount = 0; //Set the count to 0 delay (500); //Wait half a second Calc = ((RPMcount * 120)/fanspace[fan].fandiv); //Multiply RPMcount by 120 (2 seconds) before dividing by the fan's divider Serial.println (Calc); //Prints the number calculated above } Edited October 19, 2010 by burners ~~--Feel Free to Steal my Sigs --~~FLAT LOOK____________________________________ROUNDED LOOK Link to comment Share on other sites More sharing options...
jeffmx Posted December 26, 2011 Share Posted December 26, 2011 Nice work, that's I'm looking for... Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now