物联网应用系统集成 笔记(部分)

面向对象概念与方法

面向对象基本概念

  • 对象(Object)

    • 定义:对象是类的实例,是现实世界中具体事物的抽象。
    • 特点:每个对象都有自己的状态(属性)和行为(方法)。
    • 示例:一本书(对象),属性包括书名、作者,行为包括打开、阅读。
  • 类(Class)

    • 定义:类是对一类对象的抽象,是对象的模板或蓝图。
    • 特点:类定义了对象的属性和行为。
    • 示例:书(类),属性包括书名、作者,行为包括打开、阅读。
  • 封装(Encapsulation)

    • 定义:封装是将对象的状态(属性)和行为(方法)绑定在一起,并隐藏对象的内部实现细节。
    • 优点:提高了代码的安全性和可维护性。
    • 示例:一个类中定义私有属性,并通过公共方法访问这些属性。
  • 继承(Inheritance)

    • 定义:继承是一个类(子类)从另一个类(父类)继承属性和行为的机制。
    • 优点:提高代码的复用性,建立类之间的关系。
    • 示例:猫类(子类)继承动物类(父类)的属性和方法。
  • 多态(Polymorphism)

    • 定义:多态是指同一个方法在不同对象中有不同的实现。
    • 优点:提高代码的灵活性和可扩展性。
    • 示例:动物类有一个叫的方法,不同动物(猫、狗)有不同的叫声实现。

面向对象特征

  • 封装(Encapsulation)

    • 实现细节对外部隐藏,只提供必要的接口。
    • 通过访问控制(如public、private、protected)来实现。
  • 继承(Inheritance)

    • 子类继承父类的属性和方法,子类可以扩展或重写父类的方法。
    • 支持代码复用,简化代码维护。
  • 多态(Polymorphism)

    • 方法的重载和重写实现多态。
    • 支持接口多态和继承多态。
  • 抽象(Abstraction)

    • 通过抽象类和接口来定义抽象概念。
    • 隐藏实现细节,只提供接口。

示例代码(C#)

对象和类

public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }

    public void Open()
    {
        Console.WriteLine("Opening the book...");
    }

    public void Read()
    {
        Console.WriteLine("Reading the book...");
    }
}

class Program
{
    static void Main()
    {
        Book myBook = new Book();
        myBook.Title = "C# Programming";
        myBook.Author = "Author Name";
        myBook.Open();
        myBook.Read();
    }
}

封装

public class Person
{
    private string name;
    private int age;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public int Age
    {
        get { return age; }
        set { age = value; }
    }

    public void DisplayInfo()
    {
        Console.WriteLine($"Name: {name}, Age: {age}");
    }
}

继承

public class Animal
{
    public void Eat()
    {
        Console.WriteLine("Eating...");
    }
}

public class Cat : Animal
{
    public void Meow()
    {
        Console.WriteLine("Meowing...");
    }
}

class Program
{
    static void Main()
    {
        Cat myCat = new Cat();
        myCat.Eat();
        myCat.Meow();
    }
}

多态

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Some generic animal sound");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Bark");
    }
}

public class Cat : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Meow");
    }
}

class Program
{
    static void Main()
    {
        Animal myDog = new Dog();
        Animal myCat = new Cat();

        myDog.MakeSound(); // 输出: Bark
        myCat.MakeSound(); // 输出: Meow
    }
}

设计模式

参考这个:https://refactoringguru.cn/design-patterns/catalog

image-20240703215405192

定义

  • 设计模式:是一套被反复使用、多数人知晓、经过分类编目的、代码设计经验的总结。使用设计模式是为了使代码可复用、让代码更容易被他人理解、确保代码可靠性。

分类

