SonarFPGA


Sonar FPGA Code

This page describes the progress of the Sonar FPGA code.

This FPGA code is intended to get the SRF04 sonar sensor working. In order to make the sonar sensor do anything, it must receive a trigger pulse from the HandyBoard. The sensor then emits an ultrasonic pulse and sets its output line high until the echo is receive or it times out.

In order to generate the trigger pulse, the 25MHz clock and a button input were used. When the button is pressed, a counter is reset and a digital output to the sonar sensor is set high. The signal will remain high until the counter reaches a value of 250, then returns to 0. The value 250 was selected because 250 clock cycles at 25MHz yield the 10 microsecond pulse needed for the trigger pulse.

module pulser(CLOCK, BUTTON, DIGOUT);
   input CLOCK;
   input BUTTON;
   output DIGOUT;

       reg [0:0] temp = 0;
       reg [7:0] usec;
   always @ ( posedge CLOCK )
   begin
        if(BUTTON == 1)
        begin
              usec <= usec +1;
              if(usec == 250)
                      temp <= 0;
        end
              
        else // BUTTON PRESSED
        begin
              usec <= 0;
              temp <= 1;
        end
   end

   assign DIGOUT = temp;
endmodule

Note that the digital output signal to the board uses an intermediate temp value. This is due to restrictions in the Verilog environment and has no impact on the end result of the code. A problem that was encountered was that the sonar pulse is triggered as soon as the board is powered on. We concluded that the button, which is active low, has a value of 0 before being brought up to the value of 1 (unpressed).

After the trigger pulse is sent, the sonar sensor emits its ultrasonic pulse and sets a signal line high. Another Verilog module was designed to wait for this pulse. When the signal goes from low to high (DIGIN = 1; pulse emited, waiting for echo) a timer is started similar to the one in the pulser module. When the signal drops back to low, the timer is latched so the value can be used. For debugging purposes, an elaborate case statement was used to map the range of valid sensor times to 16 bits to be displayed on the LED. The 4-bit number represented by the LEDs is low for close distances and high for far distances.

module listener(DIGIN, LEDS, CLOCK);
  input DIGIN;
  output [3:0] LEDS;

       input CLOCK;
       reg [3:0] store = 0;
       reg [31:0] usec = 0;
       reg [31:0] value = 0;
       //reg [0:0] temp = 0;
always @ (posedge CLOCK)
begin
if(DIGIN == 1)
begin
       usec <= usec + 1;
       store <= 0;
       value <= 0;
end

else
       value <= usec;
       // giant if/else if ladder to map time to 16 bit number
       //  results of ladder are stored in store[]
 			
end
       assign LEDS[0] = store[0];
       assign LEDS[1] = store[1];
       assign LEDS[2] = store[2];
       assign LEDS[3] = store[3];

endmodule

A slight inaccuracy is introduced by checking DIGIN = 1 instead of posedge DIGIN. This code was used because Verilog did not allow nested posedge signals to be used. When the signal to DIGIN goes high, it could take a clock cycle or two for the comparison to work. The error could be compounded or reduced when the signal returns to the low state. In any case, the total error in timing is negligible.

When the pulser and listener are combined and loaded into the FPGA, the HandyBoard is able to successfully use the sonar on boot. A future extension of this work would be to incorporate this code into the HandyBoard code so that the timer in the listener module can be stored to a register than can be read and converted into a distance or a different unit of time. Also, the code could be reworked so that the trigger pulse is generated from a function call rather than a button press.

It is believed that the if/else ladder is causing some problems. Since this is only used for debug purposes, it is not a large concern.

A page with technical specifications for the SRF04 can be found at http://www.robot-electronics.co.uk/htm/srf04tech.htm.

Contributors

  • Matt Bailey
  • Dave Cedia
  • Andrew Chandler
  • Michael Howlett
  • Joell Michel