martes, 10 de abril de 2018



Ultrasonic sensor HC-RS04 for robotics applications using VHDL





In this sample, I show how to design the architecture of the ultrasonic sensor for robotics applications. A number represented in the seven segment display correspond to some distance defined in the distant calculation entity.

Finally, it is a part of my complete FPGA course. If you interested in my course or you need help in your projects as freelancer contact me at:
postgraduatecahg@gmail.com 


Figure 1. Working principle.


Solution:



Figure 2. TOP Design.




Figure 3. RTL schematic. 



library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity HCRS04 is
    Port ( clk : in  STD_LOGIC;
           echo : in  STD_LOGIC;
           Trigger : out  STD_LOGIC;
  an0 : out std_logic;
           display_out : out  STD_LOGIC_VECTOR (6 downto 0));
end HCRS04;

architecture Behavioral of HCRS04 is

COMPONENT TriggerGen
PORT(
clk : IN std_logic;          
trigger : OUT std_logic
);
END COMPONENT;

COMPONENT counter
PORT(
clk : IN std_logic;
reset : IN std_logic;
enable : IN std_logic;          
q : OUT std_logic_vector(19 downto 0)
);
END COMPONENT;
COMPONENT distance_calculation
PORT(
echo_count : IN std_logic_vector(19 downto 0);          
distance : OUT std_logic_vector(3 downto 0)
);
END COMPONENT;

COMPONENT display_decoder
PORT(
distance_in : IN std_logic_vector(3 downto 0);          
display_out : OUT std_logic_vector(6 downto 0)
);
END COMPONENT;

signal Trigger_out: std_logic;
signal echo_counter1 : STD_LOGIC_VECTOR (19 downto 0);
signal echo_count : STD_LOGIC_VECTOR (19 downto 0);
signal distance_bits : std_logic_vector(3 downto 0);

begin

Inst_TriggerGen: TriggerGen PORT MAP(
clk,
Trigger_out 
);
Inst_counter: counter PORT MAP(
clk,
Trigger_out,
echo,
echo_counter1 
);
process(echo) begin
if falling_edge(echo) then
echo_count <= echo_counter1;
end if;
end process;
Inst_distance_calculation: distance_calculation PORT MAP(
echo_count,
distance_bits 
);
Inst_display_decoder: display_decoder PORT MAP(
distance_bits,
display_out 
);

Trigger <= Trigger_out;
an0 <= '1';


end Behavioral;

---------------------- TriggerGen ----------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity TriggerGen is
generic (n: integer :=20);
    Port ( clk : in  STD_LOGIC;
           trigger : out  STD_LOGIC);
end TriggerGen;

architecture Behavioral of TriggerGen is

signal tick: std_logic_vector(n-1 downto 0) := (others =>'1');
constant nclks: integer := 750000; --1000000; --it corresponds to 20ms
begin
  process (clk) begin
   if clk'event and clk = '1' then
    if tick < nclks-1 then
     tick <= tick + 1;
    else
     tick <= (others => '0');
     end if;
   end if;
  end process;
 trigger <= '1' when (tick < 500) else '0'; 
end behavioral;

----------------------------- counter  -----------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

entity counter is
generic (N: integer := 20);
    Port ( clk : in  STD_LOGIC;
           reset : in  STD_LOGIC;
           enable : in  STD_LOGIC;
           q : out  STD_LOGIC_VECTOR (N-1 downto 0));
end counter;

architecture Behavioral of counter is

signal tick: std_logic_vector(N-1 downto 0);

begin

process (reset, clk, enable) begin

if reset = '1' then
tick <= (others => '0');
elsif clk'event and clk = '1' then
if enable = '1' then
tick <= tick + 1;
end if;
end if;
end process;

q <= tick;

end Behavioral;

------------------------------------ distance_calculation  -------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;


entity distance_calculation is
port(
echo_count : in STD_LOGIC_VECTOR (19 downto 0);
distance : out  STD_LOGIC_VECTOR (3 downto 0)
);
end distance_calculation;