设计模式主要分为三大类:

  1. 创建型模式

    • 单例模式(Singleton Pattern)

      • 确保一个类只有一个实例,并提供一个全局访问点。

      • 示例代码:

      public class Singleton
      {
         private static Singleton instance;
      
         private Singleton() { }
      
         public static Singleton Instance
         {
             get
             {
                 if (instance == null)
                 {
                     instance = new Singleton();
                 }
                 return instance;
             }
         }
      }
    • 工厂方法模式(Factory Method Pattern)

      • 定义一个用于创建对象的接口,让子类决定实例化哪一个类。

      • 示例代码:

      public abstract class Product { }
      
      public class ConcreteProductA : Product { }
      public class ConcreteProductB : Product { }
      
      public abstract class Creator
      {
         public abstract Product FactoryMethod();
      }
      
      public class ConcreteCreatorA : Creator
      {
         public override Product FactoryMethod() => new ConcreteProductA();
      }
      
      public class ConcreteCreatorB : Creator
      {
         public override Product FactoryMethod() => new ConcreteProductB();
      }
    • 抽象工厂模式(Abstract Factory Pattern)

      • 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

      • 示例代码:

      public interface IAbstractFactory
      {
         IProductA CreateProductA();
         IProductB CreateProductB();
      }
      
      public interface IProductA { }
      public interface IProductB { }
      
      public class ConcreteFactory1 : IAbstractFactory
      {
         public IProductA CreateProductA() => new ProductA1();
         public IProductB CreateProductB() => new ProductB1();
      }
      
      public class ConcreteFactory2 : IAbstractFactory
      {
         public IProductA CreateProductA() => new ProductA2();
         public IProductB CreateProductB() => new ProductB2();
      }
      
      public class ProductA1 : IProductA { }
      public class ProductA2 : IProductA { }
      public class ProductB1 : IProductB { }
      public class ProductB2 : IProductB { }
  2. 结构型模式

    • 适配器模式(Adapter Pattern)

      • 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

      • 示例代码:

      public interface ITarget
      {
         void Request();
      }
      
      public class Adaptee
      {
         public void SpecificRequest() => Console.WriteLine("Specific request");
      }
      
      public class Adapter : ITarget
      {
         private readonly Adaptee _adaptee;
      
         public Adapter(Adaptee adaptee)
         {
             _adaptee = adaptee;
         }
      
         public void Request() => _adaptee.SpecificRequest();
      }
    • 装饰器模式(Decorator Pattern)

      • 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

      • 示例代码:

      public abstract class Component
      {
         public abstract void Operation();
      }
      
      public class ConcreteComponent : Component
      {
         public override void Operation() => Console.WriteLine("ConcreteComponent Operation");
      }
      
      public abstract class Decorator : Component
      {
         protected Component component;
      
         public void SetComponent(Component component)
         {
             this.component = component;
         }
      
         public override void Operation()
         {
             if (component != null)
             {
                 component.Operation();
             }
         }
      }
      
      public class ConcreteDecoratorA : Decorator
      {
         public override void Operation()
         {
             base.Operation();
             Console.WriteLine("ConcreteDecoratorA Operation");
         }
      }
      
      public class ConcreteDecoratorB : Decorator
      {
         public override void Operation()
         {
             base.Operation();
             AddedBehavior();
         }
      
         void AddedBehavior() => Console.WriteLine("ConcreteDecoratorB AddedBehavior");
      }
    • 代理模式(Proxy Pattern)

      • 为其他对象提供一种代理以控制对这个对象的访问。

      • 示例代码:

      public interface ISubject
      {
         void Request();
      }
      
      public class RealSubject : ISubject
      {
         public void Request() => Console.WriteLine("RealSubject Request");
      }
      
      public class Proxy : ISubject
      {
         private RealSubject realSubject;
      
         public void Request()
         {
             if (realSubject == null)
             {
                 realSubject = new RealSubject();
             }
             realSubject.Request();
         }
      }
  3. 行为型模式

    • 观察者模式(Observer Pattern)

      • 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

      • 示例代码:

      public interface IObserver
      {
         void Update();
      }
      
      public class ConcreteObserver : IObserver
      {
         public void Update() => Console.WriteLine("Observer Updated");
      }
      
      public interface ISubject
      {
         void Attach(IObserver observer);
         void Detach(IObserver observer);
         void Notify();
      }
      
      public class ConcreteSubject : ISubject
      {
         private List observers = new List();
      
         public void Attach(IObserver observer) => observers.Add(observer);
         public void Detach(IObserver observer) => observers.Remove(observer);
         public void Notify()
         {
             foreach (var observer in observers)
             {
                 observer.Update();
             }
         }
      }
    • 策略模式(Strategy Pattern)

      • 定义一系列算法,并将每个算法封装起来,使它们可以相互替换,算法的变化不会影响使用算法的客户。

      • 示例代码:

      public interface IStrategy
      {
         void AlgorithmInterface();
      }
      
      public class ConcreteStrategyA : IStrategy
      {
         public void AlgorithmInterface() => Console.WriteLine("Algorithm A");
      }
      
      public class ConcreteStrategyB : IStrategy
      {
         public void AlgorithmInterface() => Console.WriteLine("Algorithm B");
      }
      
      public class Context
      {
         private IStrategy strategy;
      
         public Context(IStrategy strategy)
         {
             this.strategy = strategy;
         }
      
         public void ContextInterface() => strategy.AlgorithmInterface();
      }
    • 命令模式(Command Pattern)

      • 将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化。

      • 示例代码:

      public interface ICommand
      {
         void Execute();
      }
      
      public class ConcreteCommand : ICommand
      {
         private readonly Receiver receiver;
      
         public ConcreteCommand(Receiver receiver)
         {
             this.receiver = receiver;
         }
      
         public void Execute() => receiver.Action();
      }
      
      public class Receiver
      {
         public void Action() => Console.WriteLine("Receiver Action");
      }
      
      public class Invoker
      {
         private ICommand command;
      
         public void SetCommand(ICommand command)
         {
             this.command = command;
         }
      
         public void ExecuteCommand() => command.Execute();
      }

