Funciones de arduino no andan

Buenas a todos. Espero alguien me pueda ayudar con este código, ya que me vuelve loco.
El problema es el siguiente: quiero crear una función ( llamada voltímetro) y resulta que no me funciona.
Me parece que el problema viene porque la función que quiero crear cuenta con "Millis" pero no sé cómo resolverlo.
Probé con Float voltímetro, int voltímetro y con VOID voltímetro y de ninguna forma funciona.
Compila bien, sin ningún error pero no funciona. Cabe aclarar que el código si lo hago en el void loop funciona perfectamente.
Les dejo el código y ojalá me puedan dar una mano. Saludos a todos.
C:
#include <Wire.h>

#include <Adafruit_ADS1X15.h>

#include <Filters.h> //Biblioteca fácil para hacer los cálculos

#include <SPI.h>     //Bibliotecas para la pantalla OLED

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // Ancho de pantalla OLED, en píxeles
#define SCREEN_HEIGHT 32 // Altura de la pantalla OLED, en píxeles
#define OLED_RESET    -1 //

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaración del nombre para mostrar (display)

float testFrequency = 50;                     //frecuencia de la señal de prueba (Hz)
float windowLength = 40.0/testFrequency;     // cuánto tiempo promediar la señal, para estadístico
int Sensor = 0; //Entrada analógica del sensor, aquí está A0
float intercept = -0.04; // para ser ajustado en base a las pruebas de calibración
float slope = 0.0405; //  para ser ajustado en base a las pruebas de calibración
float current_Volts; // Voltaje
unsigned long printPeriod = 1000; //Frecuencia de actualización
unsigned long previousMillis = 0;
float amperimetro;
float potencia;
float amperaje;
float voltaje;

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Inicie la pantalla OLED
  display.clearDisplay();
  display.setTextSize(1);                 
  display.setTextColor(WHITE);             
  display.setCursor(1,1);             
  display.print("Tecno industrial");
  display.setCursor(1,20);
  display.setTextSize(1);
  display.print("AC vatimetro");
  display.display();
  delay(2000);
}

void loop() {
      float voltaje = voltimetro();
      display.clearDisplay();
      display.setTextSize(4);       //tamaño del texto que seguirá         
      display.setTextColor(WHITE);  //su color           
      display.setCursor(1,1);      //posición desde la que quieres empezar a escribir         
      display.print(voltaje,1);
      display.setCursor(115,00);
      display.setTextSize(2);
      display.print("V");
      display.setCursor(115,15);
      display.setTextSize(1);
      display.print("AC");
      display.display();
}

float voltimetro() {
  RunningStatistics inputStats;                //Líneas de vida fáciles, el cálculo real del RMS requiere una gran cantidad de codificación
  inputStats.setWindowSecs( windowLength );

  while( true ) { 
    Sensor = analogRead(A0);  // leer el análogo en valor
    inputStats.input(Sensor);  // iniciar sesión en la función de estadísticas

    if((unsigned long)(millis() - previousMillis) >= printPeriod) {
      previousMillis = millis();   // tiempo de actualización cada segundo
      Serial.print( "\n" );

      current_Volts = intercept + slope * inputStats.sigma(); //Calibraciones para compensación y amplitud
      current_Volts= current_Volts*(40.3231);                //Otras calibraciones para la amplitud
      Serial.print( "\tVoltage: " );
      Serial.print( current_Volts ); //El cálculo y la visualización del valor están hechos, el resto es si está utilizando una pantalla OLED

    return current_Volts;
    }
  }
  }
 
Última edición por un moderador:
Ese código está ilegible y es claro que no tenés NPI de programación.
Cuando se pueda leer podemos empezar a discutir...
 
No se mucho de Arduino pero a primera vista se ve que esta mal fundamentado el codigo, lo ideal es que lo disenes por bloques, primero lo primero, el codigo de funcionamiento de la pantalla y revisar las funciones de la biblioteca filters.
 
