目录
本项目中介绍了电子琴系统的整体的设计,并基于超高速硬件描述语言VHDL在相关的芯片上编程实现的。本设计是采用EDA技术设计的一个简易的十三音符电子琴,该系统基于计算机中时钟分频器的原理,可以通过对时钟脉冲的分频,并根据按键输入设置分频系数,进而控制无源蜂鸣器的发声频率,实现一个简易电子琴的设计。
基于Quartus Ⅱ软件平台,本小组运用VHDL语言对简易电子琴进行了基础设计,程序仿真以及波形验证。该电子琴的代码中主要实现了分频,消抖,模式选择,琴键发声等功能,超速硬件描述语言VHDL编程实现,能够实现高中低三个音阶的切换,每个音阶对应八个不同的琴键。系统实现是用硬件描述语言VHDL按照模块化方式进行设计,然后进行编程、时序仿真、总体整合。本系统的功能比较齐全,对于实际的电子琴功能仿真程度较高,具有一定的实用价值。
在实现功能上,该电子琴可以实现三个音阶的按键切换,并设置有钢琴黑键功能,最大程度上模拟了实际使用的电子琴功能,不具备自动弹奏功能,仅能实现手动控制发声。


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
use IEEE.STD_LOGIC_arith.ALL;
entity piano3 is
Port ( CLK : in STD_LOGIC;
BB1,BB2: IN STD_LOGIC;--高低八度开关
BB3: IN STD_LOGIC;--黑键开关
SS1,SS2,SS3,SS4,SS5,SS6,SS7,SS8: in STD_LOGIC; --开关1-8
LED: out STD_LOGIC_VECTOR (6 downto 0); --数码管
EN_LED: OUT STD_LOGIC_VECTOR (7 downto 0);--数码管选择
RSST: in STD_LOGIC;--复位/静音
SND : out STD_LOGIC);--输出声音
end piano3;
architecture Behavioral of piano3 is
SIGNAL CP0:INTEGER RANGE 0 TO 500000; --分频计数
SIGNAL CP:STD_LOGIC; --分频时钟50HZ用以消抖
signal fm:INTEGER range 0 to 50000000;--声音时长
signal CT:INTEGER; --CT为计数最大值决定音阶
signal CT0:INTEGER range 0 to 50000000;--CT0计数
signal sound:std_logic; --输出声音
signal flag:std_logic;
SIGNAL S1,S2,S3,S4,S5,S6,S7,S8,B1,B2,B3,RST:STD_LOGIC;
SIGNAL MODE:STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL MUL:INTEGER;
signal HEX:std_logic_vector(3 downto 0);--七段信号
signal HEXX:std_logic_vector(5 downto 0);
--------------------------------------------------
begin
SND <= sound;
--------------------------------------------------------
-----------------数码管模块------------------------
HEXX<=HEX&B1&B2;
WITH HEXX SELECT
LED<= ----------默认
"1111001" when "000000", --1
"0100100" when "000100", --2
"0110000" when "001000", --3
"0011001" when "001100", --4
"0010010" when "010000", --5
"0000010" when "010100", --6
"1111000" when "011000", --7
"0000000" when "011100", --8
"0111111" when "111100", ---
"1111001" when "000011", --1
"0100100" when "000111", --2
"0110000" when "001011", --3
"0011001" when "001111", --4
"0010010" when "010011", --5
"0000010" when "010111", --6
"1111000" when "011011", --7
"0000000" when "011111", --8
"0111111" when "111111", ---
----------LOW
"1111001" when "000010", --1
"0100100" when "000110", --2
"0110000" when "001010", --3
"0011001" when "001110", --4
"0010010" when "010010", --5
"0000010" when "010110", --6
"1111000" when "011010", --7
"0000000" when "011110", --8
"1000111" when "111110", --L
----------HIGH
"1111001" when "000001", --1
"0100100" when "000101", --2
"0110000" when "001001", --3
"0011001" when "001101", --4
"0010010" when "010001", --5
"0000010" when "010101", --6
"1111000" when "011001", --7
"0000000" when "011101", --8
"0001001" when "111101", --H
"0111111" when others;
WITH HEX SELECT
EN_LED<= "11111110" when "0000", --1
"11111101" when "0001", --2
"11111011" when "0010", --3
"11110111" when "0011", --4
"11101111" when "0100", --5
"11011111" when "0101", --6
"10111111" when "0110", --7
"01111111" when "0111", --8
"00000000" when others; ---
-------------------------------------------------------
----------------消抖模块---------------------------
PROCESS(CLK)
BEGIN
IF RISING_EDGE(CLK) THEN
IF CP0 = 500000 THEN
CP0<=0;
CP <= NOT CP;
ELSE CP0 <=CP0+1;
END IF;
END IF;
END PROCESS;
PROCESS(CP)
BEGIN
IF RISING_EDGE(CP) THEN
S1 <= SS1;
S2 <= SS2;
S3 <= SS3;
S4 <= SS4;
S5 <= SS5;
S6 <= SS6;
S7 <= SS7;
S8 <= SS8;
B1 <= BB1;
B2 <= BB2;
B3 <= BB3;
RST <= RSST;
END IF;
END PROCESS;
------------------------------------------------------------
-----------------高低八度模式选择-------------------
MODE<=B1&B2;
PROCESS(MODE)--S1设置低八度,S2设置高八度,S1和S2相同时为中八度(默认)
BEGIN
IF MODE="00" OR MODE="11" THEN
MUL<=2;
ELSIF MODE="10" THEN
MUL<=4;
ELSIF MODE="01" THEN
MUL<=1;
END IF;
END PROCESS;
---------------------------------------------------------
------------------频率设置模块---------------------
PROCESS(RST,CLK)--根据模式设置声音频率
BEGIN
--------------------------------------------------
IF B3 = '0' THEN
IF S1='0' THEN
CT<=47777*MUL;
HEX<="0000";
flag<='1';
ELSIF S2='0' THEN
CT <=42567*MUL;
HEX<="0001";
flag<='1';
ELSIF S3='0' THEN
CT <=37922*MUL;
HEX<="0010";
flag<='1';
ELSIF S4='0' THEN
CT <=35793*MUL;
HEX<="0011";
flag<='1';
ELSIF S5='0' THEN
CT <=31888*MUL;
HEX<="0100";
flag<='1';
ELSIF S6='0' THEN
CT <=28409*MUL;
HEX<="0101";
flag<='1';
ELSIF S7='0' THEN
CT <=25310*MUL;
HEX<="0110";
flag<='1';
ELSIF S8='0' THEN
CT <=23888*MUL;
HEX<="0111";
flag<='1';
ELSE
CT <=0;
HEX<="1111";
flag<='0';
END IF;
ELSIF B3 = '1' THEN --黑键
IF S1='0' THEN
CT<=45126*MUL;
HEX<="0000";
flag<='1';
ELSIF S2='0' THEN
CT <=40193*MUL;
HEX<="0001";
flag<='1';
ELSIF S3='0' THEN
CT <=0;-----
HEX<="0010";
flag<='1';
ELSIF S4='0' THEN
CT <=33783*MUL;
HEX<="0011";
flag<='1';
ELSIF S5='0' THEN
CT <=30120*MUL;
HEX<="0100";
flag<='1';
ELSIF S6='0' THEN
CT <=26824*MUL;
HEX<="0101";
flag<='1';
ELSIF S7='0' THEN
CT <=0;-----
HEX<="0110";
flag<='1';
ELSIF S8='0' THEN
CT <=22563*MUL;
HEX<="0111";
flag<='1';
ELSE
CT <=0;
HEX<="1111";
flag<='0';
END IF;
END IF;
---------------------------------------------------------
---------------------核心分频模块------------------
IF RST ='1' THEN --因为接开关S8所以RST为1时静音,为0时允许发出声音
sound <='1';
ELSE
IF rising_edge(clk) then
if flag='1' then
IF CT0 = CT THEN
CT0 <= 0;
SOUND <=NOT SOUND;
ELSIF CT0 /= CT THEN
CT0 <= CT0 + 1;
ELSE
sound <= '1';
CT0 <= 0;
END IF;
else
sound <= '1';
CT0 <= 0;
END IF;
end if;
END IF;
end process;
--------------------------------------------------
--------------------------------------------------
end Behavioral;
(1)单个按键发声功能,即基本分频功能实现
首先编写核心分频模块,实现最简单的按一个键出一个波形的功能,输出声音时长取决于按键时长,可以设置变量CT0来对时钟脉冲进行计数,CT为对应音阶相对应的脉冲计数上限值,CT0每达到该上限值对声音SOUND信号进行翻转,CT0未达到该上限值CT则进行加1。如果RST开关在有效位置,则输出声音SOUND始终为1。
对应的代码如下:
IF RST ='1' THEN
sound <='1';
ELSE
IF rising_edge(clk) then
if flag='1' then
IF CT0 = CT THEN
CT0 <= 0;
SOUND <=NOT SOUND;
ELSIF CT0 /= CT THEN
CT0 <= CT0 + 1;
ELSE
sound <= '1';
CT0 <= 0;
END IF;
else
sound <= '1';
CT0 <= 0;
END IF;
end if;
END IF;
end process;
在仿真时可以先将CT设置为一个较小的数字,便于查看仿真时查看波形,验证基本功能。而在实际上板烧录时,则需要根据实际的不同的音阶及音调频率计算CT值,下图是小组组员根据实际频率计算的CT值。
(2)根据不同频率扩展到8个按键S1,S2,S3,S4,S5,S6,S7,S8
在核心的分频实现单个按键发声功能后,类似的可以根据计算的计数值表设置好同音阶的另外几个计数值,原理与单个按键类似。这里我们考虑到了烧录到FPGA板子时管脚设置的便利性问题,并没有将八个按键设置为一个长度为8的向量,而是设置了8个不同的变量S1,S2,S3,S4,S5,S6,S7,S8,这样在设置管脚时,只需要一一对应的设置管脚,更加方便快捷。这八个按键作为输入,为反逻辑(0有效),当Si(i=1...8)='0'时,则视为按下按键,发出该按键对应频率的琴音。
IF S1='0' THEN
CT<=47777*MUL;
HEX<="0000";
flag<='1';
ELSIF S2='0' THEN
CT <=42567*MUL;
HEX<="0001";
flag<='1';
ELSIF S3='0' THEN
CT <=37922*MUL;
HEX<="0010";
flag<='1';
ELSIF S4='0' THEN
CT <=35793*MUL;
HEX<="0011";
flag<='1';
ELSIF S5='0' THEN
CT <=31888*MUL;
HEX<="0100";
flag<='1';
ELSIF S6='0' THEN
CT <=28409*MUL;
HEX<="0101";
flag<='1';
ELSIF S7='0' THEN
CT <=25310*MUL;
HEX<="0110";
flag<='1';
ELSIF S8='0' THEN
CT <=23888*MUL;
HEX<="0111";
flag<='1';
ELSE
CT <=0;
HEX<="1111";
flag<='0';
END IF;
(3)根据高中低三个音阶及黑键功能设置模式选择开关B1,B2,B3
根据三个不同的音阶设定计数初值。为了简化代码,提高运行效率,我们设置了模式选择的中间变量MODE与频率倍数中间变量MUL。其中,我们将B1和B2两个开关的外部输入视为一个两位向量MODE,B1,B2改变时会频率倍数变量MUL赋给不同值(1,2,4),而MUL变量则作为按键发声部分代码后的一个系数变量,改变发声的频率值(详见上2部分代码)。
-----------------高低八度模式选择-------------------
MODE<=B1&B2;
PROCESS(MODE)--S1设置低八度,S2设置高八度,S1和S2相同时为中八度(默认)
BEGIN
IF MODE="00" OR MODE="11" THEN
MUL<=2;
ELSIF MODE="10" THEN
MUL<=4;
ELSIF MODE="01" THEN
MUL<=1;
END IF;
END PROCESS;
将B3单独设置,用于模拟实际钢琴中“黑键”的功能,即B3=1或0时分别算出两种不同的频率计数初值赋予CT。
(4)根据按下琴键的不同设置对应显示的七段码显示管
本设计中共设计了8个不同的按键,我们根据八个按键由低到高的顺序排序,当按下某一琴键时,显示译码管上就会显示此时按下的按键序号,以及当前对应发声模式:高八度——H,低八度——L,中八度(默认)——不显示。
-----------------数码管模块------------------------
HEXX<=HEX&B1&B2;
WITH HEXX SELECT
LED<= ----------默认
"1111001" when "000000", --1
"0100100" when "000100", --2
"0110000" when "001000", --3
"0011001" when "001100", --4
"0010010" when "010000", --5
"0000010" when "010100", --6
"1111000" when "011000", --7
"0000000" when "011100", --8
"0111111" when "111100", ---
"1111001" when "000011", --1
"0100100" when "000111", --2
"0110000" when "001011", --3
"0011001" when "001111", --4
"0010010" when "010011", --5
"0000010" when "010111", --6
"1111000" when "011011", --7
"0000000" when "011111", --8
"0111111" when "111111", ---
----------LOW
"1111001" when "000010", --1
"0100100" when "000110", --2
"0110000" when "001010", --3
"0011001" when "001110", --4
"0010010" when "010010", --5
"0000010" when "010110", --6
"1111000" when "011010", --7
"0000000" when "011110", --8
"1000111" when "111110", --L
----------HIGH
"1111001" when "000001", --1
"0100100" when "000101", --2
"0110000" when "001001", --3
"0011001" when "001101", --4
"0010010" when "010001", --5
"0000010" when "010101", --6
"1111000" when "011001", --7
"0000000" when "011101", --8
"0001001" when "111101", --H
"0111111" when others;
WITH HEX SELECT
EN_LED<= "11111110" when "0000", --1
"11111101" when "0001", --2
"11111011" when "0010", --3
"11110111" when "0011", --4
"11101111" when "0100", --5
"11011111" when "0101", --6
"10111111" when "0110", --7
"01111111" when "0111", --8
"00000000" when others; ---








