Cómo leer varios datos por puerto serie de un Arduino uno?

buenos dias, soy nuevo en cuanto a programacion de arduino aunque me gusta la plataforma, como sea hace poco me pregunte como un brazo robotico de uno de los laboratorios podia moverse en linea recta coordinando sus articulaciones, poco despues descubri que era un principio de cinematica inversa, mi duda radica en que requiero enviar varios valores en grados por el puerto usb a un arduino pero no se como empaquetarlos y desempaquetarlos por poner un ejemplo

se envia desde sharp develop por el puerto serie la siguiente cadena de numeros "3020" donde el primer numero seria el valor en grados del primer servo y los 2 digitos siguientes del segundo,como seria la programacion para separar la cadena o si alguien me presentace una mejor idea se lo agradeceria, perdon si la informacion es un poco impresisa pero soy bastante nuevo en el tema de trabajar con el puerto serial

este seria un codigo que me encontre vagando por la red pero no se si sirva para este caso el codigo no es mio

Código:
// zoomkat 11-22-10 serial servo (2) test 
 // for writeMicroseconds, use a value like 1500 
 // for IDE 0019 and later 
 // Powering a servo from the arduino usually DOES NOT WORK. 
 // two servo setup with two servo commands 
 // send eight character string like 15001500 or 14501550 

 #include <Servo.h> 
 String readString, servo1, servo2; 
 Servo myservo1;  // create servo object to control a servo 
 Servo myservo2; 

 void setup() { 
 Serial.begin(9600); 
 myservo1.attach(6);  //the pin for the servo control 
 myservo2.attach(7); 
 Serial.println("servo-test-21" );  // so I can keep track of what is loaded 
 } 

 void loop() { 

 while (Serial.available()) { 
 delay(10); 
 if (Serial.available() >0) { 
 char c = Serial.read();  //gets one byte from serial buffer 
 readString += c;  //makes the string readString 
 } 
 } 

 if (readString.length() >0) { 
 Serial.println(readString);  //see what was received 

 // expect a string like 07002100 containing the two servo positions 
 servo1 = readString.substring(0, 4);  //get the first four characters 
 servo2 = readString.substring(4, 8);  //get the next four characters 

 Serial.println(servo1);  //print ot serial monitor to see results 
 Serial.println(servo2); 

 int n1;  //declare as number 
 int n2; 

 char carray1[6];  //magic needed to convert string to a number 
 servo1.toCharArray(carray1, sizeof(carray1)); 
 n1 = atoi(carray1); 

 char carray2[6]; 
 servo2.toCharArray(carray2, sizeof(carray2)); 
 n2 = atoi(carray2); 

 myservo1.writeMicroseconds(n1);  //set servo position 
 myservo2.writeMicroseconds(n2); 
 readString=""; 
 } 
 } ...
 
Última edición por un moderador:
Hola amigo,

Mira lo primero que debes hacer es buscar una librería en la Red de sharp develop que emule un puerto Serie con el USB, por otra parte, si lo que deseas es recibir datos por el puerto serie del arduino leete el siguiente link:

panamahitek.com/comunicacion-serial-con-arduino

Ahora, como lo que deseas es recibir una cadena de caracteres la mejor opción es crear un arreglo que reciba la información y la valla almacenando en el buffer, de manera que, cuando llegue un caracter finalizador de trama dejo de almacenar y activo una bandera.

Pienso que podrías modificar la trama, un ejemplo podría ser como el siguiente 3020#, donde el 30 son los grados del primero, el 20 del segundo y el # el caracter finalizador de trama.

una opción seria como el siguiente ejemplo el cual, no entra a procesar la información hasta que no llegue la cadena completa, es decir, se espera el caracter #.

La información se va almacenando en cada posición del arreglo, en la [0] el número 3, en la [1] el 0 y así sucesivamente hasta almacenar todos los datos.

unsigned char buffer[9];
unsigned char i=0, ok=0;
int input;

//Se configura el puero serie a 9600 baudios
void setup(){
Serial.begin(9600);
}

void loop(){
//Si se recibió un dato entra
if (Serial.available()>0){
input=Serial.read(); //Leo dato
if(input!='#'){
buffer=input;
buffer[i+1]='\0';
i++;
}else ok=1;
}

//Si ya llego toda la trama entra aqui
if(ok==1){
//leo el buffer, proceso información y borro el buffer
ok=0; //bajo bandera
i=0; //borro el contador
}
}

Te recomiendo que empieces emulando el puerto serie con un Hyperterminal o Putty o Hterm o cualquier programa en el que lo puedas emular, así vas enviando voz mismo la trama a tu gusto y vas probando si el programa funciona.
 
Última edición:
en efectote agradesco la explicacion la verdad me quebre un poco la cabeza de como poder hacer eso y gracias por la pronta respuesta,estaba en llenar desde el principio el buffer y usar un termino como separador como dices en ese caso un "#" gracias por la respuesta :)



solo como una duda extra me podrian explicar como una vez recibido el codigo lo separo o localizo en una variable por decir asi ya recibi la cadena completa y el separador ya llego en este caso "#"
y deseo acceder a las primeras 2 cifras en esta cadena para igualarlas a una variable como Servo1 y tomar las otras cifras para otra variable por decir Servo2 como seria esta parte del codigo

la verdad es que me siento tonto preguntandolo pero aun asi gracias por la ayuda
 
Última edición:
menymp,

no programo en arduino, pero te recomiendo leas la función que comparte nuestro compañero scooter creo que es la solución a ese problema --> parseint()

Por otra parte, tenes dos formas de poder hacer el trabajo, la primera enviando el número como caracteres, tal cual como se planteo arriba, para ese caso hay funciones que realizan la conversión directamente (parseint()), y en otros casos se realiza un calculo con la tabla ASCII para determinar el valor que llega, mira este link:

www.forosdeelectronica.com/f24/leer-teclado-4x4-lcd-40092/

La segunda forma es enviar directamente el número, es decir, no enviar los caracteres uno por uno, si no que cargas el entero directamente y lo envías, luego de enviar los dos número ps envías cualquier caracter finalizador que escojas. Así cuando vas a leer supongamos la posición [0] ya tiene almacenado el dato que corresponde al servo 1, en la posición [1] el servo 2, y en la [3] el finalizador.

En C hay una función que se llama sscanf(), esta también te puede servir para hacer la conversión, te recomiendo la leas, la cosa es que no se si arduino la tenga.

ya es a tu gusto como desees hacer la comunicación.

saludos.
 
Última edición:
ya descubri el problema, no es necesario enviar el valor en grados por el puerto serial si con el arduino ya puedo realizar las ordenes internas de convercion de cinematica inversa empleando la libreria math.h que ya se encuantra por defecto en los compiladores c y el de arduino no es la exepcion, les adjunto un archivo que es un ejemplo de a que me refiero.
 

Adjuntos

  • Nuevo documento de texto (3).txt
    17.1 KB · Visitas: 296
Ten en cuenta que la cpu del arduino es limitada y ciertos cálculos puede que se le atraviesen.
Si funciona lo suficientemente rápido perfecto, si no una opción es calcular el el PC que a todos les sobran GFlops y pasar los datos "masticados"
 
Atrás
Arriba