This example shows how to use the Grove ultrasonic_ranger on the board. The Ultrasonic sensor has a maximal range of 400 cm, a minimal range of 3 cm and resolution of 1 cm.
If no obstacle is seen by the sensor, 500 cm will be returned by default.
In this notebook, we only show how to control the grove ultrasonic ranger using the Pmod interface. A PYNQ Pmod Grove adapter is required in this notebook. With proper changes in this notebook, users can also control the ultrasonic ranger using the Arduino shield.
In [1]:
from pynq.overlays.base import BaseOverlay
base = BaseOverlay("base.bit")
The following program assumes that the ultrasonic sensor is attached to the G1 connector of the Pmod Grove adapter, and the adapter is connected to PMODA.
For the timer controller, the control registers are shown as follows:
Register name | Register functionality | Register value |
---|---|---|
TCSR0 | Timer 0 Control and Status Register | 0x00 |
TLR0 | Timer 0 Load Register | 0x04 |
TCR0 | Timer 0 Counter Register | 0x08 |
TCSR1 | Timer 1 Control and Status Register | 0x10 |
TLR1 | Timer 1 Load Register | 0x14 |
TCR1 | Timer 1 Counter Register | 0x18 |
In [2]:
%%microblaze base.PMODA
#include "xparameters.h"
#include "xtmrctr.h"
#include "gpio.h"
#include "timer.h"
#include <pmod_grove.h>
#define TCSR0 0x00
#define TLR0 0x04
#define TCR0 0x08
#define TCSR1 0x10
#define TLR1 0x14
#define TCR1 0x18
#define MAX_COUNT 0xFFFFFFFF
void create_10us_pulse(gpio usranger){
gpio_set_direction(usranger, GPIO_OUT);
gpio_write(usranger, 0);
delay_us(2);
gpio_write(usranger, 1);
delay_us(10);
gpio_write(usranger, 0);
}
void configure_as_input(gpio usranger){
gpio_set_direction(usranger, GPIO_IN);
}
unsigned int capture_duration(gpio usranger){
unsigned int count1, count2;
count1=0;
count2=0;
XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TLR0, 0x0);
XTmrCtr_WriteReg(XPAR_TMRCTR_0_BASEADDR, 0, TCSR0, 0x190);
while(!gpio_read(usranger));
count1=XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0, TCR0);
while(gpio_read(usranger));
count2=XTmrCtr_ReadReg(XPAR_TMRCTR_0_BASEADDR, 0, TCR0);
if(count2 > count1) {
return (count2 - count1);
} else {
return((MAX_COUNT - count1) + count2);
}
}
unsigned int read_raw(){
gpio usranger;
usranger = gpio_open(PMOD_G1_A);
create_10us_pulse(usranger);
configure_as_input(usranger);
return capture_duration(usranger);
}
In [3]:
from pynq import Clocks
def read_distance_cm():
raw_value = read_raw()
clk_period_ns = int(1000 / Clocks.fclk0_mhz)
num_microseconds = raw_value * clk_period_ns * 0.001
if num_microseconds * 0.001 > 30:
return 500
else:
return num_microseconds/58
In [4]:
read_distance_cm()
Out[4]: