Go Down

Topic: Proyecto Wifi ESP8266 Como Servidor WEB (Read 4245 times) previous topic - next topic

samu41

Quote
Primero no puedes tener 1000000 valores. No te da la memoria.
Segundo para que guardar en float algo que lees como unsigned int? Eso es como minimo poco eficiente.
Bueno, puse 1000000 pero con un numero muy grande me vale que lo soporte un float, luego reduciría la memoria.
Con lo que dices de segundo, no guardo un int, guardo ya el valor de la aceleración directamente, porque si tuviese que guardar el valor en bruto sería un poco lío, ya que no veo m/s^2 sino un número que a saber a qué valor de aceleración corresponde (Se que se puede calcular, de hecho lo hago, pero es algo transparente para el usuario).

Con lo que respecta del código que me has puesto, no entiendo muy bien con lo que hace, ya que no estoy familiarizado con esas librerías y el logger (al poner en el vector ={0} inicializas todos los valores a 0 no? Esta bien saberlo).

La cosa es que no se cuantas muestras puede hacer en una medición, ya que como has visto varía mucho dependiendo del ejercicio, y no sólo el ejercicio, sino de la persona y el peso que manejes, por eso no puedo decir que muestree cada x, ya que puedo perder algo, yo muestreo todas las veces que me deje el código para que sea mas exacto, es decir, que el unico periodo de tiempo que dejo que pase entre muestreo y muestreo es el tiempo que tarda la placa en ejecutar las instrucciones (que creo que no es poco, ya que hay varios ciclos de por medio).

Saludos, sigo abierto a tus sugerencias, es algo complicado y me gustaría que saliese bien

surbyte

Quote
La cosa es que no se cuantas muestras puede hacer en una medición, ya que como has visto varía mucho dependiendo del ejercicio,
Bueno eso es mas que importante para determinarse. De lo contrario podrias tener un criterio conservador y tomar una muestra cada 5 mseg y entonces extender el tiempo considerablemente.

guardar el valor en bruto y hacerlo convertido es exactamente igual. Porque puedes disponer de el cuando quieras.
No hace falta guardar un float que son 4 bytes cuando alcanza con guardar solo 2 y tener el doble de muestras.

Se comprende?
Si crees que seria mas aconsejable disponer de mas capacidad porque no consideras guardar en una SD?

samu41

Mas o menos sí, aunque ahí también estás suponiendo que el vector tiene 5000 espacios de memoria no? No estarías sobredimensionando también? De todas formas, si no se llega a las 5000 muestras en el levantamiento debería saber al menos la última posición

samu41

Buenas, os actualizo de como va la cosa, he hablado hoy con mi tutor y me ha dicho en resumidas cuentas que lo que he hecho no vale para nada, entonces lo que tengo intención de hacer es:

-Muestrear continuamente la aceleración, con lo que escribiste surbyte de la interrupción, cada X useg e ir almacenandoles en un vector de 5000 muestras (no se debería llenar) mediante el metodo de buffer circular, si se acabasen los valores empezarían a machacar los del principio.
-Coger dos valores de aceleración y sus instantes, calcular su área (sería la integral), con lo que obtendría un valor de velocidad y lo almacenaría en otro vector igual que el de aceleración de 5000 muestras, así continuamente cogería el ultimo valor cogido y el siguiente, calcularía su área y obtendría un valor de velocidad.
-Solo me quedaría con los valores de velocidad que se corresponderían con dos 0, lo cual indicaría que está parado y entre esos instantes debería haber hecho la fuerza.
-Para hallar la velocidad media calcularia el promedio de todos esos valores de velocidad comprendidos entre los dos nulos.


Ahora mi pregunta es: en el código que pusiste :

Code: [Select]
#include <TimerOne.h>                       // https://github.com/PaulStoffregen/TimerOne
#default MUESTRAS    20000
volatile unsigned int vector[MUESTRAS] = {0};
volatile unsigned int i = 0;

void setup(void) {
 
  Timer1.initialize(500);         // 500 useg
  Timer1.attachInterrupt(logger); // tomo datos cada 500 useg
  Serial.begin(9600);
}

void logger(void) {
  vector[i++] = analogread(A0);
}



Yo lo que entiendo ahí es que en el setup al poner eso, en otro thread paralelo el codigo cada 500useg coge una muestra y lo mete en el vector. Mis preguntas:

1º.El setup tiene que tener obligatoriamente el void? o se puede dejar como viene por defecto en arduino?
Code: [Select]
void setup(){}

2º.Podría usar el vector en la función loop o en otra función tal cual está o debería poner este código?

Code: [Select]
int logger(int vector[i]) {
  vector[i++] = analogread(A0);
}


Es que no estoy familiarizado con las interrupciones en Arduino, en ensamblador di algo pero no tiene nada que ver.

Saludos y muchas gracias, que este proyecto creo que me está quedando un poco grande

surbyte

