它为 SPIKE™ 产品组合中的 LEGO® Technic™ 电机和传感器提供四个连接器。可用的传感器包括距离传感器、颜色传感器和多功能力传感器。角度电机有多种尺寸,包括集成编码器,可以查询以找到它们的位置。
Build HAT 适合所有具有 40 针 GPIO 接头的 Raspberry Pi 计算机,包括键盘系列设备(加上带状电缆或其他扩展设备)。连接的 LEGO® Technic™ 设备可以与标准的 Raspberry Pi 配件(如摄像头模块)一起在 Python 中轻松控制。
Raspberry Pi Build HAT 电源 (PSU) 单独提供 ,旨在为 Build HAT 和 Raspberry Pi 计算机以及所有连接的 LEGO® Technic™ 设备供电。
乐高®教育系列 SPIKE™ Prime 套装 45678 和 SPIKE™ Prime 扩展套装 45681® 包含在 Build HAT 支持的一系列有用组件。
将 9 毫米垫片连接到板底部。将 Raspberry Pi Build HAT 安装到 Raspberry Pi 上。确保你把它放在正确的位置。与其他 HAT 不同,所有组件都在底部,为顶部的面包板或乐高®元件留出了空间。
如果要访问 Raspberry Pi 的 GPIO 引脚,可以添加可选的高接头并使用 15 mm 垫片。
以下引脚由 Build HAT 本身使用,您不应将任何东西连接到它们。
Raspberry Pi 启动后,单击 Raspberry 菜单按钮,然后选择“首选项”,然后选择“Raspberry Pi 配置”,打开 Raspberry Pi 配置工具。
单击 “interfaces” 选项卡并调整 Serial 设置,如下所示:
如果您正在运行 Raspberry Pi Headless并使用 raspi-config,请从第一个菜单中选择“Interface Options”。
然后是“P6 Serial Port”。
禁用串行控制台:
并启用串行端口硬件。
最终设置应如下所示。
如果您进行了任何更改,则需要在此时重新启动。
连接外部电源(建议使用官方 Raspberry Pi Build HAT 电源 ),但任何能够通过 DC 5521 中心正极桶形连接器(5.5 毫米× 2.1 毫米× 11 毫米)提供 48W 功率的可靠 +8V±10% 电源都将为 Build HAT 供电。除非您使用的是键盘系列设备,否则您不需要将额外的 USB 电源连接到 Raspberry Pi。
您可以选择将 Build HAT 与 Python 或 .NET 结合使用。
要安装 Build HAT Python 库,请打开终端窗口并运行以下命令:
$ sudo apt install python3-build-hat
Bookworm 之前的 Raspberry Pi OS 版本无法使用 apt 访问该库。相反,请运行以下命令以使用 pip 安装库:
$ sudo pip3 install buildhat
有关 Build HAT Python 库的更多信息,请参阅 ReadTheDocs。
有许多电机可与 Build HAT 配合使用。
将电机连接到 Build HAT 上的端口 A。LPF2 连接器需要以正确的方式向上插入。如果连接器不容易滑入,请旋转 180 度,然后重试。
启动 Thonny IDE。添加下面的程序代码:
from buildhat import Motor
motor_a = Motor('A')
motor_a.run_for_seconds(5)
单击 play/run 按钮运行程序。如果这是自 Raspberry Pi 启动后您第一次运行 Build HAT 程序,则在将固件复制到开发板时将暂停几秒钟。您应该会看到红色 LED 熄灭,绿色 LED 亮起。Python 程序的后续执行将不需要此暂停。
您的电机应顺时针旋转 5 秒钟。
更改程序的最后一行并重新运行。
motor_a.run_for_seconds(5, speed=50)
电机现在应该转动得更快。再做一次更改:
motor_a.run_for_seconds(5, speed=-50)
电机应以相反(逆时针)方向转动
通过单击 Thonny 中的加号按钮创建新程序。添加以下代码:
from buildhat import Motor
motor_a = Motor('A')
while True:
print("Position: ", motor_a.get_aposition())
运行程序。抓住电机并转动轴。您应该会看到 Thonny REPL 中打印的数字发生了变化。
有大量传感器可与 Build HAT 配合使用。
将颜色传感器连接到 Build HAT 的端口 B,将力传感器连接到端口 C。
创建另一个新程序:
from signal import pause
from buildhat import ForceSensor, ColorSensor
button = ForceSensor('C')
cs = ColorSensor('B')
def handle_pressed(force):
cs.on() print(cs.get_color())
def handle_released(force):
cs.off()
button.when_pressed = handle_pressed
button.when_released = handle_released
pause()
运行它并将彩色物体(乐高®元素是理想的)放在颜色传感器前面,然后按下力传感器柱塞。传感器的 LED 应亮起,并且最接近的颜色的名称应显示在 Thonny REPL 中。
Microsoft 的 .NET Framework 无法通过 Raspberry Pi 上的 apt 获得。但是,您可以按照 Microsoft 的官方说明安装 .NET 框架。或者,有一个简化的第三方路由可以将 .NET 工具链发送到您的 Raspberry Pi。
$ wget -O - https://raw.githubusercontent.com/pjgpetecodes/dotnet5pi/master/install.sh | sudo bash
安装 .NET Framework 后,您可以创建项目:
$ dotnet new console --name buildhat
这会在 buildhat 子目录中创建一个默认程序,我们需要位于该目录中才能继续:
$ cd buildhat
您现在需要安装以下 nuget 包:
$ dotnet add package System.Device.Gpio --version 2.1.0
$ dotnet add package Iot.Device.Bindings --version 2.1.0
您可以使用 dotnet run 命令运行该程序。现在让我们尝试一下,以确保一切正常。它应该打印 “Hello World!”
$ dotnet run
Hello World!
(当指示在以下说明中“运行程序”时,您只需重新运行 dotnet run)
在下面的说明中,您将编辑文件 buildhat/Program.cs,这是在运行上述命令时生成的 C# 程序。
任何文本编辑器都可以编辑 C# 代码,包括 Geany,这是预装的 IDE/文本编辑器。Visual Studio Code(通常称为“VS Code”)也是一种流行的替代方案。
Raspberry Pi Built HAT 在乐高®术语中被称为“砖块”,您可以使用 Build HAT 串行协议从 .NET 直接与它通信。
您可以按如下方式创建 brick 对象:
Brick brick = new("/dev/serial0");
但您需要记住在代码末尾处理 brick。
brick.Dispose();
如果您想避免调用 brick.最后 dispose,然后使用 using 语句创建你的 brick:
using Brick brick = new("/dev/serial0");
在这种情况下,当程序结束时,您的积木将被自动丢弃。
您可以收集各种软件版本、签名和输入电压:
var info = brick.BuildHatInformation;
Console.WriteLine($"version: {info.Version}, firmware date: {info.FirmwareDate}, signature:");
Console.WriteLine($"{BitConverter.ToString(info.Signature)}");
Console.WriteLine($"Vin = {brick.InputVoltage.Volts} V");
函数 GetSensorType、GetSensor 将允许您检索有关已连接传感器的任何信息。
SensorType sensor = brick.GetSensorType((SensorPort)i);
Console.Write($"Port: {i} {(Brick.IsMotor(sensor) ? "Sensor" : "Motor")} type: {sensor} Connected: ");
在此示例中,您还可以使用 IsMotor 静态函数来检查连接的元件是传感器还是电机。
if (Brick.IsActiveSensor(sensor))
{
ActiveSensor activeSensor = brick.GetActiveSensor((SensorPort)i);
}
else
{
var passive = (Sensor)brick.GetSensor((SensorPort)i);
Console.WriteLine(passive.IsConnected);
}
ActiveSensor 具有一系列高级属性和功能,可以了解传感器的每个元素。也可以从它们的 brick 中调用原始函数。这将允许您选择特定模式并执行高级场景。虽然这是可能的,但已经创建了 motor 和 sensor 类,让您的生活更轻松。
大多数传感器都根据其特殊属性实现事件。您只需订阅 PropertyChanged 和 PropertyUpdated。更改的 1 将在值更改时触发,而更新的 1 将在属性成功更新时触发。根据所使用的模式,某些属性可能会一直在后台更新,而其他一些属性可能会偶尔更新。
您可能只对颜色变化或电机位置变化感兴趣,将其用作转速表。在这种情况下,PropertyChanged 就是您所需要的!
Console.WriteLine("Move motor on Port A to more than position 100 to stop this test.");
brick.WaitForSensorToConnect(SensorPort.PortA);
var active = (ActiveMotor)brick.GetMotor(SensorPort.PortA);
bool continueToRun = true;
active.PropertyChanged += MotorPropertyEvent;
while (continueToRun)
{
Thread.Sleep(50);
}
active.PropertyChanged -= MotorPropertyEvent;
Console.WriteLine($"Current position: {active.Position}, eventing stopped.");
void MotorPropertyEvent(object? sender, PropertyChangedEventArgs e)
{
Console.WriteLine($"Property changed: {e.PropertyName}");
if (e.PropertyName == nameof(ActiveMotor.Position))
{
if (((ActiveMotor)brick.GetMotor(SensorPort.PortA)).Position > 100)
{
continueToRun = false;
}
}
}
块可能需要很长时间才能初始化。已实现对传感器连接的等待。
brick.WaitForSensorToConnect(SensorPort.PortB);
如果您想实现高级功能,例如在一段时间后警告用户并重试,它也需要一个 CancellationToken。
有两种类型的电机, 无源电机和有源电机。有源电机将提供详细的位置、绝对位置和速度,而无源电机只能通过速度进行控制。
可以使用一组通用的功能来控制电机的速度。有 2 个重要的参数:SetPowerLimit 和 SetBias:
train.SetPowerLimit(1.0);
train.SetBias(0.2);
接受的值仅为 0.0 到 1.0 之间。功率限制是一种方便的 ay ,可以按比例减少最大功率。
为电流端口设置的偏置值,该值与正电机驱动值相加,并从负电机驱动值中减去。这可以用来补偿大多数直流电机在转动之前需要一定量的驱动力这一事实。
创建转动电机时的默认值为 0.7 的功率限制和 0.3 的偏置。
典型的无源电机是火车和较旧的 Powered Up 电机。可以设置和读取 Speed 属性。它是目标和被测速度,同时这些传感器无法测量它们。该值介于 -100 到 +100 之间。
还提供控制 Start、Stop 和 SetSpeed 的功能。以下是如何使用它的示例:
Console.WriteLine("This will run the motor for 20 secondes incrementing the PWM");
train.SetPowerLimit(1.0);
train.Start();
for (int i = 0; i < 100; i++)
{
train.SetSpeed(i);
Thread.Sleep(250);
}
Console.WriteLine("Stop the train for 2 seconds");
train.Stop();
Thread.Sleep(2000);
Console.WriteLine("Full speed backward for 2 seconds");
train.Start(-100);
Thread.Sleep(2000);
Console.WriteLine("Full speed forward for 2 seconds");
train.Start(100);
Thread.Sleep(2000);
Console.WriteLine("Stop the train");
train.Stop();
主动电机具有 Speed、AbsolutePosition、Position 和 TargetSpeed 作为特殊属性。即使电机停止,它们也会连续读取。
代码片段展示了如何获取电机、启动它们并读取属性:
brick.WaitForSensorToConnect(SensorPort.PortA);
brick.WaitForSensorToConnect(SensorPort.PortD);
var active = (ActiveMotor)brick.GetMotor(SensorPort.PortA);
var active2 = (ActiveMotor)brick.GetMotor(SensorPort.PortD);
active.Start(50);
active2.Start(50);
// Make sure you have an active motor plug in the port A and D
while (!Console.KeyAvailable)
{
Console.CursorTop = 1;
Console.CursorLeft = 0;
Console.WriteLine($"Absolute: {active.AbsolutePosition} ");
Console.WriteLine($"Position: {active.Position} ");
Console.WriteLine($"Speed: {active.Speed} ");
Console.WriteLine();
Console.WriteLine($"Absolute: {active2.AbsolutePosition} ");
Console.WriteLine($"Position: {active2.Position} ");
Console.WriteLine($"Speed: {active2.Speed} ");
}
active.Stop();
active2.Stop();
Advance 功能可用于主动电机。您可以请求在几秒钟内移动到特定位置、特定绝对位置。以下是几个示例:
// From the previous example, this will turn the motors back to their initial position:
active.TargetSpeed = 100;
active2.TargetSpeed = 100;
// First this motor and will block the thread
active.MoveToPosition(0, true);
// Then this one and will also block the thread
active2.MoveToPosition(0, true);
每个函数都允许您在执行作时阻止或不阻止线程。请注意,对于绝对和相对位置移动,存在几度的容差。
brick.WaitForSensorToConnect(SensorPort.PortA);
var active = (ActiveMotor)brick.GetMotor(SensorPort.PortA);
active.TargetSpeed = 70;
Console.WriteLine("Moving motor to position 0");
active.MoveToPosition(0, true);
Console.WriteLine("Moving motor to position 3600 (10 turns)");
active.MoveToPosition(3600, true);
Console.WriteLine("Moving motor to position -3600 (so 20 turns the other way");
active.MoveToPosition(-3600, true);
Console.WriteLine("Moving motor to absolute position 0, should rotate by 90°");
active.MoveToAbsolutePosition(0, PositionWay.Shortest, true);
Console.WriteLine("Moving motor to position 90");
active.MoveToAbsolutePosition(90, PositionWay.Shortest, true);
Console.WriteLine("Moving motor to position 179");
active.MoveToAbsolutePosition(179, PositionWay.Shortest, true);
Console.WriteLine("Moving motor to position -180");
active.MoveToAbsolutePosition(-180, PositionWay.Shortest, true);
active.Float();
您可以将电机置于浮动位置,这意味着它不再有约束。这是您在将电机用作转速表、移动电机和读取位置时可以使用的一种模式。如果电机上仍有约束,则可能无法移动它。
与电机一样,您有主动和被动传感器。最新的传感器处于活动状态。被动的的是灯和简单的按钮。主动式是距离或颜色传感器,以及小型 3×3 像素显示器。
按钮/触摸无源传感器有一个特定的属性 IsPressed。按下按钮时,该属性设置为 true。下面是一个包含事件的完整示例:
brick.WaitForSensorToConnect(SensorPort.PortA);
var button = (ButtonSensor)brick.GetSensor(SensorPort.PortA);
bool continueToRun = true;
button.PropertyChanged += ButtonPropertyEvent;
while (continueToRun)
{
// You can do many other things here
Thread.Sleep(50);
}
button.PropertyChanged -= ButtonPropertyEvent;
Console.WriteLine($"Button has been pressed, we're stopping the program.");
brick.Dispose();
void ButtonPropertyEvent(object? sender, PropertyChangedEventArgs e)
{
Console.WriteLine($"Property changed: {e.PropertyName}");
if (e.PropertyName == nameof(ButtonSensor.IsPressed))
{
continueToRun = false;
}
}
被动灯是火车灯。它们可以打开,您可以控制它们的亮度。
brick.WaitForSensorToConnect(SensorPort.PortA);
var light = (PassiveLight)brick.GetSensor(SensorPort.PortA);
// Brightness 50%
light.On(50);
Thread.Sleep(2000);
// 70% Brightness
light.Brightness = 70;
Thread.Sleep(2000);
// Switch light off
light.Off()
有源传感器类是所有有源传感器(包括有源电机)都继承的通用类。它们包含一组属性,这些属性涉及它们如何连接到 Build HAT、模式、详细的 Combi 模式、硬件、软件版本和名为 ValueAsString 的特定属性。值 as string 包含作为字符串集合的最后一个度量。测量值到达 P0C0: +23 -42 0,枚举将包含 P0C0:、+23、-42 和 0。这样做是为了如果您使用高级模式并自行管理 Combi 模式和命令,您将能够获得测量值。
所有有源传感器都可以运行特定的测量模式或组合模式。您可以使用 SelectModeAndRead 和 SelectCombiModesAndRead 函数通过高级模式设置一个,并具有您希望持续拥有的特定模式。请务必了解更改模式或设置新模式将停止之前的模式。
可以在 Combi 模式中组合的模式列在 CombiModes 属性中。当您设置其中一种模式时,传感器的属性将自动更新。
WeDo Tilt Sensor 具有特殊的 Tilt 属性。类型是一个点,X 是 X 倾斜,Y 是 Y 倾斜。这些值从 -45 到 + 45,它们被限制在这些值上并表示度数。
您可以使用 ContinuousMeasurement 属性为此传感器设置连续测量。
brick.WaitForSensorToConnect(SensorPort.PortA);
var tilt = (WeDoTiltSensor)brick.GetSensor(SensorPort.PortA);
tilt.ContinuousMeasurement = true;
Point tiltValue;
while(!console.KeyAvailable)
{
tiltValue = tilt.Tilt;
console.WriteLine($"Tilt X: {tiltValue.X}, Tilt Y: {tiltValue.Y}");
Thread.Sleep(200);
}
WeDo 距离传感器通过 Distance 属性为您提供以毫米为单位的距离。
brick.WaitForSensorToConnect(SensorPort.PortA);
var distance = (WeDoDistanceSensor)brick.GetSensor(SensorPort.PortA);
distance.ContinuousMeasurement = true;
while(!console.KeyAvailable)
{
console.WriteLine($"Distance: {distance.Distance} mm");
Thread.Sleep(200);
}
该力传感器测量施加在其上的压力以及是否被压迫。可以通过 Force 和 IsPressed 属性访问这两个属性。
brick.WaitForSensorToConnect(SensorPort.PortA);
var force = (ForceSensor)brick.GetSensor(SensorPort.PortA);
force.ContinuousMeasurement = true;
while(!force.IsPressed)
{
console.WriteLine($"Force: {force.Force} N");
Thread.Sleep(200);
}
这是一个小型 3×3 显示屏,带有 9 个不同的 LED,可以单独控制。该类公开了能够控制屏幕的函数。以下是使用它们的示例:
brick.WaitForSensorToConnect(SensorPort.PortA);
var matrix = (ColorLightMatrix)brick.GetSensor(SensorPort.PortA);
for(byte i = 0; i < 10; i++)
{
// Will light every led one after the other like a progress bar
matrix.DisplayProgressBar(i);
Thread.Sleep(1000);
}
for(byte i = 0; i < 11; i++)
{
// Will display the matrix with the same color and go through all of them
matrix.DisplayColor((LedColor)i);
Thread.Sleep(1000);
}
Spanbrg = stackalloc byte[9] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Spancol = stackalloc LedColor[9] { LedColor.White, LedColor.White, LedColor.White,
LedColor.White, LedColor.White, LedColor.White, LedColor.White, LedColor.White, LedColor.White };
// Shades of grey
matrix.DisplayColorPerPixel(brg, col);
SPIKE 颜色传感器:
颜色和距离传感器:
这些颜色传感器具有多种特性和功能。您可以获得 Color、ReflectedLight 和 AmbiantLight。
最重要的是,颜色和距离传感器可以测量距离并具有对象计数器 。它将自动计算将进出该范围的对象数量。这确实允许对从传感器前面经过的物体进行计数。距离限制为 0 到 10 厘米。
brick.WaitForSensorToConnect(SensorPort.PortC);
var colorSensor = (ColorAndDistanceSensor)brick.GetActiveSensor(SensorPort.PortC);
while (!Console.KeyAvailable)
{
var colorRead = colorSensor.GetColor();
Console.WriteLine($"Color: {colorRead}");
var reflected = colorSensor.GetReflectedLight();
Console.WriteLine($"Reflected: {reflected}");
var ambiant = colorSensor.GetAmbiantLight();
Console.WriteLine($"Ambiant: {ambiant}");
var distance = colorSensor.GetDistance();
Console.WriteLine($"Distance: {distance}");
var counter = colorSensor.GetCounter();
Console.WriteLine($"Counter: {counter}");
Thread.Sleep(200);
}
这是一个距离传感器,它确实实现了一个 Distance 属性,该属性将以毫米为单位给出距离。此 ContinuousMeasurement 模式也可用。
brick.WaitForSensorToConnect(SensorPort.PortA);
var distance = (UltrasonicDistanceSensor)brick.GetSensor(SensorPort.PortA);
distance.ContinuousMeasurement = true;
while(!console.KeyAvailable)
{
console.WriteLine($"Distance: {distance.Distance} mm");
Thread.Sleep(200);
}
您可以在
Python 库文档的完整详细信息也可以在 ReadTheDocs 上找到 。您可以在 .NET IoT Github 存储库中找到有关 .NET 库的更多信息。
您还可以关注 Raspberry Pi Foundation 的项目。
Build HAT 库支持 SPIKE™ Portfolio 中包含的所有 LEGO® Technic™ 设备,以及 LEGO® Mindstorms Robot Inventor 套件和其他使用 PoweredUp 连接器的设备。
Raspberry Pi Build HAT 的机械图。
原文(英文):https://www.raspberrypi.com/documentation/accessories/build-hat.html
PID控制算法是结合比例、积分和微分三种环节于一体的控制算法,它是连续系统中技术最为成熟、应用最为广泛的一种控制算法。
这台 EC500 混动挖掘机,零件数高达 2359,价格也飙到 399.99 欧元。功能上预计搭载多电机、遥控模块或齿轮切换结构。不出意外,这将成为整个2025 年乐高机械组最重磅的一款。
这是积木悬浮术??乐高现在已经不归地球管了吗? NO!这是物理,是【张力】! 果然,学好数理化,走遍天下都不怕~
我们将用 Raspberry Pi 开始我们探索超级计算和科学编程科学领域的激动人心的旅程。
最近我们对1:1还原的乐高汽车模型进行盘点,为大家分享下那些令人惊奇的乐高汽车模型。
在2006年,荧幕上的马自达 RX-7一展其惊人的“漂移”能力,捕获了无数迷弟。谁能想到在18年后的今天,双鹰CaDA竟带来了一款C61502 马自达RX7机械组套装,以1:8旗舰级别的比例,逼真还原了这一特立独行的跑车。