C# Mono DataReceived does not respond

Hi I have this C# code example and I'm trying to run it on monodevelop:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace Serial
{
    class Program
    {
	  static SerialPort port;
		
	  static void Main(string[] args)
	  {
		Console.WriteLine("Beging Serial...");
		BeginSerial(9600, "/dev/ttyACM0");
		port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
		port.Open();
		Console.WriteLine("Serial Started.");
		Console.WriteLine(" ");
		Console.WriteLine("Ctrl+C to exit program");
		Console.WriteLine("Send:");

		for (; ; )
		{
		    Console.WriteLine(" ");
		    Console.Write("> ");
		    port.WriteLine(Console.ReadLine());
		}
	  }

	  static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
	  {
		for (int i = 0; i < (10000 * port.BytesToRead) / port.BaudRate; i++);	 //Delay a bit for the serial to catch up
		Console.WriteLine(port.ReadLine());
	  }

	  static void BeginSerial(int baud, string name)
	  {
		port = new SerialPort(name, baud);
	  }
    }
}

I debug the code step by step but static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) doesn't seem to trigger so I don't get the arduino reply

arduino code that works on arduino IDE serial monitor:

int sensorPin = 0; 
int photocellPin = 1;
int photocellReading;
 
void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);   
}
 
void loop(void) {
  if (Serial.available() > 0)
  {
    char sr = Serial.read();

    switch(sr)
    {
      case '0':
      {
        // Temp measurement
        int reading = analogRead(sensorPin);  
         
        // converting that reading to voltage, for 3.3v arduino use 3.3
        float voltage = reading * 5.0;
        voltage /= 1024.0; 
         
        // print out the voltage
        //Serial.print(voltage); Serial.println(" volts");
         
        // now print out the temperature
        float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
        //to degrees ((volatge - 500mV) times 100)
        Serial.println(temperatureC); //Serial.println(" degress C");
        
        // now convert to Fahrenheight
        /*float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
        Serial.print(temperatureF); Serial.println(" degress F");*/
        break;
      }
      case '1':
      {
        // Light measurement
        photocellReading = analogRead(photocellPin);  
         
        Serial.print("Photocell reading = ");
        Serial.print(photocellReading); // the raw analog reading
         
        // We'll have a few threshholds, qualitatively determined
        if (photocellReading < 10) {
        Serial.println(" - Dark");
        } else if (photocellReading < 200) {
        Serial.println(" - Dim");
        } else if (photocellReading < 500) {
        Serial.println(" - Light");
        } else if (photocellReading < 800) {
        Serial.println(" - Bright");
        } else {
        Serial.println(" - Very bright");
        }
        break;
      }
      case '2':
      {
        Serial.println("No implementation for analog pin A2");
        break;
      }
      case '3':
      {
        Serial.println("No implementation for analog pin A3");
        break;
      }
      case '4':
      {
        Serial.println("No implementation for analog pin A4");
        break;
      }
      case '5':
      {
        Serial.println("No implementation for analog pin A5");
        break;
      }
    }
  }
}

Any ideas?

Thanks in advanced!

PS: Arduino rocks!

in "ordinary MS" c# you can define what char(s) define a new line on the serial port.

I had some strange problems with a VB.net program until i defined that in the port declaration.

I don't have my VB code here right now, but you should be able to figure it out.

Also you probably need to define some of the other port settings as well.

		for (int i = 0; i < (10000 * port.BytesToRead) / port.BaudRate; i++);	 //Delay a bit for the serial to catch up

This is crap. The readLine function on the next line blocks until a carriage return is received, so farting around for a while before calling the function is useless.

Why are all your functions static?

The Arduino does not respond until it receives some serial data. Perhaps it would be useful to blink the LED or watch the receive LED ((and tell us what you are sending) to verify that the Arduino actually receives something.

What happens if you open the Serial Monitor, instead, and send data from there?

PaulS:

		for (int i = 0; i < (10000 * port.BytesToRead) / port.BaudRate; i++);	 //Delay a bit for the serial to catch up

This is crap. The readLine function on the next line blocks until a carriage return is received, so farting around for a while before calling the function is useless.

Why are all your functions static?

The Arduino does not respond until it receives some serial data. Perhaps it would be useful to blink the LED or watch the receive LED ((and tell us what you are sending) to verify that the Arduino actually receives something.

What happens if you open the Serial Monitor, instead, and send data from there?

As I said with serial monitor everything goes well.

Static because it's a console app.

Arduino receives the command, the led blinks, the problem is not the arduino but the DataReceived event in C#. It never raises. I use some lame code like...

		    port.WriteLine(Console.ReadLine());
			Console.Write(port.ReadExisting());

and I get responses from arduino, that means that works, but after a while the program stuck.

I still believe that the problem is that the datareceived event doesn't raise and I can't find out why.

Any code modification you have to propose?

Thanks

Try port.read in stead of port .readline.

Also in ordinary MS C# you need to use a delegate for the function that reads the serial port becaue the UI and the serial stuff runs in two different threads.

I don't know is this is the case when you use MONO and console apps.

MikMo:
Try port.read in stead of port .readline.

same thing, after some replies it gets stuck, something like buffering

I modified my post with the delagate stuff, don't know if it is relevant in youe case.

I think I might have had this problem before, to solve it, I just used a timer object's onTick to poll the serial port instead.

My temporary solution...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace Serial
{
    class Program
    {
		static SerialPort port;
		
		static void Main(string[] args)
		{
			BeginSerial(9600, "/dev/ttyACM0");
			port.Open();
			
			while (true)
			{
				string reader = Console.ReadLine();
				if(reader.Length > 0)
				{
					port.WriteLine(reader);
					Thread PortListener = new Thread(ListenPort);
					PortListener.IsBackground = true;
					PortListener.Start();
				}
			}
		}
		
		static void ListenPort() {
			Console.WriteLine(port.ReadLine());
		}
		
		static void BeginSerial(int baud, string name)
		{
			port = new SerialPort(name, baud, Parity.None, 8, StopBits.One);
		}
    }
}

at least it works :slight_smile:

Good. It's kind of like using a delegate :slight_smile:

Yes, I try to use delegate but I couldn't manage