0

I am new to Arduino and I am making a Walking Quadruped using BotBoarduino as microcontroller. I want to install an Ultrasonic Sensor HC-SR04 so that it will stop when an obstacle is detected. I have connected the sensor to Arduino UNO. RX-TX of both the boards are cross-connected. Now I have written this code for UNO:

const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distance;

void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(9600); // Starts the serial communication
}

void loop() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(100);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance= duration*0.034/2;
  // Prints the distance on the Serial Monitor
  Serial.println(distance);

  delay(200);
}

And I am doing this on BotBoarduino:

int byteRead;

void setup(){
  Serial.begin(9600);
}

void loop() {
  while (Serial.available()) 
  {
    byteRead = Serial.read();     
  }

  if(byteRead >= 10)
  {
    walk(); 
  }
  else
  { 
    stand();
  }
}

Whenever distance = 10 or above, let it walk. Else stop.

But it's not working. It's not stopping on obstacles. Sensor is doing its work perfectly, but I think Botboarduino is not getting the values.

Any idea guyz?

  • you need to look at the output of your Serial.println and what you are receiving in, if the distance is 40 it is printing a '4' and a '0' then you are reading in a single byte, which would give you an ascii 4 which in decimal is 34 so you will never get a byte that is less then 10 (0-10 are all non printable characters) – Chad G Apr 5 '18 at 20:32
1

You have a misconception, how the Serial interface works.

The Serial interface is basically a stream of bytes (and sometimes start/stop and parity bits, which you normally don't care about) without any structure. This has to be implemented by you.

Also you have to understand, that you don't and cannot know, when a specific byte actually is being send. The fact that you typed a complete string into the serial monitor (or send a string via one call for Serial.println()) does NOT mean, that they are transmitted as a complete packet. The bytes of the string are send one after another and there may be a short delay between two arbitrary bytes. So with your reading while() loop, you are reading bytes until there is a delay long enough for the microcontroller to notice or until the message is send complete. You cannot know, which is the case for this very specific transaction. Also it seems odd, that you are only using the last read byte in your code, since the variable byteRead is overwritten on every while() loop cycle.

Then there is the format, in which you can send data through Serial.

  1. Binary data: Since it is a byte stream, you can directly use the binary values of the bytes to reflect the data. This is easy and good for cases, in which only one value of the size of one byte is transfered every time. So there is no need to distinguish between different parts of the message. In this case you have to use Serial.write() on your sending end. This will write binary data. (You will not be able to see the values in your serial monitor, since it is displaying only ASCII-encoded characters).
  2. ASCII-encoded data string: You are using Serial.println(), which sends an ASCII-encoded string representing the data followed by a NEWLINE character ('\n'). In case of the value 10 you are currently sending 3 bytes: '1', '0', '\n'. In this method, you are using a delimiter character (in this case '\n') to mark the end of a message. On the receiving end you have to read all bytes into a buffer, until you are receiving the delimiter character. Then you can process the message as a whole. In your case you would convert the ASCII-encoded string into an integer variable (for example with the function atoi())

To exactly explain, what is happening with your code: As Chad wrote in his comment, you are trying to use the binary value of a byte, that is an ASCII-encoded character. When looking at an ASCII table, you can see, that there is no printable character with a binary value under 10. So, since you send only printable characters with Serial.println(), There will never be a value, that is under 10.

So now you have 2 options:

  1. Send the variable as binary data in one (!!!) byte (since you are not using distances as big as 255cm the value can fit in there; just make sure, that the byte variable does not roll over) and use every read byte on the receiving end for your code.
  2. Send the variable as ASCII-encoded data with Serial.println() and do the correct processing of the resulting message on the receiving end. Refer to the Serial examples in the Arduino IDE for this. You can directly integrate their code into yours.
  • Thanks! I just changed Serial.println(distance) to Serial.write(distance). Now it is sending the exact value. – Sammy Apr 6 '18 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.