5.实现按键消抖
在代码的基本部分全部实现完成后,我们对8个琴键按键,3个模式选择开关,和一个复位开关加入了消抖代码。其思路为将输入时钟信号CLK进行分频,得到低频中间信号CP0,以所得的CP0
----------------消抖模块---------------------------
PROCESS(CLK)
BEGIN
IF RISING_EDGE(CLK) THEN
IF CP0 = 500000 THEN
CP0<=0;
CP <= NOT CP;
ELSE CP0 <=CP0+1;
END IF;
END IF;
END PROCESS;
PROCESS(CP)
BEGIN
IF RISING_EDGE(CP) THEN
S1 <= SS1;
S2 <= SS2;
S3 <= SS3;
S4 <= SS4;
S5 <= SS5;
S6 <= SS6;
S7 <= SS7;
S8 <= SS8;
B1 <= BB1;
B2 <= BB2;
B3 <= BB3;
RST <= RSST;
END IF;
END PROCESS;
下载程序到开发板前需要仿真查错,由于QURTUS仿真功能时间很短,不能实现真实的音阶频率仿真(50M晶振的频率分频需要很久)于是在填入不同音节对应分频系数前,新建专门用于仿真的工程文件,把分频系数调小到仿真可清晰看出变化的程度。更改后仿真分频系数如下:
PROCESS(CLK)
BEGIN
IF B3 = '0' THEN
IF S1='0' THEN
CT<=1*MUL;
HEX<="0000";
flag<='1';
ELSIF S2='0' THEN
CT <=2*MUL;
HEX<="0001";
flag<='1';
ELSIF S3='0' THEN
CT <=3*MUL;
HEX<="0010";
flag<='1';
ELSIF S4='0' THEN
CT <=4*MUL;
HEX<="0011";
flag<='1';
ELSIF S5='0' THEN
CT <=5*MUL;
HEX<="0100";
flag<='1';
ELSIF S6='0' THEN
CT <=6*MUL;
HEX<="0101";
flag<='1';
ELSIF S7='0' THEN
CT <=7*MUL;
HEX<="0110";
flag<='1';
ELSIF S8='0' THEN
CT <=8*MUL;
HEX<="0111";
flag<='1';
ELSE
CT <=0;
HEX<="1111";
flag<='0';
END IF;
ELSIF B3 = '1' THEN
IF S1='0' THEN
CT<=1*MUL;
HEX<="0000";
flag<='1';
ELSIF S2='0' THEN
CT <=2*MUL;
HEX<="0001";
flag<='1';
ELSIF S3='0' THEN
CT <=0;-----
HEX<="0010";
flag<='1';
ELSIF S4='0' THEN
CT <=3*MUL;
HEX<="0011";
flag<='1';
ELSIF S5='0' THEN
CT <=4*MUL;
HEX<="0100";
flag<='1';
ELSIF S6='0' THEN
CT <=5*MUL;
HEX<="0101";
flag<='1';
ELSIF S7='0' THEN
CT <=0;-----
HEX<="0110";
flag<='1';
ELSIF S8='0' THEN
CT <=6*MUL;
HEX<="0111";
flag<='1';
ELSE
CT <=0;
HEX<="1111";
flag<='0';
END IF;
END IF;
(1)设置ENDTIME为 10us