串口助手的开发

开串口

private void btnOpen_Click(object sender, EventArgs e)
{
    if (isOpen == false)
    {
        setSerialParam(cmbPortName.Text, Convert.ToInt32(cmbBaudRate.Text),
            Convert.ToInt32(cmbDataBit.Text), (Parity)cmbParity.SelectedIndex,
            (StopBits)cmbStopBit.SelectedIndex + 1);
        serialPort1.Open();
        isOpen = true;
        btnOpen.Text = "关闭串口";
    }
    else
    {
        serialPort1.Close();
        isOpen = false;
        btnOpen.Text = "打开串口";
    }
}

串口发送

private void btn_Send_Click(object sender, EventArgs e)
{
    if(rtbSend != null && serialPort1.IsOpen)
    {

        serialPort1.Write(sendBuffer.ToArray(),0,sendBuffer.Count);
        rtbReceive.SelectionColor = rtbReceive.ForeColor;
        tsslSendCount.Text = Convert.ToString(sendCount);
        rtbReceive.SelectionColor = Color.Green;
        rtbReceive.AppendText("[Send] " + rtbSend.Text + "\n");
        sendCount += sendBuffer.Count;

    }
    else
    {
        MessageBox.Show("串口未打开或发送框没有数据!");
    }
}

串口接收

private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string dataReceived = sp.ReadExisting();
        Console.WriteLine($"接收到数据: {dataReceived}");
    }

数据大/小端模式

  • 大端模式: 高字节在低地址,低字节在高地址。
  • 小端模式: 高字节在高地址,低字节在低地址。一般PC使用小端模式。

数据校验方式

  • 校验位: 确保数据传输的完整性和正确性。
  • 校验算法:
    • CRC: 循环冗余校验码,常用于数据通信。
    • LRC: 纵向冗余校验,常用于工业领域。
    • Checksum: 累加和校验。
    • 异或校验(BCC): 高效的奇偶校验方法。

数据协议解析

  • 关键: 队列的先进先出逻辑。
  • 协议结构: 帧头(0xFF)+数据长度+数据+CRC。
  • 示例: 数据样本 FF+04+31323334+0A30。

文件读取

  • StreamReader 类: 实现一个 TextReader,使其以特定编码从字节流中读取字符。
  • 命名空间: System.IO
  • 操作: 文件读取和发送按钮点击响应。

文件写入

  • StreamWriter 类: 实现一个 TextWriter,使其以特定编码向流中写入字符。
  • 命名空间: System.IO
  • 操作: 选择路径和保存数据按钮点击响应。