architecture Behavioral of distance_calculation is

begin

Distance <="0000" when (echo_count < 2900) else --0cm
  "0001" when (echo_count > 2900 and echo_count < 8700) else --3cm
  "0010" when (echo_count > 8700 and echo_count < 14500) else --3-5cm
  "0011" when (echo_count > 14500 and echo_count < 21750) else --5-7.5cm
  "0100" when (echo_count > 21750  and echo_count < 27550) else --7.5-9.5cm
  "0101" when (echo_count > 27550  and echo_count < 30450) else --9.5-10.5cm
  "0110" when (echo_count > 30450 and echo_count < 33350) else --10.5-11.5cm
  "0111" when (echo_count > 33350 and echo_count < 37700) else --11.5-13cm
  "1000" when (echo_count > 37700 and echo_count < 40600) else --13-14cm
  "1001" when (echo_count > 40600 and echo_count < 46400) else --14-16cm
  "1010" when (echo_count > 46400 and echo_count < 49300) else --16-17cm
  "1011" when (echo_count > 49300 and echo_count < 52200) else --17-18cm; 
  "1100" when (echo_count > 52200 and echo_count < 55100) else --18-19cm; 
  "1101" when (echo_count > 55100 and echo_count <58000) else --19-20cm; 
  "1110" when (echo_count > 58000 and echo_count < 63800) else --20-22cm; 
  "1111";--more than 22cm
end Behavioral;


-----------------------------  display_decoder   ------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity display_decoder is
    Port ( distance_in : in  STD_LOGIC_VECTOR (3 downto 0);
           display_out : out  STD_LOGIC_VECTOR (6 downto 0));
end display_decoder;

architecture Behavioral of display_decoder is

begin

display_out <="1000000" when distance_in = "0000" else 
  "1111001" when distance_in = "0001" else
  "0100100" when distance_in = "0010" else
  "0110000" when distance_in = "0011" else
  "0011001" when distance_in = "0100" else
  "0010010" when distance_in = "0101" else
  "0000010" when distance_in = "0110" else
  "0111000" when distance_in = "0111" else
  "0000000" when distance_in = "1000" else
  "0011000" when distance_in = "1001" else
  "0000110";

end Behavioral;


--------------------------------  Test Bench of All----------------
USE ieee.std_logic_1164.ALL;

