Can't store the values I get from my temperature in the database.

I am working on a project where I use the DS18B20 temperature sensor with Arduino to get the temperature, and then I store these temperatures in an Access database. Now I was able to get the temperature values from DS18B20 and show them using the Arduino software. But for the second part of my work, I did a windows form application that contains a code that is supposed to take these temperature values and store them in the database. but when I run this application, as soon as I press any of the buttons in it, I get the following error:

"An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll Additional information: The port is closed."

This exception only appears when I have the arduino software running and getting the temperature values. When it's not running, nothing happens, and the buttons don't work. here is the code of my WFApplication.

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.Ports;

namespace test1
{
    public partial class Form1 : Form
    {
        int j = 0;
        SerialPort sp1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            sp1 = new SerialPort("COM4", 9600);
            sp1.Open();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sp1.Write("a");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            sp1.Write("b");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            string POT = sp1.ReadExisting();
            label1.Text = POT;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (j < 4)
                j++;
            sp1.Write(j.ToString());
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (j > 0)
                j--;
            sp1.Write(j.ToString());
        }

    }
}

And for the record I am using C#. So what could the problem be? Thanks in advance.

I am working on a project where I use the DS18B20 temperature sensor with Arduino to get the temperature, and then I store these temperatures in an Access database. Now I was able to get the temperature values from DS18B20 and show them using the Arduino software. But for the second part of my work, I did a windows form application that contains a code that is supposed to take these temperature values and store them in the database. but when I run this application, as soon as I press any of the buttons in it, I get the following error:

"An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll Additional information: The port is closed."

This exception only appears when I have the arduino software running and getting the temperature values. When it's not running, nothing happens, and the buttons don't work. here is the code of my WFApplication.

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.Ports;

namespace test1
{
    public partial class Form1 : Form
    {
        int j = 0;
        SerialPort sp1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            sp1 = new SerialPort("COM4", 9600);
            sp1.Open();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sp1.Write("a");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            sp1.Write("b");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            string POT = sp1.ReadExisting();
            label1.Text = POT;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (j < 4)
                j++;
            sp1.Write(j.ToString());
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (j > 0)
                j--;
            sp1.Write(j.ToString());
        }

    }
}

And for the record I am using C#. So what could the problem be? Thanks in advance.

Are you sure Arduino becomes COM4 ?

Yes I am using com4

Do you know WHEN the Form1_Load event occurs? I'd add a button to the form, and open the serial port in the Click event for that button. A dropdown list to show the available ports and a list of speeds would be useful, too.

Then, of course, handle the exceptions.

you don't check the return values of any call (aka good weather programming)

sp1 = new SerialPort("COM4", 9600);
rv = sp1.open();

why do you assume sp1 = new SerialPort("COM4", 9600); returns a valid value?

sp1 = new SerialPort("COM4", 9600);

if (sp1 != null) 
{  
  try
  {
    rv = sp1.open();
  }
  catch()
  {
    // open failed ...
  }
}

sp1 = new SerialPort("COM4", 9600);
sp1.Open();

sp1.open() should be in a try catch construct as it can throw exceptions. ignoring them makes code less robust.


update: oops I cross-answered ...

A method I succesfully implemented in vb.net involves looking at this registry key:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM

(it's a folder, actually)

inside it you'll find "arduino" serial ports are those containing "VCP".

You can use a timer to check once in a second or two if a new "VCP" port has been added, and assume it's the one arduino is attached to.

I'm a newbie too, and I don't understand anything about your code, but this might be all you need

http://www.parallax.com/tabid/393/default.aspx

It isn't made for, but can be adapted to, Arduino. The vital serial commands look like this:

Serial.println("LABEL,Time,InTemp,OutTemp,diff,DrainTemp");

  sensors.setResolution(InThermo, 12);
  sensors.setResolution(OutThermo, 12);
  sensors.setResolution(DrainThermo, 12);

void loop() {
  running();
  GetClock();
  myFile = SD.open(filename, FILE_WRITE);//<<<<<<<<<<<<< OPEN
  if (hour == 0 && minute == 0 && second <2)
  {
    getFileName();
  }
 Serial.print("DATA,TIME,       "); 

  int ret=0;
  //get the values from the DS8B20's 
  sensors.requestTemperatures();

  float InTemp = (sensorValue(InThermo));
  float OutTemp = (sensorValue(OutThermo));  
  float DrainTemp = (sensorValue(DrainThermo)); 

  float diff = OutTemp - InTemp;

  datastreams[0].setFloat(InTemp);
  datastreams[1].setFloat(OutTemp);
  datastreams[2].setFloat(DrainTemp);
  datastreams[3].setFloat(diff);
  Serial.print(InTemp);
  Serial.print(" ,  ");
  Serial.print(OutTemp);
  Serial.print(" ,  ");
  Serial.print(DrainTemp);
  Serial.println(" ,  ");

  lcd.setCursor(49,0);
  lcd.print(InTemp);
  lcd.setCursor(49,1);

Nick, the OP has a problem with a C# program running on the PC, which gets data from Arduino. There's nothing a sketch can do here... :slight_smile:

zahidaoui:
Yes I am using com4

Sorry, missed this reply before posting my note about com port discovery...

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Threads merged.

  • Moderator

tuxduino:
Nick, the OP has a problem with a C# program running on the PC, which gets data from Arduino. There's nothing a sketch can do here... :slight_smile:

OK. I said

this might be all you need

which still applies. And, in this case, the solution actually is in how the Arduino exports the data.

NickPyner:

tuxduino:
Nick, the OP has a problem with a C# program running on the PC, which gets data from Arduino. There's nothing a sketch can do here... :slight_smile:

OK. I said

this might be all you need

which still applies. And, in this case, the solution actually is in how the Arduino exports the data.

The OP error is this (please reread the first post):

"An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll Additional information: The port is closed."

This happens when the C# program tries to open COM4. At that point, how the data coming from Arduino is formatted is irrelevant.

:slight_smile:

tuxduino:
The OP error is this (please reread the first post):

Not necessarily.

It could be that the OP's real error is that he is taking the wrong approach, trying to re-invent the wheel, and ending up with a square one.

Needless to say, he has every right to bash his head against a brick wall for the intellectual exercise, but there is no suggestion that that is his intent. The intent could be to actually solve the problem, and the problem is reasonably clear (please re-read the title of the post, large orange letters).

I have no idea about what OP is trying to do in C# but, as far as this forum is concerned, he is like me, a newbie by definition, and both of us have been faced with the same problem. The principle difference between us is that I can send my temperatures to a database, and he can't. Hence my post.

Hopefully OP will find it a useful approach, he might even find it a blessed relief........

I overlooked this part:

This exception only appears when I have the arduino software running and getting the temperature values. When it's not running, nothing happens, and the buttons don't work. here is the code of my WFApplication.

To OP: you can't have two applications open the same com port at the same time. If you have the Arduino IDE running and serial monitor open, COM4 (or whatever it is) is locked. You have to close the serial monitor or probably quit the entire Arduino IDE before your C# app can open COM4.

This will make the "port locked" error go away.

If the program doesn't work, keeping the Arduino IDE open is not the solution.

private void timer1_Tick(object sender, EventArgs e)
        {
            string POT = sp1.ReadExisting();
            label1.Text = POT;
        }

I usually code in vb.net, but... I don't see where you initialize and start timer1, not where you associate timer1_Tick method with the timer1 tick event...