定时发送数据

  • 操作: 添加定时器实现定时发送数据功能。

RTS/DTR/底部菜单栏

  • RTS/DTR: 实现相应的功能。
  • 底部状态栏: 用于显示相关状态信息。
// 打开文件
private void OpenFileButton_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();
        if (openFileDialog.ShowDialog() == DialogResult.OK)
        {
            using (StreamReader reader = new StreamReader(openFileDialog.FileName))
            {
                displayTextBox.Text = reader.ReadToEnd();
            }
        }
    }
// 写入文件
 private void SaveFileButton_Click(object sender, EventArgs e)
    {
        SaveFileDialog saveFileDialog = new SaveFileDialog();
        if (saveFileDialog.ShowDialog() == DialogResult.OK)
        {
            using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName))
            {
                writer.Write(inputTextBox.Text);
            }
        }
    }

窗口传值

内置委托、委托传参和事件传参详解

内置委托

  1. Action:

    • 无返回值。

    • 可以有0到16个参数。

    • 例子:

      Action action = (x, y) => Console.WriteLine($"Int: {x}, String: {y}");
      action(10, "Hello");
  2. Func:

    • 有返回值。

    • 可以有0到16个参数。

    • 例子:

      Func func = (x, y) => x + y;
      int result = func(2, 3);
      Console.WriteLine(result);
  3. Predicate:

    • 返回布尔值。

    • 常用于检查条件。

    • 例子:

      Predicate isPositive = x => x > 0;
      bool result = isPositive(5);
      Console.WriteLine(result);

委托传参

  1. 传值方式:

    • 通过直接传递具体的参数值调用委托方法。

    • 例子:

      delegate void MyDelegate(string message);
      MyDelegate del = (msg) => Console.WriteLine(msg);
      del("Hello, World!");
  2. 传递Lambda表达式:

    • 使用Lambda表达式作为参数。

    • 例子:

      delegate int MathOperation(int x, int y);
      MathOperation add = (a, b) => a + b;
      int sum = add(10, 20);
      Console.WriteLine(sum);

事件传参

  1. EventHandler:

    • 标准事件处理委托类型,无参数。

    • 例子:

      public event EventHandler MyEvent;
      protected virtual void OnMyEvent()
      {
       MyEvent?.Invoke(this, EventArgs.Empty);
      }
  2. EventHandler:

    • 带泛型参数的事件处理委托类型,允许传递额外的事件数据。

    • 例子:

      public class MyEventArgs : EventArgs
      {
       public string Message { get; set; }
      }
      
      public event EventHandler MyEvent;
      
      protected virtual void OnMyEvent(string message)
      {
       MyEvent?.Invoke(this, new MyEventArgs() { Message = message });
      }

实例代码

内置委托实例

using System;

class Program
{
    static void Main()
    {
        // Action 示例
        Action<int, string> action = (x, y) => Console.WriteLine($"Int: {x}, String: {y}");
        action(10, "Hello");

        // Func 示例
        Func<int, int, int> func = (x, y) => x + y;
        int result = func(2, 3);
        Console.WriteLine(result);

        // Predicate 示例
        Predicate<int> isPositive = x => x > 0;
        bool isPos = isPositive(5);
        Console.WriteLine(isPos);
    }
}

委托传参实例

using System;

class Program
{
    // 定义委托
    delegate void MyDelegate(string message);

    static void Main()
    {
        // 使用Lambda表达式赋值给委托
        MyDelegate del = (msg) => Console.WriteLine(msg);
        // 调用委托
        del("Hello, World!");
    }
}

事件传参实例

using System;

class Program
{
    // 自定义事件数据
    public class MyEventArgs : EventArgs
    {
        public string Message { get; set; }
    }

    // 定义事件
    public event EventHandler<MyEventArgs> MyEvent;

    protected virtual void OnMyEvent(string message)
    {
        MyEvent?.Invoke(this, new MyEventArgs() { Message = message });
    }

    static void Main()
    {
        Program program = new Program();
        // 订阅事件
        program.MyEvent += Program_MyEvent;
        // 触发事件
        program.OnMyEvent("Hello from event!");
    }

