串口下拉框去掉电脑自带的 COM1,只留实训台上的 COM2–COM5;展开时每个串口后面用灰字标出接的设备(ADAM-4017+、ADAM-4150、ZigBee 协调器、LED 屏),选中后的值还是 COM2 这样的串口名,和真机一致。项目 5 任务 3 跳过 COM1 的写法照书保留,任务说明补一句;使用说明、设计方案同步;按位置选串口的测试下标跟着改
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
50946467f6
commit
50dced4d37
9 files changed
+26
-15
No files matched your search
+1
-1
@@ -55,7 +55,7 @@
|
||||
|
||||
**还原真实行为**:在后台线程里直接修改控件,会抛出和 VS 中按 F5 调试时一样的"线程间操作无效"异常;单选按钮、复选框、下拉框的事件顺序与真实 WinForms 一致。
|
||||
|
||||
**教材要求的运行能力**:多窗体(`Show`、`Hide`、`Close`,项目 1 的登录程序就用到);控制台输出面板(`Console.WriteLine`);虚拟 COM 口(`SerialPort.GetPortNames()` 返回 COM1–COM5,保留"选串口、点打开"的操作步骤)。
|
||||
**教材要求的运行能力**:多窗体(`Show`、`Hide`、`Close`,项目 1 的登录程序就用到);控制台输出面板(`Console.WriteLine`);虚拟 COM 口(`SerialPort.GetPortNames()` 返回 COM2–COM5,对应实训台的四台设备,保留"选串口、点打开"的操作步骤)。
|
||||
|
||||
**导入与导出 VS 工程**:设计器能读懂 VS 生成的 `Designer.cs`,教材配套的 19 个参考工程可直接导入,作为初始模板和参考答案;学生作品也能导出为 VS 工程,在机房真机上运行。
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ namespace System.IO.Ports;
|
||||
/// </summary>
|
||||
public class SerialPort : Component
|
||||
{
|
||||
/// <summary>COM1 是电脑自带串口,COM2–COM5 对应实训台上的 4017、4150、ZigBee 协调器和 LED 屏</summary>
|
||||
private static readonly string[] VirtualPorts = { "COM1", "COM2", "COM3", "COM4", "COM5" };
|
||||
/// <summary>COM2–COM5 对应实训台上的 4017、4150、ZigBee 协调器和 LED 屏,不提供电脑自带的 COM1</summary>
|
||||
private static readonly string[] VirtualPorts = { "COM2", "COM3", "COM4", "COM5" };
|
||||
|
||||
public SerialPort() { }
|
||||
|
||||
@@ -19,7 +19,7 @@ public class SerialPort : Component
|
||||
|
||||
public static string[] GetPortNames() => (string[])VirtualPorts.Clone();
|
||||
|
||||
public string PortName { get; set; } = "COM1";
|
||||
public string PortName { get; set; } = "COM2";
|
||||
public int BaudRate { get; set; } = 9600;
|
||||
public int DataBits { get; set; } = 8;
|
||||
public int ReadTimeout { get; set; } = -1;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
1. 点 **+ 新建类**,建 `RecordClass`,写两个静态成员:`string[,] record = new string[50, 2]`(每条记录存时间和内容)、`int recoudeindex = 0`(下一条记录存在第几行)。
|
||||
2. Form1 的代码开头加上 `using System.IO.Ports;`、`using DeviceCtrlLibrary;`、`using DeviceCtrlLibrary.Model;`;全局变量:`ADAM4150ResModel ResModel;`、`bool IsOpen = false;`、`string LED_MSG = "";`。
|
||||
3. **Form1_Load**:清空两个下拉框,用 for 循环加串口号;遇到 `COM1`(电脑自带的串口)就 `continue` 跳过。
|
||||
3. **Form1_Load**:清空两个下拉框,用 for 循环加串口号;遇到 `COM1`(电脑自带的串口)就 `continue` 跳过。平台上没有 COM1,这段照书保留,在机房真机上才用得到。
|
||||
4. **btn_Open 的 Click**:打开时调用 `adam4150Helper.Open(com_environmentPort.Text)` 和 `ledHelper.OpenLedCom(com_ledPort.Text)`,按钮改成"关闭";关闭时关闭 ADAM-4150 串口,按钮改回"开启"。
|
||||
5. **btn_get 的 Click**:
|
||||
- 用 `adam4150Helper.SetData()` 读出数据存进 `ResModel`,清空 `LED_MSG`,显示当前时间,火焰、烟雾两个框先写"正常";
|
||||
|
||||
@@ -214,7 +214,7 @@ try {
|
||||
async (s) => {
|
||||
const window = s.window!
|
||||
window.action('com_lamp', { action: 'dropDown' })
|
||||
window.action('com_lamp', { action: 'select', index: 3 })
|
||||
window.action('com_lamp', { action: 'select', index: 2 })
|
||||
window.action('btn_open', { action: 'click' })
|
||||
await Bun.sleep(300)
|
||||
// 设备消息由服务器记进实训台状态,再以 board 消息推给浏览器
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ const latencies = await Promise.all(
|
||||
const form = instance.form!
|
||||
const id = (name: string) => findId(form, name)!
|
||||
send(instance, { type: 'action', id: id('com_Port'), action: 'dropDown' })
|
||||
send(instance, { type: 'action', id: id('com_Port'), action: 'select', index: 4 })
|
||||
send(instance, { type: 'action', id: id('com_Port'), action: 'select', index: 3 })
|
||||
send(instance, { type: 'action', id: id('btn_Open'), action: 'click' })
|
||||
send(instance, { type: 'action', id: id('txt_SendText'), action: 'text', value: '压力测试' })
|
||||
await Bun.sleep(200)
|
||||
|
||||
@@ -196,7 +196,7 @@ test('项目2 任务2:温度读数来自实训台,滑块变化后再次获
|
||||
const { runner, id } = await startSample('p2-t2-模拟量采集')
|
||||
const port = id('com_port')
|
||||
// 串口列表在 Load 里就已填好
|
||||
runner.send({ type: 'action', id: port, action: 'select', index: 1 })
|
||||
runner.send({ type: 'action', id: port, action: 'select', index: 0 })
|
||||
runner.send({ type: 'action', id: id('btn_Open'), action: 'click' })
|
||||
const textOf = (name: string) =>
|
||||
runner
|
||||
@@ -224,7 +224,7 @@ test('项目3 任务1:单选按钮切换,事件顺序与 WinForms 一致,
|
||||
await runner.waitFor('patch', (m) => m.changes.some((c) => c.id === lamp && c.prop === 'IsOn' && c.value === true))
|
||||
expect(runner.messages.some((m) => m.type === 'device')).toBe(false)
|
||||
|
||||
runner.send({ type: 'action', id: id('com_port'), action: 'select', index: 3 })
|
||||
runner.send({ type: 'action', id: id('com_port'), action: 'select', index: 2 })
|
||||
runner.send({ type: 'action', id: id('btn_open'), action: 'click' })
|
||||
|
||||
// 选"关":先触发"开"的 CheckedChanged(又开一次),再触发"关"的 CheckedChanged,最终关灯
|
||||
@@ -241,8 +241,8 @@ test('项目3 任务1:单选按钮切换,事件顺序与 WinForms 一致,
|
||||
|
||||
test('项目3 任务2:勾选人体开关后,有人经过时 5 秒内路灯打开', async () => {
|
||||
const { runner, id } = await startSample('p3-t2-人体红外ZigBee联动')
|
||||
runner.send({ type: 'action', id: id('com_lamp'), action: 'select', index: 3 })
|
||||
runner.send({ type: 'action', id: id('com_environment'), action: 'select', index: 2 })
|
||||
runner.send({ type: 'action', id: id('com_lamp'), action: 'select', index: 2 })
|
||||
runner.send({ type: 'action', id: id('com_environment'), action: 'select', index: 1 })
|
||||
runner.send({ type: 'action', id: id('btn_open'), action: 'click' })
|
||||
|
||||
// 复选框的 Click 里读取 Checked:此时 Checked 必须已经是 true
|
||||
@@ -316,7 +316,7 @@ test('项目1 任务2:计算器(装箱拆箱)和多态', async () => {
|
||||
|
||||
/** 选 COM3、点"开启",等定时器读到实训台上的传感器 */
|
||||
async function openAdam4150(runner: Runner, id: (name: string) => string) {
|
||||
runner.send({ type: 'action', id: id('com_port'), action: 'select', index: 2 })
|
||||
runner.send({ type: 'action', id: id('com_port'), action: 'select', index: 1 })
|
||||
runner.send({ type: 'action', id: id('btn_open'), action: 'click' })
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onKey))
|
||||
|
||||
<h3>5. 虚拟实训台</h3>
|
||||
<ul>
|
||||
<li>运行区下面是虚拟实训台,代替书上的实物设备。程序打开的串口:COM2 → ADAM-4017+,COM3 → ADAM-4150,COM4 → ZigBee 协调器,COM5 → LED 屏。</li>
|
||||
<li>运行区下面是虚拟实训台,代替书上的实物设备。程序打开的串口:COM2 → ADAM-4017+,COM3 → ADAM-4150,COM4 → ZigBee 协调器,COM5 → LED 屏。程序里的串口下拉框展开时,每个串口后面也会用灰字标出接的设备。</li>
|
||||
<li>拖动滑块(或点一下滑块再按方向键)调温度、湿度、光照;点人体红外、烟雾、火焰、红外对射切换有无。程序控制的灯、警示灯、LED 屏会跟着变化。</li>
|
||||
<li>
|
||||
两盏照明灯:<b>照明灯 1</b> 接 ZigBee 继电器节点 1(项目 3 的路灯),<b>照明灯 2</b> 接 ADAM-4150 的 DO1(项目 7 的教室、寝室、会议室);警示灯接
|
||||
|
||||
@@ -58,6 +58,8 @@ const items = computed(() => (p.value.Items as string[] | undefined) ?? [])
|
||||
const editable = computed(() => p.value.DropDownStyle !== 'DropDownList')
|
||||
const combo = ref<HTMLElement>()
|
||||
const listStyle = ref<CSSProperties>({})
|
||||
/** 串口列表里每个口后面用灰字标出实训台上接的设备,只是提示,下拉框的值还是 COM2 这样的串口名 */
|
||||
const portDevices: Record<string, string> = { COM2: 'ADAM-4017+', COM3: 'ADAM-4150', COM4: 'ZigBee 协调器', COM5: 'LED 屏' }
|
||||
|
||||
function openDropDown() {
|
||||
if (!enabled.value) return
|
||||
@@ -73,7 +75,7 @@ function openDropDown() {
|
||||
listStyle.value = {
|
||||
left: `${rect.left}px`,
|
||||
top: `${rect.bottom}px`,
|
||||
width: `${el.offsetWidth}px`,
|
||||
minWidth: `${el.offsetWidth}px`,
|
||||
transform: `scale(${rect.width / el.offsetWidth || 1})`,
|
||||
font: css.font,
|
||||
color: css.color,
|
||||
@@ -177,7 +179,9 @@ const itemHeight = computed(() => `${(p.value.ItemHeight as number | undefined)
|
||||
<span class="wf-combobox-arrow" @mousedown.prevent="openDropDown">▾</span>
|
||||
<Teleport to="body">
|
||||
<ul v-if="dropDownOpen" class="wf-combobox-list" :style="listStyle">
|
||||
<li v-for="(item, index) in items" :key="index" @mousedown.prevent="selectItem(index)">{{ item }}</li>
|
||||
<li v-for="(item, index) in items" :key="index" @mousedown.prevent="selectItem(index)">
|
||||
{{ item }}<span v-if="portDevices[item]" class="wf-combobox-hint">{{ portDevices[item] }}</span>
|
||||
</li>
|
||||
<li v-if="items.length === 0" class="wf-combobox-empty"> </li>
|
||||
</ul>
|
||||
</Teleport>
|
||||
|
||||
@@ -196,6 +196,13 @@
|
||||
|
||||
.wf-combobox-list li {
|
||||
padding: 1px 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 串口后面的设备名提示:比列表文字淡,悬停变蓝底白字时也看得清 */
|
||||
.wf-combobox-hint {
|
||||
margin-left: 1.5em;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.wf-combobox-list li:hover {
|
||||
|
||||
Reference in new issue
Block a user