Ese código está ilegible y es claro que no tenés NPI de programación.
Cuando se pueda leer podemos empezar a discutir...
Ni de poner niks tampoco. Anda que poner el correo...
No tinc paraules!
Buenas a todos. Espero alguien me pueda ayudar con este código, ya que me vuelve loco.
Si
El problema es el siguiente: quiero crear una función ( llamada voltímetro) y resulta que no me funciona.
Vale
Me parece que el problema viene porque la función que quiero crear cuenta con "Millis" pero no sé cómo resolverlo.
No parece que sea eso, ¿Que te hace suponerlo?
Probé con Float voltímetro, int voltímetro y con VOID voltímetro y de ninguna forma funciona.
A ver, si una función ha de devolver un float, pues solo vale float. ¿O es que no sabes que significan esas palabras?; Se ve que no.
Compila bien, sin ningún error pero no funciona. Cabe aclarar que el código si lo hago en el void loop funciona perfectamente.
Claro porque en void loop se ejecuta
Les dejo el código y ojalá me puedan dar una mano. Saludos a todos.
Saludos

C:
#include <Wire.h>

#include <Adafruit_ADS1X15.h>

#include <Filters.h> //Biblioteca fácil para hacer los cálculos

#include <SPI.h>     //Bibliotecas para la pantalla OLED

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // Ancho de pantalla OLED, en píxeles
#define SCREEN_HEIGHT 32 // Altura de la pantalla OLED, en píxeles
#define OLED_RESET    -1 //

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaración del nombre para mostrar (display)

float testFrequency = 50;                     //frecuencia de la señal de prueba (Hz)
float windowLength = 40.0/testFrequency;     // cuánto tiempo promediar la señal, para estadístico
int Sensor = 0; //Entrada analógica del sensor, aquí está A0
float intercept = -0.04; // para ser ajustado en base a las pruebas de calibración
float slope = 0.0405; //  para ser ajustado en base a las pruebas de calibración
float current_Volts; // Voltaje
unsigned long printPeriod = 1000; //Frecuencia de actualización
unsigned long previousMillis = 0;
float amperimetro;
float potencia;
float amperaje;
float voltaje;
Vale, esta parte me la creo, es quilométrica y seguramente sobre la mitad pero vale
C:
#include <Wire.h>

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Inicie la pantalla OLED
  display.clearDisplay();
  display.setTextSize(1);              
  display.setTextColor(WHITE);          
  display.setCursor(1,1);          
  display.print("Tecno industrial");
  display.setCursor(1,20);
  display.setTextSize(1);
  display.print("AC vatimetro");
  display.display();
  delay(2000);
}
También me creo esta parte, lo del delay 2000 me produce hilaridad máxima pero vamos, si en tu vida sobran dos segundoa cuando se enciende algo y te ayuda a perderlos cada vez que enciendes el aparato...
C:
void loop() {
      float voltaje = voltimetro();
      display.clearDisplay();
      display.setTextSize(4);       //tamaño del texto que seguirá      
      display.setTextColor(WHITE);  //su color        
      display.setCursor(1,1);      //posición desde la que quieres empezar a escribir      
      display.print(voltaje,1);
      display.setCursor(115,00);
      display.setTextSize(2);
      display.print("V");
      display.setCursor(115,15);
      display.setTextSize(1);
      display.print("AC");
      display.display();
}
¿Que haces redefiniendo lo definido 10000 veces por segundo e imprimiendo sin parar lo mismo?

C:
float voltimetro() {
  RunningStatistics inputStats;                //Líneas de vida fáciles, el cálculo real del RMS requiere una gran cantidad de codificación
  inputStats.setWindowSecs( windowLength );

  while( true ) {
    Sensor = analogRead(A0);  // leer el análogo en valor
    inputStats.input(Sensor);  // iniciar sesión en la función de estadísticas

    if((unsigned long)(millis() - previousMillis) >= printPeriod) {
      previousMillis = millis();   // tiempo de actualización cada segundo
      Serial.print( "\n" );

      current_Volts = intercept + slope * inputStats.sigma(); //Calibraciones para compensación y amplitud
      current_Volts= current_Volts*(40.3231);                //Otras calibraciones para la amplitud
      Serial.print( "\tVoltage: " );
      Serial.print( current_Volts ); //El cálculo y la visualización del valor están hechos, el resto es si está utilizando una pantalla OLED

    return current_Volts;
    }
  }
  }
Esto lo puedes borrar todo porque no se ejecuta nunca; en el loop no lo llamas. Tu función no funciona porque no la llamas.
Si luego la llamas ¿Que diantres hace un while true en una función?¿Es para intentar tumbar el sistema, te molesta que funcione?
 
Última edición:
Ni de poner niks tampoco. Anda que poner el correo...
No tinc paraules!

Si
Vale

No parece que sea eso, ¿Que te hace suponerlo?

A ver, si una función ha de devolver un float, pues solo vale float. ¿O es que no sabes que significan esas palabras?; Se ve que no.

Claro porque en void loop se ejecuta

Saludos


Vale, esta parte me la creo, es quilométrica y seguramente sobre la mitad pero vale

También me creo esta parte, lo del delay 2000 me produce hilaridad máxima pero vamos, si en tu vida sobran dos segundoa cuando se enciende algo y te ayuda a perderlos cada vez que enciendes el aparato...

¿Que haces redefiniendo lo definido 10000 veces por segundo e imprimiendo sin parar lo mismo?


Esto lo puedes borrar todo porque no se ejecuta nunca; en el loop no lo llamas. Tu función no funciona porque no la llamas.
Si luego la llamas ¿Que diantres hace un while true en una función?¿Es para intentar tumbar el sistema, te molesta que funcione?

Ya esto fue aclarado de un solo plumazo por:
Ese código está ilegible y es claro que no tenés NPI de programación.
Cuando se pueda leer podemos empezar a discutir...

y dejado en suspenso por:
Las funciones de Arduino SI funcionan, apuesto que la/s causa/s son otras. :unsure: (No quiero ser mordaz.)

Perdido en una nube negra...
 
Simple;
- Organiza mejor el código
- Usa banderas o flags
- Evita o elimina de tu vida el "delay"
- Sigue el camino que debería tomar cada paso, y razona si lo hace bien o no.
 
Usas float voltaje esta bien, pero si ya la tienes como gobal úsala así solo como voltaje sin redefinir el float que solo te enredarás. Esto no causa falla pero puede causar confusión entre globales y locales luego.

¿Pero que te falla del código o que no hace y se supone que debería hacer?
Por que si el objetivo era mandar un email, pues sí, está todo mal, así nunca funcionará. Si era al menos enviar texto al UART pues te falta un Serial.begin() en el setup para iniciar ese puerto antes de usar el Serial.print que pones en tu float voltimetro(). Si no lo haces puedes causar que el buffer se quede en espera de un dato que nunca saldrá del puerto y eso te congele todo el programa.

Fuera de eso no encuentro problemas aunque la manera en la que manejas la función podría mejorarse.
 
Gracias a todos por responder. la finalidad del codigo es hacer un sensor de potencia en(W). para ello utilizo un sensor amperimetro y un voltimetro. La idea es hacer dos funciones; una para el codigo del amperimetro y otra para el codigo del voltimetro y luego multiplicar los resultados.
la parte que subi es la del voltimetro. que cuando se ejecuta como funcion, esta no anda. (pero si ejecuto el codigo directo andaperfecto)
 
Pero revisa tu código que estas metiendo un serial.print sin inicializar el puerto, si no lo haces la funcion puede enviar el byte al puerto, pero se queda en espera de que este se libere para enviar el siguiente byte del buffer.

El problema es que no se realiza ninguna validación, el código no da error por que no está pensando de si el dato saldrá o no, se queda en espera hasta que salga, lo que nunca ocurre y atora tu programa.

O lo remueves o pones en el setup un Serial.begin(bauds) para iniciarlo.
 
Atrás
Arriba