Entendiendo el buffer de transmisión en serie en Arduino

0

A partir de una pregunta diferente que publiqué, me di cuenta de que me cuesta mucho entender qué está sucediendo exactamente en Serial.print, Serial.read, etc. y el búfer. Usaré mi código como un ejemplo específico y espero que alguien pueda aclararme estas preguntas.

Así que estoy leyendo los valores de los sensores a través de AnalogInput, luego los estoy imprimiendo en una línea, vea aquí:

Laformaenqueentiendocómofuncionaestoes:

  1. ElArduinoleelosvaloresdelsensorylosalmacenaenvariables.
  2. Lasvariablesseimprimenenunasolalíneaenelmonitordeserie.
  3. Enjuagueyrepita.

¿Cómocuentolacantidaddebitsqueestoyenviandoalmonitorenserie?¿Esparacadalíneaqueimprimo(queenesecasoseríadeaproximadamente1052bits)?Sieseeselcaso,entoncesaunavelocidadenbaudiosde9600bits/segdeberíapoderimprimirvariaslíneasenunsegundo.

¿Elbúfertomaesalíneayluegosevacíaparalasiguiente?

Estoysegurodequeyapuedesdecirquetengoalgunaspreguntasbásicassobrecómofuncionanexactamenteelbúferyelmonitordeserie.¡Apreciomuchotutiempo!Gracias.

Porfavoravísemesinecesitoaclararalgo.Además,aquíestámicódigo:

//Dataacquisition//updatedMarch30,2017//Note:ThisversionisforTEMPERATURE,HUMIDITYandPRESSUREdataacquisitionALONE.Nomotor/conveyorcontrol.//***GLOBALVARIABLES***//floatlfactor=125.0;floatafactor=1.15;///////////////////////////StandardsetupwithanalogReferenceto5Volts.voidsetup(){Serial.begin(9600);}voidloop(){//******THERMOCOUPLES*******////getvoltagereading//[code];TC#-Locationfloattcv1=analogRead(A4)*(5.0/1024.0);//TC1floattcv2=analogRead(A7)*(5.0/1024.0);//TC2floattcv3=analogRead(A8)*(5.0/1024.0);//TC3floattcv4=analogRead(A9)*(5.0/1024.0);//TC4floattcv5=analogRead(A10)*(5.0/1024.0);//TC5//converttotemperatureusingcustomequationbasedon5Vreferencefloattc1=(188.7755*tcv1)-245.3959;floattc2=(188.7755*tcv2)-245.3959;floattc3=(188.7755*tcv3)-245.3959;floattc4=(188.7755*tcv4)-245.3959;floattc5=(188.7755*tcv5)-245.3959;//******HUMIDITYSENSORS********//floaths1=(((analogRead(A13)*(5.0/1024.0))/5.0)*100.0);//HS1floaths2=(((analogRead(A15)*(5.0/1024.0))/5.0)*100.0);//HS2//******PRESSURESENSORS********////obtainvoltagesignalfromSensirionsensorfloatpvolt=analogRead(A0)*(4.995/1024.0);//converttoPascalsusingequationfromdatasheet,includingaltitudecompensation//P=lfactor*(voltage[V]-.250)/3.750floatpressure=lfactor*(pvolt-.250)/3.750;floatpascals=pressure*afactor;Serial.print("TC1");
Serial.print(":");
Serial.print(tc1);
Serial.print(";");

Serial.print("TC2");
Serial.print(":");
Serial.print(tc2);
Serial.print(";");

Serial.print("TC3");
Serial.print(":");
Serial.print(tc3);
Serial.print(";");

Serial.print("TC4");
Serial.print(":");
Serial.print(tc4);
Serial.print(";");

Serial.print("TC5");
Serial.print(":");
Serial.print(tc5);
Serial.print(";");    

Serial.print("RH 1");
Serial.print(":");
Serial.print(hs1);
Serial.print(";");  

Serial.print("RH 2");
Serial.print(":");
Serial.print(hs2);
Serial.print(";");

Serial.print("Pressure");
Serial.print(":");
Serial.print(pascals);
Serial.print(";");

Serial.println("");
delay(1000); 

  }
    
pregunta L. Paw

3 respuestas

-1

En realidad creo que necesitas leer algunos conceptos básicos del sitio web de Arduino.

  1. Monitor serie & serial.print no tiene nada en común. El monitor es solo un programa de PC que se lee desde el puerto serie. serial.print: función ejecutada en la uC soldada a su placa Arduino.

  2. serial.print devuelve el número de bytes enviados.

  3. serial.print no tiene ningún búfer, ya que el ATmegah es un recurso muy limitado.
  4. Intente no usar flotadores: su uso es muy lento y requiere muchos recursos (muy limitados). Puede hacer los mismos cálculos utilizando enteros correctamente escalados.
  5. Si aprende a programar, intente evitar retrasos.
respondido por el P__J__
-1

Si lo llamas 10 bits por carácter, no estarás muy lejos.

No creo que haya ningún búfer de software involucrado aquí, más bien, cada llamada a serial.print está tomando cada carácter que se le pide que imprima, esperando que el transmisor UART no esté ocupado y que lo escriba en el UART antes Volviendo a hacer el siguiente personaje.

La llamada a serial.printLn solo está enviando el par CR / LF necesario para mover el cursor a la siguiente línea.

Una forma más rápida y eficiente de trabajar es mantener un búfer de anillo y alimentar al UART en interrupción, lo que permitiría que la acción del UART se desarrolle detrás del escenario siempre que el búfer no se llene, pero estos chips tienen poco ram, por lo que probablemente no se está haciendo (el búfer debería ser lo suficientemente largo como para mantener la mayor parte de una línea para que sea útil, por lo que tal vez 128 bytes o menos).

    
respondido por el Dan Mills
-1

Por lo que yo entiendo, el Atmega328P utilizado en Arduino UNO tiene un búfer de transmisión (transmisión) y un búfer RX (recepción) de hardware TX. De forma predeterminada, el tamaño de cada uno es de 64 bytes.

Cuando lleguen los datos, llegarán al búfer de RX de una manera Primero en entrar, primero en salir (FIFO). En su código debe decidir cómo leer estos datos. Al llamar a Serial.read, elimina un byte del búfer FIFO RX. Tenga en cuenta que si no lee y los datos siguen llegando, en un punto, todo el búfer de 64 bytes estará lleno y se perderá cualquier otro dato nuevo.

Por lo tanto, debe tener cuidado con lo que espera recibir del búfer RX, y no llenarlo sin saberlo.

El búfer de TX funciona de manera similar. Siempre que llame a Serial.print o Serial.write, se enviará un byte o bytes al búfer de TX de hardware y se enviará tan pronto como el hardware sea capaz de hacerlo (determinado principalmente por la velocidad de transmisión). Si llama a esa función demasiado / demasiado rápido, el búfer de hardware de TX se inundará y no se enviará ningún dato nuevo que desee enviar más allá del tamaño de 64 bytes.

Ver este código:

  

Serial.print ("Hello");

En realidad, se enviarán 6 bytes al búfer de TX, y luego se transmitirán automáticamente. Son el código ASCII de los 5 caracteres en "Hola" más el valor decimal 0, que es el carácter terminador de cadena.

O

  

Serial.println ("Hello");

En realidad, se enviarán 8 bytes al búfer de TX, son el código ASCII de los 5 caracteres de "Hola" más el terminador de cadena, más 2 caracteres: "\ r" y "\ n" para el final de la línea.

  

¿Cómo cuento la cantidad de bits que estoy enviando al monitor en serie?   ¿Es para cada línea que imprimo (que en ese caso sería aproximadamente 1052)?   bits)?

Así que ahora ya sabes el número de bytes enviados al búfer en serie, solo divide entre 8 para obtener el número de bits. Pero la cantidad de bits realmente no importa aquí porque la serie funciona con bytes.

  

¿El búfer toma esa línea y luego se vacía para la siguiente?

No. Todo lo que envíe al búfer de TX se transmitirá tan pronto como el hardware pueda hacerlo. No limpia nada. Dale algo de tiempo (referencia a la velocidad en baudios + algún margen) para no inundar el búfer de TX y estará vacío cuando se complete la transmisión.

Tenga en cuenta que puede cambiar el tamaño del búfer de TX y RX en el código.

    
respondido por el Dave

Lea otras preguntas en las etiquetas