Can you tell what I'm doing from code alone? If not, there must be a mistake.

Simple background information:

I am using a RC Car and two DC motors one steers and the other drives forward. I want to make this car operate autonomously. Are you able to interpret what my code is telling this car to do? The code currently doesn’t work as intended and I am wondering why. So, if you guys tell me it’s going to do something it’s not intended to do then I could find the problem.

Thanks and best of luck :smiley: .

#include <AFMotor.h>

AF_DCMotor motor2(1);
AF_DCMotor motor1(3);
#define trigPin 9
#define echoPin 2

void setup(){
  Serial.begin (9600);//start serial
  pinMode(trigPin, OUTPUT);//sensor set-up
  pinMode(echoPin, INPUT);//sensor set-up
  pinMode(4, OUTPUT);//led pin set-up
  pinMode(7, OUTPUT);//led pin set-up
  motor1.setSpeed(0);//drive speed set

  motor1.run(RELEASE);//motor switched off (should be off any way)

  motor2.setSpeed(135);//stearing speed set

  motor2.run(RELEASE);//motor switched off (should be off anyway)

}

void loop()
{
  int sensorValue = analogRead(A0); //read the input on analog pin 0
  int sensorBalue = analogRead(A1); //read the input on analog pin 1
  delay(1); //delay in between reads for stability
  
  motor1.run(FORWARD);//motor default position forward
  
  while (sensorValue > 1000) {
    digitalWrite(4, HIGH);
    delay(200);
    digitalWrite(4, LOW);
    delay(200);
    motor2.run(BACKWARD);   
  }
  while (sensorBalue > 1000) {
    digitalWrite(7, HIGH);
    delay(200);
    digitalWrite(7, LOW);
    delay(200); 
motor2.run(FORWARD);
  }
  int duration, distance;//defining values
  digitalWrite(trigPin, HIGH);//signal sent to sensor
  delayMicroseconds(2000);//for 2000 microseconds
  digitalWrite(trigPin, LOW);//then switched off
  duration = pulseIn(echoPin, HIGH);//time taken for signal to echo back
  distance = (duration/2) / 29.1;//converting the duriation of echo to a distance in cm
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");//if no echo is recieved
  }
  else {
    Serial.print(distance);//print the distance
    Serial.println(" cm");//in cm to the serial monitor
  }
  if (distance <=0 ){
    motor1.run(RELEASE);//stop motors if the wires short
    motor2.run(RELEASE);//stop motors if the wires short
  }
  if (distance <=30){//If the car is closer than 30cm to an object
    motor1.run(RELEASE);//stop drive motor
    delay (2000);//wait 2 seconds
    motor1.run(BACKWARD);//drive the car backward
    delay (1000);//for 1 second
    motor1.run(RELEASE);//stop the car
    delay (2000);//wait 2 seconds
    motor2.run(FORWARD);//steer the car to the left
    delay (1000);//steer for 1 second
    motor2.run(RELEASE);
    delay (250);//wait 1/4 of a second
    motor1.run(FORWARD);
    delay (2000);
    motor1.run(RELEASE);
  }
}

not sure what else it does, but it does nothing most of the time.

‘delay’ stops anything from happening until the delay times out.
it is a blocking function.

You're trying to handle things that take more than a very short time all one after the other in a single pass through loop(). Result is that what should work smoothly together turns into wait in line to happen one at a time.

There are many tutorials teaching how to make many things work together at once. The first link at the bottom of my post is to one that is very complete, explained in simple terms and has example codes.

I expect that you will get links to other examples very soon.

Instead of asking what's wrong with the code maybe you should tell us what your problem is and why you're posting .

Rash, his code says it. It's going to run jerky and uncoordinated if it runs at all. It's going to be extremely unresponsive as to any attempt at control. It's top-down code trying to do a real time job.

@GoforSmoke,
Yeah, I saw that but the fact that he posted that code means he has no idea what 'normal' code looks like
so maybe he wouldn't know it was bunk. He didn't mention anything about the behavior of the car so we can't assume he knows there is anything wrong with the coding technique in general. He asked if we could tell what his code does, not if we think it sucks.