(2)为了仿真结果更明显,仿真时间内有更多CLK时钟信号,将其设置为周期20ns的方波。

(3)RST为复位键‘1’有效,赋初值,同时RST为1时应实现静音功能。
、
S1 S2为琴键,1有效,S1最初设置为0检验静音功能,后再RST为‘0’时检验声音分频功能。S2错开S1有效时间有效,检验不同按键功能。
(4)B1 B2为模式选择键,设置如下:



如上图仿真结果,静音按键下按下琴键,只会有数码管显示,不会对蜂鸣器输出声音。

如上图,S1和S2分别有效时,输出的频率是2倍的关系,同时具体周期也与仿真代码分频模块中设置相同,同时数码管译码前的数据正确。

如上图仿真结果,不同模式下按下不同琴键对应输出频率和仿真代码模式选择模块中设置相同,模式功能实现。
电子综合设计是培养我们综合运用所学知识,提出和解决问题能力的重要学习活动。通过这次实践,我们对FPGA的工作原理与使用都有了进一步的理解,更重要的是提高了自主研究学习的能力。
刚开始,我们研读设计要求,通过网络等各种方式查询相关的资料。通过对这些资料的学习,我们大致了解了本次课程设计相关的知识,例如Quartus Ⅱ软件的使用与VHDL语言等,锻炼了我们搜集信息的能力。
开发过程中,通过学习资料,我们对DE2-115板卡的各个部分有了更深层次的了解,也熟悉了一些引脚的分配方法。在编程方面,通过Quartus Ⅱ软件的开发,使我们加深了对FPGA的工作原理的理解,熟悉了VHDL语言的结构和编程规则。通过DE2-115板与外部设备的配合实现我们所需的相关功能。
此次课程设计中,我们遇到了一系列的问题,也看到了自身的不足。代码的编写部分我们花费了大量时间。由于上学期数电中接触过ISE软件,因此一开始我们小组考虑采用ISE进行代码编写与仿真,而实际上板时直接迁移至Quartus Ⅱ软件中,完成课程设计。代码思路也与现在的最终成果思路不太一致,当时我们考虑到板卡中按键数量不够无法满足实际需要,便按照拨动开关作为琴键设计,而非最终的按键开关设计,且触发源我们采用上升沿和下降沿均可以触发,即对于拨动开关,我们在上拨和下拨时都会让琴发出声音,并设定声音延时时长为0.25s,较为符合电子琴的实际效果。
当时在ise软件中,这一思路的代码已经通过了软件编译和波形仿真,能够实现我们想要的初步功能,只差加入显示译码管和消抖功能上板了。但是后来在第一次集中烧录时,我们满怀信心的将原本ISE中的代码迁移至Quartus Ⅱ软件进行编译烧录时,却遇到了很大的问题——代码根本无法通过调试!我们尝试进行修改,但无奈报错实在太多,让我们非常苦恼。后来我们无奈的向老师求助,老师在看了我们的代码后,很确定的告诉我们,我们这种边沿触发的方式是完全错误的,FPGA根本无法执行这样的指令,且由于时钟速度过快,边沿触发也很难进行消抖处理,我们当时就如同晴空霹雳一般,心里想着三个人三个周末的努力居然就这么白白浪费了,真是心有不甘。但后来组员们也镇静下来,最终商讨后决定使用Quartus Ⅱ软件重新编写代码,由一开始的单个按键,重新走一遍设计流程。有了第一次的失败经验,大家的信心有些受挫,甚至有组员考虑过临时更换题目,但后来也都坚持了下来。最终经历了两个周末,第二版代码成功编译并完成仿真,上板烧录,实现了这一实践设计。
从开始设计到最终完成代码编写,我们小组花费了一个月左右的时间,代码的最终实现离不开三位组员共同努力相互帮助,也离不开老师的耐心指导。最后,感谢组员的相互帮助,以及老师的精心指导,让我们小组得以完成这次课程设计。









