Project 1

Contents

  • Introduction
  • Hardware
  • Phase 1
  • Phase 2
  • Conclusion
  • Code
  • Introduction

    The goal of project 1 is to become familiar with embedded systems programming techniques, the required hardware, and software/hardware interfacing issues. Project 1 is divided into two phases. Phase 1 consists of connecting all the necessary sensors and actuators into a single station. Phase 2 consists of separating the single station into a base and a remote station. The two stations communicate through bluetooth radio.

    Hardware

    There are 7 different hardware components used in project 1.

    Arduino Mega 2560

    The Arduino Mega 2560 is based on Atmel AVR ATmega 2560 MCU. The board has:

    • 54 digital input/output pins
    • 4 UARTs
    • 16 analog inputs
    • 1 USB connection
    • 1 power jack
    • 1 reset button

    KY-008 Laser Module

    The Keyes laser fires a small but intense beam. It has 3 pins: GND, +5V, and a middle pin which is not connected.

    DFROBOT LCD Keypad Shield

    The LCD keypad shield is designed for Arduino boards and consists of 5 keys. The display has 2 rows and 16 columns.

    Servo Motor

    The servo motor will control the position of the laser and is controlled through a joystick.

    Joystick

    The joystick contains 5 pins: GND, +5V, VRx, VRy, and SW. The VRx pin is used to read the x value, the VRy pin to read the y value, and the SW pin for the push button on the joystick.

    Bluetooth HC-06

    The bluetooth hardware can be configured to function as a master or a slave, the name and the PIN can also be changed.

    Lightsensor

    When the lightsensor is exposed to light, the resistance goes up. Connecting the lightsensor requires using a pull-down resistor. The lightsensor works by splitting voltage which is why the 10k resistor is needed (Pull-up/down resistors are used to deal with floating voltages, like on the joystick button).

    Phase 1

    All of the hardware components (except bluetooth) are connected to a single Arduino Mega 2560. The figure below shows the connected components.


    Three functions run in a loop about every 100 milliseconds (10 Hz): movementTask, laserTask, and lightSensorTask. The movement task reads the x value (0-1023) from the joystick pin and maps it to a value between 800 and 2200 microseconds and writes it to the servo. The servo's movement is controlled by writing a microsecond value between 500 and 2500, where 1500 is the middle. The method also keeps track of the 2 previous values written to the servo and computes the new value to be written to the servo by weighting the newest value at 60%, the second most recent value at 30%, and the third most recent value at 10%. This helps reduce noise and provide a smoother motion from the servo.

    The laser task performs a digital read from the SW pin on the joystick (denoted by joyZ) and if the push-button on the joystick is pressed, turns on the laser by writing a value of HIGH to the pin.

    The light sensor task performs an analog read (A/D conversion) on the pin connected to the photocell. The value is small when there is little light hitting the photocell. We determined through trial and error that a reading greater than 350 meant the photocell was exposed to excess light, and thus concluded anything higher meant a laser was being fired. One end of the photocell is connected to power, and the other to a 10K pull-down resistor and ground. The point between the pull-down resistor and the photocell is connected to an analog input on the Arduino Mega 2560. This is illustrated by the figure below:

    The LCD displays the current position of the servo, whether the laser is on or off, and whether the light sensor is being shot or not. Each of the three functions is responsible for updating the display, but later this functionality will be moved out into its own task. Phase 1 is concluded with a block diagram showing all the components connected to the Arduino Mega 2560 station.

    Phase 2

    In Phase 2, the existing system components of Phase 1 were split between two Arduino ATMega2560 boards. The goal was to have one board function as the "base" station, and the other as the "remote" station (which would eventually be connected to a Roomba and function as our "laser tank"). Both systems were also required to operate using a time-triggered scheduler so that CPU utilization could be minimized. Using a USB logic-analyzer, the expected timing requirements of all I/O devices were tested and optimized.

    Apart from the split into two boards, several changes were made to the system in Phase 2. Three additional light sensors were wired in parallel with the single sensor from Phase 1 - this was done to increase the accuracy of the "Red Solo Cup" target (seen in Phase 1 photo). Because an additional Arduino ATMega2560 board was introduced, Bluetooth adapters were wired to the RX1 and TX1 pins on each board so that the two boards could communicate wirelessly over a bi-directional serial connection. Two new Bluetooth tasks (Receive and Send) were created on each station for this purpose. The bluetooth configuration procedure can be found here. The block diagram configuration of the entire system in Phase 2 is as follows:

    Time Triggered Architecture

    A time-triggered architecture (TTA) was also incorporated for phase 2. The library that was used can be downloaded with the phase 2 code in the appendix. This architecture allowed "tasks" to be created and periodically scheduled on both stations. The methods written in Phase 1 were split between the two stations and periodically scheduled using the TTA. Additionally, the new Bluetooth tasks were scheduled on each station. To store control information sent from both stations, a fixed-sized queue was instantiated for each I/O device. When the "Bluetooth Receive" function runs on either station, the control information that is received is stored in the dedicated queue for the device it was intended for. The data is used (and dequeued) when the respective device task runs on its periodic schedule. Each queue was implemented as a circular array with a length of 10, which drops new data entries when it is full (although this has never been observed to be the case). The array can queue 9 items as the last spot is not used to ensure a full queue does not behave like an empty queue.

    Base Station

    The base station has five tasks that use the TTA library to run on a fixed schedule. They are:

    1. laserTask - Scheduled every 100ms, with a 25ms offset

      The laser tasks samples the push-button on the joystick using a digital read. It also keeps track of the previous state of the laser and only sends new information to the remote station when the value changes.

    2. bluetoothReceive - Scheduled every 150ms, with a 0ms offset

      The bluetooth receive function checks the Serial connection for any incoming packets and processes them. This includes putting the packet data into the correct queue for other tasks to pick up. More about packets is discussed later on.

    3. lightSensorTask - Scheduled every 100ms, with a 20ms offset

      The light sensor task reads the value of the photocell and stores it. There are four photocells wired in parallel in order to detect the laser hitting the cup directly, or on the inside edges.

    4. screenTask - Scheduled every 150ms, with a 50ms offset

      The screen task updates the LCD display with the position of the servo and state of the laser. These values come from the remote station, but this task just checks the screen queue to see if the screen needs updating and does the updating if required. The photocell state is also displayed on the LCD as "HIT" or "Clear".

    5. movementTask - Scheduled every 200ms, with a 15ms offset

      The movement task reads values from the joystick and maps them to a degree value between 5 and 175. If the joystick is between 88 and 92, it is in what is considered the "dead zone". This means the servo should stop moving where it is. The value is sent in degrees to the remote station where the logic lies to control the servo.

    Remote Station

    The remote station has four tasks that use the TTA library to run on a fixed schedule. They are:

    1. laserTask - Scheduled every 100ms, with a 20ms offset

      If there is data available in the laser data queue, this task simply dequeues the data and uses the value obtained to control the state of the laser (0 for on, 1 for off).

    2. servoTask - Scheduled every 25ms, with a 0ms offset

      Since it was imagined that the servo motor would eventually control a sort of "laser turret" on top of the Roomba Tank, it was decided that controls sent to the servo motor must give precise and consistent control to the operator. To meet this requirement, control-data for the servo is sent as a degree between 5 and 175. If the value is between 5 and 30, each call to the servo task by the TTA decrements the value by 3, providing a fast motion in the required direction. If the value is between 30 and 88, it is decremented by 1, providing precise control of the servo at a slower speed. The same exists from 92 to 150, and 150 to 175. This means the joystick effectively has 5 zones. The middle means don't move. Slightly to the -x direction means move slowly in that direction, sharply to the -x direction means move quickly that way, and the same for the +x direction. The decision to control the servo motor using this type of relative positioning means that the sampling frequency of the servoTask is relatively higher than the other tasks, although it provides for very exact movement.

    3. bluetoothReceive - Scheduled every 50ms, with a 5ms offset

      This function checks the Bluetooth serial connection for incoming information. If there is something available, it reads the first byte to determine what kind of control data has been sent, and places it in the appropriate I/O device queue.

    4. bluetoothSend - Scheduled every 100ms, with a 35ms offset

      The base station must receive information confirming what actions have been taken on the remote station, so that it can display it on an LCD. This function compiles the current state of the laser (0 or 1) and the servo (5-175) into a packet, and prints it with a header byte to the Bluetooth serial UART1 pin.

    Packets were designed to send state information for each of the I/O devices. The first byte of each packet determines what I/O device is being sent control information (ie: 0 for LASER, 1 for SERVO, 2 for SCREEN). If the device being controlled is the servo motor, an additional byte is sent that tells the remote station how many subsequent digits of data to read. Finally, the control data is sent. For the laser, this is a single binary value (representing on or off); for the servo, it is a set of digits that when combined, are equal to a degree signal between 5 and 175 to control the servo motor. The Bluetooth Receive function that was created reads in and processes these packets and stores them in a fixed-length queue. Each I/O task then dequeues data from the queue and uses it to control each respective device.

    Logic-Analyzer

    The USB logic-analyzer ensured timing requirements were met. Initially on the base station, the screenTask was taking a long enough time that it delayed the laserTask. This is seen in the figure below between 0.7 and 0.8s. The channels correspond to:

    • Channel 0: laserTask
    • Channel 1: bluetoothReceive
    • Channel 2: lightSensorTask
    • Channel 3: screenTask
    • Channel 5: movementTask
    • Channel 7: CPU idle time



    After adjusting the offsets and timing so that no conflicts occured and everything remained responsive, we came up with the times stated in the above Remote and Base station sections and captured the following logic-analyzer outputs for the base and remote station respectivly:

    The base station channels are listed again for convenience:

    • Channel 0: laserTask
    • Channel 1: bluetoothReceive
    • Channel 2: lightSensorTask
    • Channel 3: screenTask
    • Channel 5: movementTask
    • Channel 7: CPU idle time



    For the remote station, the corresponding channels are:

    • Channel 0: laserTask
    • Channel 1: servoTask
    • Channel 2: bluetoothReceive
    • Channel 3: bluetoothSend
    • Channel 4: CPU idle time



    CPU Utilization

    The following table shows data taken from the logic-analyzer about each task and the computed CPU utilization of each task. For the base station:

    laserTask Period = 0.100217s Width = 0.133833ms Frequency = 9.967Hz CPU util = 0.13339%
    bluetoothReceive Period = 0.1502475s Width = 76.08333us Frequency = 6.6557Hz CPU util = 0.05064%
    lightSensorTask Period = 0.1005703s Width = 0.1180833ms Frequency = 9.943298Hz CPU util = 0.11741%
    screenTask Period = 0.14925283s Width = 4.23963333ms Frequency = 6.70004Hz CPU util = 2.84067%
    movementTask Period = 0.2003315s Width = 0.2910833ms Frequency = 4.991726Hz CPU util = 0.14530%
    Total CPU util = 3.28721% Total CPU idle = 96.7128%

    And the remote station:

    laserTask Period = 99.95083ms Width = 5.833333us Frequency = 10.004919Hz CPU util = 0.000006%
    servoTask Period = 24.38783ms Width = 70.75us Frequency = 41.004053Hz CPU util = 0.29010%
    bluetoothReceive Period = 50.50625ms Width = 8.3333us Frequency = 19.7995Hz CPU util = 0.01649%
    bluetoothSend Period = 0.1005094s Width = 0.34333ms Frequency = 9.949316Hz CPU util = 0.34159%
    Total CPU util = 0.64819% Total CPU idle = 99.3318%

    Sampling Frequencies

    As can be seen in the below tables, we estimated the lowest sampling frequency for each I/O device in order for the system to still run smoothly. The base station's frequencies are as follows:

    laserTask Lowest sampling frequency = 10Hz
    bluetoothReceive Lowest sampling frequency = 6.66Hz
    lightSensorTask Lowest sampling frequency = 10Hz
    screenTask Lowest sampling frequency = 6.66 Hz
    movementTask Lowest sampling frequency = 5Hz

    The remote station's frequencies are as follows:

    laserTask Lowest sampling frequency = 10Hz
    servoTask Lowest sampling frequency = 40Hz
    bluetoothReceive Lowest sampling frequency = 20Hz
    bluetoothSend Lowest sampling frequency = 10Hz

    Conclusion

    The main goal of project 1 is to work towards eventually mounting the remote-station on top of a Roomba. The base-station will then be able to control the movement of the Roomba as well as the position of the laser. Using the TTA has ensured that the embedded system is meeting all timing requirements. This was verified using a logic-analyzer. The total CPU utilization was calculated to be 3.28721% for the base station, and 0.64819% for the remote station, which provides confidence going into project 2.

    Code

    Download the phase 1 source code here.
    Download the phase 2 source code here.