how to get all drives in a PC. and types of every drive and free-space of each
i.e. System-Drive, CD-Drive, DVD-Drive, Removable, ... etc.
If a system is attached with a new drive may be a pen drive or external hard disc.
How to detect them at time of attachment ?
To get a list of the drives, you can use the System.IO.DriveInfo class:
foreach(var drive in DriveInfo.GetDrives())
{
Console.WriteLine("Drive Type: {0}", drive.DriveType);
Console.WriteLine("Drive Size: {0}", drive.TotalSize);
Console.WriteLine("Drive Free Space: {0}", drive.TotalFreeSpace);
}
Unfortunately, this doesn't provide a way to listen for USB Key Insertions. There is another question dealing with that you could check out:
.NET - Detecting USB Drive Insertion and Removal...
public string getalldrivestotalnfreespace()
{
string s = " Drive Free Space TotalSpace FileSystem %Free Space DriveType\n\r========================================================================================\n\r";
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
double ts = 0;
double fs = 0;
double frprcntg = 0;
long divts = 1024 * 1024 * 1024;
long divfs = 1024 * 1024 * 1024;
string tsunit = "GB";
string fsunit = "GB";
if (drive.IsReady)
{
fs = drive.TotalFreeSpace;
ts = drive.TotalSize;
frprcntg = (fs / ts) * 100;
if (drive.TotalSize < 1024)
{
divts =1; tsunit = "Byte(s)";
}
else if (drive.TotalSize < (1024*1024))
{
divts = 1024; tsunit = "KB";
}
else if (drive.TotalSize < (1024 * 1024*1024))
{
divts = 1024*1024; tsunit = "MB";
}
//----------------------
if (drive.TotalFreeSpace < 1024)
{
divfs = 1; fsunit = "Byte(s)";
}
else if (drive.TotalFreeSpace < (1024 * 1024))
{
divfs = 1024; fsunit = "KB";
}
else if (drive.TotalFreeSpace < (1024 * 1024 * 1024))
{
divfs = 1024 * 1024; fsunit = "MB";
}
s = s +
" " + drive.VolumeLabel.ToString() +
"[" + drive.Name.Substring(0, 2) +
"]\t" + String.Format("{0,10:0.0}", ((fs / divfs)).ToString("N2")) + fsunit +
String.Format("{0,10:0.0}", (ts / divts).ToString("N2")) + tsunit +
"\t" + drive.DriveFormat.ToString() + "\t\t" + frprcntg.ToString("N2") + "%"+
"\t\t" + drive.DriveType.ToString();
s = s + "\n\r";
}
}
return s;
}
The ouput should look like :-
Environment.GetLogicalDrives();
MSDN link
You can get the drives and info quite easily
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
Console.WriteLine(drive.Name);
Console.WriteLine(drive.TotalSize);
}
There's a good article on detecting adding/removing drives on CodeProject
Environment.GetLogicalDrives();
MSDN link
The WMI libraries will probably help. Also there's a codeproject article that talks about this:
http://www.codeproject.com/KB/cs/UsbManager.aspx
Here is the answer to your first question. To get all logical drives you can try this:
string[] drives = Environment.GetLogicalDrives();
The System.IO.DriveInfo class is the place to start. The DriveType property can tell you what you are looking for.
To get all the drives currently attached:
DriveInfo[] allDrives = DriveInfo.GetDrives();
And for the detection you have to listen to WMI events. Check this out: http://www.techtalkz.com/c-c-sharp/182048-need-detect-insertion-removal-usb-drive.html
Related
I've built a C# application to interact with a Control System at work. It calculates some values and/or pulls them from a spreadsheet and then writes them to an OPC server using EasyOPCClient. When I run this application, it will run for 3-5 minutes the first time, close, and reopen, then run 30 seconds to 2 minutes from that point on. Each time it closes and restarts with no errors printed to the console (at least that I can see before it closes), and I don't see anything in the event logs that would make it close. Does anyone see anything I'm doing in the program that would cause that? This is my first attempt at multi-threading, so it wouldn't surprise me if it were something with that.
using System;
using System.IO;
using System.Threading;
using OpcLabs.EasyOpc.DataAccess;
using Excel = Microsoft.Office.Interop.Excel;
/// <summary>
/// OPC Simulator:
/// Used to assist in training operators on how to use Honeywell Experion System
/// Simulates PID and DEVCTL inputs and outputs; uses historical data from ParcView to simulate DACA blocks
///
/// Date: 07/14/2022
/// Authours:
/// </summary>
namespace OPCTest
{
public class Program
{
public static double[] genFunction(int number_of_samples, float amplitude, float frequency_in_hz)
{
/*
* Function: Generates an array of points sampled from a noisy sine wave function.
*
* IN: number_of_samples - The number of samples to generate
* amplitude - Multiplier to scale the function
* frequency_in_hz - Frequency of the generated signal
*
* OUT: An array of integers sampled from the generated sine wave.
*/
Random rand = new Random();
// Initialize any needed variables
double[] points = new double[number_of_samples];
float time;
int samples;
// Generates a noisy signal
for(samples = 0; samples < number_of_samples; samples++)
{
time = samples / (frequency_in_hz);
points[samples] = amplitude * (Math.Sin(2.0f * Math.PI * frequency_in_hz * time / 5.0f + rand.Next(0, 100))
+ 1/5 * Math.Sin(2.0f * Math.PI * frequency_in_hz * time + rand.Next(0, 100))
+ 3 * (Math.Sin(2.0f * Math.PI * frequency_in_hz * time / 100.0f + rand.Next(0, 100))));
}
return points;
}
public static void DACA(EasyDAClient client)
{
/*
* Function: Simulates DACA block I/Os using a function generator
*
* IN: None
*
* OUT: None
*
*/
//var client = new EasyDAClient();
string textFile = #"C:\Temp\DACAs.txt"; // Path to file with CMs containing DACAs in it. CM name only
float pveulo, pveuhi, pvloalm, pvhialm, pvllalm, pvhhalm; // Initialize all of the useful PV alarms and variables
float pv, pvlo, pvhi; // PVs that will be used in calculations
float shift; // Initialize the variable that will vertically shift the signal to the correct magnitude
float amplitude; // Initialize the variable that will determine the amplitude of each PV signal
double[] signal; // Initialize an array of points that will be used to store a generated signal
// Read a text file line by line.
string[] lines = File.ReadAllLines(textFile);
while (true)
{
if (File.Exists(textFile))
{
// Iterate through DACAs in text file
foreach (string line in lines)
{
try
{
// Store the necessary variables
pvhi = pveuhi = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEUHI").ToString());
pvlo = pveulo = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEULO").ToString());
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVHHALM.TP").ToString().Split(' ')[0], out pvhhalm))
{
// Console.WriteLine("PVHIHI: " + pvhhalm);
pvhi = pvhhalm;
}
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVHIALM.TP").ToString().Split(' ')[0], out pvhialm))
{
// Console.WriteLine("PVHI: " + pvhialm);
pvhi = pvhialm;
}
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVLLALM.TP").ToString().Split(' ')[0], out pvllalm))
{
// Console.WriteLine("PVLOLO: " + pvllalm);
pvlo = pvllalm;
}
if (float.TryParse(client.ReadItem("", "HWHsc.OPCServer", line + ".DACA.PVLOALM.TP").ToString().Split(' ')[0], out pvloalm))
{
// Console.WriteLine("PVLO: " + pvloalm);
pvlo = pvloalm;
}
// Console.WriteLine("PVHI: " + pvhi + " PVLO: " + pvlo);
amplitude = ((pvhi - pvlo) / 2.0f) * 0.0375f;
shift = ((pvhi - pvlo) * 0.8f) + pvlo; // Shift the signal up to oscillate between the bounds of the PV
// Generate the signal
signal = genFunction(10, amplitude, 0.003f);
foreach (float sig in signal)
{
pv = sig + shift;
client.WriteItemValue("", "HWHsc.OPCServer", line + ".DACA.PV", pv);
// Console.WriteLine(line + ": " + pv);
}
}
catch(Exception e)
{
// Note the failures
Console.WriteLine("DACA Failed at: " + line + "\n\t" + e + "\n");
}
}
System.Threading.Thread.Sleep(1000);
}
}
}
public static void DEVCTLA(EasyDAClient client)
{
/*
* Function: Simulates DEVCTLA block I/Os
*
* IN: client - OPC Client that will be used to read and write to the Experion server
*
* OUT: None
*/
string textFile = #"C:\Temp\DEVCTLAs.txt";
string gop, gpv;
// Read a text file line by line.
string[] tags = File.ReadAllLines(textFile);
while (true)
{
foreach (string tagName in tags)
{
try
{
gop = client.ReadItemValue("", "HWHsc.OPCServer2", tagName + ".DEVCTLA.GOP").ToString();
gpv = client.ReadItemValue("", "HWHsc.OPCServer2", tagName + ".DEVCTLA.GPV").ToString();
if (gpv != gop) client.WriteItemValue("", "HWHsc.OPCServer2", tagName + ".DEVCTLA.GPV", gop);
}
catch(Exception e)
{
Console.WriteLine("DEVCTLA Failed at: " + tagName + "\n\t" + e + "\n");
}
}
System.Threading.Thread.Sleep(1000);
}
}
public static void PID(EasyDAClient client)
{
/*
* Function: Simulates PID block I/Os
*
* IN: client - OPC Client that will be used to read and write to the Experion server
*
* OUT: None
*/
string textFile = #"C:\Temp\PIDs.txt"; // Path to file with CMs containing PIDs in it. CM name only - I plan to make this browsable by the user
double OP = 0; // Place to store OP of PID
double pveulo = 0; // Place to store PVEULO from DACA
double pveuhi = 0; // Place to store PVEUHI from DACA
double PV = 0; // Place to store calculated PV to write to DACA
double ctlactn = 1; // Place to store Control Action - 0 = Direct, 1 = Reverse
// Read a text file line by line.
string[] lines = File.ReadAllLines(textFile);
foreach (string line in lines)
{
try
{
client.WriteItemValue("", "HWHsc.OPCServer", line + "PIDA.MODE", "AUTO"); // Put PID Loops in Automatic
}
catch { }
}
while (true)
{
if (File.Exists(textFile))
{
// Iterate through PIDs in text file
foreach (string line in lines)
{
try
{
// Store the PVEULO
pveulo = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEULO").ToString());
// Store the PVEUHI
pveuhi = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEUHI").ToString());
// Store the OP
OP = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".PIDA.OP").ToString());
// Store the PV
try
{
PV = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".PIDA.PV").ToString());
}
catch
{
PV = 0;
}
// Store the Control Action
try
{
ctlactn = float.Parse(client.ReadItemValue("", "HWHsc.OPCServer", line + ".PIDA.CTLACTN").ToString());
}
catch (Exception e)
{
//ctlactn2 = client.ReadItemValue("", "HWHsc.OPCServer", line + "PIDA.CTLACTN").ToString();
//ctlactn2 = e.ToString();
}
// If PV is 0, write the halfway point to it so the PID doesn't start in a wound up position
if (PV == 0)
{
// Write the halfway point of the pv range to the PV
client.WriteItemValue("", "HWHsc.OPCServer", line + ".DACA.PV", (pveuhi - pveulo) / 2);
}
if (ctlactn == 1)
{
// Calculate the PV based off the OP * PV Range + some noise
PV = (OP * 0.01 * (pveuhi - pveulo) + pveulo) + 0.008 * OP;
}
else
{
// Calculate the PV based off the OP * PV Range + some noise
PV = ((106.9 - OP) * 0.01 * (pveuhi - pveulo) + pveulo) - 0.008 * (106.9 - OP);
}
// Write the calculated PV to the DACA
client.WriteItemValue("", "HWHsc.OPCServer", line + ".DACA.PV", PV);
}
catch(Exception e)
{
// Note the failures
Console.WriteLine("PID Failed at: " + line + "\n\t" + e + "\n");
Thread.Sleep(300000);
}
}
System.Threading.Thread.Sleep(1000);
}
}
}
public static void PView(EasyDAClient client)
{
/*
* Function: Simulates DACA block I/Os using historical ParcView data
*
* IN: client - OPC Client that will be used to read and write to the Experion server
* xLWB - The excel workbook containing the ParcView data
* OUT: None
*/
// Connect to the Excel spreadsheet
Excel.Application xLApp = new Excel.Application();
Excel.Workbook xLWB = xLApp.Workbooks.Open(#"C:\Temp\ParcView_Data_Copy_2.xlsx");
Excel.Worksheet rawData = xLWB.Sheets[1];
Excel.Worksheet locData = xLWB.Sheets[2];
Excel.Range rawDataRange = rawData.UsedRange;
Excel.Range locDataRange = locData.UsedRange;
// Determine the size of the spreadshees
int rawDataRow = rawDataRange.Rows.Count;
int rawDataCol = rawDataRange.Columns.Count;
int locDataRow = locDataRange.Rows.Count;
string tagName;
float[] tagValues = new float[locDataRow];
do
{
// Loop through each row of data
for (int i = 1; i <= rawDataRow; i++)
{
// Console.WriteLine((rawDataRow - i) + " Remaining");
// Get data for tag
for (int j = 1; j <= locDataRow; j++)
{
tagName = locDataRange.Cells[j, 1].Value2.ToString();
try
{
if (rawDataRange.Cells[i, j] != null && rawDataRange.Cells[i, j].Value2 != null)
tagValues[j - 1] = float.Parse(rawDataRange.Cells[i, j].Value2.ToString());
client.WriteItemValue("", "HWHsc.OPCServer", tagName + ".DACA.PV", tagValues[j - 1]);
}
catch (Exception e)
{
Console.WriteLine("PVIEW Failed at: " + tagName + "\n\t" + e + "\n");
Thread.Sleep(300000);
}
}
Thread.Sleep(2000);
}
} while (true);
}
static void Main(string[] args)
{
try
{
// Initialize OPC Client
EasyDAClient client = new EasyDAClient();
EasyDAClient client2 = new EasyDAClient();
// Initialize threads using Threads class
Thread PViewThread = new Thread(() => PView(client));
Thread PIDThread = new Thread(() => PID(client2));
//Thread DACAThread = new Thread(() => DACA(client));
//Thread DEVCTLAThread = new Thread(() => DEVCTLA(client));
// Start the threads
PViewThread.Start();
PIDThread.Start();
//DACAThread.Start();
//DEVCTLAThread.Start();
}
catch (Exception e)
{
Console.WriteLine("MAIN: \n\t" + e);
Thread.Sleep(300000);
}
}
}
}
A C# program can launch another instance of itself with Process.Start. This code does not do that. It can be restarted by a task scheduler or if it is installed as a Windows service or by another application.
But I see that you have several Thread.Sleep in there. Those are probably responsible for the observed behavior. So, the program is not closing and restarting automatically. It is simply sleeping from time to time.
Especially when an exception occurs Thread.Sleep(300000); is called, making the program sleep for 5 minutes. If the exceptions occur randomly, this would explain it happening at random intervals.
E.g. float.Parse throws an exception when the string is not a valid float. Consider using TryParse instead. Example
string s = client.ReadItemValue("", "HWHsc.OPCServer", line + ".DACA.PVEUHI").ToString();
if (float.TryParse(s, out float pvhi)) {
pveuhi = pvhi;
...
} else {
Console.WriteLine($"\"{s}\" is not a valid float in line {line}");
}
Basically, I am calibrating and applying offsets within unity. But the range of rotation isn't accurate and I'm wondering if its because of the wrong sensitivity application. I wanted help figuring out a way to stabilize the rotation as well as increase the range of rotation as it goes only form 0-90 and it shakes a lot.
Unity Code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
public class MPU6050_3 : MonoBehaviour
{
public GameObject target;
SerialPort stream = new SerialPort("COM3", 115200);
string[] accgyValues = new string[10];
int buffersize = 1000; //Amount of readings used to average, make it higher to get more precision but sketch will be slower (default:1000)
int acel_deadzone = 2; //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge (default:8)
int giro_deadzone = 1; //Giro error allowed, make it lower to get more precision, but sketch may not converge (default:1)
float ax, ay, az, gx, gy, gz, gx_f, gy_f, gz_f;
float mean_ax, mean_ay, mean_az, mean_gx, mean_gy, mean_gz, state = 0;
float ax_offset = 0, ay_offset = 0, az_offset = 0, gx_offset = 0, gy_offset = 0, gz_offset = 0;
bool cal;
public float factor = 1;
public bool enableRotation;
public bool enableTranslation;
//float acc_normalizer_factor = 0.00025f;
float gyro_normalizer_factor = 1.0f/65.5f;
void Awake()
{
stream.Open();
//stream.ReadTimeout=50;
}
void Update()
{
if (state == 0)
{
accel();
Debug.Log("\nReading sensors for first time...");
state++;
Debug.Log("State is:"+state);
}
else if (state == 1)
{
Debug.Log("\nCalculating offsets...");
calibration();
state++;
Debug.Log("State is:" + state);
}
else if (state == 2)
{
accel();
Debug.Log("SensorW/Offset:" + mean_ax + ":" + mean_ay + ":" + mean_az + ":" + mean_gx + ":" + mean_gy + ":" + mean_gz);
Debug.Log("Offset:" + ax_offset + ":" + ay_offset + ":" + az_offset + ":" + gx_offset + ":" + gy_offset + ":" + gz_offset);
state++;
Debug.Log("State is:" + state);
}
else if (state == 3)
{
getaccgy();
//if (enableTranslation) target.transform.position = new Vector3(ax+ax_offset, az-az_offset, ay-ay_offset);
gx_f = (gx + gx_offset) * gyro_normalizer_factor;
gy_f = (gy + gy_offset) * gyro_normalizer_factor;
gz_f = -(gz + gz_offset) * gyro_normalizer_factor ;
if (enableRotation) target.transform.rotation = Quaternion.Euler(gx_f * factor, gz_f * factor, gy_f * factor);
Debug.Log("ValueRot "+ gx_f +" " + gy_f + " " + gz_f);
Debug.Log("State is:" + state);
}
}
public void getaccgy()
{
stream.Write("r");
Debug.Log("In accel");
string value;
accgyValues = new string[10];
value = stream.ReadLine();
accgyValues = value.Split(",");
ax = int.Parse(accgyValues[0]); //* acc_normalizer_factor;
ay = int.Parse(accgyValues[1]); //* acc_normalizer_factor;
az = int.Parse(accgyValues[2]); //* acc_normalizer_factor;
gx = int.Parse(accgyValues[3]); //* gyro_normalizer_factor;
gy = int.Parse(accgyValues[4]); //* gyro_normalizer_factor;
gz = int.Parse(accgyValues[5]); //* gyro_normalizer_factor;
Debug.Log("GetACCGY");
Debug.Log("SensorW/Offset:" + ax + ":" + ay + ":" + az + ":" + gx + ":" + gy + ":" + gz);
}
void accel()
{
float i = 0f, buff_ax = 0f, buff_ay = 0f, buff_az = 0f, buff_gx = 0f, buff_gy = 0f, buff_gz = 0f;
while (i < 1101)
{
getaccgy();
if (cal)
{
ax = ax + ax_offset;
ay = ay + ay_offset;
az = az + az_offset;
gx = gx + gx_offset;
gy = gy + gy_offset;
gz = gz + gz_offset;
}
if (i > 99 && i < (buffersize + 100))
{ //First 100 measures are discarded
buff_ax += ax;
buff_ay += ay;
buff_az += az;
buff_gx += gx;
buff_gy += gy;
buff_gz += gz;
}
if (i == (buffersize + 100))
{
mean_ax = buff_ax / buffersize;
mean_ay = buff_ay / buffersize;
mean_az = buff_az / buffersize;
mean_gx = buff_gx / buffersize;
mean_gy = buff_gy / buffersize;
mean_gz = buff_gz / buffersize;
Debug.Log("Mean:" + mean_ax + ":" + mean_ay + ":" + mean_az + ":" + mean_gx + ":" + mean_gy + ":" + mean_gz);
}
i++;
Debug.Log("Mean Sensor");
Debug.Log("Buffer Size is" + buffersize + "i mean" + i);
Debug.Log("SensorW/Offset:" + ax + ":" + ay + ":" + az + ":" + gx + ":" + gz);
}
}
void calibration()
{
cal = true;
Debug.Log("Callibration Entered");
ax_offset = -mean_ax / 8;
ay_offset = -mean_ay / 8;
az_offset = (16384 - mean_az) / 8;
gx_offset = -mean_gx / 4;
gy_offset = -mean_gy / 4;
gz_offset = -mean_gz / 4;
int ready = 0;
while (ready < 7)
{
//accelgyro.setXAccelOffset(ax_offset);
//accelgyro.setYAccelOffset(ay_offset);
//accelgyro.setZAccelOffset(az_offset);
//accelgyro.setXGyroOffset(gx_offset);
//accelgyro.setYGyroOffset(gy_offset);
//accelgyro.setZGyroOffset(gz_offset);
accel();
Debug.Log("..." + ready);
if (Math.Abs(mean_ax) <= acel_deadzone) ready++;
else ax_offset = ax_offset - mean_ax / acel_deadzone;
if (Math.Abs(mean_ay) <= acel_deadzone) ready++;
else ay_offset = ay_offset - mean_ay / acel_deadzone;
if (Math.Abs(16384 - mean_az) <= acel_deadzone) ready++;
else az_offset = az_offset + (16384 - mean_az) / acel_deadzone;
if (Math.Abs(mean_gx) <= giro_deadzone) ready++;
else gx_offset = gx_offset - mean_gx / (giro_deadzone + 1);
if (Math.Abs(mean_gy) <= giro_deadzone) ready++;
else gy_offset = gy_offset - mean_gy / (giro_deadzone + 1);
if (Math.Abs(mean_gz) <= giro_deadzone) ready++;
else gz_offset = gz_offset - mean_gz / (giro_deadzone + 1);
if (ready == 6) break;
}
}
}
Arduino Code:
Just a simple code to get the raw values:
// I2Cdev and MPU6050 must be installed as libraries
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
/////////////////////////////////// CONFIGURATION /////////////////////////////
//Change this 3 variables if you want to fine tune the skecth to your needs.
int buffersize=1000; //Amount of readings used to average, make it higher to get more precision but sketch will be slower (default:1000)
int acel_deadzone=8; //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge (default:8)
int giro_deadzone=1; //Giro error allowed, make it lower to get more precision, but sketch may not converge (default:1)
// default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
//MPU6050 accelgyro;
MPU6050 accelgyro(0x68); // <-- use for AD0 high
int16_t ax, ay, az,gx, gy, gz;
int mean_ax,mean_ay,mean_az,mean_gx,mean_gy,mean_gz,state=0;
int ax_offset,ay_offset,az_offset,gx_offset,gy_offset,gz_offset;
/////////////////////////////////// SETUP ////////////////////////////////////
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
// COMMENT NEXT LINE IF YOU ARE USING ARDUINO DUE
TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz). Leonardo measured 250kHz.
// initialize serial communication
Serial.begin(115200);
// initialize device
accelgyro.initialize();
//wait for ready
//while (Serial.available() && Serial.read()); // empty buffer
//while (!Serial.available()){
//Serial.println(F("Send any character to start sketch.\n"));
//delay(1500);
//}
//while (Serial.available() && Serial.read()); // empty buffer again
}
// start message
//Serial.println("\nMPU6050 Calibration Sketch");
//delay(2000);
//Serial.println("\nYour MPU6050 should be placed in horizontal position, with package letters facing up. \nDon't touch it until you see a finish message.\n");
//delay(3000);
// verify connection
//Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
//delay(1000);
// reset offsets
//accelgyro.setXAccelOffset(0);
//accelgyro.setYAccelOffset(0);
//accelgyro.setZAccelOffset(0);
//accelgyro.setXGyroOffset(0);
//accelgyro.setYGyroOffset(0);
//accelgyro.setZGyroOffset(0);
void loop() {
if(Serial.available() > 0)
{
char ltr = Serial.read();
if(ltr == 'r')
{
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
Serial.print(ax);
Serial.print(",");
Serial.print(ay);
Serial.print(",");
Serial.print(az);
Serial.print(",");
Serial.print(gx);
Serial.print(",");
Serial.print(gy);
Serial.print(",");
Serial.println(gz);
Serial.flush();
}
}
}
I'm using this code to get cpu temperature, but I'm getting 'not supported' instead of the temperature.
public static string getCpuTemperature()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSAcpi_ThermalZoneTemperature");
//Win32_TemperatureProbe
foreach (ManagementObject queryObj in searcher.Get())
{
double temp = Convert.ToDouble(queryObj["CurrentTemperature"].ToString());
double temp_critical = Convert.ToDouble(queryObj["CriticalTripPoint"].ToString());
double temp_cel = (temp / 10 - 273.15);
double temp_critical_cel = temp_critical / 10 - 273.15;
return temp_cel.ToString() + " _ " + temp_critical_cel.ToString();
}
}
catch (ManagementException e)
{
//MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
return e.Message.ToString();
}
return "";
}
I've googled the problem and have seen many answers for this including,
- the motherboard doesn't support this feature
- run VS with administration right
etc...
but none of them are true, because programs like OpenHardwareMonitor and SpeedFan show the temperature of cpu and gpu, Hdd temperature, cpu fan speed, and all other informations.
I want to know how do they do that? how is that I get 'not supported' message and these programs don't.
This is not a complete answer but hopefully it helps.
After perusing the code at https://code.google.com/p/open-hardware-monitor/source/browse/trunk/, I can't fully understand this code without downloading it all and investigating further.
The magic seems to happen here,
public override void Update() {
base.Update();
for (int i = 0; i < coreTemperatures.Length; i++) {
uint eax, edx;
// if reading is valid
if (Ring0.RdmsrTx(IA32_THERM_STATUS_MSR, out eax, out edx,
1UL << cpuid[i][0].Thread) && (eax & 0x80000000) != 0)
{
// get the dist from tjMax from bits 22:16
float deltaT = ((eax & 0x007F0000) >> 16);
float tjMax = coreTemperatures[i].Parameters[0].Value;
float tSlope = coreTemperatures[i].Parameters[1].Value;
coreTemperatures[i].Value = tjMax - tSlope * deltaT;
} else {
coreTemperatures[i].Value = null;
}
}
...
This code extracts the temperature data from the result of Ring0.RdmsrTx.
I believe Ring0 is a C implementation of a ring buffer, the code of which is in the repository here. This reads the Model Specific Register data from the CPU driver.
There is more detail in this question.
Easiest way would be probably to find a tool that can output the information you need in machine-readable way and then process that output. SpeedFan logs temperature to logs, you could just read the latest reading from the logs.
I realize this might not be an ideal solution, but it is the only universal. Querying CPU temperature in a Windows system is not an easy task.
I'm probably very late to answer this, but just in case someone stumbles upon this in the future, here's the way I did it:
public string getCPUTemp()
{
UpdateVisitor updateVisitor = new UpdateVisitor();
Computer computer = new Computer();
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
string res = "";
for (int i = 0; i < computer.Hardware.Length; i++)
{
if (computer.Hardware[i].HardwareType == HardwareType.CPU)
{
for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
{
if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature) res = String.Concat(res, (computer.Hardware[i].Sensors[j].Name + ": " + computer.Hardware[i].Sensors[j].Value.ToString() + "ÂșC" + "\r"));
if (computer.Hardware[i].Sensors[j].Value.ToString() == "") { res = ""; return res; }
}
}
}
It worked perfectly with me (even though it didn't work for the GPU part). You just have to download OpenHardwareMonitor (https://openhardwaremonitor.org/), then add the reference to the OpenHardwareMonitorLib.dll which is in the \openhardwaremonitor\Bin\Debug folder, then add "using OpenHardwareMonitor.Hardware;" at the top.
Hope it can still help someone even if not OP!
So let me give you a rundown of what everything is:
the first section just gets a drives size information
Sizer is a class that returns an array
The arrays contains (size converted to 4 digits,size label, raw size) I pasted the code at the bottom for better understanding
The labels are just labels that will show you the size
Now, I just know deep inside that there is a more efficient way of doing this and I an having a brain fart and can't figure it out. There has got to be a way to do this with a loop or is this really the best way to get this done?
private void driveList_SelectedIndexChanged(object sender, EventArgs e)
{
DriveInfo wow = therehasgottobeanotherway[driveList.SelectedIndex];
if (wow.IsReady)
{
//get drive sizes
long tot = wow.TotalSize;
long free = wow.TotalFreeSpace;
long aval = wow.AvailableFreeSpace;
sizer totSize = new sizer(tot);
sizer freeSize = new sizer(free);
sizer avalSize = new sizer(aval);
String[] tots = totSize.getSizeStringType();
String[] frees = freeSize.getSizeStringType();
String[] avals = avalSize.getSizeStringType();
totalSizeLabel.Text = tots[0] + tots[1];
freeSizeLabel.Text = frees[0] + frees[1];
avalSizeLabel.Text = avals[0] + avals[1];
driveName.Text = wow.VolumeLabel;
}
else
{
driveName.Text = "Drive Not Ready";
}
}
using System;
namespace compy
{
internal class sizer
{
private long fSize;
private String[] fSizer = new String[3];
public sizer(long fs)
{ fSize = fs; }
public String[] getSizeStringType()
{
fSizer[2] = Convert.ToString(fSize);
if (fSize > 0 && fSize < 1024)
{
fSizer[0] = Convert.ToString(fSize);
fSizer[1] = " Bytes";
}
else if (fSize > 1024 && fSize < 1048576)
{
fSizer[0] = Convert.ToString(fSize / 1000);
fSizer[1] = " Kilobytes";
}
else if (fSize > 1048576 && fSize < 1073741824)
{
fSizer[0] = Convert.ToString(fSize / 1000 / 1000);
fSizer[1] = " Megabytes";
}
else if (fSize > 1073741824 && fSize < 1099511627776)
{
fSizer[0] = Convert.ToString(fSize / 1000 / 1000 / 1000);
fSizer[1] = " Gigabytes";
}
else if (fSize > 1099511627776 && fSize < 1.1259e15)
{
fSizer[0] = Convert.ToString(fSize / 1000 / 1000 / 1000);
fSizer[1] = " Terabyte";
}
return fSizer;
}
}
}
What makes you think it needs optimization...does it run slow? Don't mess up readable code to make it run insignificantly faster.
If you want to improve the code, changes lines like this:
else if (fSize > 1048576 && fSize < 1073741824)
to this:
else if (fSize > 0x100000 && fSize < 0x40000000)
PS: Are you sure your numbers are correct?
You could make Sizer a static class and make getSizeStringType() a static method. Then pass in long fSize as an argument.
So driveList_SelectedIndexChanged would look something like this:
DriveInfo wow = therehasgottobeanotherway[driveList.SelectedIndex];
if (wow.IsReady)
{
String[] tots = sizer.getSizeStringType(wow.TotalSize);
String[] frees = sizer.getSizeStringType(wow.TotalFreeSpace);
String[] avals = sizer.getSizeStringType(wow.AvailableFreeSpace);
totalSizeLabel.Text = tots[0] + tots[1];
freeSizeLabel.Text = frees[0] + frees[1];
avalSizeLabel.Text = avals[0] + avals[1];
driveName.Text = wow.VolumeLabel;
}
else
{
driveName.Text = "Drive Not Ready";
}
Aside from that, instead of using arrays in the sizer, you could make a third class that stores the 4 digits, label and raw size. Then the getSizeStringType() method could return an instance of this class instead of an array. That would make things a little less messy but will require more code. But in the end, your asking opinions here.
first of all, your condition is not closed region such as the size is just 1024, 1048576...
there is a loop method but is not a more efficient way
String[] aStrSizeUnit = new String[] { " Bytes", " Kilobytes", " Megabytes", " Gigabytes", " Terabyte" };
int iSizeLevel = 0;
long iSizeTmp = (long)fSize;
fSizer[2] = Convert.ToString(fSize);
while (iSizeTmp > 0)
{
fSizer[0] = Convert.ToString(fSize / Math.Pow(1000 , iSizeLevel));
fSizer[1] = aStrSizeUnit[iSizeLevel];
iSizeTmp /= 1024;
iSizeLevel++;
}
I have found plenty of information on how to look at physical drives but I need to monitor several mount points on my physical drives. I would prefer to do this through wmi but any .NET objects that could do it would be fine as well.
So I figured this one out finally. With WMI its a constant battle against poor documentation and just figuring out this stuff on your own.
RESOURCES
wbemtest for testing your queries
wbemtest reference
scriptomatic for generating wmi scipts in several languages
scriptomatic
The code:
using System;
using System.IO;
using System.Management;
using System.Diagnostics;
namespace Monitor
{
class Program
{
static void Main(string[] args)
{
double Free, Size, FreePercentage;
DateTime Now = DateTime.Now;
string scopeStr = string.Format(#"root\cimv2", "TestSqlServer");
ManagementScope scope = new ManagementScope(scopeStr);
scope.Connect();
string queryString = "SELECT * FROM Win32_Volume WHERE DriveLetter IS NULL";
SelectQuery query = new SelectQuery(queryString);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
Console.WriteLine("Entering Volume loop: ");
foreach (ManagementObject disk in searcher.Get())
{
Console.WriteLine("foreach Volume: ");
//-------------------------------------------------------------------------
//Console.WriteLine("Free %" + double.Parse(disk["FreeSpace"].ToString()) / double.Parse(disk["Capacity"].ToString()) * 100);
FreePercentage = double.Parse(disk["FreeSpace"].ToString()) / double.Parse(disk["Capacity"].ToString()) * 100;
//-------------------------------------------------------------------------
string _MountPoint = disk["Name"].ToString();
//Console.WriteLine("Free: " + disk["FreeSpace"].ToString());
Free = Math.Round(Convert.ToDouble(disk["FreeSpace"]) / (1024 * 1024), 2);
Console.WriteLine("Free: " + Free + " MB");
//Console.WriteLine("Capacity: " + disk["Capacity"].ToString());
Size = Math.Round(Convert.ToDouble(disk["Capacity"]) / (1024 * 1024), 2);
Console.WriteLine("Size: " + Size + " MB");
if (_MountPoint[_MountPoint.Length - 1] == Path.DirectorySeparatorChar)
{
_MountPoint = _MountPoint.Remove(_MountPoint.Length - 1);
}
_MountPoint = _MountPoint.Replace("\\", "\\\\\\\\");
string _MountPointQueryString = "select * FROM Win32_MountPoint WHERE Directory=\"Win32_Directory.Name=\\\"" + _MountPoint + "\\\"\"";
SelectQuery _MountPointQuery = new SelectQuery(_MountPointQueryString);
using (
ManagementObjectSearcher mpsearcher =
new ManagementObjectSearcher(scope, _MountPointQuery))
{
Console.WriteLine("Entering directory Foreach loop: ");
foreach (ManagementObject mp in mpsearcher.Get())
{
Console.WriteLine("Foreach directory: ");
try
{
//Console.WriteLine("Volume: " + mp["Volume"].ToString());
Console.WriteLine("Directory: " + mp["Directory"].ToString());
string Volume = mp["Directory"].ToString().Replace("Win32_Directory.Name=", "");
if (FreePercentage <= 5.00)
{
throw new Exception("\nLabel: " + Volume + "\nSeverity: " + EventLogEntryType.Error + "\nTime: " + Now + "\nMessage: disk space threshhold: " + CalculateUsedSpace(Free, Size) + " % used (" + Free + "MB" + " free)");
}
}
catch (Exception ex)
{
EventLog.WriteEntry("DriveStats Warning", "Message: " + ex.Message, EventLogEntryType.Error);
}
}
}
}
}
}
static double CalculateUsedSpace(double f, double s)
{
double UsedPercentage;
if (s == 0)
{
return f;
}
else if (s >= 0 && f == 0)
{
UsedPercentage = 100.00;
return UsedPercentage;
}
else
{
double UsedSpace = s - f;
UsedPercentage = (UsedSpace / s) * 100;
UsedPercentage = Math.Round(UsedPercentage, 2);
//Console.WriteLine("Used Percentage: " + UsedPercentage);
return Math.Round(UsedPercentage, 2);
}
}
static double CalculateFreePercentage(double f, double s)
{
double FreePercentage;
if (f == 0)
{
FreePercentage = 0;
return FreePercentage;
}
else
{
FreePercentage = (f / s) * 100;
//Console.WriteLine("Free Percentage: " + FreePercentage);
return Math.Round(FreePercentage, 2);
}
}
}
}