I'm trying to figure out, what and how can get as unique identification number or any other kind of ID equivalent from particular Arduino Uno micro-controller from C# desktop application with serial port data
In case of Uno, I have COM3 open:
myport.PortName = comPort;
myport.BaudRate = 9600;
myport.Open();
But I'm not sure, how to read such data as ID of chip, for example with EEPROM Get :
#include <EEPROM.h>
void setup() {
float f = 0.00f;
int eeAddress = 0;
Serial.begin(9600);
while (!Serial) {
}
Serial.print("Read float from EEPROM: ");
EEPROM.get(eeAddress, f);
Serial.println(f, 3);
secondTest(); //Run the next test.
}
struct MyObject {
float field1;
byte field2;
char name[10];
};
void secondTest() {
int eeAddress = sizeof(float);
MyObject customVar;
EEPROM.get(eeAddress, customVar);
Serial.println("Read custom object from EEPROM: ");
Serial.println(customVar.field1);
Serial.println(customVar.field2);
Serial.println(customVar.name);
}
void loop() {}
and C#:
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = myport.ReadExisting();
}
I get some completely misunderstood result:
Read float from EEPROM: ovf
Read custom object from EEPROM:
ovf
95
_^^]]]\\\\fedc
What must be the output variable to get unique id from particular micro-controller:
Serial.println(customVar.field2);
Serial.println(customVar.name);
Atmega328P used in official Arduino UNO does not have any factory-programmed unique ID. However, Atmega328PB does have 10 bytes long preprogrammed serial number.
Atmega328PB seems to be quite compatible with Atmega328P. Differences are described in this application note: http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42559-Differences-between-ATmega328P-and-ATmega328PB_ApplicationNote_AT15007.pdf
You can read serial number with boot_signature_byte_get() function from avr/boot.h: https://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html#gaf375d2543ba38dc56697b4f4bc37a717
There are boards available with Atmega328PB chip, just google for "Atmega328PB arduino".
In case you cannot change the chip, then you would need to generate and program unique ID into your chip yourself.
Related
I'm making a C# Win forms app that reads data from an arduino over serial port, parses it and displays it in a textbox.
My problem is that the value in the textbox is always a few seconds older than the value being sent by arduino even if I slow down the arduino to send the data once per second.
I know the problem must be in my C# code because when I read the serial port using a serial monitor everything's fine.
my code:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
string msgType;
string serialMsg;
serialMsg = port.ReadLine();
if(serialMsg.Substring(0, 1) != "#")
{
return;
}
msgType = serialMsg.Substring(1, 4);
if(msgType == "VOLT") // recieve supply voltage reading
{
textBox1.Invoke((MethodInvoker)delegate { textBox1.Text = serialMsg.Substring(5, serialMsg.Length - 5); });
}
if (msgType == "AMPS") // recieve supply current reading
{
textBox2.Invoke((MethodInvoker)delegate { textBox2.Text = serialMsg.Substring(5, serialMsg.Length - 5); });
}
if (msgType == "LOAD") // recieve load current reading
{
textBox3.Invoke((MethodInvoker)delegate { textBox3.Text = serialMsg.Substring(5, serialMsg.Length - 5); });
}
}
The messages coming from the arduino are in this format: # + TYPE + DATA
Can you tell me what's slowing it down?
I was sending the messages from the arduino too quickly so I put a 50ms delay between them
I also used ReadExisting instead of ReadLine
This solved all the lagging
I am working with the Xamarin Forms in combination with the I2C devices and the Raspberry Pi. I programmed in C# and the Raspberry Pi was installed with Windows IoT. And I have encountered a problem about the parameter access.
I have a microtimer in the UWP project and I want to read the data from the analog input every 100ms. In the OnTimedEvent, there is a caculation which requires the some parameters which are set in the PCL project,the namespace is "I2CADDA.MainPage.xaml.cs". I tried to set these parameters as public static.
public static double gainFactor = 1;
public static double gainVD = 1;
And in the UWP project , I use the dependency service because I have to use the micro timer, so the realization of the interface is done in "I2CADDA.UWP.MainPage.xaml.cs", in the function OnTimedEvent, I tried to get the parameters from PCL project file.
public void OnTimedEvent(object sender, MicroLibrary.MicroTimerEventArgs timerEventArgs)
{
byte[] readBuf = new byte[2];
I2CDevice.ReadI2C(chan, readBuf); //read voltage data from analog to digital converter
sbyte high = (sbyte)readBuf[0];
int mvolt = high * 16 + readBuf[1] / 16;
val = mvolt / 204.7 + inputOffset;
val = val / gainFactor / gainVD; //gainFactor and gainVD shows not exist in current context
}
It seems that the UWP project can not have access to the PCL project in normal way. May I ask how can I solve this problem? Thank you very much!!!
In C#, to call a static Field, you should use the class name to call it,
In your code, the static Fields are in the I2CADDA.MainPage.xaml.cs, and for instance, they are in the I2CADDA.MainPage class, you can call the field as
double Factor = I2CADDA.MainPage.gainFactor;
double VD = I2CADDA.MainPage.gainVD;
So your above code should be like this:
public void OnTimedEvent(object sender, MicroLibrary.MicroTimerEventArgs timerEventArgs)
{
byte[] readBuf = new byte[2];
I2CDevice.ReadI2C(chan, readBuf); //read voltage data from analog to digital converter
sbyte high = (sbyte)readBuf[0];
int mvolt = high * 16 + readBuf[1] / 16;
val = mvolt / 204.7 + inputOffset;
val = val / I2CADDA.MainPage.gainFactor / I2CADDA.MainPage.gainVD;
}
Please also make sure you have reference the PCL in your UWP project.
I'm trying to write a program in C# to communicate with my Arduino UNO from my computer via a serial connection. At the moment I'm just writing a simple application that establishes contact with the Arduino, and then with several controls to control each pin on the arduino; either read a value from it or write a value to it.
I've managed to establish contact with the Arduino and to set pin-values, but it doesn't always want to obey my commands. I set up a few check boxes, and when I check a box, an LED should turn on, and off when I un-check it. The problem is that sometimes the LED's just stay on or off and I have to click the box a few times before it responds again, or reset my circuit...
I was trying to do some fault-finding, but couldn't get to the root of the problem: is it my app or is it the Arduino code?
Here are the relevant pieces of my code:
private void sendValue(int RW, int _Pin, int Val) //send from my app to serial port
{
if (CommPort.IsOpen)
{
CommPort.WriteLine(RW.ToString() + "," + _Pin.ToString() + "," + Val.ToString());
}
}
private void chP9_CheckedChanged(object sender, EventArgs e) //call the sendValue routine
{
if (chP9.Checked)
{
sendValue(1, 9, 255); //('Write', to pin 9, 'On')
}
else
{
sendValue(1, 9, 0); //('Write', to pin 9, 'Off')
}
}
This is my C# code, it compiles a comma-delimited string to send over the serial port to be read by the Arduino.
Here's the Arduino code:
int RW; //0 to read pin, 1 to write to pin
int PN; //Pin number to read or write
int Val; //Value to write to pin
void setup() {
Serial.begin(38400);
}
void loop() {
ReadIncoming();
ProcessIncoming();
}
void ReadIncoming()
{
if(Serial.available() > 0)
{
RW = Serial.parseInt();
PN = Serial.parseInt();
Val = Serial.parseInt();
}
while(Serial.available() > 0) //Clear the buffer if any data remains after reading
{
Serial.read();
}
}
void ProcessIncoming()
{
if(RW == 0)
{
pinMode(PN, INPUT);
}
else
{
pinMode(PN, OUTPUT);
analogWrite(PN, Val);
}
}
parseInt just takes out the first integer value it finds, stores it and throws away the comma, and does it again and again, but it seems a bit counter-intuitive.
I think my problem lies here:
while(Serial.available() > 0) //Clear the buffer if any data remains after reading
{
Serial.read();
}
I think the App is sending data faster than the Arduino code could handle, especially with this loop, but what do I do with excess data?
I don't like to use the parseInt, but it's the only way I could find to read my instructions correctly. How do I send a byte array from C# and read that array into an array in Arduino?
I've pointed out my hypotheses, and explored alternatives but couldn't get any solutions. What suggestions do you guys have for me?
It is not that clear to me why it works at all. You ought to consider a smarter way to encode the command. You need only three bytes:
private void sendValue(int RW, int _Pin, int Val) {
var cmd = new byte[] { (byte)RW, (byte)_Pin, (byte)Val };
ComPort.Write(cmd, 0, cmd.Length);
}
Then you just need to read those 3 bytes on the Arduino end:
void ReadIncoming() {
if (Serial.available() >= 3) {
RW = Serial.read();
PN = Serial.read();
Val = Serial.read();
ProcessIncoming();
}
}
How to Control USB to Parallel Port using C#?
USB to Parallel Port: IEEE-1284 (36Pins)
IEEE-1284 Pin Configuration Image:
http://i.stack.imgur.com/b75Z5.png
OS(Operating System): Windows 7 x64
Programming Language: C#
My Code:
private void button1_Click(object sender, EventArgs e)
{
try
{
int address = System.Convert.ToInt16(textBox1.Text);
int value = System.Convert.ToInt16(textBox2.Text);
AccessPort.output(address, value);
}
catch(Exception ex)
{
MessageBox.Show("Error: " + ex.ToString());
}
}
AccessPort Class:
static class AccessPort
{
[DllImport("inpout32.dll", EntryPoint = "Out32")]
public static extern void output(int address, int value);
[DllImport("inpout32.dll", EntryPoint = "Inp32")]
public static extern int input(int adress);
}
I have LED(Light Emitting Diode) Connected to D0. When I Set Address to 1 and Value to 1 and Click Button it dont gives Error but LED wont Light UP because inpout32.dll is library for real Parallel Port but I have USB to Parallel Port or My Address and Value is Incorrect for USB to Parallel Port.
How to Light Up LED with USB to Parallel Port(LPT) using C# Programming Language ?
What is wrong there is that the port adress isn't 1. To check the port adress go to device manager, expand ports(COM & LPT), double click the lpt port(parallel port) that you want and go to the tab resources and get this value(see the link below)
http://i.imgur.com/kcEMCGY.png
then, you must change how you convert the address to a int, because the port address will be in hexadecimal:
int address = System.Convert.ToInt16(textBox1.Text, 16);
then in the address textbox just put that value(in my case it's 0378).
I am currently working on a robotics project with Arduino. I want to access the serial port from different methods at different times.
For instance, I want to read the ADC at time t1 and get the motor currents at time t2. So I create readADC() and motorCurrents() methods which should both return int arrays of different sizes. The serial port data received is given below.
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int n = serialPort1.BytesToRead;
serialPort1.Read(data, 0, data.Length);
}
I have implemented all the relevant coding on the Arduino side. I also have set the serial port. I need to implement the following commands in C#
private int[] ReadADC()
{
string input = "AN\n"; // This is the command for reading the ADC on the Wildthumper board.
serialPort1.Write(input);
// The Wildthumper now sends 11 bytes, the last of which is '*' and the first
// 10 bytes are the data that I want. I need to combine two bytes together
// from data received and make five values and return it.
for (int i = 0; i < 5; i++)
{
adcValues[i] = data[0 + i * 2] <<8+ data[1 + i * 2];
}
return adcValues;
// Where data is the bytes received on serial port;
}
Similarly:
private int[] getMotorCurrents()
{
string input = "MC\n"; // Wildthumper board command
serialPort1.Write(input);
// The Wildthumper now sends 5 bytes with the last one being '*'.
// And the first four bytes are the data that I want.
for (int i = 0; i < 2; i++)
{
MotorCurrents[i] = data[0 + i * 2] <<8 +data[1 + i * 2];
}
return MotorCurrents;
}
First of all, the number of bytes sent to me change. So how can I use a global variable? For data (the variable used to store serial data received as given above)?
You need to create a global variable and save the data to it when data received fires. This isn't hard.
Here is a code example:
public class myclass{
public string arduinoData = "";
private void serialPort1_DataReceived(
object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
this.arduinoData = serialPort1.ReadLine(data, 0, data.Length);
}
//....The rest of your code, such as main methods, etc...
}