The process for mounting my sensor started with cutting another piece of wood. I also had to shave down one of my spacers because it was too thick. From there it was simply a matter of pushing screws through the sensor's screw holes, and using nuts to connect it with the newly cut wood. Using a right-angle bracket, I screwed the wood into the piece atop my servo. And voila, it works!
If only. To get the result of the video above requires programming. This programming I'd have loved to have done a month ago, but my car was not exactly finished back then. So I've been writing a lot of code in a couple days. The code for the Arduino is a form of C++ that is modified to be easier to code in. I have done a significant amount of coding already. If not for what is hopefully just a small issue, I could have also uploaded a video of my car not hitting a wall.
That issue is one of a faulty sensor. However, the sensor isn't always faulty - it only appears to have issues when I'm also driving the car's motors. The reason for this is one of voltage spikes (I hope) - the sensor's readings get messed up when the motors start because of the change in the distribution of power. I do have a way to fix it, though. The picture below is from the sensor's manufacturer showing exactly how to solve this sort of issue. And hopefully that is the only sort of issue, as the sensor normally works fine.
So the start of the code is just a whole bunch of variables and constants. There are a couple constants to allow fine-tuning of the car, but most of them are the port numbers on the Arduino into which various wires are attached. Each motor requires three wires passed to the motor driver: IN1 and IN2 are set either HIGH/LOW or LOW/HIGH to indicate which direction the motor should turn (they are digital ports, meaning they are binary and thus only have two states; HIGH is an output of, say, 5V and LOW is an output of 0V). PWM is pulse-width modulation, which indicates the speed of the motor. PWM is where the output is toggled On/Off over a set of time. The higher the PWM output, the more of that time is spent being HIGH then LOW (the Arduino site has a good explanation of this).
There are two required methods in any Arduino program (or sketch, as it is called): setup and loop. Setup is called when the program starts. In my setup method, I'm merely connecting the Arduino to my computer through a serial port to allow for debug outputs. All of my normal setup routines occur in the loop function. The reason for this is I've implemented a button that allows me to tell the car to start and stop, without having to turn the power off every time. My loop function behaves differently depending on which state it is in (held in a simple integer variable), allowing me to have start and end routines for my car without leaving the program.
Moving on to my motor control. My motor driver has a standby mode which, if set, turns power off to the motors. By default this mode is turned on, meaning that I have to manually turn it off for my motors to work. The drive motor is controlled by giving a function a velocity from +/- 0-100, which the function then maps to a PWM value of 0-255 (as that's a byte of data). There is also a function to brake the drive motor. For steering, I have three functions: steerLeft, steerRight, steerStraight. As I had discovered previously, for my steering motor to work, I just turn it on full power (a PWM signal of 255 meaning always HIGH). These functions just set the direction the motor turns (steerStraight turns the motor off).
My code is a little more complex when it comes to my sonar sensor. To start, I have a function getDistance which returns the current distance detected by the sensor. Right now it is a little more complicated, because I have two LEDs which I'm trying to use to communicate the latest reading. The function readDistance interfaces directly with the sensor. The point of this function is in case I have to change that interface (right now it is PWM, but it can also be analog voltage or serial communication), I only have to change one line. The function that calls readDistance is an insertion sort, meaning that, for a given number of entries, reads from the scanner and places them in ascending order into an array. I have two filters as well to control the quality of my sensor's data. The medianFilter takes the array of values and returns the median value. The modeFilter returns the most commonly occurring distance, or if no distance occurs more than once, returns the medianFilter.
For my servo, the function moveServo will be the most commonly called. This takes the constant SERVO_STEP and changes the angle of the servo by that amount. It will also reverse the direction of the servo if necessary (meaning, if the servo is moving to the left but is at 0 degrees, it will move to the right for the next turn). I have the function fullScan which takes the servo and scans a full 180 degrees (following SERVO_STEP's value). This function will require a little more work, as the purpose of it is to initially populate an array with everything in front of the car.
So with my three major components down - motors, sensor, servo - I just need to come up with some functions that tie all of those together. Hopefully that won't take too long, and I'll have a working car quite soon!
Next: Journal Entry #8.5