This chapter consists of project testing and results as well as the problems faced during the project completion.
I2C Communication between Raspberry Pi and Arduino
After connecting the Raspberry Pi and the Arduino through I2C, the environment on the Raspberry Pi is set up. The Raspberry Pi identifies Arduino Uno by detecting the slave address sent by Arduino Uno. The slave address is set through the uploaded program code on the Arduino. The following test was conducted for testing the I2C bus between the Raspberry Pi and the Arduino. The address was set to 00×04. Below is the result when i2cdetect –y 1 is typed allowing the Raspberry Pi to detect the connected slaves through I2C.
pi@raspberrypi:~/$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- 04 -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
The above result demonstrates that the Raspberry Pi has successfully detected a slave with address 00×04.
I2C 8-bit Limit and Proposed Solution to transmit More Than 8 Bits
For accurate positioning, the system usually needs sensors (encoder or ultrasonic system) which provide high resolution of more than 8 bits. For large distances, ultrasonic sensor also provides values that are bigger than 8 bits. However, it can only send 8 bits with I2C communication. Therefore, it is required here to split data of more than 8 bits into 8 bit chunks. For example, data of 12 bits can be split into two chunks (6 bits for each or 8 bits plus 4 bits) and remaining 2 bits can be used to decode information representing data into high or low 6 bits. However, this approach is suitable if the data sent over I2C is of 12 bits. Otherwise, in case of expanded protocol, there is a need to data in packets that should start with an opcode byte followed by any data. Therefore, the receiver of I2C communication consists of a table for the opcode containing information concerning the number of consecutive bytes to read and what to do with them. Thus, we will have opcode byte telling for 12 bits. The 2 next bytes should be read followed by actual 12-bit sensor value. Even though this approach is more robust, it is more time consuming and may introduce some delay that equals to the time necessary to send one word.
Send 1 Byte through I2C Bus between Raspberry Pi and Arduino Uno
Figure 4-1 is the result of sending 1 byte through I2C bus.
Send 2 Byte or more through I2C Bus between Raspberry Pi and Arduino Uno
Figure 4-2 shows the result of sending more than 1byte through I2C Bus.
Figure 4-3 shows the result of the second test through I2C bus.
Refer for Appendix A for more information about the code.
Encoders Test
As mentioned earlier in the design chapter, the motors and the encoders are interconnected. Also, there are 2 channels, Channel A and Channel B, on each encoder. Channel B is 90° out of phase. The motor direction is illustrated by the outputs transition order. It means that when the motor is moving forward, Channel B lags with 90° out of phase whereas Channel A leads. On the other hand, when the motor is moving backward, channel B leads Channel A by 90° out of phase. Figure 4-4 shows encoders testing when the motor moves forward and backward (on the screen channel A = yellow, channel B = white).
It is possible to calculate the motor speed from Figure 4-3 by using the equation 4-1 as:
Motor speed RPM=Transition frequency Hz×Encoder CPR Encoder pulses per revolution
(4-1)
RPM=2×11×10-3×48 1050=91.4 RPM
The motor was running supplied by 4-5V. Therefore, the speed was expected to be less than the full speed i.e. 120RPM. The motor speed is proportional to the supply voltage.
Figure 4-5 shows the Arduino readings over the encoder pulses output. Interrupt was used on the code so that Arduino Uno has two interrupt pins; digital pin 2 which is interrupt 0 and digital pin 3 which is interrupt 1. Interrupt is an event which causes the suspension in a currently running task. It performs a different task and then returns to the first running task. Interrupt can help in the faster requisition of as it is not a part of the scan cycle. It would be hard to read and count every rising and falling change in the encoder if it was in the cycle itself. This is the reason interrupt is used.
Arduino counts the pulses when the motor moves forward to give a positive value increasing. On the other hand, Arduino counts the output pulses and gives minus value decreasing when the motor moves backward. Figure 4-5 shows the result from the Arduino serial port. The program code refers to Appendix A.
Ultrasonic Ranging Sensor Testing
The wiring connection and the working mechanism of ultrasonic ranging sensor have already been discussed in the design chapter. Ultrasonic gives the distance in time which is the output pulse width. Figure 4-6 illustrates the test conducted for obtaining the relationship between pulse width in m sec and the object distance D.
Position and Control Robot Testing using Encoder
The first test done is to control the robot from initial point (0, 0) and position using encoders. Figure 4-7 shows the result of the first testing; three points were tested on each quadrant (still working on the figure).
Path following Positioning and Control
A test was done to make the robot follow a certain path given by the supervisor. The path consists of three points. Figure 4-8 shows the result of the test where the blue line is the target path by the supervisor and the orange line is the robot path (still working on the figure).
Raspberry Pi must be connected to a public network such as the Internet
A tunnel connection is established after the three points above are followed appropriately. The transferred data type provided by SSH is encrypted data transfer between the Raspberry Pi and supervisor’s PC. Figure below shows the steps to connect the laptop to the Raspberry Pi over SSH using Putty.
Project Program Codes
There are two main program codes executed during the robot process. One code is executed on the Raspberry Pi for data processing whereas the other code is the Arduino code for controlling the robot.
Raspberry Pi Program Code
When the code is executed on the Raspberry Pi:
Identify the initial point (0, 0) in cm
Ask Arduino Uno for the robot’s current position(x0, y0)
Request the supervisor to enter target point position (xt, yt)
Identify at which quadrant is the target point
Quadrant 1; x is positive; y is positive, Quadrant 2; x is negative; y is positive
Quadrant 3; x is negative; y is negative, Quadrant 4; x is positive; y is negative
Calculate the Angle (θ) between the current point and the target point (as mentioned earlier)
Calculate the Distance (D) from the current point and the target point (as mentioned earlier)
Send the command (Angle (θ) and Distance (D)) to the Arduino over I2C
Receive the new position of the robot and store it in (x0, y0)
Arduino Uno Program Code
When the code is executed on the Arduino Uno:
Calculate the robot’s current position from the encoders or the ultrasonic (as mentioned earlier)
Send the robot’s current position x0, y0 to the Raspberry Pi over I2C
Wait for target commands (Angle (θ) and Distance (D)) sent by the Raspberry Pi over I2C
When the target angle and distance is received from the Raspberry Pi;
Turn by command target angle using encoders: Arduino will move the right motor forward and the left motor backward where the robot will turn to left on the center till it reaches the given target angle
Travel to command target distance using encoders: Arduino will move the right and the left motors forward till the robot reaches the given target distance
Return to angle 0 using encoders: Arduino will move the left motor forward and the right motor backward where the robot will turn to right on the center till it returns to angle 0
Send the robot’s current position (x0, y0) to the Raspberry Pi over I2C
Make the angle and distance equal to 0