element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
RIoTboard
  • Products
  • Dev Tools
  • Single-Board Computers
  • RIoTboard
  • More
  • Cancel
RIoTboard
Blog Riotboard and Ultrasonic Sensor (HC-SR04)
  • Blog
  • Forum
  • Documents
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join RIoTboard to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: tusharp
  • Date Created: 31 Mar 2016 11:24 AM Date Created
  • Views 1288 views
  • Likes 3 likes
  • Comments 1 comment
  • embedded freescale arm9 linux kernel driver ubuntu imx6
  • tusharp riotboard hc-sr04 sr04 sonar gpio
Related
Recommended

Riotboard and Ultrasonic Sensor (HC-SR04)

tusharp
tusharp
31 Mar 2016

In this small guide I will demonstrate how to integrate Riotboard with Ultrasonic sensor HC-SR04 .

 


image

 

Step1:

 

export ARCH & CROSS_COMPILE to environment path.

 

in my case its like below, yours might be different.

$ export ARCH=arm

$ export CROSS_COMPILE=<PATH_TO_TOOLCHAIN>/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-

 

Step2:

create a directory

$ mkdir driver

 

create a file named "Makefile"  and replace with your KDIR value, below is mine.

 

obj-m := sr04.o

KDIR := /home/tushar/riot_github/kernel_out/lib/modules/3.0.35-02887-g731b440/build

PWD := $(shell pwd)

 

all:

  $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:

  $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean

 

next we will create the driver for sr04 module, create file "sr04.c" with below contents in it.

 

#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/interrupt.h> 


MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("HC-SR04 ultrasonic sensor");


#define HCSR04_ECHO 113 
#define HCSR04_TRIGGER 112

static int gpio_irq=-1;
static int valid_value = 0;


static ktime_t echo_start;
static ktime_t echo_end;

// write to "/sys/class/hcsr04/value"
static ssize_t hcsr04_value_write(struct class *class, struct class_attribute *attr, const char *buf, size_t len) 
{
  printk(KERN_INFO "Buffer len %d bytes\n", len);
  return len;
}


// read from "/sys/class/hcsr04/value"
static ssize_t hcsr04_value_read(struct class *class, struct class_attribute *attr, char *buf) 
{
  int counter;
  gpio_set_value(HCSR04_TRIGGER,1);
  udelay(10);
  gpio_set_value(HCSR04_TRIGGER,0);
  valid_value=0;
  counter=0;
  while (valid_value==0) {
  if (++counter>23200) {
  return sprintf(buf, "%d\n", -1);;
  }
  udelay(1);
  }
  return sprintf(buf, "%lld\n", ktime_to_us(ktime_sub(echo_end,echo_start)));;
}


// Sysfs definitions for hcsr04 class
static struct class_attribute hcsr04_class_attrs[] = {
  __ATTR(value, S_IRUGO | S_IWUSR, hcsr04_value_read, hcsr04_value_write),
  __ATTR_NULL,
};


// Name of directory created in /sys/class
static struct class hcsr04_class = {
  .name = "hcsr04",
  .owner = THIS_MODULE,
  .class_attrs = hcsr04_class_attrs,
};


// Interrupt handler on ECHO signal
static irqreturn_t gpio_isr(int irq, void *data)
{
  ktime_t ktime_dummy;
  if (valid_value==0) {
  ktime_dummy=ktime_get();
  if (gpio_get_value(HCSR04_ECHO)==1) {
  echo_start=ktime_dummy;
  } else {
  echo_end=ktime_dummy;
  valid_value=1;
  }
  }
  return IRQ_HANDLED;
}


static int hcsr04_init(void)
{
  int rtc;

  printk(KERN_INFO "HC-SR04 driver init...\n");


  if (class_register(&hcsr04_class)<0) goto fail;


  rtc=gpio_request(HCSR04_TRIGGER,"TRIGGER");
  if (rtc!=0) {
  printk(KERN_INFO "Error %d\n",__LINE__);
  goto fail;
  }


  rtc=gpio_request(HCSR04_ECHO,"ECHO");
  if (rtc!=0) {
  printk(KERN_INFO "Error %d\n",__LINE__);
  goto fail;
  }


  rtc=gpio_direction_output(HCSR04_TRIGGER,0);
  if (rtc!=0) {
  printk(KERN_INFO "Error %d\n",__LINE__);
  goto fail;
  }


  rtc=gpio_direction_input(HCSR04_ECHO);
  if (rtc!=0) {
  printk(KERN_INFO "Error %d\n",__LINE__);
  goto fail;
  }


  rtc=gpio_to_irq(HCSR04_ECHO);
  if (rtc<0) {
  printk(KERN_INFO "Error %d\n",__LINE__);
  goto fail;
  } else {
  gpio_irq=rtc;
  }


  rtc = request_irq(gpio_irq, gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED , "hc-sr04.trigger", NULL);


  if(rtc) {
  printk(KERN_ERR "Unable to request IRQ: %d\n", rtc);
  goto fail;
  }




  return 0;


fail:
  return -1;


}

static void hcsr04_exit(void)
{
  if (gpio_irq!=-1) {
  free_irq(gpio_irq, NULL);
  }
  gpio_free(HCSR04_TRIGGER);
  gpio_free(HCSR04_ECHO);
  class_unregister(&hcsr04_class);
  printk(KERN_INFO "HC-SR04 disabled.\n");
}

module_init(hcsr04_init);
module_exit(hcsr04_exit);

 

 

Now hit "make" command to compile the above driver.

 

Step3:

 

connect the Vcc    pin in hc-sr04 to Pin2 in J13.

connect the Trig   pin in hc-sr04 to Pin5 in J13.

connect the Echo  pin in hc-sr04 to Pin6 in J13.

connect the Gnd   pin in hc-sr04 to Pin4 in J13.

 

Now copy the compiled sr04.ko to  /opt/ in riotboard.

 

Next insert the compiled module using insmod:

insmod sr04.ko

 

Now configure the Trigger & Echo for gpio in Riotboard terminal:

devmem 0x20E009C w 0x5

devmem 0x20E00A0 w 0x5

 

Prepare sr04 for capturing values:

 

Export the gpio pins

echo 112 > /sys/class/gpio/export

echo 113 > /sys/class/gpio/export

 

Set the Direction

echo out > /sys/class/gpio/gpio112/direction

echo 1 > /sys/class/gpio/gpio112/value

 

 

To view the sonar values , hit below command

cat /sys/class/hcsr04/value

 

Step4:

To continuously view values & object distance in cm i wrote a small python script.

create a file "sr04_distance.py"  in riotboard terminal with below contents:

 

#!/usr/bin/python
f = open("/sys/class/hcsr04/value",'r')
d=f.read()
f.close()
if (long(d)==-1):
  print "N.A."
else:
  print "%.1f cm" % (float(d)/58)

 

 

With all connections ready, run the sr04_distance.py script:

$ python sr04_distance.py

 

The sonar will display values as objects encountered in its way .

 

 

Note: during module testing if found  this hc-sr04 module range is max 3 metres.

 

 

That's all.

 

Thanks

Tushar

Attachments:
sr04.zip
  • Sign in to reply
  • salih.mutlu@gmail.com
    salih.mutlu@gmail.com over 8 years ago

    Hi,

    A very nice tutorial. I have some questions:

     

    1) In driver, you set gpios as input or output, why do you export also in user space?

    2) If I want that "devmem 0x20E009C w 0x5" command in driver, what should I do?

    3) If I want to build it into the kernel statically, is there anything that I have to do?

     

    Thanks

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube