Saludos
Tengo este detalle, he simulado una onda sinusoidal usando for y la funcion sin() , dentro de void loop, me di cuenta al imprimir por serial la funcion millis () se relentiza como si tuviera un delay() , la funcion de este codigo es que se ejecute y simule la onda todo el tiempo en el loop y mostrarla en la pantalla . Como podriar reemplazar el ciclo for y usar otra manera para evitar q el tiempo se relentize , por que tambien le voy a integrar y mostar un contador en la misma pantalla y el tiempo el conteo en seg no va acorde 1,2, 3, 4, 5 si no q va contando 2 , 4 pausa y salta a 7 , 9 , 11 , 13 , 17 y asi sucesivamete .
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#define TFT_DC 8
#define TFT_CS 10
#define TFT_RST -1
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
float j = 2 * 3.1416 / 360 ;
byte n = 1 ;
byte fase = 0 ;
void setup()
{
Serial.begin(9600);
tft.initR(INITR_GREENTAB); //
tft.fillScreen(ST7735_BLACK);
tft.setRotation(3);
/// dentro del setup se muestra la onda bien
for ( long i = 0 ; i < 2200; i++)
{
float y = 60 - sin( n * i * j - fase) * 10 ;
float x = i * 55 / 700 ; // normal 110/500
tft.drawCircle(x, y, 1, ST7735_WHITE);
}
}
void loop() {
/// aqui es donde se debe ejecutar sin relentizar el tiempo
for ( long i = 0 ; i < 2200; i++)
{
float y = 60 - sin( n * i * j - fase) * 10 ;
float x = i * 55 / 700 ;
tft.drawCircle(x, y, 1, ST7735_WHITE);
}
Serial.println(millis()); // muestra tiempo relentizado no acorde
}
El cálculo de las funciones trigonométricas (seno, coseno, etc) supone para el Arduino un coste de procesamiento elevado, por lo que cada vez que llamas a dichas funciones se produce un retraso.
De igual manera ocurre si utilizas floats.
No tengo nada en contra de las librerias de Adafruit pero en lo que se refiere a pantallas gráficas el proceso de dibujado es lento.
Si a todo esto le sumas que tienes un for de 2200 elementos y dentro realizas las tres cosas... no sé el retraso que te provocará pero casi seguro que unos cuantos segundos.
Te voy a dar algunas sugerencias:
Usa enteros en vez de floats para hacer los calculos.
Usa una tabla de enteros con el calculo del seno. Cada vez que quieras conocer
el seno de un ángulo usala:
tablaseno[angulo]
Reduce a lo mínimo imprescindible el número de veces que se tiene que ejecutar lo de dentro del for, en vez de 2200 que fueran un centenar o similar.
Por último usa una librería que sea rápida. Te recomiendo que le eches un vistazo a la libreria Arduino_ST7735_Fast de cbm80amiga, he probado varias de sus librerias y son mucho más rápidas en el procesamiento y en el dibujado.
Utiliza un Arduino que no sea un UNO. Si sigues las sugerencias anteriores lo mas probable es que te quedes sin memoria RAM: la tabla de senos ocuará espacio y el búfer de dibujado de la libreria dependerá de la resolución, así que con 2K de RAM dudo que no tengas problemas.
hola Surbyte ,
La idea de todo esto es simular la onda senoidal en la pantalla para tft de 1.8 " en una parte x,y de la pantalla usando un sensor de voltaje ZMPT101B , para saber si esta recibiendo voltage o no , pero ralentiza mucho el codigo , aparte por que esta dentro un condicional..
if (V1rms >= 90 && V1rms <= 135) {
pixels.setBrightness(127);
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // VERDE
pixels.setPixelColor(17, pixels.Color(0, 255, 0)); // VERDE
pixels.show();
for ( long i = 0 ; i < 1000 ; i++) //
{
float y = 17 - sin( n * i * j - fase) * 8 ;
float x = i * 25 / 450 ; //
tft.drawCircle(x, y, 1, ST7735_BLACK);
}
tft.fillRect(12, 47, 140, 15, ST7735_GREEN); // aqui simular la onda
}
Se me esta ocurriendo graficar directamente la entrada del sensor del voltage tomando como referecia el voltage y mostrarla en la pantalla.
saludos , para hacer todo esto q me sugeriste he tenido q ir por parte , estoy aprendiendo y consegui informacion un generador para graficar , usando la tabla pero se me tranco el juego en poderla gafricar en la pantalla. estaba usando un nano , pero cambie a un mega , al principo pense que era por falta de memoria . use la libreria y es bastante rapida para los grafico.
otra opcion seria , como estoy usando un sensor de voltaje ZMPT101B , es graficar directamente la onda que genera el sensor y mostrarla en la tft ..
La idea de todo esto es simular la onda senoidal en la pantalla para tft de 1.8 " en una parte x,y de la pantalla usando un sensor de voltaje ZMPT101B , para saber si esta recibiendo voltage o no , pero ralentiza mucho el codigo , aparte por que esta dentro un condicional..
if (V1rms >= 90 && V1rms <= 135) {
pixels.setBrightness(127);
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // VERDE
pixels.setPixelColor(17, pixels.Color(0, 255, 0)); // VERDE
pixels.show();
for ( long i = 0 ; i < 1000 ; i++) //
{
float y = 17 - sin( n * i * j - fase) * 8 ;
float x = i * 25 / 450 ; //
tft.drawCircle(x, y, 1, ST7735_BLACK);
}
tft.fillRect(12, 47, 140, 15, ST7735_GREEN); // aqui simular la onda
}
Simular la onda que genera? Tienes los conceptos de las cosas equivocados.
Simular y mostrar datos de un sensor son cosas diferentes.
Simular es crear una señal usando funciones trigonométricas, agregando ruido, etc.
Eso lo puedes visualizar en tu TFT sin problemas.
Diferente conceptualmente es leer datos de tun sensor ZMPT101B y visualizarlo.
Solo eso, los lees, no los generas con trigonometría y los presentas.
Al final, la presentación en uno u otro caso es la misma. Pero la fuente es diferente, una será simulada y la otra real.
for ( long i = 0 ; i < 1000 ; i++) //
{
float y = 17 - sin( n * i * j - fase) * 8 ;
float x = i * 25 / 450 ; //
tft.drawCircle(x, y, 1, ST7735_BLACK);
}
aqui puedes ver mi diseño echale un vistazo Test a ver que opinas
yo entiendo lo que estoy haciendo, lo que se me vaya ocurriendo lo voy haciendo,pero antes hago muchas pruebas , funciona perfecto sin el ciclo for , por que no se ralentiza , el tiempo de respuesta es vital para detectar cualquier evento , solo queria mejorarlo visualmente intgrando visualmente el efecto de onda.
Cuando haces esto estas priorizando el ciclo a todo lo demas.
Si ya sabes cuanto te van a dar los valores para que los calculas 1 y otra vez.
Pues los calculas una vez lo pones en un gran array usando PROGMEM, los recuperas porque estarán en memoria FLASH ylos presentas 1 a 1.
Ahora porque 1 a 1, porque eso será lo que hagas cuando leas tu sensor. Y como lees el sensor d emodo que sea fiel al momento en que tengas que reproducir la senoide o cuasi senoide porque ya verás que no lo es tal. Pues usando un timer que te releva de la tarea.
Tu lees con un timer, almacenas en un buffer y muestras los datos que van saliendo en el display asiendo asincrónica una cosa con la otra. Lo que es sincrónico o sea, se toman muestras en el tiempo prefijado x el timer es la toma de datos.
Esos datos van a un buffer y este buffer es el que presentas en el display, a medida que presentas un punto lo liberas tambien.
Por cierto, a todo este debate nunca te pusiste a ver el tiempo que demora tu TFT en presentar un pixel, pues sorpréndete con lo que descubrirás. Son lentos comparativamente.
Si no utilizas ninguna función para limpiar la pantalla, también puedes utilizar
el loop como bucle for.
Un ejemplo:
long i; // La declaro fuera.
void loop() {
//
// otro codigo
//
// Si no llegamos al final dibujamos.
if ( i<1000 ) {
float y = 17 - sin( n * i * j - fase) * 8 ;
float x = i * 25 / 450 ; //
tft.drawCircle(x, y, 1, ST7735_BLACK);
i++: // El siguiente paso.
}
else {
i=0; // Cuando llegamos a 1000 empezamos.
}
}
La velocidad de dibujado será lo que te retrases al ejecutar "otro codigo". Si es rápido será rápido. Claro está esto funcionará si no limpias la pantalla o rellenas con otra cosa.
De todas formas no llego a entender la variable "j", "fase" ni como calculas las posiciones x e y.