General Discussion

official

#1

General discussion of the Wi-Fi Bot - Part 2 module.


#2

It might be worth adding a zoomed in picture of how the ESP module is inserted, since it can be plugged in flipped left-to-right.


#3

You guys really lost me on the Ultrasonic code…

Mostly this:

int uS = sonar.ping();
// Calculate distance in cm
int distance = uS / US_ROUNDTRIP_CM;

Where the heck is US_ROUNTRIP_CM getting is value from? I assume this is something that comes from the sonar.ping function that lives inside the NewPing.h library? Also, why are we dividing anything here?

I really wish there was a bit more explanation in these sections…I don’t feel like the comments in the provide code are really helping me learn anything :frowning:


#4

Also, I had this question from part one:

// Constants for motor control functions
#define STEPTIME 600
#define STRAIGHTSPEED 200
#define TURNSPEED 120
#define TURNTIME 300

What is the STEPTIME and TURNTIME values for? I mean, I know that they are used in the goForward() and goRight() etc functions…but what exactly do they do? It’s being used to give the the pmsTimeout variable a value…but I guess I’m wondering what that does exactly.


#5

Correct, US_ROUNDTRIP_CM comes from NewPing.h, the included library:

#define US_ROUNDTRIP_CM 57

I didn’t like that, so I changed my code to what I thought was more straightforward:

  // Check for obstacle
  unsigned long distance;
  distance = sonar.ping_cm();

If you open the NewPing.h text file in your favorite text editor (e.g. Notepad++) you can skim through the available constants and methods. Or you can Google it to see if there’s nice on-line documentation. For this one, there is:

http://playground.arduino.cc/Code/NewPing#Methods

Also looking at NewPing.cpp directly, the ping_cm() method is just the ping() method divided by the US_ROUNDTRIP_CM constant:

return (echoTime / US_ROUNDTRIP_CM);

The reason to divide is to convert microseconds, which is what the sensor outputs, into centimeters, which we can more easily understand. So you get microseconds divided by microseconds/cm, giving you cm.

I think a lot of the component code (e.g. ultrasonic sensor, wifi module) comes from sample code found elsewhere on-line, so I don’t think many comments were added in the Thimble code, perhaps under the assumption that people that were curious would go out and find more information elsewhere. I think several folks here are hoping future kits include more learning and explanations right here in this site.


#6

@thouis asked about this too, here:

You’re right that these aren’t used in Part 1. I think probably the main code was written for the full Part 2, and then not edited down fully when publishing Part 1. So Part 1 ended up with some extra stuff you didn’t really need, or was confusing.


#7

One more before I go to bed.

Here is my code for having the robot move forward unless it detects something. If it does it should turn right until it no longer detects something, at which time it should continue moving forward.

The code is pretty fat with useless stuff in there, because I havent gone in and cleaned out things I don’t need yet, but you’ll get the basic idea. Anyways, things work OK, but I find the reporting from the sonar module is a bit twitchy, making my robot jitter a bit back and forth between the forward and turning when close to objects.

#include <NewPing.h>

#define TRIGGER_PIN  10
#define ECHO_PIN     7
#define MAX_DISTANCE 200

// Boolean (True or False) variable to control whether or not
// the motors move
bool obstacleDetected = false;

// Sonar object (ultrasonic module)
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

// Pin assignments
#define AIN1 3
#define AIN2 4
#define APWM 5
#define BIN1 12
#define BIN2 13
#define BPWM 11
#define STBY 6


// Constants for motor control functions
#define STEPTIME 600 
#define STRAIGHTSPEED 100
#define TURNSPEED 50
#define TURNTIME 300

// Array to track current PWM values for each channel (A and B)
int pwms[] = {APWM, BPWM};

// Offsets to be used to compensate for one motor being more powerful
byte leftOffset = 0;
byte rightOffset = 0;

// Variable to track remaining time
unsigned long pwmTimeout = 0;

// Function to write out pwm values
void writePwms(int left, int right){
    analogWrite(pwms[0], left);
    analogWrite(pwms[1], right);
}

// Move the robot forward for STEPTIME
void goForward(){
    // If an obstacle was detected, stop
    if(obstacleDetected){
        goRight();
    } else {
        // Otherwise, advance
        digitalWrite(STBY, HIGH);
        digitalWrite(AIN1, LOW);
        digitalWrite(AIN2, HIGH);
        digitalWrite(BIN1, LOW);
        digitalWrite(BIN2, HIGH);
        writePwms (STRAIGHTSPEED-leftOffset,STRAIGHTSPEED-rightOffset);
        pwmTimeout = millis() + STEPTIME;
    }
}

// Move the robot backward for STEPTIME
void goBack(){
    // If an obstacle was detected, stop
    if(obstacleDetected){
        stop();
    } else {
        // Otherwise, advance
        digitalWrite(STBY, HIGH);
        digitalWrite(AIN1, HIGH);
        digitalWrite(AIN2, LOW);
        digitalWrite(BIN1, HIGH);
        digitalWrite(BIN2, LOW);
        writePwms (STRAIGHTSPEED-leftOffset,STRAIGHTSPEED-rightOffset);
        pwmTimeout = millis() + STEPTIME;
    }
}

// Turn the robot left for TURNTIME
void goLeft(){
    // If an obstacle was detected, stop
    if(obstacleDetected){
        stop();
    } else {
        // Otherwise, advance
        digitalWrite(STBY, HIGH);
        digitalWrite(AIN1, HIGH);
        digitalWrite(AIN2, LOW);
        digitalWrite(BIN1, LOW);
        digitalWrite(BIN2, HIGH);

        writePwms (TURNSPEED,TURNSPEED);
        pwmTimeout = millis() + TURNTIME;
    }
}

