El ejemplo DiskSamplerLog1 vemos que imprime las muestras en formato csv pero en la paginaweb, no como archivo descargable. Queremos usar el DiskSamplerLog4 (por ser configurable) con la habilidad de escribir a un archivo descargable csv ya que las muestras necesitadas ahora son de 5 veces por segundo.
Podrian ilustrarnos sobre como usar el DiskLogAddString, porque tenemos en la compilación un error en la última fila (el ultimo canal. Logrmos descargar archivo csv pero contenido en formato distinto, binario.
Buenos días Miguel,
Le paso el link al ejemplo DiskSamplerLog1 modificado para que tenga las opciones de DiskSamplerLog4 :
www.slicetex.com/docs/an/an036/files/examples/DiskSamplerLog1B.zipSi bien, al ser algo tan genérico el ejemplo, es recomendable que en su proyecto lo optimice.
En este caso se ha modificado en función
SamplersInit() de archivo
Samplers.p para que los archivos del log tengan extensión CSV.
DiskLogInit(1, "vin", "csv", "/web", 36000, 500, DISKLOG_OPT_PPPPPXXX|DISKLOG_OPT_SEMICOLON|DISKLOG_OPT_CIRCULAR|DISKLOG_OPT_FAST_WRITE)
También, como le expliqué en otro ejemplo, puede modificarlo en este lugar para que tengan en el nombre de archivo la fecha
YYYYMMDD.csv, si es necesario.
En el evento
@OnVinBufFullA() se utiliza el código original del ejemplo
DiskSamplerLog1, prácticamente sin cambios, siendo la parte fundamental
DiskLogAddString() que escribe texto en el archivo CSV.
@OnVinBufFullA()
{
new TimeStart
//
// Guardar estampa de tiempo del inicio del evento.
//
TimeStart = TimeGetMillis()
//
// Copiar todas las muestras desde el buffer interno del "sampler" al array temporales.
//
// Nota: Las muestras de cada canal son colocadas en una dimensión del array por vez.
// Como el array tiene dos dimensiones, utilizamos solo un índice para seleccionar el canal,
// ver definición del array en Samplers.inc.
//
for(new Ch=0; Ch < SAMPLERS_CH; Ch++)
{
VinGetBuf(Ch+1, VinBuf[Ch], 0, SAMPLERS_BUF_SIZE)
}
//
// Guardar todas las muestras VIN en la entrada del log de tarjeta Micro-SD.
//
for(new i=0; i < SAMPLERS_BUF_SIZE; i++)
{
//
// Atención: El siguiente códígo es para SAMPLERS_CH=5, si es diferente, debe adaptar la función
// DiskLogAddString() para que tome más o menos argumentos de acuerdo a la cantidad de canales.
//
if(SAMPLERS_CH == 5)
{
// Agregar una entrada con formato de cadena de texto al canal 1 del DiskLog de la tarjeta Micro-SD.
// Nota[1]: Separamos cada valor con ";" para que cumpla con el formato de archivo CSV.
// Nota[2]: Los valores analógicos son "float" y llevan punto decimal. En Excel debe especificar si un número tiene "." o "," para el decimal.
// Nota[3]: Puede convertir a voltaje con VinToVoltage() en una variable intermedia y luego aplicar la función MathScale() para converir a unidades de ingeniería.
DiskLogAddString(1, "%f;%f;%f;%f;%f", \
VinToVoltage(1, VinBuf[0][i], 12), \
VinToVoltage(2, VinBuf[1][i], 12), \
VinToVoltage(3, VinBuf[2][i], 12), \
VinToVoltage(4, VinBuf[3][i], 12), \
VinToVoltage(5, VinBuf[4][i], 12))
}
else
{
// Error!... Si SAMPLERS_CH es distinto a 5, debe adaptar este código
// para que imprima en el archivo CSV más/menos canales.
DiskLogAddString(1, "Adaptar codigo en @OnVinBufFullA!")
}
}
//
// Calcular tiempo insumido de procesamiento por el evento para mostrar en la página web.
//
SamplerEventTimeMS = TimeGetMillis() - TimeStart
}
Notar como la función DiskLogAddString() se encarga de imprimir las muestras al archivo de texto en formato CSV:
DiskLogAddString(1, "%f;%f;%f;%f;%f", \
VinToVoltage(1, VinBuf[0][i], 12), \
VinToVoltage(2, VinBuf[1][i], 12), \
VinToVoltage(3, VinBuf[2][i], 12), \
VinToVoltage(4, VinBuf[3][i], 12), \
VinToVoltage(5, VinBuf[4][i], 12))
Es lo logra con la cadena de formato
"%f;%f;%f;%f;%f", donde cada código
%f indica que debe remplazarse por un valor float del argumento variable de la función. Colocamos punto y coma ";" como separador, ya que así es el formato CSV.
Por ejemplo, el primer código
%f corresponde a
VinToVoltage(1, VinBuf[ 0 ][ i ], 12), que convierte a voltaje la muestra almacenada en el array
VinBuf[][] del canal 1 a voltaje (ver manual). Ya que las muestras almacenadas por los SAMPLER están en formato binario, por lo que primero se convierten a voltaje y luego lo imprimimos a texto.
También puede colocar el valor de voltaje en una variable intermedia, por ejemplo, en el array Voltage[] y luego imprimir con DiskLogAddString():
new Float: Voltage[6]
Voltage[1] = VinToVoltage(1, VinBuf[0][i], 12)
Voltage[2] = VinToVoltage(2, VinBuf[0][i], 12)
Voltage[3] = VinToVoltage(3, VinBuf[0][i], 12)
Voltage[4] = VinToVoltage(4, VinBuf[0][i], 12)
Voltage[5] = VinToVoltage(5, VinBuf[0][i], 12)
DiskLogAddString(1, "%f;%f;%f;%f;%f", Voltage[1] , Voltage[2] , Voltage[3], Voltage[4], Voltage[5])
Entonces, si quiere convertir a unidades de ingeniería, puede utilizar la función
MathScale(InValue, InMin, InMax, OutMin, OutMax) de forma simple. Esta función, escala el valor
InValue entre los límites
InMin e
InMax a los valores
OutMin y
OutMax.
Por ejemplo, supongamos que 0V representan 10 °C, mientras que 5V representan 85 °C, hacemos:
MathScale(InValue, 0, 5, 10, 85)
Cualquier valor de InValue entre 0 y 5 será escalado proporcionalmente entre 10 y 85.
Si fuera corriente, por ejemplo supongamos que 4 mA representan 10 °C, mientras que 20 mA representan 85 °C, hacemos:
MathScale(InValue, 4, 20, 10, 85)
Cualquier valor de InValue entre 4 y 20 será escalado proporcionalmente entre 10 y 85.
Entonces, yendo a DiskLogAddString(), podemos remplazar como:
new Float: Sensors[6]
Sensors[1] = MathScale(VinToVoltage(1, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[2] = MathScale(VinToVoltage(2, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[3] = MathScale(VinToVoltage(3, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[4] = MathScale(VinToVoltage(4, VinBuf[0][i], 12), 0, 5, 10, 85)
Sensors[5] = MathScale(VinToVoltage(5, VinBuf[0][i], 12), 0, 5, 10, 85)
DiskLogAddString(1, "%f;%f;%f;%f;%f", Sensors[1] , Sensors[2] , Sensors[3], Sensors[4], Sensors[5])
Obviamete, si son 6 canales, debés agregar una %f más al código de formato:
DiskLogAddString(1, "%f;%f;%f;%f;%f;%f", Sensors[1] , Sensors[2] , Sensors[3], Sensors[4], Sensors[5], Sensors[6])
Es cuestión de que lo dejes optimizado y prolijo para tu proyecto específico.
Los códigos de formato admisibles para DiskLogAddString() son los mismos que para la función
nLcdPrintf(), por ejemplo %f para float, y %d para enteros, podés ver una explicación de lo códigos en el
Manual de Programación, buscar
nLcdPrintf(), sección 9.2.
Saludos!