1.将设计下载在FPGA 中。点击菜单项Tools->Programmer。打开程序下载环境。

2.点击Hardware Setup 按钮,选择USB。点击 Close 确认设置。


3.下载程序。在Programmer界面中,将文件列表中Program/Configure 属性勾上,点击Start,精度条显示100%时完成下载。

我正在从erb文件切换到HAML。我将hamlgem添加到我的系统中。我创建了app/views/layouts/application.html.haml文件。我应该只删除application.html.erb文件吗?此外,仍然有/public/index.html文件被呈现为默认页面。我想创建自己的默认index.html.haml页面。我应该把它放在哪里以及如何使系统呈现该文件而不是默认索引文件?谢谢! 最佳答案 是的,您可以删除任何已转换为HAML的View的ERB版本。至于你的另一个问题,删除public/index/h
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我想验证一个电子邮件地址是否是PayPal用户。是否有API调用来执行此操作?是否有执行此操作的ruby库?谢谢 最佳答案 GetVerifiedStatus来自PayPal'sAdaptiveAccounts平台会为您做这件事。PayPal没有任何codesamples或SDKs用于Ruby中的自适应帐户,但我确实找到了编写codeforGetVerifiedStatusinRuby的人.您需要更改该代码以检查他们拥有的帐户类型的唯一更改是更改if@xml['accountStatus']!=nilaccount_status
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我想知道我应该如何着手这个项目。我需要每周向人们发送一次电子邮件。但是,这必须在每周的特定时间自动生成并发送。编码有多难?我需要知道是否有任何书籍可以提供帮助,或者你们中的任何人是否可以指导我。它必须使用rubyonrails进行编程。因此有一个网络服务和数据库集成。干杯 最佳答案 为什么这么复杂?您只需安排工作。您可以使用Delayed::Job例如。Delayed::Job让您可以使用run_at符号在特定时间安排作业,如下所示:Delayed::Job.enqueue(SendEmailJob.new(...),:run_
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n
我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:
文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3