I made a small gadget with an Arduino that sends 2 values via serial to my c# program (potentiometer value for volume and switch button to change output device). The volume part is already complete but I'm not being able to change between the two output devices (monitor audio and Headphones).
My code at the moment:
using AudioSwitcher.AudioApi.CoreAudio;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Volume
{
public partial class Form1 : Form
{
//msg recieved by serial
String msg;
string[] tokens;
//active device
CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
String PHONES = "Headphones (Razer Kraken USB)";
String COLUNA = "ASUS VP228-4 (NVIDIA High Definition Audio)";
public Form1()
{
//open port for serial msg and start timmer
InitializeComponent();
serialPort1.Open();
timer1.Enabled = true;
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//handling of the msg
msg = serialPort1.ReadLine();
tokens = msg.Split('%');
}
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = tokens[0];
label2.Text = tokens[1];
label6.Text = defaultPlaybackDevice.FullName;
//change volume
defaultPlaybackDevice.Volume = Int32.Parse(tokens[0]);
//change output device
if (tokens[1] == "ON")
{
if (defaultPlaybackDevice.FullName == PHONES)
{
//do nothing
}
else
{
//change to monitor output
}
}
else
{
if (defaultPlaybackDevice.FullName == COLUNA)
{
//do nothing
}
else
{
//change to headphones
}
}
}
}
}
I am using an API called AudioSwitcher.AudioApi.CoreAudio which should allow me to do what I want but I am not being able to find how.
First you need to get all the PlaybackDevices
IEnumerable<CoreAudioDevice> devices = new CoreAudioController().GetPlaybackDevices();
and then you can make a function to change your Default playbackdevice with the fullname like this
private void ChangeOutput(string op)
{
foreach (CoreAudioDevice d in devices)
{
if (d.FullName == op)
d.SetAsDefault();
}
}
Related
I am trying to make a program for controlling axis servos but have a small problem with sending values to the Arduino through serial (USB). It seems data don't arrive in the correct format. For purpose of testing, I made a special Arduino code to see what's wrong.
Arduino code:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
String received;
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available()>0)
{
received=Serial.readString();
}
Serial.println("received: "+received);
}
C# code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
namespace ServoControl
{
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
}
SerialPort Sp = new SerialPort();
String AngleX = "0";
String AngleY = "0";
String AngleZ = "0";
String rec = "";
private void Form1_Load(object sender, EventArgs e)
{
Sp.PortName = "COM8";
Sp.BaudRate = 9600;
Sp.DataReceived += Sp_DataReceived;
}
private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
rec=Sp.ReadLine();
}
//when value changed on slider
private void xAxisServo_Scroll(object sender, EventArgs e)
{
if (AngleX!= xAxisServo.Value.ToString())
{
AngleX = xAxisServo.Value.ToString(); valueXaxis.Text = AngleX;
}
if (Sp.IsOpen == true & int.Parse(AngleX) <= 180)
{
Sp.WriteLine(AngleX.ToString());
}
else
{
Sp.Open();
}
}
//when value changed in value box
private void valueXaxis_TextChanged(object sender, EventArgs e)
{
if (int.TryParse(valueXaxis.Text, out int res)==true && int.Parse(valueXaxis.Text)<=180)
{
AngleX = valueXaxis.Text;
xAxisServo.Value = int.Parse(AngleX);
}
if (int.TryParse(valueXaxis.Text, out int res2) == true && int.Parse(valueXaxis.Text) > 180)
{
AngleX = "180";
}
if (Sp.IsOpen == false)
{
Sp.Open();
}
if (Sp.IsOpen == true)
{
Sp.WriteLine(AngleX.ToString());
}
}
private void timer1_Tick(object sender, EventArgs e)
{
textBox1.Text = rec;
}
}
}
I was able to send one value for axis X by function Serial.parseInt(); I was able to read a value from a string in Arduino, but I need to send more than one and I have problem with sending and receiving string.
I have tested a lot with Arduino serial monitor and it seems when sending through builtin monitor in Arduino IDE it works as expected got correct string back, but when using C# checking through textbox1 it shows only received and when not interrupted shows an only bunch of nonsense changing every second.
In reaction to that, I've tried to replace WriteLine with Write because I don't know the background of Arduino very well so I don't how Arduino proceeds data using Serial.readString();.
I've tried to find how builtin serial monitor in Arduino IDE works if in C# or if not in C# at least how are data send.
Any idea why I am getting different results with IDE serial monitor and C#.
Concatenate the Serial.read then add a terminating character to cut the concatenation:
char received;
while(Serial.available()>0)
{
if(received=='#') // put the # in the end of your data
{
Serial.println("received: "+String(received));
break;
}
received+=Serial.read();
}
THIS QUESTION MAY SEAM A DUPLICATE, BUT NOT. after a long period of search on internet and no, result, then had to seek for assistance.
All solutions apply to loading available ports in a combo box and the user checks one at a go. But the automation feature then dies.
thus, im looking for assistance on how the modem can connect automatically from the available ports without user interaction (USER FRIENDLINESS)
FOR THE COMBO BOX, IT IS WORKING FINE AS BELOW,
using GsmComm.GsmCommunication;
using GsmComm.PduConverter;
using GsmComm.Server;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace COMM_All
{
public partial class Comm_F : Form
{
public Comm_F()
{
InitializeComponent();
}
private void COM_PORTS()
{
string[] ports = SerialPort.GetPortNames();
txtGPort1.Items.AddRange(ports);
txtGPort2.Items.AddRange(ports);
}
private void Form1_Load(object sender, EventArgs e)
{
COM_PORTS();
}
private void Modem1_Click(object sender, EventArgs e)
{
if (txtGPort1.Text == "") { MessageBox.Show("Invalid Port Name"); return; }
comm = new GsmCommMain(txtGPort1.Text, 9600, 8);
Cursor.Current = Cursors.Default;
bool retry;
do
{
retry = false;
try
{
Cursor.Current = Cursors.WaitCursor; comm.Open(); Cursor.Current = Cursors.Default;
//MessageBox.Show("Modem Connected Sucessfully");
txtGStatus1.Text = "Connected Sucessfully";
comm.EnableMessageNotifications();
MessageBox.Show("Message notifications activated.");
}
catch (Exception)
{
Cursor.Current = Cursors.Default;
if (MessageBox.Show(this, "GSM Modem is not available", "Check",
MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning) == DialogResult.Retry)
retry = true;
else { return; }
}
} while (retry);
}
}
}
Note: Computer has multiple usb devices;
I am new to access arduino using C#.
I am using Arduino Uno board for serial communication using my C# code. But when i Open the Serial port and wait for some time to ready the serial port, I am getting Question Marks(????) on serial port. I don't know why this happen.
I am using "Threading.Sleep" after opening the port. If i remove it, then it works fine. How can i wait after opening the port? I wants to wait for some time after opening the Serial Port for further process.
Thank you.
Arduino code:
void setup()
{
Serial.begin(115200);
pinMode(13, OUTPUT);
}
void loop()
{
if (Serial.available() > 0)
{
String data = Serial.readString();
Serial.print(data);
if (data == "Ping")
{
Serial.write("OK");
}
if (data == "ON")
{
digitalWrite(13, HIGH);
}
else
{
digitalWrite(13, LOW);
}
}
}
C# Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO.Ports;
namespace Form1.cs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
comboBox1.Items.Clear();
foreach (string port in SerialPort.GetPortNames())
{
comboBox1.Items.Add(port);
Console.WriteLine("Port Added.");
}
}
private void ConBtn_Click(object sender, EventArgs e)
{
serialPort1.PortName = comboBox1.SelectedItem.ToString();
if (serialPort1.IsOpen == false)
{
serialPort1.Open();
if (serialPort1.BytesToRead > 0)
{
Console.WriteLine("value in buffer");
string val = serialPort1.ReadExisting();
Console.WriteLine(val);
}
}
Thread.Sleep(1000);
Console.WriteLine("#####");
string bufferval3 = serialPort1.ReadExisting(); //Question Mark displaying between this.
Console.WriteLine(bufferval3);
Console.WriteLine("#####");
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
Console.WriteLine("Port Closed.");
}
}
private void DisConBtn_Click(object sender, EventArgs e)
{
serialPort1.Close();
Status.Text = "Disconnected";
Status.ForeColor = Color.DarkRed;
}
private void OnBtn_Click(object sender, EventArgs e)
{
serialPort1.Write("ON");
}
private void OffBtn_Click(object sender, EventArgs e)
{
serialPort1.Write("OFF");
}
}
}
What I have is a medical record database that is accessed via PuTTY (SSH client). The cards themselves will only have Client name, record number in a barcode format (still determining the barcode type to be used), and client registration date.
1) We can get the data output as .zpl for Zebra Barcode label printers or formats compatible with laser printers like HP or Brother in a RAW format.
2) What output WILL the ZXP 3 SDK accept?
3) Can the SDK be set up to wait for and accept data coming at it using a command line from something like RedMon?
The cards themselves will only have the printed data, no mag stripe, smart chips, laminates or anything like that.
Mahalo in advance.
I would not recommend using either RedMon nor the SDK, as neither are required for what you are trying to do, and they both are time-vampires. Instead, I would write a small Windows Forms application which listens on a TCP port to receive the print job and send it to the standard printer which uses the Zebra driver.
Have the MUMPS application send an XML document via the Remote Print support in VT100. The example I have been using is below:
^[[5i
<patient>
<name first="John" last="Smith" />
<mrn>A04390503</mrn>
<dob>1991-03-12</dob>
</patient>
^[[4i
Configure a printer on the windows client to redirect to TCP/IP:
Add Printer
Local printer
Create a new port
Standard TCP/IP Port
Hostname: 127.0.0.1
Port name: CardFormatter
Uncheck "Query the printer and automatically select the driver to use"
Device type: Custom
Protocol: Raw
Port: 9101
Driver: Generic / Text Only
Start the application at logon, and print from the server. The MUMPS application will send back the XML, which Putty prints to the Text printer, which gets sent to the C# application on localhost. The C# application interprets the XML and prints to the actual printer via the Zebra driver or SDK.
Note: This only assumes one interactive session per workstation. If you are using fast-user-switching or terminal services, further care must be taken to ensure things work properly.
Example App:
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TrayApplicationContext());
}
}
}
TrayApplicationContext.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
trayIcon.Dispose();
}
}
}
}
PrintHandler.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace PassThroughPrinterTest
{
partial class PrintHandler : Form
{
public PrintHandler()
{
InitializeComponent();
}
public void HandlePrintData(object sender, PrintDataReceivedEventArgs args)
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler<PrintDataReceivedEventArgs>(HandlePrintData), sender, args);
return;
}
this.Show();
var sXml = Encoding.UTF8.GetString(args.PrintData);
this.PrintCard(XDocument.Parse(sXml));
this.Hide();
}
private void PrintCard(XDocument xDocument)
{
var nameElement = xDocument.Root.Element("name");
var lastName = nameElement.Attribute("last").Value;
var firstName = nameElement.Attribute("first").Value;
var mrn = xDocument.Root.Element("mrn").Value;
var printDoc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
PrinterName = "Adobe PDF"
},
DocumentName = "Patient ID Card"
};
var cardPaperSize = new PaperSize("Card", 337, 213) { RawKind = (int)PaperKind.Custom };
printDoc.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrintPage += (s, e) =>
{
var gfx = e.Graphics;
// print the text information
var fArial12 = new Font("Arial", 12);
gfx.DrawString(lastName, fArial12, Brushes.Black, new RectangleF(25, 25, 200, 75));
gfx.DrawString(firstName, fArial12, Brushes.Black, new RectangleF(25, 100, 200, 75));
// add a code39 barcode using a barcode font
// http://www.idautomation.com/free-barcode-products/code39-font/
// var fCode39 = new Font("IDAutomationHC39M", 12);
// gfx.DrawString("(" + mrn + ")", fArial12, Brushes.Black, new RectangleF(25, 200, 200, 75));
// or by using a barcode library
// https://barcoderender.codeplex.com/
// var barcode = BarcodeDrawFactory.Code128WithChecksum.Draw(mrn, 20, 2);
// gfx.DrawImage(barcode, 50, 200);
e.HasMorePages = false;
};
printDoc.Print();
}
}
}
PrintListener.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace PassThroughPrinterTest
{
sealed class PrintListener : IDisposable
{
private TcpListener listener;
public event EventHandler<PrintDataReceivedEventArgs> PrintDataReceived;
public PrintListener(int port)
{
this.listener = new TcpListener(IPAddress.Loopback, port);
this.listener.Start();
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
public void Dispose()
{
this.listener.Stop();
}
private void listener_AcceptClient(IAsyncResult iar)
{
TcpClient client = null;
bool isStopped = false;
try
{
client = this.listener.EndAcceptTcpClient(iar);
}
catch (ObjectDisposedException)
{
// this will occur in graceful shutdown
isStopped = true;
return;
}
finally
{
if (!isStopped)
{
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
}
Debug.Assert(client != null);
try
{
byte[] printData;
using (var clientStream = client.GetStream())
using (var buffer = new MemoryStream())
{
clientStream.CopyTo(buffer);
printData = buffer.ToArray();
}
OnPrintDataReceived(printData);
}
catch
{
// TODO: add logging and error handling for network issues or processing issues
throw;
}
finally
{
client.Close();
}
}
private void OnPrintDataReceived(byte[] printData)
{
var handler = PrintDataReceived;
if (handler != null)
{
handler(this, new PrintDataReceivedEventArgs(printData));
}
}
}
}
TrayApplicationContext.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
listener.Dispose();
trayIcon.Dispose();
}
}
}
}
PrintDataReceivedEventArgs.cs
using System;
namespace PassThroughPrinterTest
{
class PrintDataReceivedEventArgs : EventArgs
{
public byte[] PrintData { get; set; }
public PrintDataReceivedEventArgs(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
this.PrintData = data;
}
}
}
This program is used to display the data and store the data into a txt file using the input from the pic18f4550.
when the GUI received the input data is '1 ', the GUI should display the data and store the data into a txt file. data can be saved, but the data are keep repeating itself without stopping if the input is still in a state of '1 '.
how should i do, if i want to store the data just once even the input still '1'?
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Monitoring_System
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
// Create the USB reference device object (passing VID and PID)
theUsbDemoDevice = new usbDemoDevice(0x04D8, 0x003F);
// Add a listener for usb events
theUsbDemoDevice.usbEvent += new usbDemoDevice.usbEventsHandler(usbEvent_receiver);
// Perform an initial search for the target device
theUsbDemoDevice.findTargetDevice();
}
// Create an instance of the USB reference device
private usbDemoDevice theUsbDemoDevice;
// Listener for USB events
private void usbEvent_receiver(object o, EventArgs e)
{
// Check the status of the USB device and update the form accordingly
if (theUsbDemoDevice.isDeviceAttached)
{
// Device is currently attached
// Update the status label
usb_status.Text = "Status : USB Device Connected";
}
else
{
// Device is currently unattached
// Update the status label
usb_status.Text = "Status : USB Device Unplugged";
cr1v.Visible = false;
cr1i.Visible = false;
cr2v.Visible = false;
cr2i.Visible = false;
cr3v.Visible = false;
cr3i.Visible = false;
tr1v.Visible = false;
tr1i.Visible = false;
tr2v.Visible = false;
tr2i.Visible = false;
tr3v.Visible = false;
tr3i.Visible = false;
}
}
private void button_exit_Click(object sender, EventArgs e)
{
this.Hide();
Form4 f2 = new Form4();
f2.ShowDialog();
}
private void timer1_Tick_1(object sender, EventArgs e)
{
if(theUsbDemoDevice.isDeviceAttached)
{
// Read the push button state
bool sw1 = theUsbDemoDevice.sw1();
if (sw1 == true)
{
cr1i.Visible = false;
cr1v.Visible = true;
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"D:\Desktop\log data.txt", true))
{
file.WriteLine("Class Room 1 in use");
file.Close();
}
}
else if (sw1 == false)
{
cr1i.Visible = true;
cr1v.Visible = false;
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"D:\Desktop\log data.txt", true))
{
file.WriteLine("Class Room 1 vacant");
file.Close();
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Hide();
Form5 f2 = new Form5();
f2.ShowDialog();
}
}
}
It looks like you are using a timer. Every tick your timer is writing to a file. You need to re-work your logic to either not include a timer. Or, disable it after a write, and re-enable it on another event.