上位机可以通过串口控制舵机、蜂鸣器。
示例:
Esp8266部分
基于Arduino,依赖库:U8g2、Servo。
接线引脚看代码哈。
#include <Arduino.h>
#include <Servo.h>
#include <U8g2lib.h>
/***OLED 引脚 */
#define SCL 5 /* 时钟引脚*/
#define SDA 4 /* 数据引脚*/
#define RES 14 /* 复位引脚*/
#define DC 12 /* 命令控制引脚*/
#define CS 13 /* 片选引脚*/
/***蜂鸣器 引脚 */
#define BuzzerPin 15
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/SCL, /* data=*/SDA, /* cs=*/CS, /* dc=*/DC, /* reset=*/RES);
Servo sg90;
/**
* @brief 初始化OLED屏幕
*
*/
void OLED_Init(void);
/**
* @brief OLED显示SG90的角度
*
* @param i 角度 0~180
*/
void OLED_SG90(int i);
/**
* @brief 串口接收
*/
void Serial_Recv(void);
/**
* @brief 设置SG90舵机角度
*
* @param angle 角度 0-180
*/
void Set_SG90(int angle);
/**
* @brief 蜂鸣器初始化
*
*/
void Init_Buzzer(void);
/**
* @brief 设置蜂鸣器
*
* @param mode 模式
* 1 -> di(短)
* 2 -> di~(长)
* 3 —> di~di(短、急促的)
*/
void Set_Buzzer(int mode);
void setup()
{
Serial.begin(115200);
OLED_Init();
sg90.attach(2);
Set_SG90(90);
OLED_SG90(90);
Init_Buzzer();
Set_Buzzer(2);
}
void loop()
{
Serial_Recv();
}
char buf[4] = {0x00};
void Serial_Recv()
{
if (Serial.available() >= 4)
{
Serial.readBytes(buf, 4);
/***报文: FF __ __ FE */
if (buf[0] == 0xFF && buf[3] == 0xFE)
{
if (buf[1] == 0x00)
{
/**舵机: FF 00 __ FE*/
Set_SG90(buf[2]);
OLED_SG90(buf[2]);
Serial.write(buf, 4);
delay(20);
}
else if (buf[1] == 0x01)
{
/** 蜂鸣器: FF 01 __ FE*/
Set_Buzzer(buf[2]);
Serial.write(buf, 4);
delay(20);
}
}
}
}
void Set_SG90(int angle)
{
sg90.write(angle);
}
char oled_buf[4];
void OLED_SG90(int i)
{
u8g2.setCursor(50, 40);
sprintf(oled_buf, "%03d", i);
u8g2.print(oled_buf);
u8g2.sendBuffer();
}
void OLED_Init(void)
{
u8g2.begin(); // 初始化 u8g2
u8g2.disableUTF8Print(); // 关闭UTF-8模式
u8g2.setFont(u8g2_font_unifont_t_chinese2); // use chinese2 for all the glyphs of "你好世界"
u8g2.setFontDirection(0);
u8g2.clearBuffer();
u8g2.setCursor(0, 15);
u8g2.print("SG90:");
u8g2.setCursor(20, 40);
u8g2.print("P:");
u8g2.sendBuffer();
}
void Init_Buzzer(void)
{
pinMode(BuzzerPin, OUTPUT);
}
void Set_Buzzer(int mode)
{
switch (mode)
{
case 0:
digitalWrite(BuzzerPin, HIGH);
delay(100);
digitalWrite(BuzzerPin, LOW);
break;
case 1:
digitalWrite(BuzzerPin, HIGH);
delay(300);
digitalWrite(BuzzerPin, LOW);
break;
case 2:
digitalWrite(BuzzerPin, HIGH);
delay(50);
digitalWrite(BuzzerPin, LOW);
delay(50);
digitalWrite(BuzzerPin, HIGH);
delay(50);
digitalWrite(BuzzerPin, LOW);
break;
default:
break;
}
}
上位机部分
串口数据帧可以看esp代码
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow"
Height="250"
Width="800">
<StackPanel>
<StackPanel HorizontalAlignment="Left"
Orientation="Horizontal"
Height="30"
Margin="50 50 0 0">
<Label Content="舵机:" />
<Slider x:Name="slider"
HorizontalAlignment="Left"
Margin="10 0 0 0 "
Minimum="0"
Maximum="180"
PreviewMouseUp="slider_MouseUp"
Width="604"
Value="{Binding Pos}"
Height="23">
</Slider>
<Label x:Name="label"
Content="{Binding Pos, StringFormat={}{0}d}"
HorizontalAlignment="Left"
Height="23"
Width="40"
Margin="10 0 0 0 "
VerticalAlignment="Top" />
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
Margin="50 20 0 0">
<Label Content="蜂鸣器:" />
<Button Height="25"
Width="70"
Margin="10 0 0 0 "
Content="Mode 1"
Click="btn_buzz_mode1"/>
<Button Height="25"
Width="70"
Margin="10 0 0 0 "
Content="Mode 2"
Click="btn_buzz_mode2"/>
<Button Height="25"
Width="70"
Margin="10 0 0 0 "
Content="Mode 3"
Click="btn_buzz_mode3" />
<Button Height="25"
Width="70"
Margin="10 0 0 0 "
Content="Mode 4"
Click="btn_buzz_mode4" />
</StackPanel>
</StackPanel>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
using System.Threading;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private SerialPort serialPort;
private MainViewModel m;
public MainWindow()
{
InitializeComponent();
m = new MainViewModel();
this.DataContext = m;
// 初始化串口设置
serialPort = new SerialPort("COM8", 115200); // 替换为实际的串口号和波特率
serialPort.DataReceived += SerialPort_DataReceived; // 接收回调
serialPort.Open();
if (serialPort.IsOpen == false)
{
Debug.WriteLine("串口打开失败,请检查是否有占用!");
}
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// 处理接收到的数据
byte[] buffer = new byte[serialPort.BytesToRead];
serialPort.Read(buffer, 0, buffer.Length);
string receivedData = BitConverter.ToString(buffer).Replace("-", " ");
Dispatcher.Invoke(() =>
{
//ReceivedDataTextBox.Text += + Environment.NewLine;
Debug.WriteLine(receivedData);
});
}
private void slider_MouseUp(object sender, MouseButtonEventArgs e)
{
byte[] bytes = new byte[4];
bytes[0] = 0xFF;
bytes[1] = 0x00;
bytes[2] = BitConverter.GetBytes(m.Pos)[0];
bytes[3] = 0xFE;
serialPort.Write(bytes, 0, bytes.Length);
Thread.Sleep(30);
}
private void btn_buzz_mode1(object sender, RoutedEventArgs e)
{
byte[] bytes = new byte[4];
bytes[0] = 0xFF;
bytes[1] = 0x01;
bytes[2] = 0x00;
bytes[3] = 0xFE;
serialPort.Write(bytes, 0, bytes.Length);
Thread.Sleep(30);
}
private void btn_buzz_mode2(object sender, RoutedEventArgs e)
{
byte[] bytes = new byte[4];
bytes[0] = 0xFF;
bytes[1] = 0x01;
bytes[2] = 0x01;
bytes[3] = 0xFE;
serialPort.Write(bytes, 0, bytes.Length);
Thread.Sleep(30);
}
private void btn_buzz_mode3(object sender, RoutedEventArgs e)
{
byte[] bytes = new byte[4];
bytes[0] = 0xFF;
bytes[1] = 0x01;
bytes[2] = 0x02;
bytes[3] = 0xFE;
serialPort.Write(bytes, 0, bytes.Length);
Thread.Sleep(30);
}
private void btn_buzz_mode4(object sender, RoutedEventArgs e)
{
byte[] bytes = new byte[4];
bytes[0] = 0xFF;
bytes[1] = 0x01;
bytes[2] = 0x03;
bytes[3] = 0xFE;
serialPort.Write(bytes, 0, bytes.Length);
Thread.Sleep(30);
}
}
}
MainViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApp1
{
internal class MainViewModel : INotifyPropertyChanged
{
private int pos;
public int Pos
{
get => pos;
set
{
this.pos = value;
RaisePropertyChanged("Pos");
}
}
public event PropertyChangedEventHandler? PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
标签:u8g2,舵机,void,bytes,System,using,WPF,buf,8266sg90
From: https://www.cnblogs.com/xxing/p/17575082.html