Go Down

Topic: Leer palabra y hacer menú 100 casos? (Read 551 times) previous topic - next topic

radicalpepo

Hola chicos,
Tengo que recurrir a vosotros dado que mis conocimientos no son muy buenos en arduino.
La idea que tengo es desde una app en android pulsar botones o seleccionar de una lista y que se envie una palabra, dicha palabra dependiendo de lo que es que me haga una cosa u otra el arduino,. Serían alrededor de 100 palabras distintas, como puedo hacer el código en Arduino?
La parte de Android la tengo más o menos vista.
Gracias saludos

surbyte

Android y arduino se comunican por Bluetooth o por Internet. Tu elige y de ahi como seguir.

radicalpepo

En un principio por bluetooth, al pulsar un botón en la app que mande una palabra y el arduino que busque entre unos 100 casos y el caso que tenga esa palabra realice unas acciones.

surbyte

Usar BT es como usar el Monitor Serie para enviarle comandos asi que puedes probar con el enviando mensajes y que Arduino los reciba y haga lo que deba hacer.

Ahora el siguiente paso es que tienes 100 palabras. Bueno eso no es problema para Arduino. Se pueden almacenar en memoria flash para no consumir RAM.

Hagamos una lista con 10 palabras  y luego tu lo expandes a las otras 90.

Te daré dos ejemplos uno estilo sin Strings y otro con Strings. cual es el problema? que los Strings si no se usan bien suelen dar problemas pero no nos ocupemos de eso ahora.

Sin strings

Code: [Select]

#define CMDBUFFER_SIZE 32

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

void loop()
{
 
}
void serialEvent()
{
 static char cmdBuffer[CMDBUFFER_SIZE] = "";
 char c;
 while(Serial.available())
 {
   c = processCharInput(cmdBuffer, Serial.read());
   Serial.print(c);
   if (c == '\n')
   {
     Serial.println();
     //Full command received. Do your stuff here!
     if (strcmp("HELLO", cmdBuffer) == 0)
     {
        Serial.println("\r\nYou typed hello!");
     }
     cmdBuffer[0] = 0;
   }
 }
 delay(1);
}

char processCharInput(char* cmdBuffer, const char c)
{
 //Store the character in the input buffer
 if (c >= 32 && c <= 126) //Ignore control characters and special ascii characters
 {
   if (strlen(cmdBuffer) < CMDBUFFER_SIZE)
   {
     strncat(cmdBuffer, &c, 1);   //Add it to the buffer
   }
   else 
   {   
     return '\n';
   }
 }
 else if ((c == 8 || c == 127) && cmdBuffer[0] != 0) //Backspace
 {

   cmdBuffer[strlen(cmdBuffer)-1] = 0;
 }

 return c;
}


El segundo caso es con String

Code: [Select]

//zoomkat 3-5-12 simple delimited ',' string parce
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like wer,qwe rty,123 456,hyre kjhg,
  //or like hello world,who are you?,bye!,
 
  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      //do stuff
      Serial.println(readString); //prints string to serial port out
      readString=""; //clears variable for new input     
     } 
    else {     
      readString += c; //makes the string readString
    }
  }
}


Una vez que tienes el valor en la variable readString simplemente lo comparas asi

Code: [Select]
if (readString == "Hola") {
   // Accion
}



Yo pondría las 100 palabras en un vector de modo que se puedan comparar dentro de un ciclo.


radicalpepo

Buenas,
Entiendo que cuando dices con vectores que use:
"string vector[5] = {"5", "hola", "2.7", "8,9", "adios"};"
Pero como lo intengro en el codigo exactaemnte?
gracias saludos

surbyte

Ahh bueno, ya entendiste los dos códigos que sugerí?

Pues como te dije, dentro de un cliclo for, lo vas barriendo por índice.
El vector tiene un índice que identifica su elemento.

De tu ejemplo el
vector[0] es "5"
vector[1] es "hola"

por lo tanto si tu tienes un
Code: [Select]
for(byte i=0; i<5; i++) {
     if (readString == vector[i])
         valor = i;                      // este valor es el que te permite luego elegir que hacer
}


Con ese valor que previamente definiste como byte por supuesto.

Dentro de un switch case puedes controlar que hacer con cada palabra que resultó positiva a la comparación.
Habran 99 falsos y 1 positivo y arduino responderá a eso.

Ahora veo un programa algo grande de modo que cuidado con el arduino que uses y el consumo de memoria.

Desde ya que usar String vector[100] = {cada item} no es de mi agrado por el gran consumo en RAM.

Yo sugería que usaras PROGMEM.

Si no lo sabes es la opción que te da Arduino para guardar datos en la memoria FLASH y no consumir RAM.

radicalpepo

Buenas,
Muchas gracias por toda la ayuda que me prestas, Como se usaria PROGMEM?
Yo tengo un arduino mega.
saludos gracias

radicalpepo

#7
May 18, 2018, 04:02 pm Last Edit: May 18, 2018, 04:33 pm by surbyte
Buenas Adjunto el codigo que llevo echo hasta ahora.


Code: [Select]


#include <SoftwareSerial.h>
SoftwareSerial Bluetooth(2,3); // RX, TX Esto le decimos en que pines esta conectado el Bluetooth
                         //Cuando conecte el bluetooth pondre los pines donde lo conecte

int pin18 = 18;  //reserva
int pin19 = 19;  //reserva

int pin20 = 20;
int pin21 = 21;
int pin22 = 22;
int pin23 = 23;
int pin24 = 24;
int pin25 = 25;
int pin26 = 26;
int pin27 = 27;
int pin28 = 28;
int pin29 = 29;
int pin30 = 30;
int pin31 = 31;
int pin32 = 32;
int pin33 = 33;
int pin34 = 34;
int pin35 = 35;
int pin36 = 36;
int pin37 = 37;
int pin38 = 38;
int pin39 = 39;
int pin40 = 40;
int pin41 = 41;
int pin42 = 42;
int pin43 = 43;
int pin44 = 44;
int pin45 = 45;
int pin46 = 46;
int pin47 = 47;
int pin48 = 48;
int pin49 = 49;
int pin50 = 50;
int pin51 = 51;
int pin52 = 52;
int espera = 150; // El tiempo que se esperara

String dato = "";

void setup(){

for(int i=18;i<=52;i++){ //SE INICIALIZAN TODOS LOS PINES COMO SALIDA
 pinMode(i, OUTPUT);
}


//Inicializamos el valor de transmisión.
Serial.begin(9600);//Inicializamos el serial normal
Bluetooth.begin(9600); //inicializamos bluetooth

}

void loop() {
//INICIALIZAMOS TODOS LOS PINES COMO APAGDOS
    for (int i= 18; i<=52; i++)
     {
    digitalWrite(i,LOW);
     //delay(500);
     }
//Declaramos un sentencia, Mientras el puerto Serial este disponible se empieza el ciclo

while (Bluetooth.available())
 {
  

   String dato = Bluetooth.readStringUntil('\n');
   switch ('dato'){
   case 'dato' == 'A.ON' ; //Si en el caso de ser A.ON la varible enviada, entonces
      {
       digitalWrite(pin20,HIGH);
       }
       break;
      
   case 'dato' == 'A.OFF' ; //Si en el caso de ser A.OFF la variable enviada, entonceS
     {
       digitalWrite(pin20,LOW);
     }
       break;

  
//escribimos los demas casos!


   }
 }
}

surbyte