    private static void Program_MyEvent(object sender, MyEventArgs e)
    {
        // 处理事件
        Console.WriteLine(e.Message);
    }
}

数据绘图

1. Chart控件

概述

  • Chart控件是Winform .Net Framework 4自带的控件,用于绘制曲线图、柱状图等各种类型的图表。
  • 在任何给定的图表中,内部绘图位置是x轴和y轴线内的矩形区域,其中绘制了数据点。

属性

  • ChartAreas: 可以添加多个ChartAreas,代表作图区域,默认有一个ChartAreas[0]。
  • Series: 每个ChartAreas中可以有多个Series,Series是一些列点(Points)的集合,这些点与X轴和Y轴构成了图表。

示例代码

using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

public class ChartExample : Form
{
    private Chart chart;

    public ChartExample()
    {
        chart = new Chart();
        chart.Dock = DockStyle.Fill;
        this.Controls.Add(chart);

        ChartArea chartArea = new ChartArea();
        chart.ChartAreas.Add(chartArea);

        Series series = new Series();
        series.ChartType = SeriesChartType.Line;
        series.Points.AddXY(1, 10);
        series.Points.AddXY(2, 20);
        series.Points.AddXY(3, 30);
        chart.Series.Add(series);
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new ChartExample());
    }
}

2. 静态绘图

概述

  • 静态绘图是在图表中绘制不随时间变化的静态数据,一般用于显示历史数据或一次性数据。

示例代码

public void PlotStaticData(Chart chart)
{
    Series series = new Series();
    series.ChartType = SeriesChartType.Bar;
    series.Points.AddXY("A", 10);
    series.Points.AddXY("B", 20);
    series.Points.AddXY("C", 30);
    chart.Series.Add(series);
}

3. 动态绘图

概述

  • 动态绘图是在图表中绘制实时更新的数据,常用于显示传感器数据、股票行情等。

示例代码

using System;
using System.Timers;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

public class DynamicChartExample : Form
{
    private Chart chart;
    private Timer timer;
    private Random random = new Random();
    private int xValue = 0;

    public DynamicChartExample()
    {
        chart = new Chart();
        chart.Dock = DockStyle.Fill;
        this.Controls.Add(chart);

        ChartArea chartArea = new ChartArea();
        chart.ChartAreas.Add(chartArea);

        Series series = new Series();
        series.ChartType = SeriesChartType.Line;
        chart.Series.Add(series);

        timer = new Timer();
        timer.Interval = 1000; // 每秒更新一次
        timer.Elapsed += Timer_Elapsed;
        timer.Start();
    }

    private void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (chart.InvokeRequired)
        {
            chart.Invoke(new Action(() => UpdateChart()));
        }
        else
        {
            UpdateChart();
        }
    }

    private void UpdateChart()
    {
        xValue++;
        int yValue = random.Next(0, 100);
        chart.Series[0].Points.AddXY(xValue, yValue);
        if (chart.Series[0].Points.Count > 20)
        {
            chart.Series[0].Points.RemoveAt(0); // 保持图表数据点数量不超过20
        }
        chart.ChartAreas[0].RecalculateAxesScale(); // 自动调整坐标轴
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new DynamicChartExample());
    }
}

串口接收数据-动态绘图

概述

  • 实现通过串口接收数据并实时更新图表,实现动态绘图。

示例代码

using System;
using System.IO.Ports;
using System.Timers;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

public class SerialDynamicChartExample : Form
{
    private Chart chart;
    private Timer timer;
    private SerialPort serialPort;
    private int xValue = 0;

    public SerialDynamicChartExample()
    {
        chart = new Chart();
        chart.Dock = DockStyle.Fill;
        this.Controls.Add(chart);

        ChartArea chartArea = new ChartArea();
        chart.ChartAreas.Add(chartArea);

        Series series = new Series();
        series.ChartType = SeriesChartType.Line;
        chart.Series.Add(series);

        serialPort = new SerialPort("COM1", 9600);
        serialPort.DataReceived += SerialPort_DataReceived;
        serialPort.Open();

        timer = new Timer();
        timer.Interval = 1000; // 每秒更新一次
        timer.Elapsed += Timer_Elapsed;
        timer.Start();
    }