Is the OP trolling ?

Potentially.

There are so many little (and big) contradictions and WTF expectations in that post.

I guess they could be quite young?

If so, then maybe I spoke too soon, but they do eventually need to learn how to think 'how is my post going to interpreted by people who don't know everything about my project that I know'.

1:1:
they do eventually need to learn how to think 'how is my post going to interpreted by people who don't know everything about my project that I know'.

Well for a start they should learn to put explanatory comments in. Trivial comments that just repeat the code like this....

int sensorValue = analogRead(A0); //read the input on analog pin 0

.... don't help a whole lot.

But then again I once worked with a guy whose mantra was:

I don't comment my code: if it was difficult to write it should be difficult to read.

Thanks and best of luck

Best of luck to you too, my good man.

JimboZA:
I don't comment my code: if it was difficult to write it should be difficult to read.

I'm doing some vision processing work at the moment - pretty much 'robustifying' a process and finding myself at the 'not much gain for a lot of work' end - can say this comment resonates with me! Some of the convoluted band-aid style things I am applying to fix rare boundary conditions are very hard to code logically, attempting to write meaningful (one would hope) comments takes longer to write than the code itself.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Can you please post a copy of your sketch, using code tags?
Please use code tags.. See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html

Tom...... :slight_smile:
(I'll ask once and once only.)
(One ping and one ping only...Hunt for Red October)

raschemmel:
@GoforSmoke,
Yeah, I saw that but the fact that he posted that code means he has no idea what 'normal' code looks like
so maybe he wouldn't know it was bunk. He didn't mention anything about the behavior of the car so we can't assume he knows there is anything wrong with the coding technique in general. He asked if we could tell what his code does, not if we think it sucks.

For one thing, his code is the "normal" top-down approach that beginner to intermediate PC programmers crank out as unthinkingly as making counting variables int.

It's not normal real time code but that doesn't seem to get taught so much.

I can tell what his code does and part of that is suck! So sorry, but it's true!
However... the code is not the coder who can learn better. I started out like that myself in 1980!

I have a take on comments that comes from years of fixing code that had been danced through to the point where the comments did not describe the code more often than not. I learned to ignore them and adopt the then-old saying that "The code IS the comments.". Heck, I've seen English that made less sense than most code I've come across.

GoForSmoke:
“The code IS the comments.”

Yes! I’ve grown accustomed this myself, it’s interesting coming up with variable and method names that make sense on their own, but also make sense when combined. Doesn’t always work out, but can save a lot of commenting…

Some languages have some really counter-intuitive elements though:

Just now dealing with mousecall backs in c++:

typedef pair<vector<Point>, int> mouseClickType;

void onMouse(int event, int x, int y, int f, void* ptr){
 mouseClickType *mouseClickData = static_cast<mouseClickType *>(ptr);

 if(event == CV_EVENT_LBUTTONDOWN){  
 mouseClickData->first.push_back(Point(x,y));
 mouseClickData->second++;
 }
}

Then to access the mouseClickData I have to use ‘get<0>(mouseClickData)’ and ‘get<1>(mouseClickData)’ - yeech :fearful:

So just to get back to, you know, being able to name my own ($%&#ing) variables I #define them thusly:

#define markerInitPositions get<0>(mouseClickData)  
#define clickCount get<1>(mouseClickData)

I bet someone is groaning right now - I’ve done some cardinal sin?

:smiley:

Associated thought>> I wonder how often helps to have an IDE that pops up hovering definitions of your code? It helps me greatly, but if I were to switch to a text editor, or god forbid someone had a printout of my code - well, that’s the real test

1:1:
Is the OP trolling ?

Thank You, good sir! And no, 1:1 or at least I didn't think I was.

Alright, I, um... admittedly didn't know how this post would come off, but hey first times can be rough. I'll aim to clear up some of the ambiguity I left behind here in my next post.

Firstly, what was I looking for by making this thread? I was attempting to see if my code made sense in an self explanatory way and if this code was coherent, then I was looking to see if I could receive some pointers from you guys (even though the code was incoherent, I got a lot of pointers).

Since it sucks, I would like to ask if you guys can help me to improve my code, so that it will function as intended.

However, before I do that I am required to properly explain everything that is going on with the code and my project.

Proper Explanation

As I may have alluded to in my initial post, I am looking to make an Autonomous RC Car that detects objects via the HC-SR04 and follows any line found through the two Infrared Sensors, shown above, attached to the breadboard. I will try my best to explain this.

Code Deconstruction:

#include <AFMotor.h>

AF_DCMotor motor2(1);
AF_DCMotor motor1(3);

At the beginning of my code, I include the stuff from the library I downloaded from somewhere (I think it was adafruit) and assign the the term motor2 to the front steering DC motor that is connected to M1, as shown in the first image. Then, I go on to the term motor1, assigning that, as well, to a DC motor, but that motor is what controls the drive and is connected to M3 on the motor shield (shown in the second image).

#define trigPin 9
#define echoPin 2

void setup(){
  Serial.begin (9600);//start serial
  pinMode(trigPin, OUTPUT);//sensor set-up
  pinMode(echoPin, INPUT);//sensor set-up
  pinMode(4, OUTPUT);//led pin set-up
  pinMode(7, OUTPUT);//led pin set-up
  motor1.setSpeed(0);//drive speed set

  motor1.run(RELEASE);//motor switched off (should be off any way)

  motor2.setSpeed(255);//stearing speed set

  motor2.run(RELEASE);//motor switched off (should be off anyway)

}

Before I get into the “void setup()” section, I define two variables trigPin and echoPin. They both refer to pins on the motor shield that are connected to the HC-SR04. In the first picture, you should be able to see that trigPin (blue jumper wire) is connected to pin 9 and echoPin (green jumper wire) is connected to pin 2.

After that, I do the basic setup for the motor, trig, and echo pins, but notice that I have some unexplained pin usage going here. I’ll explain this in the next section, for the sake of consistency in image separation.

void loop()
{
  int sensorValue = analogRead(A0); //read the input on analog pin 0
  int sensorBalue = analogRead(A1); //read the input on analog pin 1
  delay(1); //delay in between reads for stability
  
  motor1.run(FORWARD);//motor default position forward

  while (sensorValue > 1000) {
    digitalWrite(4, HIGH);
    delay(200);
    digitalWrite(4, LOW);
    delay(200);
    motor2.run(BACKWARD);   
  }
  while (sensorBalue > 1000) {
    digitalWrite(7, HIGH);
    delay(200);
    digitalWrite(7, LOW);
    delay(200); 
motor2.run(FORWARD);
  }

Now! On the loop one. You can probably tell, but I was thrown for a loop in this section. I attempted to set two variables for receiving data from the infrared sensors. “analogRead(A0)” in the image is the infrared sensor lined to the yellow jumper cable (right). “analogRead(A1)” in the image is the infrared sensor connected to the white jumper cable (left).

The infrared sensors originally have 4 pins, which are, in order, from left to right, VCC, GND, DO, AO. I didn’t connect the DO pin to anything because I didn’t know what it did, but the other pins were Power (RED wire), Ground (BLACK wire), and Analog Output (YELLOW or WHITE wires).

In case you haven’t noticed, HC-SR04 wires have rectangular ends and anything connected to the breadboard is connected using cylindrical ending jumper wires.

Okay, after the sensors have been assigned their analog pins, I then, tell the arduino what I want the car to be doing when none of the conditions have been met. “motor1.run(FORWARD)” is meant to send the car driving forward in the absence of objects or lines.

In the photo, you’ll see the LEDs that I assigned pins to in the “void setup()” section. I want these to light up, left (RED) or right (GREEN), as the Infrared Sensors detect a line. This is whispered to the arduino in the “while” conditional statements, where I attempt to make the car steer in accordance with the the location of the line that the Infrared Sensors should detect.

*The values are unrealistic for the while conditional. A value x will not be >1000 because values range from about 20 to about 700 with this instrument’s sensitivity.

  int duration, distance;//defining values
  digitalWrite(trigPin, HIGH);//signal sent to sensor
  delayMicroseconds(2000);//for 2000 microseconds
  digitalWrite(trigPin, LOW);//then switched off
  duration = pulseIn(echoPin, HIGH);//time taken for signal to echo back
  distance = (duration/2) / 29.1;//converting the duriation of echo to a distance in cm
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");//if no echo is recieved
  }
  else {
    Serial.print(distance);//print the distance
    Serial.println(" cm");//in cm to the serial monitor
  }

This, is something that I’m going to skip, but it is a section of the code dedicated to the organizing and interpreting of the data received by the HC-SR04. This helps to determine the distance and is the code for scheduling when the signal will be send and how much time will be delayed for the echo to be heard.

  if (distance <=0 ){
    motor1.run(RELEASE);//stop motors if the wires short
    motor2.run(RELEASE);//stop motors if the wires short
  }
  if (distance <=30){//If the car is closer than 30cm to an object
    motor1.run(RELEASE);//stop drive motor
    delay (2000);//wait 2 seconds
    motor1.run(BACKWARD);//drive the car backward
    delay (1000);//for 1 second
    motor1.run(RELEASE);//stop the car
    delay (2000);//wait 2 seconds
    motor2.run(FORWARD);//steer the car to the left
    delay (1000);//steer for 1 second
    motor2.run(RELEASE);
    delay (250);//wait 1/4 of a second
    motor1.run(FORWARD);
    delay (2000);
    motor1.run(RELEASE);
  }
}

In the presence of an object, this code tells the car to stop for two seconds, reverse for one second, stop again for 2 seconds, steer to the left for 1 second, stop steering, wait a 0.25 second period, go forward for 2 seconds, and then stop once more.

The code goes no further than this because when testing this whole thing I realized the other parts weren’t functioning correctly. Had I not noticed this, I would have made the car do the same loop in the other direction if it found an object while doing the conditional I described above.


This is to be powered using a 9V Battery, but I would like to know the most power efficient way of powering this. I’m thinking I should power the sensors separately.

Anyways, thanks for reading (or not, I guess). Let me know if I left something out. Oh, I know a side view.

I didn't connect the DO pin to anything because I didn't know what it did,

The demodulated output signal can be directly
decoded by a microprocessor.

IR SENSOR Tutorial

If you post the link for your ir sensor breakout boards we can discuss your specific sensors but it would appear from the Sparkfun tutorial that it is the PWM out from the sensor when reading codes from a hand held remote (such as a TV remote control or a general purpose (universal) remote:

Receiving a signal from the TSOP85338 can be done on the BeagleBone using its gpio pins. In order to do this, the bitrate must be known initially or measured somehow. Once the bitrate is known, you can write a program that waits until an interrupt is received on a particular gpio pin that triggers on "both" edges. Essentially this will wait for the output of the TSOP85338 to change states. After it triggers, you can read the data received at intervals that match the bitrate until the message is received. This can be done for a set number of bits or until a terminating sequence occurs (user defined). Ex) if transmitting 8-bit char values, you can wait for a \0 ascii character to know that the message has been received.

[EDIT] (Today at 2:39 AM)
It is clear from the mounting arrangement that your application is detecting distance to an object
the black line tape, not decoding TV remote control signals.
[EDIT]

This is to be powered using a 9V Battery, but I would like to know the most power efficient way of powering this. I'm thinking I should power the sensors separately.

If you are referring to the rectangular PP3 smoke alarm batteries you might want to reconsider that since they are rated for about 300 mAh.

The IR Sensor I have is the FC-03. And it's supposed to be reading for the black lines that I put down using electrical tape, since this is supposed to be a line following Car.

And it supposed to be reading for the black lines that I put down using electrical tape, since this is supposed to be a line following Car.

And how's that working out for you ?

raschemmel:
And how's that working out for you ?

Hmm... I'm not quite sure, but I think it works fine with this test code:

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}
 
// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}

The values jumped to a higher number when the Sensor is placed on a darker pigmented object vs when it is placed on a white surface. Despite what I observe though, correlation does not equal causation, so I'm not sure if that is why the values jumped.

All I know is that an IR Sensor on a yellow surface gave me 61 and that same IR Sensor face down on black tape placed on that same surface gave me 672.