11: Computer Programming
Coding my Final Project
Since there isn’t a particular assignment for Computer Programming Week, I decided I would put my progress coding the final project into this documentation page to give an in-depth view into my process.
In the earlier weeks, I first coded a simple analogRead()
function to get and average a reading from a Hall Magnetic Sensor from an analog pin. I also used a time-based movement code to run my first car prototype. I used a latex glove with copper leads to drive a motor. Then, I worked on simple serial communication of my magnetic sensor values between two Arduinos. Now, for my final project, it’s time to combine all of these tasks to execute into a few working programs.
From my earlier tests, serial commmunication seemed to be working fine – my RF modules were able to transmit and receive bytes and send over readings when needed. However, when it was time to actually execute movements, I ran into many issues.
My first problem was that the motors weren’t moving when they received the commands. This was because I was accidentally reassigning my value for recdata
, the data that my chip was receiving, to a different variable. Once I fixed that issue, the motors were executing the commands in small chunks instead of smoothly. One of my problems was that I was resetting my data
byte to send as 0 in the wrong place so it was receiving two different bytes, so I deleted that issue.
However, it was still only executing the commands in chunks rather than smooth movements.
With Nathan’s help, we realized that the code to process the data probably used a delay of some sort, and that delay was preventing everything else in the void loop from running for that time. So, we used the radio interrupt example code from the RF module library to see which functions we needed to include for an interrupt. An interrupt function usually stops whatever the code is currently doing to run whichever functions it calls, but we used the interrupt function to allow the processing data code, which was in a separate function, to run without bothering the motor code. So, only when the processing data loop received a new movement number the movement code would switch to do a different movement.
Next, I tried running my code from my glove to my car. However, it would only run within a very short range. I realized the range was set to close by accident in the example RX/TX code, so I had to make the range larger, which helped. When I tried to turn right, when the rec_data byte was 3, my car seemed to work fine. However, when I tried to turn left, when the rec_data byte was 2, my car would start running the turn left command and be unable to get out of the loop.
My Arduino Nano would also get very very hot. When we plugged into my receiving Nano into the serial monitor, the code would actually display the name of the program, which only shows up when the code is restarted. However, I wasn’t pressing the reset button, so we realized that my motor was drawing too much power. To fix this, I first switched the power pin on the motor driver from 5V to VCC/VIN so it could draw enough power to make the motors happy. I also checked my soldering on the faulty motor with the multimeter – turns out I also had a short and some sketchy connections.
After these fixes, my code seemed to work well, it was just time to test my code repeatedly. Unfortunately, I was being dumb and accidentally broke off my reset button on the car’s Arduino Nano, and the reset button ended up SHORTING TWO OF MY PINS TOGETHER AND BREAKING THE BOARD. This was not ideal. I had to use the desoldering pump to initially get rid of most of the surface solder. However, I still couldn’t get the board to get off. I eventually used a heat gun to get the board off, but some pins fell off. Luckily, those were useless pins. I was able to resolder the new Nano onto the leftover pins and get my final project up and running!
These are my final movement codes and parameters:
TX:
if(sensorAveOne > 0 && sensorAveOne <= 5 && sensorAveTwo > 0 && sensorAveTwo <= 5){
//FORWARDS
data = 1;
}
else if(sensorAveOne > 0 && sensorAveOne <= 5){
//turn LEFT
data = 2;
}
else if(sensorAveTwo > 0 && sensorAveTwo <= 5){
//turn RIGHT
data = 3;
}
else if(sensorAveTwo > 5 && sensorAveTwo <= 450 && sensorAveOne > 5 && sensorAveOne <= 4n50){
//backwards
data = 4;
}
else {
//stop
data = 0;
}
RX:
if (rec_data == 1) {
//Forwards
analogWrite(3, 255);
analogWrite(5, 0);
analogWrite(6, 255);
analogWrite(9, 0);
}
else if (rec_data == 2) {
//Turn Left
analogWrite(3, 255);
analogWrite(5, 0);
analogWrite(6, 100);
analogWrite(9, 0);
}
else if (rec_data == 3) {
//Turn Right
analogWrite(3, 100);
analogWrite(5, 0);
analogWrite(6, 255);
analogWrite(9, 0);
}
else if (rec_data == 4) {
//backwards
analogWrite(3, 0);
analogWrite(5, 255);
analogWrite(6, 0);
analogWrite(9, 255);
}
else {
//Stop
analogWrite(3, 0);
analogWrite(5, 0);
analogWrite(6, 0);
analogWrite(9, 0);
}