Enums and Serial.Read problem

Hello I have the problem below and I would ask for your help

  1. I have an Android device which, with the help of the OTG, communicates serial with Arduino.
    In the Android device program have been declared Enum (for example
    enum mytype {
    hello,
    surprise,
    joy,
    sadness,
    sleep
    };

one of the above I want to send with the serial to arduino.

  1. in the arduino program I have declare the same as above
    plus
    mytype dance=hello;

when I do compilation this error appears

while (Serial.available() > 0) {
dance = Serial.read

margarita_final_enums:194: error: cannot convert 'HardwareSerial::read' from type 'int (HardwareSerial::)()' to type 'mytype'

What am I doing wrong?

sorry for my English

Thanks Nektarios

What am I doing wrong?

You posted only a snippet of the Arduino code.

So, I'll post a snippet of an answer.

You need to...

varaderos:
enum mytype {
hello,
surprise,
joy,
sadness,
sleep
};

An enum just associates the numbers 0, 1, 2 etc with the labels in it.

...R

#include <Servo.h>

Servo Servo1;
Servo Servo2;
Servo Servo3;
Servo Servo4;

enum mytype {
geia,
geia_sou,
surprise,
joy,
sadness,
wave,
wave2,
sleep
};

mytype dance=geia;

int s

void setup(){
Serial.begin(115200);
Servo1.attach(1);
Servo2.attach(2);
Servo3.attach(3);
Servo4.attach(4);

zero();
}

//===========================
void zero(){
delay(10);
Servo1.write(30);
delay(10);
Servo2.write(30);
delay(10);
Servo3.write(30);
delay(10);
Servo4.write(30);
delay(2000);
}

void sub_geia()
{
for( s=1; s<=2; s++){
delay(10);
Servo2.write(180);
delay(10);
Servo3.write(180);
delay(2000);
zero();
} //end for
} //end void

void sub_geia_sou()
{
for( s=1; s<=3; s++){
delay(10);
Servo3.write(180);
delay(2000);
zero();
} //end for
}//end void

void sub_surprise() {
delay(10);
Servo1.write(1);
delay(10);
Servo2.write(1);
delay(10);
Servo3.write(1);
delay(10);
Servo4.write(1);
delay(2000);
zero();

}//end void

void sub_joy()
{
for( s=1; s<=3; s++){
delay(10);
Servo1.write(180);
delay(10);
Servo4.write(180);
delay(1500);
Servo1.write(1);
delay(10);
Servo4.write(1);
delay(1500);
} //end for
zero();
}//end void

void sub_sadness()
{
delay(10);
Servo1.write(180);
delay(10);
Servo2.write(180);
delay(10);
Servo3.write(180);
delay(10);
Servo4.write(180);
delay(1500);
Servo1.write(100);
delay(10);
Servo2.write(100);
delay(10);
Servo3.write(100);
delay(10);
Servo4.write(100);
delay(3000);
zero();

}//end void

void sub_wave()
{
for( s=1; s<=2; s++){
delay(10);
Servo1.write(180);
delay(500);
Servo2.write(180);
delay(500);
Servo3.write(180);
delay(500);
Servo4.write(180);
delay(500);
Servo4.write(0);
delay(500);
Servo3.write(0);
delay(500);
Servo2.write(0);
delay(500);
Servo1.write(0);
delay(500);
zero();
} //end for
}//end void

void sub_wave2() {
for( s=1; s<=2; s++){
delay(10);
Servo1.write(180);
delay(500);
Servo2.write(180);
delay(500);
Servo3.write(180);
delay(500);
Servo4.write(180);
delay(1000);
zero();
} //end for
}//end void

void sub_sleep()
{
delay(10);
Servo1.write(180);
delay(10);
Servo2.write(180);
delay(10);
Servo3.write(180);
delay(10);
Servo4.write(180);
while (Serial.available() == 0) {
}

zero();

}//end void

//=============

void loop(){

while (Serial.available() > 0) { //Όταν η σειριακή θύρα δέχεται τιμές τότε
dance = Serial.read
if(dance == geia) {
sub_geia();
}
else if(dance == geia_sou) {
sub_geia_sou();
}
else if(dance == surprise) {
sub_surprise();
}
else if (dance == joy) {
sub_joy();
}
else if (dance == sadness) {
sub_sadness();
}
else if (dance == wave) {
sub_wave();
}
else if (dance == wave2) {
sub_wave2();
}
else if (dance == sleep) {
sub_sleep();
Serial.read();
}

delay(1000);
} // end while

} //end void Loop

this is my code
I want to get from the Android device an enum price and depending on the price I get at Arduino I will move my servos

Delta_G:

dance = Serial.read

First off, read needs the parenthesis if you intend to call that function.

Second, you'll have to read from serial into an int or a char type and then decide based on that what value from the enum to give dance. There's no free conversion from int to an enum type.

it is easy to give me a small example?

varaderos:
it is easy to give me a small example?

Robin2 has a very good serial handling basics tutorial.

you'll have to read from serial into an int or a char type and then decide based on that what value from the enum to give dance.

it is easy to give me a small example?

command = Serial.read();
if (command == dance)
{
  //code here for dance command
}

You can explicitly cast an int to an enum type. Before (c++12 I think), the compiler can do implicitly do it.

dance = (mytype)Serial.read();

Beware that this casting is unsafe in that the int value will be wrapped around.[/code][/code]

dance = (mytype)Serial.read();

How is that useful if the original enum has assigned say 1 to dance and then you read a 2 and assign it to dance ?

UKHeliBob:

dance = (mytype)Serial.read();

How is that useful if the original enum has assigned say 1 to dance and then you read a 2 and assign it to dance ?

enum mytype {
 geia,
 geia_sou,
 surprise,
 joy,
 sadness,
 wave,
 wave2,
  sleep
};

mytype dance=geia;

dance will assume the value of "geia_sou" if it's assigned a 1.

UKHeliBob:

dance = (mytype)Serial.read();

How is that useful if the original enum has assigned say 1 to dance and then you read a 2 and assign it to dance ?

when I write it in this way it passes compilation

what is the problem that I can encounter?

Thanks

varaderos:
when I write it in this way it passes compilation

what is the problem that I can encounter?

Thanks

The problem is that if you assign it an invalid value (say a 10), it will wrap around and become "surprise". This is considered unsafe because the program is not doing what the programmer's expecting.

Delta_G:
@UKHB

Read the code again. dance isn't one of the enum values. It's a variable name.

OK, so dance is a variable and not a member of the enum. My mistake

But I still don't see how this is useful. By casting it to mytype it will have the same value as one of the enum values but you won't know which one without testing it. It sounds like can of worms to me.

both programs (android and arduino) have been declared the same Enums
so that we do not have mistakes in communication
besides, you think there is a possibility that there may be mistakes?

thank you for your answers Nektarios

Serial Input Basics - simple reliable ways to receive data.

...R

Robin2:
Serial Input Basics - simple reliable ways to receive data.

...R

Thank you for your help

varaderos:
both programs (android and arduino) have been declared the same Enums
so that we do not have mistakes in communication
besides, you think there is a possibility that there may be mistakes?

thank you for your answers Nektarios

Yes, an enum on android is default to an int which is 4-byte.
an enum on arduino is default to an int which is 2-byte(on UNO at least)
Serial.read() only read 1 byte.

So there are 2 ways to fix these: You must either

  1. Read the whole message (multiple bytes) before casting and testing it.
    or
  2. Reduce the size of enum to 1-byte, on arduino you can do this:
enum mytype: char {
...
};

arduino_new:
Yes, an enum on android is default to an int which is 4-byte.
an enum on arduino is default to an int which is 2-byte(on UNO at least)
Serial.read() only read 1 byte.

So there are 2 ways to fix these: You must either

  1. Read the whole message (multiple bytes) before casting and testing it.
    or
  2. Reduce the size of enum to 1-byte, on arduino you can do this:
enum mytype: char {

...
};

very good explanation thank you

@varaderos, Let's go back to basics.

Is it really necessary to send the ENUM values?

At the moment this is a typical XY problem.

Tell us what you are trying to achieve and someone can probably suggest some simple solution.

...R

Delta_G:

  1. Serial.read returns an int, not a byte.

  2. The numbers we're dealing with in this code would all fit just fine in a single int.

No. read() only consume 1 byte. It returns an int to signal an error (-1).
read() does not read an int.