    private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        string data = serialPort.ReadLine();
        if (int.TryParse(data, out int yValue))
        {
            if (chart.InvokeRequired)
            {
                chart.Invoke(new Action(() => UpdateChart(yValue)));
            }
            else
            {
                UpdateChart(yValue);
            }
        }
    }

    private void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // 可以添加定时操作,这里暂时不需要
    }

    private void UpdateChart(int yValue)
    {
        xValue++;
        chart.Series[0].Points.AddXY(xValue, yValue);
        if (chart.Series[0].Points.Count > 20)
        {
            chart.Series[0].Points.RemoveAt(0); // 保持图表数据点数量不超过20
        }
        chart.ChartAreas[0].RecalculateAxesScale(); // 自动调整坐标轴
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new SerialDynamicChartExample());
    }
}

接口开发概述

接口开发是指设计和实现软件组件之间的通信方式,使得不同系统或模块能够互相交换数据和功能。以下是接口开发的关键要点:

接口类型

  1. RESTful API:

    • 基于HTTP协议,使用标准的HTTP方法(GET, POST, PUT, DELETE)。
    • 资源通过URL进行访问,通常返回JSON或XML格式的数据。
  2. SOAP API:

    • 基于XML的协议,使用HTTP、SMTP等传输协议。
    • 强类型的契约定义,通常用于企业级应用。
  3. GraphQL:

    • 提供单一端点,通过查询语言灵活获取所需数据。
    • 客户端可以指定需要的字段,减少数据传输量。

开发步骤

  1. 需求分析:

    • 明确接口的功能和数据需求,确定接口的使用场景和目标用户。
  2. 设计接口:

    • 定义接口的URL结构、请求方法、请求参数和返回格式。
    • 制定接口文档,描述接口的用途、参数和示例。
  3. 实现接口:

    • 使用服务器端语言(如Java, Python, Node.js)编写接口逻辑。
    • 连接数据库或其他数据源,处理请求并返回响应。
  4. 测试接口:

    • 使用工具(如Postman, Swagger)进行接口测试,确保功能正确。
    • 检查错误处理和边界情况,确保接口的健壮性。
  5. 部署和维护:

    • 将接口部署到服务器,并监控其性能和可用性。
    • 定期更新接口,修复漏洞,满足新的需求。

RESTful API 示例

// 使用ASP.NET Core实现一个简单的RESTful API
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private static readonly List<Product> Products = new List<Product>
    {
        new Product { Id = 1, Name = "Product1", Price = 100 },
        new Product { Id = 2, Name = "Product2", Price = 200 }
    };

    [HttpGet]
    public IEnumerable<Product> Get() => Products;

    [HttpGet("{id}")]
    public ActionResult<Product> Get(int id)
    {
        var product = Products.FirstOrDefault(p => p.Id == id);
        if (product == null)
        {
            return NotFound();
        }
        return product;
    }

    [HttpPost]
    public ActionResult<Product> Post(Product product)
    {
        product.Id = Products.Max(p => p.Id) + 1;
        Products.Add(product);
        return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
    }

    [HttpPut("{id}")]
    public IActionResult Put(int id, Product product)
    {
        var existingProduct = Products.FirstOrDefault(p => p.Id == id);
        if (existingProduct == null)
        {
            return NotFound();
        }
        existingProduct.Name = product.Name;
        existingProduct.Price = product.Price;
        return NoContent();
    }

    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
        var product = Products.FirstOrDefault(p => p.Id == id);
        if (product == null)
        {
            return NotFound();
        }
        Products.Remove(product);
        return NoContent();
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

XML

基本概念

  • XML(Extensible Markup Language)是一种类似于HTML的标记语言,但没有预定义的标记。
  • XML允许根据需求定义专属的标记,用于存储、搜索和共享数据。
  • XML格式标准化,便于在不同系统或平台间传输数据。

基本语法

  • 第一行通常为文档声明:<?xml version="1.0" encoding="UTF-8"?>
  • 必须有且仅有一个根标签,其他标签为子标签。
  • 标签区分大小写,不能以数字或下划线开头,不能包含空格和冒号。