1. Para responderte te pregunto yo también: leiste la librería TimerOne? miraste algun ejemplo? Eso es algo que toda persona de nivel universitario debería hacer. Aprender a responderte a si mismo antes de hacer consultas. Al menos eso hago yo siempre. Pregunto cuando agoté todas las instancias. Es un consejo para siempre.

Toda librería requiere de cierta inicializaición. La inicialización se hace una sola vez. Esa única vez es el setup.
El setup se escribe siempre void setup(), no hay otro modo de hacerlo. Si tienes duda busca un buen libro en Documentación y tutoriales.

2. no puedes usarlo en el loop porque esa línea tiene sentido en el contexto de la interrupción ocurrida a un intervalo dado de 500 us.

En el loop no ocurrirá de ese modo. Tendrías que activar un flag y cuando el loop pase por ahi actuaría pero quien asegura ese momento?



samu41

Sí si que lo hice, muchas gracias, la forma de obtener los datos ya la tengo mas o menos hecha, la duda que ahora tengo es la segunda que propuse del servidor para representarles y editar los datos, pongo lo que puse la otra vez:

Quote
Problema 2:

La idea era hacer un servidor web con la wemos, el cual mi tutor dijo que se podría (aunque sea mi tutor no me aporta mucho a la hora del proyecto, me dice sólamente que busque). Y sí, es cierto que se puede hacer un servidor, pero yo quería conectar mi smartphone o portátil a la placa mediante wifi y que lo único que pueda hacer por estar conectado al wifi es estar en el servidor que incorporaría el wifi del wemos. Sin embargo todo lo que he encontrado ha sido que la placa hace de Access Point (AP) pero conectándose a una Wifi y ahí le asigna una dirección IP al servidor y desde el navegador (que está conectado a la wifi de casa, no conectado mediante wifi a la placa) puedes hacer lo que querías.
Yo quisiera saber si se puede hacer que la placa haga literalmente de AP, que al buscar una wifi con tu teléfono aparezca el del arduino, conectarte, y ya en el navegador conectarte al servidor de la propia placa.
Alguna idea? Alguien que lo haya hecho? O alguna modificación respecto al que yo he encontrado para hacer lo que busco?

surbyte

Eso esta en las librerías de ESP8266.
Has visto WifiManager o ESP8266 que es la librería básica trae TCPServer.ino, hay muchos ejemplos.
Puedes usar AJAX, puedes usar javascript, HTML desde ya. Si algo hay son ejemplos y guias de Servidores con ESP8266.

Busca ESP8266 Webserver y encontrarás infinidad de ejemplos.

samu41

Estoy teniendo un problema con el servidor, ya he configurado para que la placa haga de Access Point, todo perfecto, si hago la mitica prueba de

Code: [Select]
#include <ESP8266WiFi.h> //Para hacer las conexiones wifi
#include <WiFiClient.h>  //Se requiere para enviar petición al navegador
#include <ESP8266WebServer.h>  //Maneja el HTTP del servidor

const char *ssid = "samuTFG";         //SSID del Access Point
const char *password = "samuTFGando"; //Pass

ESP8266WebServer server(80);        //Puerto de conexión que utilizaremos
                                   // Si queremos usar otro puerto en el navegador habria que poner 192.168.4.1:81 


void handleRoot() {  //Esta subrutina es llamada cuando pones la IP en el navegador, es el root del server

 // server.send(200,"text/html","<TITLE>Indice </TITLE>");
  server.send(200, "text/html", "<h1>Te acabas de conectar al BitxoFusion con WiFi y eres el fucking boss</h1>");
  server.send(200, "text/html", "<h1>Para acceder a medir squat/ bench /deadlift, añade a la url /squat</h1>");
}

void setup() {

delay(1000);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
WiFi.softAP(ssid, password);     //Arrancamos la placa en modo AP
IPAddress myIP = WiFi.softAPIP(); //Obtenemos la IP asignada
Serial.print("AP IP address: ");
Serial.println(myIP);
delay(10);
server.on("/", handleRoot); //Llamamos al root; para llamar a otra pestaña  ponemos Server.on("/squat",squat); es como 192.168.4.1/squat
//server.on("/squat", squat);
server.begin();  //Arrancamos el servidor
Serial.println("HTTP server started");

}

void loop() {

server.handleClient();//Manejamos las solicitudes del cliente

}


Si hago eso con los comentarios que están puestos aparece el mensaje de que me acabo de conectar y tal, sin embargo el de justo de abajo no, y si pongo la etiqueta <TITLE> directamente no aparece nada, a parte quiero hacer varias pestañas una de índice y otras 3, se que para ello se debe de hacer así:

Code: [Select]
Server.on("/squat",squat);

Y que luego poner en el navegador 192.168.4.1/squat pues debería bastar, pero si enciendo esa parte justo después de iniciar el index no aparece ni index ni squat, alguien sabe como tratar estos problemas? Sólo puedo hacer una línea (h1) de texto por pestaña? Porque todo lo que he visto es de una única pestaña, y la mayoría con la librería de client en vez de la de server.

Gracias

Go Up