Code: [Select]
switch ('dato'){
   case 'dato' == 'A.ON' ; //Si en el caso de ser A.ON la varible enviada, entonces



'dato' no puede ser un elemento dentro de switch()
switch() espera una variable que toma estados enteros.

case 'dato' tampoco puede ser y menos esto

Code: [Select]
   case 'dato' == 'A.ON'


Los strings van entre "" o sea algo mas apropiado sería "A.ON" pero aún asi esta mal

Te expliqué como debes hacerlo.

Y toda duda que tengas solo pones en google : Arduino PROGMEM y sabrás como se usa.



surbyte

Prueba asi

Code: [Select]
#include <SoftwareSerial.h>
SoftwareSerial Bluetooth(2,3); // RX, TX Esto le decimos en que pines esta conectado el Bluetooth
                         //Cuando conecte el bluetooth pondre los pines donde lo conecte

int pin18 = 18;  //reserva
int pin19 = 19;  //reserva

int pin20 = 20;
int pin21 = 21;
int pin22 = 22;
int pin23 = 23;
int pin24 = 24;
int pin25 = 25;
int pin26 = 26;
int pin27 = 27;
int pin28 = 28;
int pin29 = 29;
int pin30 = 30;
int pin31 = 31;
int pin32 = 32;
int pin33 = 33;
int pin34 = 34;
int pin35 = 35;
int pin36 = 36;
int pin37 = 37;
int pin38 = 38;
int pin39 = 39;
int pin40 = 40;
int pin41 = 41;
int pin42 = 42;
int pin43 = 43;
int pin44 = 44;
int pin45 = 45;
int pin46 = 46;
int pin47 = 47;
int pin48 = 48;
int pin49 = 49;
int pin50 = 50;
int pin51 = 51;
int pin52 = 52;
int espera = 150; // El tiempo que se esperara
String vector[5] PROGMEM = {"A.ON", "A.OFF", "B.ON", "B.OOF", "OFF"};
String dato = "";

void setup(){
    for (int i=18;i<=52;i++){ //SE INICIALIZAN TODOS LOS PINES COMO SALIDA
        pinMode(i, OUTPUT);
    }
    //Inicializamos el valor de transmisión.
    Serial.begin(9600);//Inicializamos el serial normal
    Bluetooth.begin(9600); //inicializamos bluetooth
}

void loop() {
//INICIALIZAMOS TODOS LOS PINES COMO APAGDOS
  for (int i= 18; i<=52; i++)  {
      digitalWrite(i,LOW);
      //delay(500);
  }
  //Declaramos un sentencia, Mientras el puerto Serial este disponible se empieza el ciclo
  while (Bluetooth.available()) {
   
    String dato = Bluetooth.readStringUntil('\n');
    for (byte i = 0; i<5; i++) {
        if (dato == vector[i]) { // si coincide entonces i me dice que posicion coincidió
            valor = i;
        }
    }
  }
  switch (valor){
      case 0:   //Si en el caso de ser A.ON la varible enviada, entonces
                digitalWrite(pin20,HIGH);
                break;
      case 1:   //Si en el caso de ser A.OFF la variable enviada, entonceS
                digitalWrite(pin20,LOW);
                break;
      case 2:   //Si en el caso de ser B.ON la variable enviada, entonceS
                digitalWrite(pin21, HIGH);
                break;
      case 3:   //Si en el caso de ser B.OFF la variable enviada, entonceS
                digitalWrite(pin21,LOW);
                break;
      case 4:   //Si en el caso de ser OFF la variable enviada, entonceS
                digitalWrite(pin22,LOW);
                break;
  }
}

radicalpepo

#10
Jul 18, 2018, 10:42 am Last Edit: Jul 18, 2018, 08:44 pm by surbyte Reason: Agregado de etiquetas de código y errores.
Buenas, ya he retomado el proyecto,
Me esta dando errores y a ver si me puedes ayudar.
gracias

Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial Bluetooth(0,1); // RX, TX Esto le decimos en que pines esta conectado el Bluetooth
                          //Cuando conecte el bluetooth pondre los pines donde lo conecte


int pin18 = 18;  //reserva
int pin19 = 19;  //reserva

int pin20 = 20; //Defino los pines con nombres para poder diferenciar mejor
int pin21 = 21; //En vez de poner solo 21 ponemos pin21
int pin22 = 22; //asi sabemos que pin21 es la salida digital 21
int pin23 = 23;
int pin24 = 24;
int pin25 = 25;
int pin26 = 26;
int pin27 = 27;
int pin28 = 28;
int pin29 = 29;
int pin30 = 30;
int pin31 = 31;
int pin32 = 32;
int pin33 = 33;
int pin34 = 34;
int pin35 = 35;
int pin36 = 36;
int pin37 = 37;
int pin38 = 38;
int pin39 = 39;
int pin40 = 40;
int pin41 = 41;
int pin42 = 42;
int pin43 = 43;
int pin44 = 44;
int pin45 = 45;
int pin46 = 46;
int pin47 = 47;
int pin48 = 48;
int pin49 = 49;
int pin50 = 50;
int pin51 = 51;
int pin52 = 52;
int espera = 150; // El tiempo que se esperara

String vector[5] PROGMEM = {"A.ON", "A.OFF", "B.ON", "B.OOF", "OFF"};
String dato = "";

void setup(){

for(int i=18;i<=52;i++){ //SE INICIALIZAN TODOS LOS PINES COMO SALIDA
  pinMode(i, OUTPUT);
}

Serial.begin(9600);//Inicializamos el serial normal
Bluetooth.begin(9600); //inicializamos bluetooth

}

void loop() {
//INICIALIZAMOS TODOS LOS PINES COMO APAGDOS
     for (int i= 18; i<=52; i++)
      {
     digitalWrite(i,LOW);
      //delay(500);
      }
//Declaramos un sentencia, Mientras el puerto Serial este disponible se empieza el ciclo
while (Bluetooth.available())
  {
    
//Declaramos una variable de tipo cadena y Se lee lo enviado desde el Bluetooth.  
    String dato = Bluetooth.readStringUntil('\n'); //lee la cadena que enviamos por bluetooth
    for (byte i = 0; i<5; i++) {
        if (dato == vector[i]) { // si coincide entonces i me dice que posicion coincidió
            valor = i;
        }
    }

    
    
    
    
    
    switch (valor){
    case 'dato' == "A.ON"; //Si en el caso de ser A.ON la varible enviada, entonces:
       {
        digitalWrite(pin20,HIGH);
        }
        break;
    case 'dato' == "A.OFF"; //Si en el caso de ser A.OFF la variable enviada, entonceS:
      {
        digitalWrite(pin20,LOW);
      }
        break;

    
//seguir todos los casos como entradas tengamos


    }
  }
}


radicalpepo

#11
Jul 26, 2018, 04:08 pm Last Edit: Jul 26, 2018, 05:06 pm by surbyte
Buenas,
Muchas gracias por la alternativa, pero no me valdría esa forma te explico porque.
Yo quiero manejar 32 reles, 2 placas de 16 cada una.
Por un lado lo que tengo en la APP de android son 32 botones, al presionar una vez se enciende el rele y al presionar mas largo se apaga, enviando un valor desde android por ejemplo una palabra (A.ON), hasta ahí bien.
Pero luego en otra sección voy a tener una lista de "funciones" por llamarlo así, es decir que yo selecciono 1 y envío una palabra al arduino y este que se vaya al caso que es y que encienda o apague varios rales a la vez.

Por eso creo que este método no me valdría.
gracias

radicalpepo

#12
Jul 26, 2018, 04:16 pm Last Edit: Jul 26, 2018, 05:06 pm by surbyte
Buenas tengo este código, y me da el siguiente error, a ver si me podeis ayudar.
Muchas gracias Saludos

Code: [Select]
Arduino:1.6.13 (Mac OS X), Tarjeta:"Arduino/Genuino Uno"

In file included from /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:28:0,
                 from sketch/Proyecto_Skoda_Octavia21-03-18.ino.cpp:1:
Proyecto_Skoda_Octavia21-03-18:48: error: variable 'vector' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 String vector[5] PROGMEM = {"A.ON", "A.OFF", "B.ON", "B.OFF", "C.OFF"};
                  ^
/Users/kirilpetrov/Documents/Arduino/Proyecto_Skoda_Octavia21-03-18/Proyecto_Skoda_Octavia21-03-18.ino: In function 'void loop()':
Proyecto_Skoda_Octavia21-03-18:118: error: 'valor' was not declared in this scope
             valor = i;
             ^
Proyecto_Skoda_Octavia21-03-18:127: error: 'valor' was not declared in this scope
     switch (valor){
             ^
Proyecto_Skoda_Octavia21-03-18:128: error: call to non-constexpr function 'unsigned char String::operator==(const char*) const'
     case dato == "A.ON"; //Si en el caso de ser A.ON la varible enviada, entonces:
               ^
Proyecto_Skoda_Octavia21-03-18:128: error: call to non-constexpr function 'unsigned char String::operator==(const char*) const'
Proyecto_Skoda_Octavia21-03-18:128: error: expected ':' before ';' token
     case dato == "A.ON"; //Si en el caso de ser A.ON la varible enviada, entonces:
                        ^
Proyecto_Skoda_Octavia21-03-18:133: error: call to non-constexpr function 'unsigned char String::operator==(const char*) const'
     case dato == "A.OFF"; //Si en el caso de ser A.OFF la variable enviada, entonceS:
               ^
Proyecto_Skoda_Octavia21-03-18:133: error: call to non-constexpr function 'unsigned char String::operator==(const char*) const'
Proyecto_Skoda_Octavia21-03-18:133: error: expected ':' before ';' token
     case dato == "A.OFF"; //Si en el caso de ser A.OFF la variable enviada, entonceS:
                         ^
exit status 1
variable 'vector' must be const in order to be put into read-only section by means of '__attribute__((progmem))'

Este reporte podría tener más información con
"Mostrar salida detallada durante la compilación"
opción habilitada en Archivo -> Preferencias.


Adjunto el código completo.

Code: [Select]


#include <SoftwareSerial.h>
SoftwareSerial Bluetooth(0,1); // RX, TX Esto le decimos en que pines esta conectado el Bluetooth
                          //Cuando conecte el bluetooth pondre los pines donde lo conecte


int pin18 = 18;  //reserva
int pin19 = 19;  //reserva

int pin20 = 20; //Defino los pines con nombres para poder diferenciar mejor
int pin21 = 21; //En vez de poner solo 21 ponemos pin21
int pin22 = 22; //asi sabemos que pin21 es la salida digital 21
int pin23 = 23;
int pin24 = 24;
int pin25 = 25;
int pin26 = 26;
int pin27 = 27;
int pin28 = 28;
int pin29 = 29;
int pin30 = 30;
int pin31 = 31;
int pin32 = 32;
int pin33 = 33;
int pin34 = 34;
int pin35 = 35;
int pin36 = 36;
int pin37 = 37;
int pin38 = 38;
int pin39 = 39;
int pin40 = 40;
int pin41 = 41;
int pin42 = 42;
int pin43 = 43;
int pin44 = 44;
int pin45 = 45;
int pin46 = 46;
int pin47 = 47;
int pin48 = 48;
int pin49 = 49;
int pin50 = 50;
int pin51 = 51;
int pin52 = 52;
int espera = 150; // El tiempo que se esperara


String vector[5] PROGMEM = {"A.ON", "A.OFF", "B.ON", "B.OFF", "C.OFF"};


String dato = "";

void setup(){

for(int i=18;i<=52;i++){ //SE INICIALIZAN TODOS LOS PINES COMO SALIDA
  pinMode(i, OUTPUT);
}
/*
pinMode(18, OUTPUT); //Reserva ESTA SERIA LA FORMA CORRECTA Y  NO LA DE ABAJO
pinMode(19, OUTPUT); //Reserva

pinMode(pin20, OUTPUT); // Definimos los PINES como salida
pinMode(pin21, OUTPUT);
pinMode(pin22, OUTPUT);
pinMode(pin23, OUTPUT);
pinMode(pin24, OUTPUT);
pinMode(pin25, OUTPUT);
pinMode(pin26, OUTPUT);
pinMode(pin27, OUTPUT);
pinMode(pin28, OUTPUT);
pinMode(pin29, OUTPUT);
pinMode(pin30, OUTPUT);
pinMode(pin31, OUTPUT);
pinMode(pin32, OUTPUT);
pinMode(pin33, OUTPUT);
pinMode(pin34, OUTPUT);
pinMode(pin35, OUTPUT);
pinMode(pin36, OUTPUT);
pinMode(pin37, OUTPUT);
pinMode(pin38, OUTPUT);
pinMode(pin39, OUTPUT);
pinMode(pin40, OUTPUT);
pinMode(pin41, OUTPUT);
pinMode(pin42, OUTPUT);
pinMode(pin43, OUTPUT);
pinMode(pin44, OUTPUT);
pinMode(pin45, OUTPUT);
pinMode(pin46, OUTPUT);
pinMode(pin47, OUTPUT);
pinMode(pin48, OUTPUT);
pinMode(pin49, OUTPUT);
pinMode(pin50, OUTPUT);
pinMode(pin51, OUTPUT);
pinMode(pin52, OUTPUT);
*/

//Inicializamos el valor de transmisión.
Serial.begin(9600);//Inicializamos el serial normal
Bluetooth.begin(9600); //inicializamos bluetooth

}

void loop() {
//INICIALIZAMOS TODOS LOS PINES COMO APAGDOS
     for (int i= 18; i<=52; i++)
      {
     digitalWrite(i,LOW);
      //delay(500);
      }
//Declaramos un sentencia, Mientras el puerto Serial este disponible se empieza el ciclo
while (Bluetooth.available())
  {
    
//Declaramos una variable de tipo cadena y Se lee lo enviado desde el Bluetooth.  
    String dato = Bluetooth.readStringUntil('\n'); //lee la cadena que enviamos por bluetooth
    for (byte i = 0; i<5; i++) {
        if (dato == vector[i]) { // si coincide entonces i me dice que posicion coincidió
            valor = i;
        }
    }

    
    
    
    
    
    switch (valor){
    case dato == "A.ON"; //Si en el caso de ser A.ON la varible enviada, entonces:
       {
        digitalWrite(pin20,HIGH);
        }
        break;
    case dato == "A.OFF"; //Si en el caso de ser A.OFF la variable enviada, entonceS:
      {
        digitalWrite(pin20,LOW);
      }
        break;

    
//seguir todos los casos como entradas tengamos


    }
  }
}


surbyte

Entiendo que no sepan inglés pero todos estudiamos un inglés básico en los colegios siempre o casi siempre.

Entonces esto

Code: [Select]
Proyecto_Skoda_Octavia21-03-18:48: error: variable 'vector' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
 String vector[5] PROGMEM = {"A.ON", "A.OFF", "B.ON", "B.OFF", "C.OFF"};


No puede creer que requiere una pregunta?

Enfatizo como digo @ArduMyth

Code: [Select]
error: variable 'vector' must be const in order to be put into read-only section by means of __attribute__((progmem))'

Ahi debes ver el problema y para mas datos no esta al final


Go Up