标签和属性

  • 标签可以包含字母、数字和其他可见字符,但需遵守命名规范。
  • 属性用于区分名称相同的标签,属性值必须用引号包裹。
  • 实体引用用于替代特殊字符,如>表示>

CDATA

  • 使用<![CDATA[ 内容 ]]>包裹不想被解析的内容。

xml写操作

using System.Xml;

public class XmlWriterExample
{
    public void WriteXml()
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;

        using (XmlWriter writer = XmlWriter.Create("example.xml", settings))
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("root");

            writer.WriteStartElement("element");
            writer.WriteAttributeString("attribute", "value");
            writer.WriteString("content");
            writer.WriteEndElement();

            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
    }
}

xml读操作

using System.Xml;

public class XmlReaderExample
{
    public void ReadXml()
    {
        using (XmlReader reader = XmlReader.Create("example.xml"))
        {
            while (reader.Read())
            {
                if (reader.IsStartElement())
                {
                    switch (reader.Name)
                    {
                        case "element":
                            string attribute = reader["attribute"];
                            string content = reader.ReadString();
                            Console.WriteLine($"Element: {attribute}, Content: {content}");
                            break;
                    }
                }
            }
        }
    }
}

自定义组件

image-20240704124359528

NModBus4的使用

NModbus4 使用笔记

简介

NModbus4 是一个用于 .NET 的开源 Modbus 协议库。支持 Modbus TCP、RTU 和 ASCII 协议,可以在 .NET Framework 和 .NET Core 项目中使用。

基本使用

  1. Modbus TCP Master

    using System;
    using System.Net.Sockets;
    using NModbus;
    
    class Program
    {
       static void Main(string[] args)
       {
           using (TcpClient client = new TcpClient("127.0.0.1", 502))
           {
               var factory = new ModbusFactory();
               var master = factory.CreateMaster(client);
    
               // 读取保持寄存器
               ushort startAddress = 0;
               ushort numberOfPoints = 5;
               ushort[] registers = master.ReadHoldingRegisters(1, startAddress, numberOfPoints);
    
               // 打印读取到的数据
               for (int i = 0; i < registers.Length; i++)
               {
                   Console.WriteLine($"Register {i + startAddress}: {registers[i]}");
               }
           }
       }
    }
  2. Modbus RTU Master

    using System;
    using System.IO.Ports;
    using NModbus;
    using NModbus.Serial;
    
    class Program
    {
       static void Main(string[] args)
       {
           using (SerialPort port = new SerialPort("COM1"))
           {
               port.BaudRate = 9600;
               port.DataBits = 8;
               port.Parity = Parity.None;
               port.StopBits = StopBits.One;
               port.Open();
    
               var factory = new ModbusFactory();
               var adapter = new SerialPortAdapter(port);
               var master = factory.CreateRtuMaster(adapter);
    
               // 读取线圈
               bool[] coils = master.ReadCoils(1, 0, 10);
    
               // 打印读取到的线圈状态
               for (int i = 0; i < coils.Length; i++)
               {
                   Console.WriteLine($"Coil {i}: {coils[i]}");
               }
           }
       }
    }
  3. Modbus Slave

    using System;
    using System.Net;
    using NModbus;
    using NModbus.Logging;
    
    class Program
    {
       static void Main(string[] args)
       {
           var factory = new ModbusFactory();
           var network = new ModbusTcpNetwork(new TcpListenerAdapter(new TcpListener(IPAddress.Any, 502)));
           var slave = factory.CreateSlave(network);
    
           slave.DataStore = DataStoreFactory.CreateDefaultDataStore();
           slave.Logger = new ConsoleModbusLogger(LogLevel.Info);
           slave.ListenAsync().GetAwaiter().GetResult();
       }
    }

主要功能

  • 读取/写入寄存器和线圈:支持功能码 1, 2, 3, 4, 5, 6, 15 和 16。
  • 事件驱动的从站:支持 Modbus TCP、RTU 和 ASCII 从站的事件驱动实现。
  • 扩展性:可以通过实现接口扩展功能。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
';