CS 153: Lab 10

Title image Fall 2018

Lab Exercise 10:

The lab today will be enhancing our rover with some additional sensors. In particular, we'll be adding the distance sensor and a photosensor (light sensor). Then we'll create some classes to manage them. The main CS concept we're introducing this week is inheritance: the ability to create child classes that get the functions and the data of their parent class.


Tasks

    Board

    For this project you will need the following items.

    1. Your rover
    2. The IR distance sensor
    3. Two small screws (provided)
    4. The Photo Transistor light sensor
    5. A 10k resistor (brown/black/orange)
    6. Two LEDs and their 560 Ohm resistors

    You can remove the AC sensor from your board. Please return it if you do not use it for your final project.

  1. Wire up the two LEDs. You can use more if you wish, but you'll need at least two.
  2. The phototransistor wiring is similar to an LED. Place the phototransistor so it crosses the central line. The shorter pin should connect to the 10k resistor, which should connect to ground. The longer pin should connect to 5V. Connect a wire from the short side of the phototransistor to an analog input such as A0.

  3. Mount the IR distance sensor on the front of your rover using two small screws (provided). Then connect the black wire to ground, the red wire to 5V, and the yellow wire to a row on your board. Run a wire from where the yellow wire is connected to an analog input such as A1.
  4. Code

    Different sensors work in different ways. But sensors that return a single analog value all share a number of properties. (1) The value captured from the sensor is an integer value, (2) the value is probably noisy enough that we want to filter it, and (3) we read the value from a pin. The only part of a sensor that may be different is how we want to interpret the raw analog reading.

  5. In a new file Sensor.h, create a Sensor class. Include Arduino.h and string.h at the top of the file. The Sensor class needs at least the following fields. Make them protected instead of private so that the child class can access them.
    • An int to store the analog pin being used.
    • An int to store the most recent reading.
    • An int to store the filter size.
    • A float to store the average reading.
    • A char array with 32 elements to store the name of the sensor.

    In addition, the class needs the following member functions. Don't forget to put Sensor:: in front of each member function name in the .cpp file.

    • Sensor(void) - a default constructor that sets all of the fields to useful default values.
    • Sensor(int pin) - a constructor that takes in a pin number and stores it as well as setting the other fields to useful default values.
    • Sensor(int pin, int fsize) - a constructor that takes in both a pin number and the filter size to use for computing the smoothed average of the sensor signal.
    • int update(void) - a function that reads from the analog pin and puts the value into the current reading field. In addition, it should update the smoothed average. Use the same equation as we used last week for calculating the smoothed averages for the ACSensor.

      If w = 1.0 / filterSize, then given an existing average A and a new reading R, the new value of the average is (1-w)*A + w*R.

    • int getReading(void) - a function that returns the most recent reading from the pin.
    • float getAvgReading(void) - a function that returns the most recent average reading.
    • float getValue(void) - a function that returns the current reading. In child classes this function should be overwritten to return a value in the proper units (e.g. cm). The sensor class version will be identical to getReading.
    • float getAvgValue(void) - a function that returns the current average reading. In child classes, this function should be overwritten to return a value in the proper units. The sensor class version will be identical to getAvgReading.
    • void print(void) - a function that prints the current reading and average reading to the Serial port.
  6. In Sensor.h, create a child class IRSensor that is derived from Sensor. You will use this class to manage the IR Distance sensor. You can use the following template, which shows how to derive IRSensor from the Sensor class. It uses the public keyword in order to give the child class access to the parent fields.

    // IR Distance sensor class, derived from Sensor
    class IRSensor : public Sensor {
     public:
     IRSensor(int pin) : Sensor(pin) {strcpy(name, "IR Distance Sensor: ");}
     // create a second constructor that takes pin and filter size
    
     // functions to override go here
    };

    The IRSensor class does not need any additional fields. It does need to include or override the following methods.

    • IRSensor(int pin, int fsize) - call the parent constructor with pin and fsize, then copy "IRSensor: " to the name field.
    • float getValue(void) - this function should return the distance in inches (or cm, your choice). Use the conversion function you created in project 3 to convert from the current raw sensor value to inches.
    • float getAvgValue(void) - this function should return the distance in inches, but use the average reading instead of the current reading.
    • void print(void) - this function should print a nice string to the serial port that includes both the raw sensor reading and the value converted to inches.
  7. In Sensor.h, create a child class LightSensor that is derived from Sensor. You will use this class to manage the Photo transitor sensor. The LightSensor class does not need any additional fields. Override or create the following methods.

    • LightSensor(int pin) - this constructor should call the corresponding Sensor constructor and copy the string "Light Sensor: " to the name field.
    • LightSensor(int pin, int fsize) - this constructor should call the corresponding Sensor constructor and copy the string "Light Sensor: " to the name field.
    • int dark(void) - this function should return 1 if the sensor value is below a threshold (e.g. 40). Otherwise it should return a zero.
    • int bright(void) - this function should return 1 if the sensor value is above a threshold (e.g. 240). Otherwise it should return a zero.

  8. Write a main program sensortest that declares an LEDBank object, an IRSensor object and a LightSensor object and starts up Serial communication. The code should then enter a loop, call the IRSensor and LightSensor update methods, and print out the values of both sensors (use the print method). Inside the loop, make one of your LEDs light up if the distance sensor is less than 8. Make the other LED light up if it is bright.

    Run your program and make sure both sensors are working properly. The LED sensor value should go down in the dark and up in the light.


When you are done with the lab exercises, you may start on the rest of the project.