ENTITY hcrs04_top IS
END hcrs04_top;
ARCHITECTURE behavior OF hcrs04_top IS 
    -- Component Declaration for the Unit Under Test (UUT)
    COMPONENT HCRS04
    PORT(
         clk : IN  std_logic;
         echo : IN  std_logic;
         Trigger : OUT  std_logic;
         an0 : OUT  std_logic;
         display_out : OUT  std_logic_vector(6 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal echo : std_logic := '0';

  --Outputs
   signal Trigger : std_logic;
   signal an0 : std_logic;
   signal display_out : std_logic_vector(6 downto 0);

   -- Clock period definitions
   constant clk_period : time := 20 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
   uut: HCRS04 PORT MAP (
          clk => clk,
          echo => echo,
          Trigger => Trigger,
          an0 => an0,
          display_out => display_out
        );

   -- Clock process definitions
   clk_process :process
   begin
clk <= '1';
wait for clk_period/2;
clk <= '0';
wait for clk_period/2;
   end process;

   echo_process :process
   begin
echo <= '0';
wait for (clk_period/2)*100000;
echo <= '1';
wait for (clk_period/2)*10000;
echo <= '0';
wait for (clk_period/2)*1600000;
end process;

END;






Figure 4.  Test bench simulation.



-------------- UCF file using Nexys II board -----------------------
#clk
NET 'clk' LOC = 'B8';

# HCRS04
  NET 'echo' LOC = 'M15' |  CLOCK_DEDICATED_ROUTE = FALSE;
NET 'Trigger' LOC = 'L17';



#Display
NET 'display_out(0)' LOC = 'L18';
NET 'display_out(1)' LOC = 'F18';
NET 'display_out(2)' LOC = 'D17'; 
NET 'display_out(3)' LOC = 'D16';
NET 'display_out(4)' LOC = 'G14';
NET 'display_out(5)' LOC = 'J17';
NET 'display_out(6)' LOC = 'H14'; 

# Anodo.
NET 'an0' LOC = 'F17'; 

lunes, 9 de abril de 2018

AC frequency meter using the PIC18F2550

This project shows an AC frequency meter using tow interrupts External interrupt and TMR0 interrupt.


Note: I can teach you or help you with yours Microcontroller or FPGA projects. If you interested contact me at: 
postgraduatecahg@gmail.com





int externals_tick = 0;  // for counting the external interrupts
float frequency = 0;
float T = 0;

// LCD pins confiuration
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RC0_bit;
sbit LCD_D5 at RC1_bit;
sbit LCD_D6 at RC2_bit;
sbit LCD_D7 at RC6_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;

sbit LCD_D4_Direction at TRISC0_bit;
sbit LCD_D5_Direction at TRISC1_bit;
sbit LCD_D6_Direction at TRISC2_bit;
sbit LCD_D7_Direction at TRISC6_bit;
// End LCD module connections

char txt[15];
char txt3[] = "frequency meter";
char txt4[] = "starting";


void interrupt() {

if(INTCON.TMR0IF)
{
  //PORTC.F0 = ~PORTC.F0;
  T = 32.768/externals_tick; // Tms
  frequency = (1/T)*1000;
  frequency =  frequency/2;
  FloatToStr(frequency, txt);
  INTCON.TMR0IF=0; // clear the TIMER0 interrupt
  TMR0L = 3; // this value is to perform ~32ms
  externals_tick = 0;
  T0CON.TMR0ON = 1;   // TMR0 is running now
}
else
{
    externals_tick++;
    INTCON.INT0IF=0; // clear the external interrupt
}

}

void main() {
 PORTC = 0;
 LATC = 0;
 TRISC = 0x00;

 ADCON1 = 0x0F;  // For digital configuration
 PORTB = 0;
 TRISB = 0xCF;

 Lcd_Init();                        // Initialize LCD

  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  Lcd_Out(1,3,txt3);                 // Write text in first row
  Delay_ms(1000);
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Delay_ms(100);
  INTCON.GIE = 1;  // global interrups are enable
  INTCON.PEIE = 1;  // pheriferical interrups.
  INTCON.INT0IE = 1; // external interrup enable
  INTCON.TMR0IE = 1; // TMR0 interrup enable

  INTCON2.INTEDG0 = 1; //1 = Interrupt on rising edge
  INTCON2.RBPU = 0;       //0= pull up
  INTCON2.TMR0IP = 1; //TMR0 Overflow Interrupt Priority bit

  T0CON.T08BIT = 1; //8 bits
  T0CON.T0CS = 0; //Timer0 Clock Source Select bit,
                 //0 = Internal instruction cycle clock (CLKO)
  T0CON.PSA = 0;  //0 = Timer0 prescaler is assigned.
                 // Timer0 clock input comes from prescaler output.
  T0CON.T0PS0 = 1; // Timer0 Prescaler Select bits
  T0CON.T0PS1 = 1; //
  T0CON.T0PS2 = 1; //
  TMR0L = 3;
  T0CON.TMR0ON = 1;   //start TMR0
  
     while(1){
     Lcd_Out(1,1,txt);
     delay_ms(100);
     }
}

sábado, 7 de abril de 2018



FPGA COURSE SYLLABUS 2018


I have the pleasure of inviting you to my FPGA course either using VHDL or Verilog.
If you are interested please contact me at:
postgraduatecahg@gmail.com

1. Introduction.

2. Design flow.
3. Types of the hardware description.
    a) Data Flow.
    b) Algorithmic design.
    c) Hierarchical design.
