Hi, I have to code an Arduino Relay controling software in C# for my final exam.
I have an Arduino Uno Wifi Rev2, a 4 relay shield (original Arduino).
Based on some codes that can be found on the Internet, I wrote this C# code (see Arduino code below):
using System;
using System.Collections.Generic;
using System.ComponentModel;
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 serial_port_teszt
{
public partial class Form1 : Form
{
SerialPort port;
public Form1()
{
InitializeComponent();
try
{
if (port == null)
{
port = new SerialPort("COM3", 9600);
port.Open();
}
}
catch (Exception)
{
throw;
}
}
private void r1_be_Click(object sender, EventArgs e)
{
PortWrite("a");
}
private void r1_ki_Click(object sender, EventArgs e)
{
PortWrite("b");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (port != null && port.IsOpen)
{
port.Close();
}
}
private void PortWrite(string m)
{
port.Write(m);
}
}
}
And this Arduino code:
String b;
int rele = 4;
int releAllapot = 0;
void setup() {
// put your setup code here, to run once:
pinMode(rele, OUTPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
b = String(Serial.read());
Serial.println(b);
if (b == "a") {
releAllapot = 1;
}
if (b == "b") {
releAllapot = 0;
}
digitalWrite(rele, releAllapot);
}
}
In the Arduino code I tried to use char instead of string, but nothing changed.
In the Arduino IDE I can control the relay with the serial monitor, but with the C# code I can't, and I don't understand why this codes aren't working, neither ChatGPT.
The BAUD and the port (COM4) are right and the same in both code.
So I hope some of you can help me, because I have to present this in two weeks.
Unfortunatelly, I can't use the Arduino IDE and the C# software at the same time, because if I use the IDE, the Visual Stuido can't use the same port...
When I only use the IDE and then I print the data to the serial port, everything works fine - obviously.
Unfortunatelly, the Uno Wifi Rev2 the only Arduino board I have.
I don't have any LCD display or other equipments like that. And if it's not necessary, I don't want to buy any just for this. I don't have enough time to experiment with this...
I thought that the IDE serial monitor and the C# code will able to run at the same time, and with (for example) Serial.println() I can monitor the datas, but don't.
Since I wrote the post I kept testing different codes, and I found one that give me a little step forward: the RX LED is now blinking when I click the button in the C# software, so now the only issue that I don't know why the other part of the code doesn't work.
C# code:
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace konzol_teszt
{
internal class Program
{
static void Main(string[] args)
{
string portName = "COM3";
int baudRate = 9600;
SerialPort arduinoPort = new SerialPort(portName, baudRate);
try
{
arduinoPort.Open();
Console.WriteLine("Soros port nyitva. A és B karaktereket küldhet.");
while (true)
{
Console.Write("Karakter küldése (A vagy B): ");
char input = Char.ToUpper(Console.ReadKey().KeyChar);
if (input == 'A' || input == 'B')
{
arduinoPort.Write(new byte[] { (byte)input }, 0, 1);
Console.WriteLine("\nKarakter elküldve: " + input);
}
else
{
Console.WriteLine("\nCsak A vagy B karaktereket fogadunk el.");
}
}
}
catch (Exception ex)
{
Console.WriteLine("Hiba történt: " + ex.Message);
}
finally
{
arduinoPort.Close();
}
}
}
}
Arduino code:
char receivedChar;
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
receivedChar = ' ';
}
void loop() {
if (Serial.available() > 0) {
receivedChar = Serial.read();
Serial.println(receivedChar);
if (receivedChar == 'A') {
digitalWrite(LED_BUILTIN, HIGH); // LED bekapcsolása
}
if (receivedChar == 'B') {
digitalWrite(LED_BUILTIN, LOW); // LED kikapcsolása
}
}
}
Yeah I tested the original one with IDE's serial monitor, with that were no problem.
With the newer one I may have an issue: after the letter B I get one cube character.
I think I end this for today because I'm kinda tired and I don't want to make any mistake by skip an obvious step in the coding or testing process.
Consider changing the C# code to display any message that is not an expected reply from the Arduino and change the Arduino code to write any debug messages to the C# on the PC. Then you can print debug messages and read them on the same PC.
Thanks for the idea, I tried it, and no response arriving from the Arduino to the C# code. The RX LED still blink for a moment when I sending an A or B letter from the console app.
I'm tried to add delay to each code, but nothing has changed. Maybe the C# code send the letter in wrong variable type?
For that matter, post the code each time you make a change and want some help with it - it's really hard to debug by guessing exactly what changed on each end.
Given that you see square symbols instead of readable chars, you might try echoing back the ascii value of each char the Arduino gets.
Have you tried changing the C# code to write to a text file instead of the serial port? Then you can test the code and check what has been written to the file after.
Thanks for the ideas, I tried all of them, the results:
Writing the letters I send (and get) to a txt: everything is all right, it's writing A and B letters to the .txt file. I tried to write out the letters that sent back from the Arduino, but Arduino doesn't send anything back.
Character to integer: The A is 65, the B is 66. As I can see, this is the decimal value of the letters in the ASCII table.
This is the codes I use right now, and I won't change until any new suggestions. I hope this is useful information to get this story to the end and solve it finally - I'm out of ideas for now...
The C# code:
using System;
using System.IO;
using System.IO.Ports;
namespace konzol_teszt
{
internal class Program
{
private static string kuldesiLogFileName = "kuldesi.log"; // A küldési log fájl neve
private static string erkezesiLogFileName = "erkezesi.log"; // Az érkezési log fájl neve
static void Main(string[] args)
{
string portName = "COM3";
int baudRate = 9600;
SerialPort arduinoPort = new SerialPort(portName, baudRate);
try
{
arduinoPort.Open();
arduinoPort.DataReceived += ArduinoDataReceived; // Hozzáadjuk a kezelőt az adat fogadásához
Console.WriteLine("Soros port nyitva. A és B karaktereket küldhet.");
while (true)
{
Console.Write("Karakter küldése (A vagy B): ");
char input = Char.ToUpper(Console.ReadKey().KeyChar);
if (input == 'A' || input == 'B')
{
arduinoPort.Write(input.ToString()); // Karakterként küldjük az adatot
Console.WriteLine("\nKarakter elküldve: " + input);
// Cast the character to an integer and print it
int charAsInt = (int)input;
Console.WriteLine("Karakter értéke mint integer: " + charAsInt);
// Mentjük a küldött adatokat a küldési log fájlba
using (StreamWriter writer = File.AppendText(kuldesiLogFileName))
{
writer.WriteLine(DateTime.Now + ": " + input);
}
// Várakozás egy kis időt, hogy a válasz elküldődjön
System.Threading.Thread.Sleep(100); // Várakozás 100 milliszekundumig
}
else
{
Console.WriteLine("\nCsak A vagy B karaktereket fogadunk el.");
}
}
}
catch (Exception ex)
{
Console.WriteLine("Hiba történt: " + ex.Message);
}
finally
{
arduinoPort.Close();
}
}
private static void ArduinoDataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;
string data = port.ReadExisting(); // Olvassuk ki az érkező adatokat
Console.WriteLine("\nArduino válasza: " + data);
// Mentjük az érkező adatokat az érkezési log fájlba
using (StreamWriter writer = File.AppendText(erkezesiLogFileName))
{
writer.WriteLine(DateTime.Now + ": " + data);
}
}
}
}
I tried with an other code to send the ASCII numbers from C# to Arduino, this doesn't worked too. There's no working solution with C# and Uno Wifi Rev2 at my current knowlege. I don't understand why the codes from the internet doesn't work, and I don't understand either why my codes doesn't work. I think there's a problem with the Arduino board, no other options left as I see.
@kodonci here is a slightly modified version that displays info in the console app, do NOT use the serial monitor.
C#
using System.IO;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.IO.Ports;
namespace konzol_teszt
{
internal class Program
{
static void Main(string[] args)
{
string portName = "COM3";
int baudRate = 9600;
SerialPort arduinoPort = new SerialPort(portName, baudRate);
try
{
arduinoPort.Open();
arduinoPort.DataReceived += ArduinoDataReceived; // Hozzáadjuk a kezelőt az adat fogadásához
arduinoPort.ReadExisting();
Console.WriteLine("Soros port nyitva. A és B karaktereket küldhet.");
while (true)
{
Console.Write("Karakter küldése (A vagy B): ");
char input = Char.ToUpper(Console.ReadKey().KeyChar);
if (input == 'A' || input == 'B')
{
arduinoPort.Write(input.ToString()); // Karakterként küldjük az adatot
Console.WriteLine("\nKarakter elküldve: " + input);
// Cast the character to an integer and print it
int charAsInt = (int)input;
Console.WriteLine("Karakter értéke mint integer: " + charAsInt);
}
else
{
Console.WriteLine("\nCsak A vagy B karaktereket fogadunk el.");
}
}
}
catch (Exception ex)
{
Console.WriteLine("Hiba történt: " + ex.Message);
}
finally
{
arduinoPort.Close();
}
}
private static void ArduinoDataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = (SerialPort)sender;
string data = port.ReadLine(); // Olvassuk ki az érkező adatokat
Console.WriteLine("\nArduino válasza: " + Convert.ToString(data) + "\n\n\n");
}
}
}