Question about the serial communication

Hello everyone,

I am currently working on a hexapod, which is programmed by an Arduino Mega 2560 controller. I am trying to control its walking with a serial communication, which means that, when I send it a 8 for instance, it will understand that it has to move up, or when I send it a 5, it has to stand up. The problem I have is to know on which port I have to work. I am currently using two ports of my Arduino shield : the first one controls the right side of the robot, when the left one controls the left one. So I do not see clearly on which port I have to read, which means do I have to write Serial1.read(), Serial2.read() or just Serial.read() ?

Here is a part of the code (don't mind the part about the move stuff, all the methods are defined in libraries)

void setup(){
  Serial.begin(115200); //For printing out data, or debugging.
  Serial2.begin(115200); // Used for control servos on left side.
  Serial1.begin(115200);// Used for control servos on right side.
  Serial.println("Write 5 to stand up and 8 to move up");
}

void loop(){
  if (Serial.available())
  {
    code = int(Serial.read());
    if (code == 5)
    {
      console.Move(legs, 3, 170, 511); //Legs move to 170 for standing up
      console.Move(legsbas, 3, 50, 511);
      console.Move(hips, 6, 480, 511); // hips move to 480 for standing up
      console.Move(hipsbas, 1, 280, 511);
      console.Move(hipshaut, 1, 580, 511);
      console.Move(axisA, 2, 0, 1); // axis group A move to 130. Prepare for walking
      console.Move(axisC, 1, 0, 1);
      console.Move(axisB, 3, 0, 1); // axis group B move 70. Prepare for walking
      Serial.print("The robot is standing up");
    }

If someone could give me a clue about the way of resolving it, I would be very grateful.

Wednesday: So I do not see clearly on which port I have to read, which means do I have to write Serial1.read(), Serial2.read() or just Serial.read() ?

Serial.read() reads from Serial Port0, TX0/RX0, (aka the USB port) Serial1.read() reads from Serial Port1, TX1/RX1 Serial2.read() reads from Serial Portt2, TX2/RX2

The serial ports are clearly marked on the silk screen of the board, so you should be able to "see" which port is connected to your "left" and "right".

I am currently using two ports of my Arduino shield

Why not use 1 port then 8L would control the left and 8R would control the right.

LarryD : because it is not compatible with the functioning of the servo driver boards I am using for my project.

James : thanks for your answer ! I now know precisely with which port I have to interact. The problem is that I did a new test to see if there was some bytes available in the USB port. Here is my test.

void setup(){
  Serial.begin(115200); //For printing out data, or debugging.
  Serial2.begin(115200); // Used for control servos on left side.
  Serial1.begin(115200);// Used for control servos on right side.
  Serial.println("Entrez 5 pour passer en position de mouvement ou 8 pour avancer");
}

void loop(){
  if (Serial.available() > 0)
  {
    code = int(Serial.read());
    if (code == 5)
    {
      console.Move(legs, 3, 170, 511); //Legs move to 170 for standing up
      console.Move(legsbas, 3, 50, 511);
      console.Move(hips, 6, 480, 511); // hips move to 480 for standing up
      console.Move(hipsbas, 1, 280, 511);
      console.Move(hipshaut, 1, 580, 511);
      console.Move(axisA, 2, 0, 1); // axis group A move to 130. Prepare for walking
      console.Move(axisC, 1, 0, 1);
      console.Move(axisB, 3, 0, 1); // axis group B move 70. Prepare for walking
      Serial.print("Le robot marche");
    }
  else
  {
    Serial.print("BUG");
  }

After that, I opened the Serial Monitor and entered a random value. It then returned me "BUG". Does it mean that this is not possible to send message to the arduino ?

When you entered a random value what would the value of the code variable be ? If it is not 5 then I am not surprised that all you got was “BUG” printed in the serial monitor.

It gives the same result if I enter 5

Try printing the value of code when you enter a 5. What do you get ?

I tried by adding this line

code = int(Serial.read());
    Serial.print(code);

And when I entered 5 in the serial monitor, it sent me "53BUG". Also, I tried with other values, and it always prints me "(code+48)BUG". Don't know why it adds 48 to the value I entered.

http://www.asciitable.com/

Look at the decimal value for '5'. You're not sending it 5, you're sending it '5'.

Wednesday: I tried by adding this line

code = int(Serial.read());
    Serial.print(code);

And when I entered 5 in the serial monitor, it sent me "53BUG". Also, I tried with other values, and it always prints me "(code+48)BUG". Don't know why it adds 48 to the value I entered.

Just what I expected. Do a Google search for ASCII codes and you will see what is going on.

Thanks you so much for your answer ! It now gives me the right value.

The last problem I encounter is about the loop function. Here is my code as it currently looks.

void setup(){
  Serial.begin(115200); //For printing out data, or debugging.
  Serial2.begin(115200); // Used for control servos on left side.
  Serial1.begin(115200);// Used for control servos on right side.
  Serial.println("Enter 5 to stand up or 8 to move up");
}

void loop(){
  if (Serial.available() > 0)
  {
    code = Serial.read();
    Serial.print(code);
    if (code == '5')
    {
      console.Move(legs, 3, 170, 511); //Legs move to 170 for standing up
      console.Move(legsbas, 3, 50, 511);
      console.Move(hips, 6, 480, 511); // hips move to 480 for standing up
      console.Move(hipsbas, 1, 280, 511);
      console.Move(hipshaut, 1, 580, 511);
      console.Move(axisA, 2, 0, 1); // axis group A move to 130. Prepare for walking
      console.Move(axisC, 1, 0, 1);
      console.Move(axisB, 3, 0, 1); // axis group B move 70. Prepare for walking
      Serial.print("The robot is standing up");
    }

    if (code == '8')
    {
      Serial.print("Le robot is moving up");
      while(1){
        console.MoveUp(hipB, 3, 100, 500); //hips group B move up 100
        console.MoveUp(axisB, 3, 60, 300);// axis group B move forward 60
        console.MoveDown(axisA, 2, 60, 300);// axis group A move backward 60
        delay(500);// waits for movement
        console.MoveDown(hipB, 3, 100, 500);//hips group B move down 100
        delay(500);// waits for movement
        console.MoveUp(hipA, 3, 100, 500);//hips group A move up 100
        console.MoveDown(axisB, 3, 60, 300);// axis group B move backward 60
        console.MoveUp(axisA, 2, 60, 300);// axis group A move forward 60
        delay(500);// waits for movement
        console.MoveDown(hipA,3, 100, 500);//hips group A move down 100
        
                }
    }}}

When I run it on my Arduino and enter 5 on the serial monitor, it writes "5The robot is standing up", which means that it managed to read the whole code. However, it does not ask the hexapod to walk, as said in the code. My opinion is that it comes from the fact that the walking algorithm should be isolated in the loop function (here, I also included the if conditions), but I do not see where I should put the ifs. I tried to declare the loop function before and just calling it to ask him to stand up, but it didn't work.

Any idea about that ?

When I run it on my Arduino and enter 5 on the serial monitor, it writes “5The robot is standing up”, which means that it managed to read the whole code. However, it does not ask the hexapod to walk, as said in the code.

Which part of your code ‘asks the hexapod to walk’ ? Is it the portion that should be activated by

    if (code == '8')

Oh well, I did not express myself correctly. What I want to do is to ask the robot to stand up by sending him the char '5', which should activate this part :

{
      console.Move(legs, 3, 170, 511); //Legs move to 170 for standing up
      console.Move(legsbas, 3, 50, 511);
      console.Move(hips, 6, 480, 511); // hips move to 480 for standing up
      console.Move(hipsbas, 1, 280, 511);
      console.Move(hipshaut, 1, 580, 511);
      console.Move(axisA, 2, 0, 1); // axis group A move to 130. Prepare for walking
      console.Move(axisC, 1, 0, 1);
      console.Move(axisB, 3, 0, 1); // axis group B move 70. Prepare for walking
      Serial.print("The robot is standing up");
    }

When I did it, the Arduino correctly printed the last sentence, but the other functions did not have any effect on the hexapod, so I was wondering if I had to change the code so this part would be the only part of the loop function (it is how it worked in the program without the messages sent to the card)

Wednesday: so I was wondering if I had to change the code so this part would be the only part of the loop function (it is how it worked in the program without the messages sent to the card)

So if you take that set of code and put it in the loop statement, it does what you want without having to send it '5'? If so, then simply create a flag variable:

int flag = 0;

When you receive '5', set the flag:

if (code == '5')
{
  flag = 1;
  // other code if necessary
}

In your loop, run the code if the flag is set.

if (flag == 1)
{
  // move the robot
}

You then have to decide what will cause the robot to stop moving, and clear the flag when that condition occurs:

if (someConditionToStopIt)
{
  flag = 0;
}

Actually, the problem is that the card correctly prints the sentence in the serial monitor ("The robot is standing up"), but the previous lines, which are supposed to make the robot stand up, have no effect.

I tried to use your method with the flag, which gives me that :

char code = '0';
int flag = 5;
// servo controller 
ServoConsole console;

void setup(){
  Serial.begin(115200); //For printing out data, or debugging.
  Serial2.begin(115200); // Used for control servos on left side.
  Serial1.begin(115200);// Used for control servos on right side.
  Serial.println("Enter 5 to stand up or 8 to move up");
  if (Serial.available() > 0)
  {
    code = Serial.read();
    Serial.print(code);
    if (code == '5')
    {
       flag = 0;
    }

    if (code == '8')
    {
      flag = 1;
    }}}
    
void loop(){
  if (flag == 0)
  {
    console.Move(legs, 3, 170, 511); //Legs move to 170 for standing up
    console.Move(legsbas, 3, 50, 511);
    console.Move(hips, 6, 480, 511); // hips move to 480 for standing up
    console.Move(hipsbas, 1, 280, 511);
    console.Move(hipshaut, 1, 580, 511);
    console.Move(axisA, 2, 0, 1); // axis group A move to 130. Prepare for walking
    console.Move(axisC, 1, 0, 1);
    console.Move(axisB, 3, 0, 1); // axis group B move 70. Prepare for walking
    Serial.print("The robot is standing up");
  }
}

But then, when I tried to upload it on the arduino and to enter 5 on the serial monitor, nothing happened. Actually, the part which is bothering me is this one :

if (Serial.available() > 0)
  {
    code = Serial.read();
    Serial.print(code);
    if (code == '5')
    {
       flag = 0;
    }

    if (code == '8')
    {
      flag = 1;
    }}

The problem is that I don't know in which function I have to put it. When I tried to put it in the setup function, nothing happened (although it was supposed to print code's value), and when I tried with putting it in the loop function, it just printed "5The robot is standing up" again and again.

I think that the programming itself is correct, but that there are some flaws, which I do not see clearly, in the structure.

What libraries are you using ? Where are the parameters to console.Move() defined ?

Try this

void setup(){
  Serial.begin(115200); //For printing out data, or debugging.
  Serial2.begin(115200); // Used for control servos on left side.
  Serial1.begin(115200);// Used for control servos on right side.

  console.Move(legs, 3, 170, 511); //Legs move to 170 for standing up
  console.Move(legsbas, 3, 50, 511);
  console.Move(hips, 6, 480, 511); // hips move to 480 for standing up
  console.Move(hipsbas, 1, 280, 511);
  console.Move(hipshaut, 1, 580, 511);
  console.Move(axisA, 2, 0, 1); // axis group A move to 130. Prepare for walking
  console.Move(axisC, 1, 0, 1);
  console.Move(axisB, 3, 0, 1); // axis group B move 70. Prepare for walking
}

void loop()
{
}

Does the bot stand up ?

I am using libraries, which were attached with the robot kit. As the parameters, I define them at the beginning of the code, just before the setup function.

#include <SoftwareSerial.h>
#include <ServoConsole.h>
#include <Hexapod_Servo.h>
#include <CDS5500_2Serials.h>
#include <Arduino.h>

int axisA[] = {0, 20, 40};
int axisC[] = {20};
int axisB[] = {10, 30, 50};
int axis[] = {0, 10, 30, 40, 50};
int hipA[] = {1, 21, 41};
int hipB[] = {11, 31, 51};
int legA[] = {2, 22, 32};
int legB[] = {12, 32, 52};
int axis2[] = {20, 30, 40, 50};
int axishaut[] = {0, 10};
int hips[] = {1, 11, 41, 51};
int hipsbas[] = {31};
int hipshaut[] = {21};
int legs[] = {2, 12, 42};
int legsbas[] = {22, 32, 52};
char code = '0';

About the code you gave me, I tried it and the bot worked perfectly. But I do not see where the problem comes from. The if condition about the Serial.available works fine, as the one about the code, because when I tried to upload it and enter ‘5’ in the serial monitor, it printed the last sentence (“The robot is standing up”). So it means that he does read the Move functions, but they do not have any effect on the bot.