아두이노를 배우는 초기에 만들어본 담배연기센서. 담배연기 혹은 휘발성연기가 발생하면 경보를 울리게 된다. 당시, 아파트 담배연기에 대응하기 위해 만들었던 장치이다. 담배연기가 발생하면 빠르게 문을 닫거나 환풍기를 틀거나 할 생각이었다.
배우는 초기라 bulky 하게 만들었는데, 아래와 같이 box안에 넣었다. 그리고 코드를 수정하여 보다 정확하게 결과를 출력할 수 있도록 하였다.
int phase1 = 9; | |
int phase2 = 10; | |
int phase3 = 11; | |
int led = 12; | |
unsigned long stepLength = 15000; | |
int minStepLength = 1200; // max 4020 RPM | |
int steps = 5; | |
void setup() | |
{ | |
pinMode(led, OUTPUT); | |
pinMode(phase1, OUTPUT); | |
pinMode(phase2, OUTPUT); | |
pinMode(phase3, OUTPUT); | |
digitalWrite(led, LOW); | |
} | |
void loop() | |
{ | |
switchStep(1); | |
switchStep(2); | |
switchStep(3); | |
if (stepLength > minStepLength) | |
{ | |
stepLength = stepLength - steps; | |
} | |
else | |
{ | |
// set the minimum pulse length | |
stepLength = minStepLength; | |
} | |
if (stepLength < 39950) | |
{ | |
digitalWrite(led, HIGH); // second gear | |
steps = 300; | |
} | |
if (stepLength < 20000) | |
{ | |
digitalWrite(led, LOW); // third gear | |
steps = 50; | |
} | |
if (stepLength < 3000) | |
{ | |
digitalWrite(led, HIGH); // fourth gear | |
steps = 2; | |
} | |
} | |
void switchStep(int stage) | |
{ | |
switch (stage) | |
{ | |
case 1: | |
digitalWrite(phase1, HIGH); | |
digitalWrite(phase2, LOW); | |
digitalWrite(phase3, LOW); | |
myDelay(stepLength); | |
break; | |
case 2: | |
digitalWrite(phase1, LOW); | |
digitalWrite(phase2, HIGH); | |
digitalWrite(phase3, LOW); | |
myDelay(stepLength); | |
break; | |
default: | |
digitalWrite(phase1, LOW); | |
digitalWrite(phase2, LOW); | |
digitalWrite(phase3, HIGH); | |
myDelay(stepLength); | |
break; | |
} | |
} | |
void myDelay(unsigned long p) | |
{ | |
if (p > 16380) | |
{ | |
delay(p / 1000); | |
} | |
else | |
{ | |
delayMicroseconds(p); | |
} | |
} |
unsigned long counter = 0; | |
unsigned long last_timestamp = 0; | |
void setup() | |
{ | |
// put your setup code here, to run once: | |
Serial.begin(115200); | |
pinMode(2, INPUT); | |
attachInterrupt(digitalPinToInterrupt(2), input, RISING); | |
} | |
void input() | |
{ | |
//cli(); | |
if (last_timestamp > 0) | |
{ | |
if (micros() - last_timestamp > 1000000) | |
{ | |
Serial.print("Freq(Hz)= "); Serial.print(counter); | |
Serial.print(" dT(us)= "); Serial.print(1000000.0f / (float)counter); | |
Serial.print(" RPM= "); Serial.println(counter * 60); | |
last_timestamp = micros(); | |
counter = 0; | |
} | |
else | |
{ | |
counter++; | |
} | |
} | |
else | |
{ | |
last_timestamp = micros(); | |
} | |
//sei(); | |
} | |
void loop() | |
{ | |
} |
library IEEE; | |
use IEEE.STD_LOGIC_1164.all; | |
use IEEE.STD_LOGIC_ARITH.all; | |
use IEEE.STD_LOGIC_UNSIGNED.all; | |
USE IEEE.NUMERIC_STD.ALL; | |
entity LCD1602 is | |
port ( | |
CLK : in std_logic; | |
Reset : in std_logic; | |
LCD_RS : out std_logic; | |
LCD_RW : out std_logic; | |
LCD_EN : out std_logic; | |
LCD_Data : out std_logic_vector(7 downto 0) | |
); | |
end LCD1602; | |
architecture Behavioral of LCD1602 is | |
type state is (set_dlnf, set_cursor, set_dcb, set_cgram, write_cgram, set_ddram, write_LCD_Data); | |
signal Current_State : state; | |
type ram1 is array(0 to 30) of std_logic_vector(7 downto 0); | |
type ram2 is array(0 to 30) of std_logic_vector(7 downto 0); | |
type ram3 is array(0 to 30) of std_logic_vector(7 downto 0); | |
constant cgram1 : ram1 := (x"46", x"50", x"47", x"41", x"2f", x"43", x"50", x"4c", x"44", x"2f", x"4D", x"43", x"55", x"20", x"20", x"20", x"57", x"57", x"57", x"2e", x"32", x"31", x"45", x"44", x"41", x"2e", x"43", x"4f", x"4d", x"20", x"20"); | |
constant cgram3 : ram3 := (x"68", x"74", x"74", x"70", x"3a", x"2f", x"2f", x"73", x"68", x"6F", x"70", x"33", x"35", x"31", x"38", x"31", x"33", x"30", x"37", x"2E", x"74", x"61", x"6F", x"62", x"61", x"6F", x"2E", x"63", x"6f", x"6d", x"2f"); | |
constant cgram2 : ram2 := (x"51", x"51", x"3a", x"39", x"30", x"36", x"36", x"30", x"36", x"35", x"39", x"36", x"20", x"20", x"20", x"20", x"54", x"65", x"6c", x"3a", x"31", x"35", x"38", x"31", x"35", x"35", x"31", x"39", x"30", x"37", x"31"); | |
signal CLK1 : std_logic; | |
signal Clk_Out : std_logic; | |
signal LCD_Clk : std_logic; | |
signal m : std_logic_vector(1 downto 0); | |
constant msgtext1 : string := "1234567---Aprilviva! "; | |
constant msgtext2 : string := "Hello from Aprilviva! "; | |
constant msgtext3 : string := "We will rock you! "; | |
-- function ConvUARTData(v: character) return std_logic_vector(7 downto 0) is | |
-- variable ud : integer(9 DOWNTO 0) := (OTHERS => '0'); | |
-- variable ch : integer(7 DOWNTO 0) := (OTHERS => '0'); | |
-- begin | |
-- ch := to_integer(character'pos(v), 8); | |
-- return ud; | |
-- end ConvUARTData; | |
begin | |
LCD_EN <= Clk_Out; | |
LCD_RW <= '0'; | |
process (CLK) | |
variable n1 : integer range 0 to 19999; | |
begin | |
if rising_edge(CLK) then | |
if n1 < 19999 then | |
n1 := n1 + 1; | |
else | |
n1 := 0; | |
Clk_Out <= not Clk_Out; | |
end if; | |
end if; | |
end process; | |
LCD_Clk <= Clk_Out; | |
process (Clk_Out) | |
variable n2 : integer range 0 to 499; | |
begin | |
if rising_edge(Clk_Out) then | |
if n2 < 499 then | |
n2 := n2 + 1; | |
else | |
n2 := 0; | |
Clk1 <= not Clk1; | |
end if; | |
end if; | |
end process; | |
process (Clk1) | |
variable n3 : integer range 0 to 14; | |
begin | |
if rising_edge(Clk1) then | |
n3 := n3 + 1; | |
if n3 <= 4 then | |
m <= "00"; | |
elsif n3 <= 9 and n3 > 4 then | |
m <= "01"; | |
else | |
m <= "10"; | |
end if; | |
end if; | |
end process; | |
process (LCD_Clk, Reset, Current_State) | |
variable cnt1 : std_logic_vector(4 downto 0); | |
begin | |
if Reset = '0' then | |
Current_State <= set_dlnf; | |
cnt1 := "11110"; | |
LCD_RS <= '0'; | |
elsif rising_edge(LCD_Clk) then | |
--Current_State <= Current_State; | |
LCD_RS <= '0'; | |
case Current_State is | |
when set_dlnf => | |
cnt1 := "00000"; | |
LCD_Data <= "00000001"; | |
Current_State <= set_cursor; | |
when set_cursor => | |
LCD_Data <= "00111000"; | |
Current_State <= set_dcb; | |
when set_dcb => | |
LCD_Data <= "00001100"; | |
Current_State <= set_cgram; | |
when set_cgram => | |
LCD_Data <= "00000110"; | |
Current_State <= write_cgram; | |
when write_cgram => | |
LCD_RS <= '1'; | |
if m = "00" then | |
--LCD_Data <= cgram1(conv_integer(cnt1))); | |
--LCD_Data <= msgtext1(conv_integer(cnt1)+1); | |
LCD_Data <= conv_std_logic_vector(character'pos(msgtext1(conv_integer(cnt1)+1)), 8); | |
elsif m = "01"then | |
-- LCD_Data <= cgram2(conv_integer(cnt1)); | |
LCD_Data <= conv_std_logic_vector(character'pos(msgtext2(conv_integer(cnt1)+1)), 8); | |
else | |
-- LCD_Data <= cgram3(conv_integer(cnt1)); | |
LCD_Data <= conv_std_logic_vector(character'pos(msgtext3(conv_integer(cnt1)+1)), 8); | |
end if; | |
Current_State <= set_ddram; | |
when set_ddram => | |
if cnt1 < "11110" then | |
cnt1 := cnt1 + 1; | |
else | |
cnt1 := "00000"; | |
end if; | |
if cnt1 <= "01111" then | |
LCD_Data <= "10000000" + cnt1;--80H | |
else | |
LCD_Data <= "11000000" + cnt1 - "10000";--80H | |
end if; | |
Current_State <= write_LCD_Data; | |
when write_LCD_Data => | |
LCD_Data <= "00000000"; | |
Current_State <= set_cursor; | |
when others => null; | |
end case; | |
end if; | |
end process; | |
end Behavioral; |
module pllsweep(input clk, output clkin, clkout, lock); | |
SB_PLL40_CORE #( | |
.FEEDBACK_PATH("SIMPLE"), | |
.PLLOUT_SELECT("GENCLK"), | |
.DIVR(4'b0000), | |
.DIVF(7'b1111111), | |
.DIVQ(3'b100), | |
.FILTER_RANGE(3'b001) | |
) uut ( | |
.LOCK(lock), | |
.RESETB(1'b1), | |
.BYPASS(1'b0), | |
.REFERENCECLK(clk), | |
.PLLOUTCORE(clkout) | |
); | |
assign clkin = clk; | |
endmodule |
Arduino Uno |
Arduino Nano |
Arduino Pro Mini |
FTDI232 |
ATmega328p DIP type |
ATmega328p Pinout |
Crystal |
Arduino Uno |
Arduino Nano |
Arduino Pro Mini |
FTDI232 |
ATmega328p DIP type |
ATmega328p Pinout |
Crystal |