4. Combination design.
5. Sequential design.
6. State machines.
7. Hierarchical design (TOP Level).
8. Simulation by test- bench.
9. Design of complex circuits.
   a) UART-Bluetooth.
      a) Transmitter.
      b) Receiver.
   b) PS2.
   c) LCD.
   d) VGA.
   e) Ultrasonic sensor HC-RS04.
   f) SPI-DAC (MCP4921).
   g) FPU (floating point unit IEEE 754).
10) Implementation of artificial neural networks.
       a) Design of the neural network.
       b) Implementation using floating point.
       c) Implementation of the sigmoid function.



Also, you can make a registration at:
https://docs.google.com/forms/d/e/1FAIpQLSfdZts2LMiqPP9xhmGjb9xaCt5hWpJsIQajFECTVrmL0w4O0Q/viewform?usp=sf_link

viernes, 6 de abril de 2018


Mealy finite state machine implemented in VHDL



In this sample the I implement the Mealy finite state machine using VHDL.
It is important to keep in mind that in the Mealy machine the output depends on the states and the inputs, in this case, the input a (see figure 2).
Finally, this post is based on the book Digital design and computer architecture by David Harris.
  
Remember that I can teach you on linea or help you in your projects as a consultant.
if you interested ask to:
postgraduatecahg@gmail.com 


Figure 1. State flow diagram.


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mealy is
port(clk, reset: in std_logic;
a: in std_logic;
y: out std_logic);
end mealy;
architecture Behavioral of mealy is
type statetype is (S0, S1, S2, S3);
signal state, nextstate: statetype;
begin
-- state register
process (clk, reset)begin
  if reset = '1' then
  state <=S0;
  elsif clk'event and clk='1' then
  state <= nextstate;
  end if;
end process;
-- next state logic
process (state, a) begin
  case state is
  when S0 =>
  if a = '1' then
  nextstate <= S1;
  else
  nextstate <= S0;
  end if;
 
  when S1 =>
  if a = '1' then
  nextstate <= S2;
  else
  nextstate <= S0;
  end if;
 
  when S2 =>
  if a = '1' then
  nextstate <= S2;
  else
  nextstate <= S3;
  end if;
 
  when S3 =>
  if a = '1' then
  nextstate <= S1;
  else
  nextstate <= S0;
  end if;
 
  when others => nextstate <= S0;
  end case;
end process;
-- Output logic
y <= '1' when (a='1' and state = S3) else '0';
end Behavioral;





Figure 2. RTL of the Mealy FSM.



Figure 3. Simulation of Mealy FSM.





The finite state machine in VHDL

In this sample, I show how to implement a finite state machine.
In the code, an asynchronous reset is implemented first. After that tow logic parts are implemented, the first logic part is for flow program or in other words the flow of state. The second logic part is for output logic.
Finally is important to know that key part is type statetype which states the implementation of the state machine.

Please remember that I can teach or solve your problems as a consultant:
postgraduatecahg@gmail.com





library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity FSM1 is
port(
clk, reset: in std_logic;
y: out std_logic);
end FSM1;
architecture Behavioral of FSM1 is
type statetype is (S0, S1, S2);
signal state, nextstate: statetype;
-- state register part
begin
process (clk, reset) begin
  if (reset='1') then
  state <= S0;
  elsif (clk'event and clk='1') then
  state <= nextstate;
  end if;
end process;
-- Next state logic
  nextstate <= S1 when state = S0 else
     S2 when state = S1 else
     S0;
-- Output logic
y <= '1' when state = S0 else '0';

end Behavioral;




Bluetooth HC05 using VHDL


In this post, I show the architecture of the RS-232 driver for the Bluetooth module HC05 which is set to work at 9600 bits/second. 

If you interested in the VHDL code its price is 10 USD. So please contact me to:postgraduatecahg@gmail.com




















BTFSS INSTRUCTION  IN ASSEMBLER FOR PIC18F In this sample, we show that how to use a switch input to make an action. Remember that I...