简体   繁体   English

使用C#从Arduino串行收集的数据进行SQL更新

[英]SQL update using data collected by C# from Arduino Serial

I am trying to write a simple program in C# that will read data output from an Arduino connected via serial, lift the relevant data out of the text strings which are formatted for ease-of-understanding in the Serial Monitor, display the two pieces of information in two read-only text boxes that act as counters (overwrite every time the information is updated), and UPDATE an SQL table with these figures. 我正在尝试编写一个简单的C#程序,它将读取通过串行连接的Arduino的数据输出,将相关数据从格式化为便于理解的文本字符串中移出串行监视器,并显示两个信息在两个用作计数器的只读文本框中(每次更新信息时都会覆盖),并使用这些数字来更新SQL表。


Example: 例:

Arduino outputs: Arduino输出:

'Day Users: 234231'
'All Users: 433241'

C# displays full message in textbox1 C#在textbox1中显示完整消息

C# displays 234231 in textbox2 C#在textbox2中显示234231

C# displays 433241 in textbox3 C#在textbox3中显示433241

C# UPDATES SQL table with something like: C#UPDATES SQL表类似于:

SqlCommand myCommand = new SqlCommand("UPDATE USER_NUMBERS
SET NUMBERZ= 234231 
WHERE UPTIME = DAYHK");

But obviously, '234231' is a variable, specified by the input from the Arduino, which then informs the content of both textbox2 and the value needed to update the SQL table. 但是显然,'234231'是一个变量,由Arduino的输入指定,然后通知textbox2的内容和更新SQL表所需的值。


I'm very new to C#, but so far I have a program which can read the serial data from the Arduino and put the entire output into textbox1, but no more. 我是C#的新手,但到目前为止,我有一个程序可以读取Arduino的串行数据,并将整个输出放入textbox1中,但仅此而已。

How can I specify a part of the incoming data that I want assigned to a value to be the text output in both textbox2 (or textbox3), and then use it to do both that and an update of the value held in my SQL table? 我如何在要分配给值的传入数据中指定一部分作为textbox2(或textbox3)中的文本输出,然后使用它来做这件事和更新SQL表中保存的值?

My code so far is thus: 到目前为止,我的代码是:

    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 Serial_Reader
{
    public partial class Form1 : Form
    {

        string RxString;

        public Form1()
        {
            InitializeComponent();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = "COM3";
            serialPort1.BaudRate = 9600;

            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                buttonStart.Enabled = false;
                buttonStop.Enabled = true;
                buttonSQL.Enabled = true;
                textBox1.ReadOnly = false;
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                buttonStart.Enabled = true;
                buttonStop.Enabled = false;
                buttonSQL.Enabled = false;
                textBox1.ReadOnly = true;
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            // If the port is closed, don't try to send a character.

            if (!serialPort1.IsOpen) return;

            // If the port is Open, declare a char[] array with one element.
            char[] buff = new char[1];

            // Load element 0 with the key character.

            buff[0] = e.KeyChar;

            // Send the one character buffer.
            serialPort1.Write(buff, 0, 1);

            // Set the KeyPress event as handled so the character won't
            // display locally. If you want it to display, omit the next line.
            e.Handled = true;
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            RxString = serialPort1.ReadExisting();
            this.Invoke(new EventHandler(DisplayText));
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen) serialPort1.Close();
        }

        private void DisplayText(object sender, EventArgs e)
        {
            textBox1.AppendText(RxString);
        }

        private void buttonSQL_Click(object sender, EventArgs e)
        {

        }

    }
 }

As you can see from 'my' adept commenting, but inept programming, I am using code from the brilliant tutorial here : and all that my program will have extra is a button to begin the SQL communication, stopped when the Serial comms are stopped, and two extra textboxes. 你可以从“我”擅长评论,但不称职的节目中,我使用的代码从辉煌教程看这里 :和所有我的计划将有额外的一个按钮,开始SQL通信,当串行通信被拦停,和两个额外的文本框。


EDIT : 编辑

The input is in the format: 输入的格式为:

Someone got up from seat number 9
All-time users on seat number 9 is: 5
Today's total users: 17
All-time total users: 17

So that non-programmers checking the serial monitor can easily understand the output. 这样,非程序员检查串行监视器就可以轻松理解输出。 The first line is always either 'Someone got up from' or 'Someone sat down on', on the second line, only the numbers change, and again on the third and fourth lines, but the numbers on the third and fourth lines (in this case the same because the system has been running less than a day) are the ones that need to be parsed. 第一行始终是“有人从那里站起来”或“有人坐下来”,在第二行上,只有数字改变了,在第三和第四行上又改变了,但是在第三和第四行上(这种情况是相同的,因为系统运行时间少于一天)是需要解析的系统。


EDIT 2 (New Code): 编辑2 (新代码):

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.Data.SqlClient;

namespace Serial_Reader
{
    public partial class Form1 : Form
    {

        string RxString;