// Turn the robot right for TURNTIME
void goRight(){
  // If an obstacle was detected, stop
    if(obstacleDetected = false){
        goForward();
    } else {
        digitalWrite(STBY, HIGH);
        digitalWrite(AIN1, LOW);
        digitalWrite(AIN2, HIGH);
        digitalWrite(BIN1, HIGH);
        digitalWrite(BIN2, LOW);

        writePwms (TURNSPEED,TURNSPEED);
        pwmTimeout = millis() + TURNTIME;
    }
}

// Stop the robot (using standby)
void stop(){
    digitalWrite(STBY, LOW); 
}

// Arduino setup function
void setup(){
    // Initialize pins as outputs
    pinMode (STBY, OUTPUT);
    pinMode (AIN1, OUTPUT);
    pinMode (AIN2, OUTPUT);
    pinMode (APWM, OUTPUT);
    pinMode (BIN1, OUTPUT);
    pinMode (BIN2, OUTPUT);
    pinMode (BPWM, OUTPUT);
    pinMode (TRIGGER_PIN, OUTPUT);
    pinMode (ECHO_PIN, INPUT);
    Serial.begin(115200);
}

// Loop (code betwen {}'s repeats over and over again)
void loop(){

    // Trigger ultrasonic ping
    int uS = sonar.ping();
    // Calculate distance in cm
    int distance = uS / US_ROUNDTRIP_CM;
    Serial.print("Ping: ");
    Serial.print(distance);
    Serial.println("cm");

    // If there is an object within 10cm of the sensor
    // NOTE: The NewPing library returns 0 if no object is detected.
    if(distance <= 20 && distance != 0){
        // Set the obstacleDetected flag to disable the motors
        obstacleDetected = true;
        
    }

    // Make the robot go Forward.
    goForward();
    
}

Thoughts and/or ideas?


#8

Thanks! You’re a machine :slight_smile:

I agree, I just posted a “suggestion” to that end. I think the power of this learning platform would be to put all the information into one spot. It’s not that I’m lazy to go look for information…it’s just that it’s a sea of information out there and that takes time. I bought into this community for the curated information because time is something I don’t have a lot of these days :frowning:

That said, I don’t see any mention of US_ROUNDTRIP_CM in the documentation you linked :frowning: So I’m still at a bit of a loss with regards to that.


#9

Yeah, I don’t think the US_ROUNDTRIP_CM is in the documentation. I’ve just found it in the NewPing.h file, which should be in the \Arduino\libraries\NewPing folder. It’s just plain text, so you can open it up to see everything in it. There’s other things like US_ROUNDTRIP_IN if you wanted to work in inches instead of centimeters.

I haven’t done much with Arduino before, so this is just speculation, but as a “maker” thing, my guess it’s assumed people will read through .h and .cpp files to see what all’s in there, like defined constants and the like.


#10

For this one I think you’d want to add a stop() and delay(1000) after your goForward(). The loop function is very fast and just repeats forever, so the stop/delay will calm it down a bit.

@david covered this a bit here:


#11

Yes, I thought about adding some delay in there, but based on your suggestion, where exactly would I be putting that delay?

My original thought would be to run the turn for a specified amount of time…but I’m not in love with that idea for a variety of reasons…


#12

I suggest going and reading the U sensor data sheet. If I understood correctly, it sends out pings at 40 KHz (you can’t hear it). The pings hit something and then bounce back and get picked up by the U sensor.

The sensor’s default is to report how much “time” went by before it heard it bounce back. The ping is travelling at the speed of sound, so it is very fast (much less than a second) to hear something back. So, once it hears something back, it reports how much time (like mSeconds).

So, if you want to know the DISTANCE, then you divide by the speed, that’s why.

Helpful?

ATB


#13

I think the motor controller sends a constant signal to drive the motors, so you need to tell it when to stop. The delay is used to control for how long the motors spin. The pwmTimeout variable was going to be used to control for how long the robot moves in a direction, but that’s not actually used in the Part 1 code. It’s not until the end of the UDP section in Part 2 that pwmTimeout gets used to turn off the motors after a specified time.


#14

let me be clear, im no programmer, im just playing around with what i understand and attempting to make it work

i had a semi working code (taolin code from Jan 17) going but lost the copy to cntrl+c after i uploaded and didnt save, and had a restart occur on my pc.

i contemplated not changing it but felt it necessary to try to give the detection some personality, or make it appear so.

im hoping to introduce a “long randNum = random(3)” to introduce a few options, such as

if random is equal to 1 goleft
equal to 2 goright
(ill have to add a function here for next one)
equal to 3 go180
that would be more amusing than a constant right turn.

also id like to add that i had to remove obstacleDetection from every function except goForward, in addition, i had to call goRight, goLeft, and goBack above the loop function or it didnt work

any other ideas coming put of the communities?


#15

i managed to reassemble the code. my left offset is 9 so take note there, still trying to cipher put how to utilize random function to make wifi robot not be so predictable

i didnt remove detection from left because it still hasnt been utilized

it just occured to me that the code looks atrocious, i clearly have no idea how to make text work properly here,

#edit:
cleaned the code up a bit. i made some comments to explain what i did and the line spacing will be off, hopefully to attract your eye, and after further comparison to the preview, im just overwhelmed trying to make the code appear as though youre looking at it inside arduino, so here it is


#16

When running the code to print distance from the ultrasonic module to the serial logger, I was getting a bunch of question marks and random characters. To fix this, I changed the baud rate in the lower right corner of the serial logger to from “9600” to “115200” to match the rate in the code. After I did that, everything worked as expected.