Introduction: Cycling Assistance System Using FPGA
Hello, and welcome to our tutorial!
Today we will show you how to design a cycling assistance system using a Digilent Basys3 board and several other components which we will describe below. The interaction with the system will be made via an user-friendly Android application.
This project came as a response to the safety of the traffic participants, be it bike riders, car drivers, or pedestrians, by increasing cyclists awareness to the surrounding environment.
The bicycle will be equipped with 3 sonars (one in the back, and two on the sides), which will sweep with the help of other 3 servo motors at 120 degrees. The information received from them will be displayed on the Android application with information about the distances to those detected objects with a specific degree of warning, based on the distance to the object. If an object is too close, a critical warning message will be displayed.
The GPS will be used to get the speed of the bike. We also add two back lights and two buttons on the handle, so that the bike rider will be able to signal the direction in which he / she is headed more easily than the well known “stretch your hand” method.
The IMU will be used to signal when the rider brakes, making both LEDs light up simultaneously.
Other facilities will be presented throughout the project description.
Step 1: Hardware and Materials
The project is divided in 3 major subsections: the mechanical part ( “What do we need?”) , the electrical part ( “How do we tie things up?”), and the software part( “How do we make it work?”).
So, what do we need?
Materials used for the mechanical part: ( Fig. 1)
- a plastic box
- a metallic support
- an external power supply
- cable ties
- 1 iron nail
- a metal wire that is easy to bend
- aluminium foil
- a metallic support
- a thick needle
- small L profiled metalic support ( should be almost the size of the Sonar sensor)
- and a bicycle( Obviously =D )
Materials and hardware for the electrical part: (Fig. 2 and 3)
- Basys3 board
- 3 X Pmod MAXSONAR
- Pmod NAV
- Pmod BT2
- Pmod GPS
- 3 X Servo motors
- 2 LEDs
- 2 resistances
- 2 buttons
- a fixed output linear regulator (LM7805)
- a battery of 9 V
- 9V battery connectors
- a solder board ( ours was about 95 x 47 mm, and we cut it into smaller pieces as needed)
- a portable smartphone battery charger
The software part:
- Vivado Design Suite WebPACK ( we used the 2016.4 version)
- Android Studio
Step 2: Assembling the Physical Components
Now lets assemble the components on the bicycle!
Task 1: Building and mounting the box on the bicycle
We tie the plastic support to the back part of the bike. This step is specific to the type of bike one has; it can be simplified if you have a bike pannier rack ( actually, if you have this, just skip the first step and go right to the second one - unfortunately we didn’t have one so we had to improvise).
1. Make 4 holes in the protective wing from the back wheel, the distance between them being 11 cm and 2.5 cm. We made the holes using an iron nail and a hammer. The diameter of the iron nail should be large enough to let you pass a wire through the hole. We had to protect the backside wheel from being pierced by the nail by supporting it with a piece of wood.
2. Make 4 holes in the plastic box, at the corners of a rectangle with length 11 cm and width 2.5 cm, centred on the plastic box ( Fig. 4). We made the holes by heating the tip of a small part of a metal wire, and piercing the plastic.
3. Attach the box to the bike. We used metal wire, by inserting from upside down the ends, then tied the wire in the middle to secure the support, and prevent it from moving. The metal wire should be longer, because later it will be used to fix the board inside the box.
Et voila! The result can be seen in Fig. 5 :)
Task 2: Building the support for the sonar Pmod
Because we can’t fix the sonar Pmod directly on the servo, we created a support for it which will be mounted on the head of the servo motor. Again, you are free if you want to do this step in a different way based on the type of servo you are using, though we will still describe how you could do it our way:
1. We made bigger holes on the cross rotating head of the servo, using the heated tip of a needle. The needle should be thick enough in order to let your wire pass through the hole it made.
2. Attach the metallic support to the plastic wheel of the servo using a metal wire.
3. Use two cable ties to secure the sonar sensor on the support as shown in Fig.6.
Task 3: Mounting the servos, the sonars and the ligts on the box
We used tape, and paper clips to fix the servos to the box. We also cut the box in specific places so the components fit, and the servos can rotate. The lights were mounted by making holes in the plastic box (for the yellow ones), or pasted with plastic. Fig. 11
Task 4: Tying all the components
As seen in Fig. 12, inside the box we have the Basys3 development board, the GPS and the BT2 modules; ecuring them with wires, cable ties, and duct tape.. On top of them, separated by cardboard is the breadboard with pins used for ground and for powering the servos. Fig 13.
Step 3: Dealing With the Electrical Part
Next we need to connect the electrical parts to the board in some way... Because the received Digilent 6/12 pin cable connectors which came with the sensors are short, we had to extend the connectors by soldering wires and pins with tin. Fig 7.a and 7.b show the connections we should make between the Basys3 board and the Pmods in our project.
This step is again divided into several tasks.
Task 1: Solder each button onto a piece of soldering board and connect it to 2 wires which are equally long enough to go from one handle of the bike to the board which is, as mentioned before on the back of the bicycle. One wire will be connected to ground and the other will be connected to a pin of the board. We needed 2 X 160 cm of wires for our bike for one button. ( fig 8)
Task 2: Do the same with the LEDs and resistances. Because we decided to put the blinkers on the back of the earlier mounted box, the needed wires will no longer be as long as mentioned above. 30 cm for each wire for us was more than enough. (fig 9)
Task 3: The power supply of the board will not be enough if we want to connect the 3 servos. So we decided to put for each servo a 9V battery. Because the used servos worked with 4.8V->6V we added a fixed output linear regulator (LM7805) which gave us a 5V output which was used to supply a servo. (fig. 10)
Future updates will include the final wiring of the Pmods. Which for now was made using the 6/12 pins Digilent cable connectors.
Step 4: Testing the Peripherals
Everything was programmed in VHDL. In this section we will explain the logic behind each implementation. We also provide the code attached below.
The PmodBT2 which is the Bluetooth module, is controled using UART protocol. We know from the datasheet that its baud rate is 115200. We need to know the oversampling rate for the receive and transmit operations. We will be using only the transmission feature for now, although we provide also code for the receiving part. The oversampling rate for the transmission is computed as the board frequency/ bluetooth baud rate which in our case is 100MHz / 115200 = 868. More on how to control and connect a bluetooth can be found on the internet. Although the pmod has 12 pins we will be connecting only 2 for RX, TX, and two for GROUND and VCC.
The PmodMAXSonar is programmed using the PWM (Pulse Width Modulation) protocol, although you can use other progamming protocols as well. We will need the pins 4 (PWM output), 5 (GND) and 6 (VCC). The RX pin will be pulled up and set as output for continuous transmission of data. We ignore the analog and TX pins. The output of this component will be the range in inches, which will be obtained by counting the length of the PWM input pulse, which is 147 micro seconds. Each time the counter reaches 14699 we increment the inches, and if the reading is greater than zero we reset the buffers to prepare for a new reading.
We transmit the sonar readings to the phone using the Bluetooth module. We computed that to send data we need to multiply the transmission oversampling rate with the number of bits needed times two. The oversampling rate is 867, the number of bits is 16, times 2, gives us 27774. Using a counter, each time this value is reached, we transmit the range. This value can be further adjusted after needs.
The LEDs have one wire connected to ground and the other to a pin. The buttons are connected the same. The board waits for a button to be pressed. When it registers a change on the buttons pins, it starts blinking one of the leds. Another pressed button stops the corresponding led. A led is logically “tied” to a button. The other led to the other button.
NOTE: the port in which the signaling wire of the button goes must be set to pull-up in the XDC file in order to work.
The Servos input PWM should have a 2ms period. This means a 50 Hz Frequency. Because the Basys3 internal clock has 100MHz frequency, in order to get the desired clock period of 50 Hz we will divide 100MHz / 50 Hz = 2000000 counts. Based on a certain filling factor we will get a certain degree for the Servo head movement which is again implemented as a counter.
Uses the module SPI_communication_NAV_AG to get data from the accelerometer, by setting the register from which we want to read data. For example, if we wish to read from x axis, we set the spi_addr to "0101001". Since we want the communication to be done at all times, we set enable to 1. Read the data from accelerometer’s X axis (master slave SPI communication). Interpret the data in gravitational acceleration units and check if it is in threshold: 1 - 5 g. If read value between thresholds notify braking signalization leds.
NOTE: these values are known from observations
The GPS is used for identifying how fast the bike goes. Data is collected via UART protocol, and comes in terms of 5 message. We only need the 5th one, VTG, to obtain the speed. All info from GPS is sent via BT2 to app, where it is eventually parsed, and needed data is extracted.
Step 5: Programming the Board
We are now ready to give life to our current system!
1. Open Vivado Design Suite and create a new project.
2. Give desired name to the project, create a constraints file, and select the part xc7a35tcpg236-1, which is the fpga core found on the Basys3 board.
3. Create new Design Sources for each of the components provided in the code files or just upload them.
4. Put the constraints file we provided in your project (if you want, it can be customized for your own needs).
5. Synthesis and Implement your Design. Generate Bitstream, Open New Target and Program your Device :)