        public Form1()
        {
              InitializeComponent();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = "COM3";
            serialPort1.BaudRate = 9600;

            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                buttonStart.Enabled = false;
                buttonStop.Enabled = true;
                buttonSQL.Enabled = true;
                textBox1.ReadOnly = true;
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                buttonStart.Enabled = true;
                buttonStop.Enabled = false;
                buttonSQL.Enabled = false;
                textBox1.ReadOnly = true;
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            // If the port is closed, don't try to send a character.

            if (!serialPort1.IsOpen) return;

            // If the port is Open, declare a char[] array with one element.
            char[] buff = new char[1];

            // Load element 0 with the key character.

            buff[0] = e.KeyChar;

            // Send the one character buffer.
            serialPort1.Write(buff, 0, 1);

            // Set the KeyPress event as handled so the character won't
            // display locally. If you want it to display, omit the next line.
            e.Handled = true;
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            RxString = serialPort1.ReadExisting();
            this.Invoke(new EventHandler(DisplayText));


        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen) serialPort1.Close();
        }

        private void DisplayText(object sender, EventArgs e)
        {
            textBox1.AppendText(RxString);

        }

        private void buttonSQL_Click(object sender, EventArgs e)
        {
            //   SqlConnection myConnection = new SqlConnection("user id=username;" +
            //                            "password=password;server=serverurl;" +
            //                            "Trusted_Connection=yes;" +
            //                            "database=database; " +
            //                            "connection timeout=30");

            do
            {
                string dayUsers, allUsers;
                string s1 = "Today's total users: ";
                string s2 = "All-time total users: ";

                if (RxString.Contains(s1))
                {
                dayUsers = RxString.Replace(s1, "");
                textDU.Text = dayUsers;
           //     string queryDay = "UPDATE USER_NUMBERS SET NUMBERZ=" + dayUsers + "WHERE UPTIME=DAYHK";
                }

                if (RxString.Contains(s2))
                {
                allUsers = RxString.Replace(s2, "");
                textAU.Text = allUsers;
           //     string queryAll = "UPDATE USER_NUMBERS SET NUMBERZ=" + allUsers + "WHERE UPTIME=ALLHK";
                }
            }
            while (serialPort1.IsOpen);
        }



        private void textDU_TextChanged(object sender, EventArgs e)
        {

        }

        private void textAU_TextChanged(object sender, EventArgs e)
        {

        }

    }
}

EDIT 3 (Incoming Data): 编辑3 (传入数据):

if (abs (then [i] - now[i]) > THRESH)
{
  Serial.print ("Someone ");
  if (now [i] > then [i])
  {
    Serial.print ("sat on");
    allusers++;
    dayusers++;
    digitalWrite(counterPin, HIGH);  // hit counter
    delay(75);
    digitalWrite(counterPin, LOW);
    val[i]++;
  }  
  else
  {
    Serial.print ("got up from");
  }  
  Serial.print (" seat number ");
  Serial.println (i);
  Serial.print ("All-time users on seat number ");
  Serial.print (i);
  Serial.print (" is: ");
  Serial.println (val[i]); 
  Serial.print ("Today's total users: ");
  Serial.println (dayusers);
  Serial.print ("All-time total users: ");
  Serial.println (allusers);
}

If you know that the input string is always in the same format, and that the numbers always have 6 digits, you may use simple substrings: 如果您知道输入字符串始终采用相同的格式,并且数字始终具有6位数字,则可以使用简单的子字符串:

int dayUsers, allUsers;
Int32.TryParse(RxString.Substring(12, 6), out dayUsers);
Int32.TryParse(RxString.Substring(32, 6), out allUsers);

Otherwise you could make the parsing a little bit more sophisticated: 否则,您可以使解析更加复杂:

int dayUsers, allUsers;
string[] parts = RxString.Split('\'', ':');
if (parts.Length > 5)
{
    Int32.TryParse(parts[2].Trim(), out dayUsers);
    Int32.TryParse(parts[5].Trim(), out allUsers);
}

Then it's just a matter of using the numbers in the text boxes and SQL query: 然后,只需使用文本框中的数字和SQL查询即可:

textBox2.Text = dayUsers.ToString();
textBox3.Text = allUsers.ToString();

string query = "UPDATE USER_NUMBERS SET NUMBERZ=" + dayUsers + "WHERE UPTIME=DAYHK"

EDIT: Given that the four lines of data is available in textBox1, you may use something like this to extract the strings containing the numbers: 编辑:鉴于textBox1中有四行数据,您可以使用类似这样的方法来提取包含数字的字符串:

string[] inputLines = textBox1.Text.Split('\n');
if (inputLines.Length == 4)
{
    string dayUsers = inputLines[2].Substring(inputLines[2].IndexOf(':') + 1).Trim();
    string allUsers = inputLines[3].Substring(inputLines[3].IndexOf(':') + 1).Trim();
}

EDIT 2: Suggestion for code parsing possibly incomplete data in TextBox1: 编辑2:建议代码解析TextBox1中的数据可能不完整:

private void buttonSQL_Click(object sender, EventArgs e)
{
    // Get unsaved input from text box
    string input = textBox1.Text;
    string[] inputLines = input.Split('\n');

    // Find and process relevant input
    foreach(string line in inputLines)
    {
        if (line.EndsWith("\r")) // Make sure line is complete
        {
            if (line.StartsWith("Today's total users: "))
            {
                string dayUsers = line.Substring(20).Trim();
                textDU.Text = dayUsers;
                // SQL query...
            }
            else if (line.StartsWith("All-time total users: "))
            {
                string allUsers = line.Substring(21).Trim();
                textAU.Text = allUsers;
                // SQL query...
            }
        }
    }

    // Only keep unparsed text in text box
    textBox1.Text = inputLines[inputLines.Length - 1];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM