在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
創(chuàng)作
電子發(fā)燒友網>電子資料下載>電子資料>FPGA供電的電磁占卜板

FPGA供電的電磁占卜板

2022-11-21 | zip | 3.77 MB | 次下載 | 免費

資料介紹

描述

利用電磁的力量在這個萬圣節(jié)與靈魂交談,使用 FPGA 驅動的占卜板,運行網絡服務器,允許用戶激活板子移動。

在今年萬圣節(jié)季節(jié)開始時播放了我最喜歡的恐怖電影和播客之后,我被 Ouija 板的想法所困擾。我想要一種免提使用的方法,這最初讓我想到了使用具有無線功能的 FPGA,運行網絡服務器供用戶連接。這與在正確時間激活的電磁鐵配對以移動板,將允許連接到與 FPGA 相同的 Wi-Fi 網絡的用戶與網頁接口以控制板的運動。

基于 Zynq 的MiniZed非常適合我作為該項目使用的理想 FPGA 板,因為它結構緊湊,內置 Murata“Type 1DX”無線模塊,支持 802.11b/g/n Wi-Fi 和藍牙 4.1,并可通過其 USB 端口供電它還有一個 8GB eMMC 內存芯片,可以通過 Wi-Fi 連接重新編程,所以我覺得它是一個理想的選擇,適合留在你可能不想經常訪問的封閉空間。這是該項目的確切用例,其中 FPGA 和相關電路將被封裝在本質上是游戲板形狀的盒子中。

為了概述所有內容,該項目有四個主要步驟:

  • MiniZed 上的 FPGA 設計(網絡服務器和 GPIO 驅動程序腳本)
  • 游戲板盒的構造與頂蓋上的占卜板設計。
  • 游戲板箱內的電磁鐵和機械部件的電路布局。
  • 根據(jù)網頁上的用戶輸入,更新 GPIO 驅動程序腳本以及何時打開電磁鐵和電機

FPGA設計

我將使用從 Avnet BSP 為 Vivado/Vitis/PetaLinux 版本 2019.2 創(chuàng)建的 PetaLinux 項目開始該項目的 FPGA 設計部分,然后修改為添加 Arduino 標頭 GPIO. 但是,只有 128MB 的 eMMC 被分區(qū)用于 initramfs 根文件系統(tǒng),作為 MiniZed 開箱即用的嵌入式 Linux 映像的默認配置。除了存儲所有項目文件之外,這還不足以安裝該項目所需的所有 Python 包。對 initramfs 根文件系統(tǒng)的任何更改在電源循環(huán)之間也不是持久的。因此,需要重新配置 PetaLinux 項目以從存儲在第二個分區(qū)中的 ext4 文件系統(tǒng)引導,該分區(qū)可以訪問 eMMC 芯片的其余 8GB 內存。這也意味著 MiniZed 上的 eMMC 需要重新分區(qū)以具有格式化為 FAT 的引導分區(qū)和格式化為 ext4 的根文件系統(tǒng)分區(qū)。

在重新分區(qū)和重新格式化 eMMC 之前,我們需要在 initramfs 中運行的當前嵌入式 Linux 版本中添加一些庫文件以格式化 eMMC,特別是在 e2fsprogs 實用程序集中用于格式化 ext4 中的分區(qū)的庫。我嘗試添加這些文件系統(tǒng)包并僅從 QSPI 閃存映像生成一個新啟動,但它使內核太大而無法放入 MiniZed 的默認分區(qū),所以我使用了這個 hack 解決方法:

  • 在 rootfs 中啟用 e2fsprogs 構建項目以獲得所需的 ext4 文件系統(tǒng)格式化文件。
  • 將 rootfs.tar.gz 精確到我計算機上的臨時位置。
  • 將所需的庫文件從 /sbin 和 /lib 復制到閃存驅動器以傳輸?shù)?MiniZed。

首先,將目錄更改為 Petalinux 項目并打開根文件系統(tǒng)配置編輯器:

cd ./minized/minized_emmc_enhanced_2019_2
petalinux-config -c rootfs

導航到 Filesystem Packages > base > e2fsprogs 并啟用所有包選項:

