Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Peripheral control with a Raspberry Pi - An ultrasonic sensor Saba Ahsan Dept. of Communication and Networking School of Electrical Engineering Aalto University, Espoo, Finland [email protected] ABSTRACT The Raspbery Pi has GPIO pins that can be used for connecting different peripherals to it, allowing hobbyists and researchers to use it for a number of embedded applications. The GPIO can be accessed through a number of languages, and the timing accuracy greatly depends on the choice of the language and the Operating system. This paper discusses the control of Raspberry Pi GPIO pins. As an example, we show control of an ultrasonic proximity sensor connected to the GPIO, using Python and C libraries and show how it can be used to create a simple burglar alarm system. Furthermore, it shows a comparison between the performance of both languages with and without additional load on the system and demonstrate that C provides more consistent and reliable results. 1. INTRODUCTION The Raspberry Pi (RPi) is a single board computer based on the Broadcom BCM2835 System on Chip (SoC) and equipped with a 700MHz ARM processor. It was primarily designed to provide an affordable computer to students for practising programming skills. However, it has also attracted a large number of hobbyists into making Do-It-Yourself (DIY) projects for different embedded applications. Its small size and small price tag make it ideal for such experimentation and since it can run Linux, it makes programming on it in popular languages such as C and Python possible as well. The RPi comes equipped with a General Purpose Input/Output (GPIO) connector, that can be used for connecting peripherals such as sensor, LEDs, motors etc. Despite its extensive use as an embedded system, the RPi is not ideally designed as an embedded system and hence is usually operating a general purpose OS, which does not have real-time timers. The accuracy of the timing control for running these peripherals depends greatly on the language and Operating system (OS) used. A baremetal approach can be used to control the GPIO pins to remove dependency on OS. In this paper, we connect an ultrasonic sensor to the RPi and use Python and C software to control it. The sensor uses sonar to calculate the distance of an obstacle in front of it. It can be used in various small projects such as burglar alarms, proximity sensing etc. In section 2 we describe the hardware of the RPi GPIO, the sensor and the circuit connections. It is followed by the software control in section 3. A brief description of the burglar alarm system is given in section 4. Section 5 contains the C vs. Python test methodology and results. The conclusions are provided in section 6. 2. HARDWARE The hardware components needed for building the alarm system include a Raspberry Pi, HC-SR04 sensor, an LED, some resistors, a USB Wifi dongle and connecting wires. The LED is used just as a visual indicator that the alarm has been tripped. The Wifi dongle is used for providing Internet connectivity to the alarm system so it can send an email to the owner if the alarm is triggered. In this section we will give a brief overview of the Raspberry GPIO pins and the sensor, followed by the required hardware connections and their explanation. 2.1 Raspberry Pi GPIO Pins The Raspberry Pi has a 2x13 pin connector for GPIO purposes. Only 17 GPIO pins of the BCM2835 are provided for GPIO use in the Raspberry Pi. Some other GPIO pins are used for internal purposes by the Pi such as for the status LEDs, audio circuitry etc. The pin numbering of the GPIO pins is not consistent with the SoC [1]. A layout of the pins is shown in Figure 1. There are pins for +5V, 3.3V and GND for powering peripherals, which is used for powering the sensor. The GPIO pins can be programmed as either input or output. They operate on 3.3 voltage levels and can burn out if a higher voltage is sent. Since the layout of pins depends on the PCB revision of RPi, it is important to check the revision before making any connections. This can be done by running the command cat /proc/cpuinfo, which prints the board revision. The board revision is not the same as the PCB revision, but a mapping of board revision to PCB revision can be obtained from RPi’s hardware history [2]. The board used for this experiment was PCB revision 2. 2.2 Ultrasonic Sensor The ultrasonic sensor [8] uses sonar for detecting the distance to an object in front of it. It has 4 pins; +5V, GND, Trigger and Echo, as shown in Figure 2. Its working current is 15mA, which is within the maximum current withdraw for the Pi’s 5V power pin. The trigger is used to send a pulse to the sensor, which tells it to start measuring distance. It then sends a sonic pulse and measures the time it takes for the pulse to reflect off the surface in front of it and return to the sensor. Finally, it sends a high pulse on the Echo pin and the time for which this pulse remains high is equal to the time it took for the sound to return to the sensor. The speed of sound is 340m/s; the distance can be calculated by the basic formula Distance = Speed × T ime (1) This, however, gives us the total distance travelled by the sound, which includes travelling to the object and then back. Therefore, it must be halved to get the actual distance of the object from the sensor. The timing diagram is show in Figure 4. 2.3 Making the connections As previously mentioned, the Raspberry Pi’s GPIO pins are intolerant to +5V input. Since, the sensor gives a +5V pulse on the Echo pin, we need to employ a voltage divider to reduce it. The voltage divider’s resistances can be calculated by the equation below, where Vo will be 3.3V and Vi will be 5V. Vo = Vi × Left bottom P1-‐01 3V3 POWER GPIO 2 GPIO 3 GPIO 4 GROUND GPIO 17 GPIO 27 GPIO 22 3V3 POWER GPIO 10 GPIO 9 GPIO 11 GROUND P1-‐25 top top P1-‐02 5V POWER 5V POWER GROUND GPIO 14 GPIO 15 GPIO 18 GROUND GPIO 23 GPIO 24 GROUND GPIO 25 GPIO 8 GPIO 7 P1-‐26 bottom Right Figure 1: Layout of GPIO pins in a Raspberry Pi (Revision 2) (2) The final circuit used is shown in Figure 3. Pin 4 (+5V) +5V Pin16 (GPIO23) Trigger Echo Ground R2=360Ω Pin15 (GPIO22) R1=240Ω Pin 6 (Gnd) Figure 3: Circuit wiring 3. SOFTWARE In this section we first explain the inner workings of GPIO control in a RPi using GPIO controller registers. It is important to know that the GPIO connector actually provides access to some of the GPIO pins of the BCM2835, and hence in order to control the pins, a basic understanding of BCM2835’s ARM peripherals [4] is required. In section 3.2, we explain how the sensor was controlled in a Linux environment using libraries. 3.1 Figure 2: The HC-SR04 Ultrasonic Sensor R2 R1 + R2 GPIO registers For controlling the ultrasonic sensor, we need to control two pins; the first one, programmed as an output, will send the trigger; the second, programmed as input, will receive the echo. We will refer to these as TRIG and ECHO; in our circuit they correspond to pins 15 and 16 respectively, as shown in Figure 3. The pins are controlled using GPIO controller registers of the BCM2835 SoC. The address range 0x20000000 to 0x20FFFFFF is for peripherals, and the GPIO controller address starts at 0x20200000. There are 41 GPIO registers, each 4 byte long. For controlling our sensor, we need to perform three operations on the pins; set the pin as input/output, write to an output pin, read from an input pin. The first six registers, registers 0-5, of the GPIO controller are used for configuring the pins as input or output. The first of these 6 is used for controlling the first 10 pins, the second for the next 10 and so on. The BCM2835 has a total of 54 GPIO pins, but as mentioned in section 2.1, only 17 of these are available on the RPi’s GPIO connector. ECHO is GPIO22 and TRIG is GPIO23 as can be inferred from Figure 1. So to control them, we would need to write to register 2 which controls GPIO 20-29. Each pin controlled by the register actually corresponds to 3 bits in that register. Since we are controlling the third and fourth pin of the 10 pins controlled by the third register, we have to write to bits 6-8 and 9-11 for each one of them respectively. To configure the pin as output the three bits take the 0012 and for input it takes the value 0002 . 10us TTL Trigger Operation 8 cycle sonic burst (40kHz) Sonic burst from sensor Duration equal to time from sending to returning sonic echo Echo Pulse Output Figure 4: Timing diagram of the Ultrasonic Sensor (Not to scale) Registers 7-8 of the GPIO controller is used for setting an output pin; 7 controls the first 32 pins and register 8 controls the remaining. In order to send a trigger we must set bit 23 (corresponding to GPIO23) of register 7 to 1 for 10 microseconds; the duration of the pulse is specified in the sensor’s datasheet. To clear the output pin, registers 10-11 are used and again 10 is for first 32 GPIOs and 11 for remaining. A 1 is written to bit 23 of register 10 to clear TRIG. Now ECHO must be read for the echo pulse. To read the current level of a pin, registers 13-14 are used, 13 for first 32 pins and 14 for the remaining. For ECHO, we have to read bit 22 of register 13. Using this principle, a baremetal program written in Assembly can be written to control the sensor [5]. However, under linux, a number of libraries in different languages are available that provide easy access to the Raspberry Pi GPIO pins. 3.2 Using Linux environment In this study, we used Debian’s flavour for RPi, known as Raspbian, which is availalable for download. The OS was installed on a 4GB SD card. The Raspbian runs Python interpreter and the C compiler out of the box, so no further installations are needed for this. For stress testing performance we used the stress test. The RPi’s GPIO pins can be controlled using libraries written in various programming languages. Python is generally more favoured by the RPi developers, but it has been seen that for certain cases, Python might be too slow in getting accurate readings from GPIO [7]. We use both Python and C to measure distance with the ultrasonic sensor. The basic flow of the program in each language is the same, as illustrated by the pseudocode below, which prints the distance in centimeters. Set Echo pin as Input Set Trigger pin as Output Sleep 100ms Set TRIG to High Sleep 10 microseconds Set TRIG to Low While ECHO is low, do nothing Set starttime as the current time While ECHO is high, do nothing Set endtime as the current time distance=(endtime-starttime)*340000/2 Print distance 3.2.1 Python We use the Python RPiGPIO library for controlling the sensor with Python [3], which needs. The delay for sending the pulse to trigger is added using the time.sleep function and time for start and end is recorded using time.time. 3.2.2 C Environment The library bcm2835 is used for controlling the GPIO pins in the C Environment. The library has to be installed on the RPi as it is not included by default in Raspbian. The function bcm2835_de layMicroseconds was used for waiting when sending the 10 microsecond pulse to the Trigger. 4. BURGLAR ALARM - DIY The burglar alarm system we created worked by detecting an opening door by monitoring the distance of the door from the sensor. The sensor must be placed at a close distance from the door and at an angle that ensures that the distance of the door from the sensor changes when the door is opened. The approximate distance from the door must be less than 10 cm when it is closed. The system will continuously measure the distance to the door and will raise an alarm if the measured distance is greater than 10cm. We joined the LED connected in series with a 120 Ω resistor to pin 23 (GPIO11) of the Raspberry Pi for the burglar alarm. The alarm triggers the LED to start blinking, and it also sends an email to a preconfigured email address, with the current date and time. 5. C VS. PYTHON TESTING Results As explained in section 2.2, the sensor provides the time taken by a sound pulse to return to the sensor after reflecting from the object in front. If the sensor and this object are not exactly perpendicular to each other, sometimes the wave will be reflected at an angle and would bounce off another object such as a wall before returning to the sensor. This behavior can result in measurements which are much higher than the distance to the object. For the 50cm case, we got some readings for both languages and with/without load that were more than twice or even thrice of the actual distance. These readings were simply ignored when compiling the results. It was not possible to measure the distance between the sensor and the object accurately enough to predict which of the two languages produces more accurate results, hence we will be using the variations in the measured distances as the primary indication of performance. Python ● C Python ● ● ● ● ● ● With Load 5.1 Table 2: Mean and Standard Deviation of measurements with load on system Test Name Language Mean Std. Dev. C 50.3076 0.2596 Test1 Python 49.8363 3.4047 C 18.1681 0.0558 Test2 Python 18.2500 0.2 C 5.666 0.1008 Test3 Python 5.7043 0.1866 No Load We did three tests for three different distances to compare the measurements by Python and C codes. For each test, we took 200 measurements for each language; 100 of which were done when there was no additional load on the RPi, and the remaining 100 were done when the system was loaded. The load condition was created using the Linux based stress command which spawns workers to create different types of compute stress on the Raspberry pi [6]. The command used is given below. stress--cpu5--io5--vm5--vm-bytes10M--timeo ut3600s This creates 5 workers spinning on sqrt(), 5 workers spinning on synchronizing data on disk and memory and 5 workers spinning on 10 Mbytes of memory allocation and deallocation, for a period of 1 hour. While the stress test was running, the CPU load on the raspberry Pi went as high as 6.9%. The three distances used are 50cm, 18cm, 5.5cm approximately. The distance calculation depends on the accuracy with which the code measures the length of the pulse on the Echo pin. This means measuring the start time, when the pin goes high; and the end time when the pin goes low. If the code records the start time late, the calculated distance will be shorter than expected, while if the end time is recorded late, the distance will be longer. A delay in both records can go unnoticed in the final result. Table 1: Mean and Standard Deviation of measurements with no load on system Test Name Language Mean Std. Dev. C 50.3910 0.2048 Test1 Python 50.3406 0.2956 C 18.1897 0.0872 Test2 Python 18.2390 0.1145 C 5.6886 0.0670 Test3 Python 5.7044 0.1476 Language The software code was written in C for this system,. The email is set up using packages ssmtp, mailutils and mpack. First, the packages need to be installed on the RPi with the following commands sudo apt-get install ssmtp sudo apt-get install mailutils sudo apt-get install mpack To configure the email, the file /etc/ssmtp/ssmtp.conf is edited with the appropriate information. The information to be added is shown below. [email protected] AuthPass=senderpass FromLineOverride=YES mailhub=smtp.gmail.com:587 UseSTARTTLS=YES Finally, when the alarm is triggered, the C program makes the following system call echo "Email Body" | mail -s "Email Subject" [email protected] Note that the RPi needs Internet connectivity for sending the email. This can be provided through Ethernet or by using a USB Wifi dongle. Most Wifi dongles are detected automatically when plugged in, but it must be configured to connect to the network. Finally, in order to make the device run independently, the burglar alarm’s code must be scheduled to run automatically at startup. To do this we need to add the following line to sudo crontab -e, where burglardaemon is the executable code for the burglar alarm. @reboot ./burglardeamon It is important to add the line to the crontab of the root user (sudo), so that the pins can be manipulated which is not allowed with root rights [9]. C ● 25 30 35 40 45 50 Measured distance (cm) Figure 5: Test 1 - Distance from object approximately 50 cm Table 1 shows the results of the measurements when there was no additional load on the system. It can be seen that the standard deviation in the measurements is always higher in Python than in C. The same behavior is observed when the system is put under load; results are shown in table 2. Figures 5, 6 and 7 show the box plots of the test results. In each case the Inter Quartile Range (IQR) for Python is greater, except for the 50 cm case. However, for the 50cm case, we see that there are many outliers for Python especially when it is under load, where one measurement is only half the actual distance. 6. Python Language No Load C ● ● ● ● ● ● ● ● With Load Python ● C ● ● ●●● In this paper, we explore the control of peripherals using the Raspberry Pi’s GPIO pins and show how it can be used in simple embedded applications such as the burglar alarm. We attempt to compare the performance of Python and C languages for measuring the duration of a pulse sent on a GPIO Input pin of the Raspberry Pi. The duration of the pulse, which is sent by an ultrasonic sensor, is subsequently used to calculate distance of the sensor from an object. It is observed that although the average distance measurement for both languages are within 1mm of each other, but the measurements taken from Python show a higher standard deviation. Under load conditions, both languages show poorer performance in comparison to no load conditions, but the outliers for Python are much more extreme than C. ● 7. 17.5 18.0 18.5 Measured distance (cm) 19.0 Figure 6: Test 2 - Distance from object approximately 18 cm Python ● ● ● ● ● Language No Load C C ● ● ● ● ● ● With Load Python ● ● 5.0 ● ● ● 5.5 CONCLUSIONS 6.0 Measured distance (cm) 6.5 Figure 7: Test 3 - Distance from object approximately 5.5 cm REFERENCES [1] Raspberry pi bcm2835 gpio. http://elinux.org/RPi_BCM2835_GPIOs. [2] Raspberry pi hardware history. http://elinux.org/RPi_HardwareHistory. [3] Ultrasonic distance measurement using python. http://www.raspberrypi-spy.co.uk/2012/12/ultrasonicdistance-measurement-using-python-part-1/. [4] Broadcom. Bcm2835 arm peripherals datasheet. http://www.raspberrypi.org/wpcontent/uploads/2012/02/BCM2835-ARM-Peripherals.pdf, 2012. [5] A. Chadwick. Baking pi – operating systems development. http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/index.html, July 2013. [6] linux.die.net. Stress - linux man page. http://linux.die.net/man/1/stress. [7] J. Pihlajamaa. Benchmarking raspberry pi gpio speed. http://codeandlife.com/2012/07/03/benchmarking-raspberrypi-gpio-speed/. [8] U. Sensor. Hc-sr04 datasheet. http://users.ece.utexas.edu/ valvano/Datasheets/HCSR04b.pdf. [9] C. H. Wiki. Cronhowto. https://help.ubuntu.com/community/CronHowto, May 2013.