poYBAGN290WAYfmJAABcSTolxhQ273.png
?

構建 PetaLinux 項目:

petalinux-build

構建完成后,在您的 PC 上創(chuàng)建一個臨時目錄以精確根文件系統(tǒng),以便您可以將所需的 sbin 和 lib 文件復制到閃存驅動器(獲取所有庫依賴項以避免 Invalid ELF Header 消息)。

mkdir -p <project path>/image/linux/tmp_rootfs
tar -xvf /image/linux/rootfs.tar.gz
cp <project path>/image/linux/tmp_rootfs/lib/libcom_err.so /dev/sda1
cp /image/linux/tmp_rootfs/lib/libcom_err.so.2 /dev/sda1
cp <project path>/image/linux/tmp_rootfs/lib/libcom_err.so.2.1 /dev/sda1
cp /image/linux/tmp_rootfs/lib/libe2p.so /dev/sda1
cp <project path>/image/linux/tmp_rootfs/lib/libe2p.so.2 /dev/sda1
cp /image/linux/tmp_rootfs/lib/libe2p.so.2.3 /dev/sda1
cp <project path>/image/linux/tmp_rootfs/lib/libext2fs.so /dev/sda1
cp /image/linux/tmp_rootfs/lib/libext2fs.so.2 /dev/sda1
cp <project path>/image/linux/tmp_rootfs/lib/libext2fs.so.2.4 /dev/sda1
cp /image/linux/tmp_rootfs/sbin/mke2fs /dev/sda1
cp <project path>/image/linux/tmp_rootfs/sbin/mkfs.ext4 /dev/sda1

將第二根 USB 電纜連接到 Minized 上的 AUX 電源端口,將 USB 閃存驅動器插入其中,然后將庫 (lib) 文件復制到 /lib 目錄,并將 make 文件系統(tǒng)文件 (mkfs) 復制到 /sbin 目錄。

root@MiniZed:~# cp /dev/sda1/libcom_err.so /lib
root@MiniZed:~# cp /dev/sda1/libcom_err.so.2 /lib
root@MiniZed:~# cp /dev/sda1/libcom_err.so.2.1 /lib
root@MiniZed:~# cp /dev/sda1/libe2p.so /lib
root@MiniZed:~# cp /dev/sda1/libe2p.so.2 /lib
root@MiniZed:~# cp /dev/sda1/libe2p.so.2.3 /lib
root@MiniZed:~# cp /dev/sda1/libext2fs.so /lib
root@MiniZed:~# cp /dev/sda1/libext2fs.so.2 /lib
root@MiniZed:~# cp /dev/sda1/libext2fs.so.2.4 /lib
root@MiniZed:~# cp /dev/sda1/mke2fs /sbin
root@MiniZed:~# cp /dev/sda1/mkfs.ext4 /sbin

將文件復制到 MiniZed 上后,移除閃存驅動器并返回 PC 上的 PetaLinux 項目。回到根文件系統(tǒng)編輯器,禁用 e2fsprogs 包,然后重建項目。

petalinux-build

繼續(xù)重新配置 Linux 映像以從 ext4 類型的外部文件系統(tǒng)引導,打開 PetaLinux 硬件配置編輯器:

petalinux-config

導航到 Image Packaging Configuration 選項卡,首先將 Root 文件系統(tǒng)類型更改為 EXT (SD/eMMC/QSPI/SATA/USB)。然后將 SD 設備的設備節(jié)點更新為 /dev/mmcblk1p2,如您所見,它將與我們將在后面的步驟中創(chuàng)建的 eMMC 中的 ext4 分區(qū)的名稱匹配。

編輯 Root 文件系統(tǒng)格式以僅包含 ext4。最后,禁用 TFTP 引導選項。

?
?
?
poYBAGN290eAT0UAAABE4u6M3vA253.png
?
1 / 4
?

保存并退出 PetaLinux 硬件配置編輯器。

我在之前的項目中介紹了如何創(chuàng)建自定義網絡服務器以在 MiniZed 上運行,以及如何使用MiniZed 的 Arduino 標頭 GPIO驅動電磁鐵我決定通過向 PetaLinux 項目添加自定義配方,從這些項目中獲取源文件并將它們打包到根文件系統(tǒng)中的用戶包中。這樣,它們將始終在 MiniZed 上的這個新的嵌入式 Linux 映像中可用。

/project-spec/meta-user/目錄中創(chuàng)建一個新的配方目錄:

mkdir -p project path>/project-spec/meta-user/recipe-knitronics

在配方目錄中創(chuàng)建特定的包目錄:

mkdir -p project path>/project-spec/meta-user/recipe-knitronics/gameboard

創(chuàng)建一個名為“files”的目錄和一個與包目錄同名的 bitbake 文件:

mkdir -p project path>/project-spec/meta-user/recipe-knitronics/gameboard/files
nano /project-spec/meta-user/recipe-knitronics/gameboard/gameboard.bb
?
?
?
pYYBAGN290mAGpN-AABn3GPR3LE951.png
?
1 / 3
?

bitbake 文件在 Yocto 工具集(PetaLinux 所基于)中的作用與 Makefile 在 PC 上的一般構建自動化中所起的作用相同。bitbake 指定如何將配方中的文件安裝到嵌入式 Linux 映像中。在這種情況下,bitbake 非常簡單,因為所需要做的就是復制 Web 服務器的項目源文件并將 GPIO 控制到嵌入式 Linux 映像的根目錄中。

為了簡化 bitbake 中的代碼,我將 webserver 目錄壓縮到一個 tarball 中,并將其指定為將復制到嵌入式 Linux 映像的根目錄中的內容。

將以下代碼添加到 bitbake 以將在根目錄的“文件”文件夾中指定的所有文件。

SUMMARY = "MiniZed Gameboard"
DESCRIPTION = "Files for MiniZed webserver-enabled gameboard"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

#FILESEXTRAPATHS_prepend := "${THISDIR}/files:"

SRC_URI += "file://gpio_driver.py \
            file://gpio_setup.py \
            file://gameboard-webserver.tar.xz;unpack=0 \
"

do_install() {
    install -d ${D}/home/root/
    cp -r ${WORKDIR}/gpio_driver.py ${D}/home/root/
    cp -r ${WORKDIR}/gpio_setup.py ${D}/home/root/
    install -m 0755 ${WORKDIR}/gameboard-webserver.tar.xz ${D}/home/root/
}

FILES_${PN} = " \
    /home/root/gpio_driver.py \
    /home/root/gpio_setup.py \
    /home/root/gameboard-webserver.tar.xz \
"

將所有源文件添加到新配方中的 files 目錄并完成 bitbake 文件后,編輯/project-spec/meta-user/conf中的 user-rootfsconfig以添加以下行:

CONFIG_gameboard

這使根文件系統(tǒng)編輯器知道新配方可作為用戶定義包的選項使用。要將其添加到下一個構建,請打開根文件系統(tǒng)編輯器:

petalinux-config -c rootfs

導航到用戶包,您將看到新包作為啟用選項。

?
?
?
poYBAGN2906AXE1HAAP0H-qZ6VA996.png
?
1 / 2
?

啟用游戲板包,然后保存并關閉根文件系統(tǒng)編輯器。

編輯/project-spec/meta-user/recipes-bsp/minized-misc/files目錄中的 wpa_supplicant.conf 文件,其中包含您要連接 MiniZed 的網絡的 Wi-Fi SSID 和密碼。

最后,構建 PetaLinux 項目:

petalinux-build

構建完成后,使用 petalinux-package 命令創(chuàng)建新的引導二進制映像:

petalinux-package --boot --fsbl <project directory>/images/linux/zynq_fsbl.elf --fpga . /images/linux/system.bit --u-boot --force

旁注:PetaLinux 2020.1 在為 SD 設備打包根文件系統(tǒng)和引導二進制文件的方式上進行了重大升級,因此雖然我認為這種方法與舊版本的 PetaLinux 相當向后兼容,但我認為它不適用于2020.1.

/image/linux目錄,將 BOOT.BIN、image.ub 和 rootfs.ext4 復制到 USB 閃存驅動器。

再次,將第二條 USB 電纜連接到 MiniZed 上的 AUX 電源端口,然后將閃存驅動器插入其中。

從根本上說,我遵循與為 FPGA 準備 SD 卡以啟動和運行其文件系統(tǒng)相同的過程,將 eMMC 視為 SD 卡。

卸載 eMMC 并在其上運行 fdisk 實用程序:

root@MiniZed:~# umount /dev/mmcblk1p1
root@MiniZed:~# fdisk /dev/mmcblk1

調整默認分區(qū)的大小,使 eMMC 的引導分區(qū) mmcblk1p1 為 512MB,而 mmcblk1p2 的剩余大小為根文件系統(tǒng)的 8GB。

Command (m for help): d
Selected partition 1
Command (m for help): n
Command action
  e   extended
  p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-232448, default 1): 1
Last cylinder or +size or +sizeM or +sizeK (122-232448, default 232448): +512M
Command (m for help): a
Partition number (1-4): 1
Command (m for help): p
Disk /dev/mmcblk1: 7616 MB, 7616856064 bytes
4 heads, 16 sectors/track, 232448 cylinders
Units = cylinders of 64 * 512 = 32768 bytes
       Device Boot      Start         End      Blocks  Id System
/dev/mmcblk1p1   *          1       15747      500032  83 Linux
Command (m for help): n
Command action
  e   extended
  p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (1-232448, default 1): 15748
Last cylinder or +size or +sizeM or +sizeK (15748-232448, default 232448): Using default value 232448
Command (m for help): p
Disk /dev/mmcblk1: 7616 MB, 7616856064 bytes
4 heads, 16 sectors/track, 232448 cylinders
Units = cylinders of 64 * 512 = 32768 bytes
       Device Boot      Start         End      Blocks  Id System
/dev/mmcblk1p1   *           1       15747      500032  83 Linux
/dev/mmcblk1p2           15748      232448     6934432  83 Linux
Command (m for help): w

鍵入“w”將新分區(qū)寫入磁盤。

退出 fdisk 實用程序后,將第二個分區(qū) (mmcblk1p2) 格式化為 ext4:

root@MiniZed:~# mkfs.ext4 -L root /dev/mmcblk1p2

創(chuàng)建一個目錄來掛載分區(qū)。

root@MiniZed:~# root@MiniZed:~# mkdir /mnt/emmc_rootfs
root@MiniZed:~# mount /dev/mmcblk1p2 /mnt/emmc_rootfs

將壓縮的根文件系統(tǒng)映像 (rootfs.ext4) 復制到該目錄。

root@MiniZed:~# cp /run/media/sda1/linux_ver1/rootfs.ext4 /mnt/emmc_rootfs/

創(chuàng)建一個臨時目錄以掛載到以防需要額外空間,然后將根文件系統(tǒng)內容復制回第一個目錄。

root@MiniZed:~# mkdir /mnt/ext4
root@MiniZed:~# mount /mnt/emmc_rootfs/rootfs.ext4 /mnt/ext4/ -o loop
root@MiniZed:~# cp -rf /mnt/ext4/* /mnt/emmc_rootfs/

卸載臨時目錄并刪除壓縮的根文件系統(tǒng)映像。

root@MiniZed:~# umount /mnt/ext4/
root@MiniZed:~# rm /mnt/emmc_rootfs/rootfs.ext4

使用新的啟動二進制映像刷新 QSPI:

root@MiniZed:~# flashcp /run/media/sda1/linux_ver1/BOOT.BIN /dev/mtd0

將第一個分區(qū) (mmcblk1p1) 格式化為 FAT:

root@MiniZed:~# mkfs.vfat -F 32 -n BOOT /dev/mmcblk1p1

創(chuàng)建一個目錄來掛載分區(qū)。

root@MiniZed:~# mkdir /mnt/emmc_BOOT
root@MiniZed:~# mount /dev/mmcblk1p1 /mnt/emmc_BOOT/

將內核映像和引導二進制映像復制到引導分區(qū)。

root@MiniZed:~# cp /run/media/sda1/linux_ver1/BOOT.BIN /mnt/emmc_BOOT/
root@MiniZed:~# cp /run/media/sda1/linux_ver1/image.ub /mnt/emmc_BOOT/

完全關閉 MiniZed,然后使用重置按鈕重新開啟。

root@MiniZed:~# shutdown -h now

重新開機后,運行 Wi-Fi 連接腳本以在 wpa_supplicant.conf 中指定的無線網絡上獲取 MiniZed:

root@MiniZed:~# wifi.sh

運行 GPIO 設置 Python 腳本以導出 MiniZed 的 Arduino 接頭上的所有引腳,以便它們可供 GPIO 驅動程序腳本使用。

root@MiniZed:~# python3 ./gpio_setup.py

將 webserver tarball 解壓縮到根目錄并通過運行主要 Python 腳本來啟動它:

root@MiniZed:~# tar -xvf gameboard-webserver.tar.xz ./
root@MiniZed:~# python3 ./gameboard-webserver/webserver.py

通過在您的 PC 或手機上的網絡瀏覽器中連接到 MiniZed 的分配 IP 來測試網絡服務器。

?
?
?
pYYBAGN291eAQqEtAACq3e17ujo785.png
?
1 / 2 ?顯然網頁設計不是我的強項...
?

現(xiàn)在,任何連接到同一個 Wi-Fi 網絡的設備都可以連接到游戲板的主頁,為游戲板鍵入下一個短語。

構建游戲板盒

當我第一次有這個項目的想法時,建造圍欄是我最缺乏經驗的,所以我決定在我當?shù)氐乃囆g用品商店四處逛逛,看看我的一些選擇是什么。由于整個項目都是基于電磁鐵的使用,我知道我想要一些薄的、有色金屬的,但也很堅固。我一直傾向于木材,當我在藝術用品商店遇到一整塊各種形狀和大小的工藝木材時,我的選擇就被鞏固了。

我想在盒子里留出足夠的空間來舒適地容納游戲板的所有內容,并能夠添加未來的更新/修復,但它至少在某種程度上仍然類似于游戲板的尺寸。所以我決定一個 1 英寸的內部厚度,只有頂部和底部的膠合板加上外部厚度是最好的中間地帶。我還想盡量減少我必須做的切割量,因為木工是一個新發(fā)現(xiàn)對我來說技能,所以我選擇將游戲板盒保持為膠合板進來的尺寸,即 12"x24"。

我最終使用的木材和用品是:

  • 24 英寸 x 1 英寸 x 1/2 英寸低音木板 - (x2) 作為盒子蓋的支撐支柱,因為膠合板非常薄,對電磁鐵的干擾最小。
  • 24 英寸 x 1 英寸 x 1 英寸低音木板 - (x4) 用于游戲板盒的側面。
  • 24 英寸 x 12 英寸 x 1/4 英寸工藝膠合板 - (x1) 作為游戲板盒的底部。
  • 24 英寸 x 12 英寸 x 1/32 英寸樺木膠合板 - (x1) 用于帶有顯靈板設計的游戲板盒蓋。
  • 斜接盒用于切割游戲板盒側面的低音木板和盒內的支撐支柱。
  • 埃爾默木匠的木膠
  • 金屬薄膜膠帶用于裝飾盒子的外部。
  • 打磨任何邊緣和表面的砂紙塊。
  • 用于安裝蓋子的螺絲,但也可以選擇在將來移除以進行更新/修復。

我首先使用斜接盒切割 24" x 1" x 1" 低音木板,使其末端具有 45 度角,為游戲板盒創(chuàng)建框架。然后我使用木膠將框架粘合在一起。然后我將框架粘在 24" x 12" x 1/4" 工藝膠合板上,形成盒子的下半部分。

?
?
?
pYYBAGN291qAdHyDAAG3ux8EkBo225.png
?
1 / 3
?

我想得到一些字母印章和油漆,以在 24" x 12" x 1/32" 樺木膠合板上手工重新創(chuàng)建占卜板設計,但經過短暫的反復試驗,很快就發(fā)現(xiàn)我沒有沒有藝術技巧讓它看起來像我想要的那樣。所以我跑到我當?shù)氐倪\輸商店打印出一張 11"x 17" 小報大小的占卜板圖像,粘在游戲板的頂部(1/32英寸厚的膠合板)。

為了構圖,我使用了在藝術用品商店找到的令人敬畏的金屬金色薄膜膠帶。我很快就知道,雖然我那把可憐的剪刀非常鈍,但這膠帶是相當堅硬的東西。

pYYBAGN292GADETDAAMHMxmxO8A179.png
?

我打破了我心愛的 Dymo 標簽制造商,添加了“Knitronics”和“Halloween 2020”標簽。

?
?
?
pYYBAGN292aAUj5YAAdsxm5w8uU364.png
?
1 / 2
?

我還將游戲板底座的邊緣包裹在相同的金色膠帶中。

游戲板盒中的電路布局

對于游戲板的膽量,我打算讓電磁鐵足夠堅固,成為唯一必要的機械部件。我購買了直徑為 1 英寸的空白金屬撞擊板,它是釹磁鐵(不是永磁體,但非常含鐵),用于連接到壓板的腳上,以便電磁鐵拉動它。

poYBAGN292uAM_6CAAZBunbcjtc706.png
?

然而,我發(fā)現(xiàn)沒有一個愛好者大小(又名合理大小)的電磁鐵足夠強大,可以從半厘米以上的地方吸引木板。

pYYBAGN293CAIdHnAAZm1hOb6ho377.png
?

這導致我實施了一個帶皮帶和滑輪系統(tǒng)的直流電機,它可以拉動電磁鐵。通過使用帶皮帶的雙極電機,我將電磁鐵連接到皮帶的底部,電機能夠在任一方向旋轉以前后拉??動電磁鐵。

poYBAGN293WAAwdaAAjh5nGYseA003.png
?

我從 Adafruit 找到了一些非常適合這項工作的迷你雙極步進電機,最后我使用 3D 打印機更換零件來更換滑輪和皮帶。

pYYBAGN293uAAds9AAmrzJw-g0I082.png
?

為了驅動電磁鐵,我使用了一個簡單的達林頓驅動電路(使用ULN2803 )來允許 MiniZed 的 GPIO 打開和關閉它們,同時保護 MiniZed 的 IO 免受從電源斷開時產生的反向電流的影響電磁鐵。對于步進電機,我使用了L293N H 橋 IC。

?
?
?
poYBAGN2936ALEbDAARFcWWOVws612.png
?
1 / 2 ?驅動電路的電路圖和原理圖。
?

更新 GPIO 驅動程序腳本

由 webserver (spell_phrase.py) 調用的 GPIO 驅動程序腳本最終負責將網頁中的字符串形式的輸入短語轉換為相應的 GPIO 切換以控制電磁鐵和電機的邏輯。

最后一分鐘的短片只讓我有一行工作,所以這就是我在這里包含的代碼。最終,該腳本由 main 函數(shù)中的一個 case 語句組成,用于在 Ouija 板 (A - M) 的第一行中的可訪問字符,以及其他四個函數(shù)。其他四個功能是用于電磁鐵和電機的 GPIO 控制器功能。

電磁鐵函數(shù)將 MiniZed 的每個 GPIO 引腳作為文件對象打開 GPIO 編號,導出引腳,然后將其設置引腳的方向輸出。

電機正向和反向功能也將每個 GPIO 引腳作為文件對象打開 GPIO 編號,導出引腳,然后將其設置引腳的方向輸出。由于步進電機將其一個完整的旋轉分成多個相等的步數(shù),這轉化為一次將電流施加到步進電機的四個相位輸入之一的特定順序;這意味著切換 H 橋的 4 個 GPIO 輸入的特定序列。

由于我使用的是 4 針步進電機,因此將其向前驅動一圈的順序如下:

步驟1:

  • 引腳0(1)
  • 引腳1(0)
  • 引腳2(1)
  • 引腳3(0)

第2步:

  • 引腳0(0)
  • 引腳1(1)
  • 引腳2(1)
  • 引腳3(0)

第 3 步:

  • 引腳0(0)
  • 引腳1(1)
  • 引腳2(0)
  • 引腳3(1)

第4步:

  • 引腳0(1)
  • 引腳1(0)
  • 引腳2(0)
  • 引腳3(1)

以相反方向驅動步進電機只需向后重復此序列即可。

最終,我測量到步進器需要大約 381 轉才能將連接在皮帶上的電磁鐵從 A 到 M 移動字母行的整個長度,字母之間大約需要 30 轉。這意味著重復上述序列 30 次將使電磁鐵(以及最終在打開時被吸引到它的板)從一個字母移動到下一個相鄰字母。

總體而言,腳本從網頁前端獲取輸入短語并將其解析為單個字符,然后通過一個巨大的 if else 語句(case 語句的 Python 版本),其中每個字符都被分配一個數(shù)值。保存前一個字符的值,兩個數(shù)值之間的差乘以在相鄰字母之間移動所需的步進器轉數(shù)提供所需的距離和方向數(shù)據(jù)。

spell_phrase.py 的代碼:

import os
import re
import sys 
import time
import requests
import subprocess

emag0 = '/sys/class/gpio/gpio999/'
emag1 = '/sys/class/gpio/gpio1000/'
motor0a = '/sys/class/gpio/gpio1001/'
motor0c = '/sys/class/gpio/gpio1002/'
motor0b = '/sys/class/gpio/gpio1003/'
motor0d = '/sys/class/gpio/gpio1004/'

def emag_on(emag):
    emagPath = emag + 'value'
    emagFile = open(emagPath,'w')
    emagFile.write('1')
    emagFile.close()

def emag_off(emag):
    emagPath = emag + 'value'
    emagFile = open(emagPath,'w')
    emagFile.write('0')
    emagFile.close()

def motor0_forward(distance):
    for x in range(1, distance):
        motorPath0a = motor0a + 'value'
        motorPath0c = motor0c + 'value'
        motorPath0b = motor0b + 'value'
        motorPath0d = motor0d + 'value'

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('1')
        motorFile0c.write('0')
        motorFile0b.write('1')
        motorFile0d.write('0')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('0')
        motorFile0c.write('1')
        motorFile0b.write('1')
        motorFile0d.write('0')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('0')
        motorFile0c.write('1')
        motorFile0b.write('0')
        motorFile0d.write('1')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('1')
        motorFile0c.write('0')
        motorFile0b.write('0')
        motorFile0d.write('1')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

def motor0_backward(distance):
    for x in range(1, distance):
        motorPath0a = motor0a + 'value'
        motorPath0c = motor0c + 'value'
        motorPath0b = motor0b + 'value'
        motorPath0d = motor0d + 'value'

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('1')
        motorFile0c.write('0')
        motorFile0b.write('0')
        motorFile0d.write('1')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('0')
        motorFile0c.write('1')
        motorFile0b.write('0')
        motorFile0d.write('1')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('0')
        motorFile0c.write('1')
        motorFile0b.write('1')
        motorFile0d.write('0')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

        motorFile0a = open(motorPath0a,'w')
        motorFile0c = open(motorPath0c,'w')
        motorFile0b = open(motorPath0b,'w')
        motorFile0d = open(motorPath0d,'w')

        motorFile0a.write('1')
        motorFile0c.write('0')
        motorFile0b.write('1')
        motorFile0d.write('0')

        motorFile0a.close()
        motorFile0c.close()
        motorFile0b.close()
        motorFile0d.close()

def spell_phrase(phrase):
    char_num = 1
    emag_on(emag0)

    if(phrase!=None):
        [char for char in phrase]:
            if char == 'a' or char == 'A':
                next_char_num = 1
                distance = (char_num - next_char_num)*30
                if distance == 0 or distance < 0:
                    # already at edge of board
                else:
                    motor0_forward(distance)

            elif char == 'b' or char == 'B':
                next_char_num = 2
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'c' or char == 'C':
                next_char_num = 3
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'd' or char == 'D':
                next_char_num = 4
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'e' or char == 'E':
                next_char_num = 5
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'f' or char == 'F':
                next_char_num = 6
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'g' or char == 'G':
                next_char_num = 7
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'h' or char == 'H':
                next_char_num = 8
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'i' or char == 'I':
                next_char_num = 9
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'j' or char == 'J':
                next_char_num = 10
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'k' or char == 'K':
                next_char_num = 11
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'l' or char == 'L':
                next_char_num = 12
                distance = (char_num - next_char_num)*30
                if distance < 0:
                    motor0_backward(distance)
                else:
                    motor0_forward(distance)

            elif char == 'm' or char == 'M':
                next_char_num = 13
                distance = (char_num - next_char_num)*30
                if distance == 0 or distance < 0:
                    motor0_backward(distance)
                else:
                    # already at edge of baord

            else:
                motor0_backward(1)
                motor0_forward(1)

        char_num = next_char_num
    else:
        phrase = "noPhrase"

    emag_off(emag0)

    return phrase

def main(arg):
    phraseOut = spell_phrase(arg)

if __name__ == "__main__":
    main(sys.argv[1])

項目總結

我在這個項目上遇到了一些障礙,然后才把它帶到我想要這個萬圣節(jié)的確切點,當前版本只依賴于輸入由字母 A - M 組成的字符串。我還想找到更安靜的步進電機,但它仍然是一個今年有趣的道具!我對 MiniZed 機械地融入這個項目感到非常滿意,我認為它將成為我未來道具建造項目的首選板。

我已經列出了一份清單,我將繼續(xù)升級主板!我認為這將成為現(xiàn)在每個萬圣節(jié)都適合我的主食。我還從機械設計和外殼制造中學到了很多東西,我已經想要升級了。明年繼續(xù)關注!

未來更新:

  • 修改網頁以在啟動時啟動。
  • 讓 GPIO 設置 Python 腳本在啟動時運行,或者讓網絡服務器在第一次啟動時運行它,然后再接受第一個輸入短語。
  • 修復短路以使其他 4 行正常工作。

下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數(shù)據(jù)手冊
  2. 1.06 MB  |  532次下載  |  免費
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費
  5. 3TC358743XBG評估板參考手冊
  6. 1.36 MB  |  330次下載  |  免費
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費
  9. 5元宇宙深度解析—未來的未來-風口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費
  11. 6迪文DGUS開發(fā)指南
  12. 31.67 MB  |  194次下載  |  免費
  13. 7元宇宙底層硬件系列報告
  14. 13.42 MB  |  182次下載  |  免費
  15. 8FP5207XR-G1中文應用手冊
  16. 1.09 MB  |  178次下載  |  免費

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費
  3. 2555集成電路應用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費
  7. 4開關電源設計實例指南
  8. 未知  |  21549次下載  |  免費
  9. 5電氣工程師手冊免費下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費
  11. 6數(shù)字電路基礎pdf(下載)
  12. 未知  |  13750次下載  |  免費
  13. 7電子制作實例集錦 下載
  14. 未知  |  8113次下載  |  免費
  15. 8《LED驅動電路設計》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費
  3. 2protel99se軟件下載(可英文版轉中文版)
  4. 78.1 MB  |  537798次下載  |  免費
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費
  11. 6電路仿真軟件multisim 10.0免費下載
  12. 340992  |  191187次下載  |  免費
  13. 7十天學會AVR單片機與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費
  15. 8proe5.0野火版下載(中文版免費下載)
  16. 未知  |  138040次下載  |  免費
主站蜘蛛池模板: 日韩免费一级毛片| 五月综合色啪| bt天堂在线最新版www| 日韩黄a级成人毛片| 四虎欧美| 亚洲五月婷| 亚洲a影院| 日韩一卡 二卡 三卡 四卡 免费视频| 三级在线观看视频网站| 欧美色a电影精品aaaa| 久久伊人色| 成人做视频免费| 国产三级a三级三级天天| 国产精品亚洲玖玖玖在线靠爱| 成人一级视频| 天天干狠狠插| 天天摸日日干| 欧美超级碰碰| 免费黄色成人| 日韩亚射吧| 久久激情网| 天天射天天摸| 久久免费视频99| 一级片在线免费| 久久久午夜| 中文字幕国产一区| 一区二区三区伦理| 欧美性狂猛xxxxxbbbbb| 国产精品不卡片视频免费观看| 天天天射| 国产成人啪精品午夜在线播放 | 色综合久久综合| 久久精品亚洲一级毛片| 亚洲综合五月天欧美| 黑人影院| 流不尽奶水的大乳h| 三级亚洲| 超级碰碰青草久热国产| 免费一级特黄特色大片| 亚洲无卡| 调教r18车肉高h男男|