Jump to content

Banner.jpg.b89429c566825f6ab32bcafbada449c9.jpg

Weather Station Ideas


Gina

Recommended Posts

I think the problem is probably in the sketch so I'm continuing here.  Since the problem seems it might be to do with the increased breeze today I'm wondering if I'm exceeding the capacity of a numeric type somewhere.  I thought I allowed plenty of headroom but maybe not.

I'm seeing gusts up to 13mph with mean speed up to 10mph. 

Let's go over the process in detail.  The anemometer produces one count per revolution and one pulse per second for 4.5mph ie. 3 pulses in the 3s Gust interval.  I thought I had designed the code to take speed up to 100mph.  At that hopefully highly unlikely speed we would get 67 pulses per sec.  (2/3 of 100.)  First integration period is 1m so 20 times the 3s period and 60x100x2/3 counts.  That's 4,000 counts.  Then we put that into the 10 integer ring array.  So far so good.  Definitely no overload.

Next, the mean speed over 10m is calculated by summing the 10 ring array locations (before dividing to get the mean).  Now a mean wind speed of 100mph would produce a sum of 10x400 = 40,000.  Oops > 32,767 BUT we aren't getting 100mph winds and this would be alright for a speed up to 100x32767/40000 = 81.9 mph.

I can't see a problem with the wind speeds I'm getting today.  Think I'll post the complete sketch and maybe someone can look through it and find my error.

// MQTT for wind sensors

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
********
Modified and added to by Gina 2020-08-21 onward
********
*/

// periods or intervals in milliseconds
const int P3s = 3000;      // integer
const int P1m = 60000u;    // unsigned integer 
const int P3m = 180000ul;  // unsigned long
long last3s = 0;
long last1m = 0;
long last3m = 0;

// ADC pins
const int An1 = 34;
const int An2 = 35;
const int An3 = 32;
const int An4 = 33;
// ADC readings
int dir1 = 0;
int dir2 = 0;
int dir3 = 0;
int dir4 = 0;

// Gray to binary table
int codeArray[16] = {0,1,3,2,7,6,4,5,15,14,12,13,8,9,11,10};
int dirn = 0;

// Direction count bins
int bin[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/* Direction compass Points - not used
String CPt[16] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE",
   "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW",  "NNW"};
*/
// 10m averaging etc.
int meanArray[10] = {0,0,0,0,0,0,0,0,0,0};
int gustArray[10] = {0,0,0,0,0,0,0,0,0,0};
int ringIndex = 0;

// Output variables
int Direction = 0; // 0-359 degrees
int meanSpeed = 0; // 0-100mph
int gustSpeed = 0; // 0-100mph

// Set GPIO for Hall Sensor
const int HallSensorPin = 4;
int PulseCount = 0, windGust = 0;
float windSpeed = 0;

#include <WiFi.h>
#include <PubSubClient.h>

// Replace the next variables with your SSID/Password combination
const char* ssid = "Ubiquity";
const char* password = "********";

const char* mqtt_server = "192.168.1.140";

WiFiClient windClient;
PubSubClient client(windClient);

char msg[50];
int value = 0;

// Checks if Hall sensor was triggered - Interrupt Handler
void IRAM_ATTR HallTriggered() {
//  Serial.println("Hall Triggered");
  ++PulseCount; // Increment count
}

int Beaufort(int mph){
  if (mph < 1) return 0;
  else if (mph <= 3) return 1;
  else if (mph <= 7) return 2;
  else if (mph <= 12) return 3;
  else if (mph <= 18) return 4;
  else if (mph <= 24) return 5;
  else if (mph <= 31) return 6;
  else if (mph <= 38) return 7;
  else if (mph <= 46) return 8;
  else if (mph <= 54) return 9;
  else if (mph <= 63) return 10;
  else if (mph <= 72) return 11;
  else return 12;
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  
  // Hall Sensor mode INPUT_PULLUP
  pinMode(HallSensorPin, INPUT_PULLUP);
  // Set HallSensor pin as interrupt, assign interrupt function and set FALLING mode
  attachInterrupt(digitalPinToInterrupt(HallSensorPin), HallTriggered, FALLING);
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("windClient")) {
      Serial.println("connected");
      // Subscribe
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//Get instantaneous wind direction - variable dirn
int readDirection(){    
    // Read wind vane optical sensor values
    dir1 = analogRead(An1);
    dir2 = analogRead(An2);
    dir3 = analogRead(An3);
    dir4 = analogRead(An4);
    // Convert Gray bits to integer
    int Gray = 0;
    if (dir1 > 2000) {Gray = 8;};
    if (dir2 > 2000) {Gray += 4;};
    if (dir3 > 2000) {Gray += 2;};
    if (dir4 > 2000) {Gray += 1;};
    //  Convert Gray to binary
    dirn = 15 - codeArray[Gray]; // correct rotation direction
    dirn = (dirn - 1) %16; // correct encoder for North
    return dirn;
}
//
void sendSpeedMessages(){
  // messages to send :-
  // wind/speed/mph -- meanSpeed
  // wind speed/force -- Beaufort(meanSpeed)
  // wind/gust/mph -- gustSpeed
  // wind/gust/force -- Beaufort(gustSpeed)
  // 
  // Convert the Mean Speed to a char array
  char msString[8];
  dtostrf(meanSpeed, 1, 1, msString);
//  Serial.print("Mean Speed: ");
//  Serial.println(msString);
  client.publish("wind/speed/mph", msString);
  
  // Convert the Mean-Speed-Force to a char array
  char bsString[8];
  dtostrf(Beaufort(meanSpeed), 1, 0, bsString);
//  Serial.print("Force: ");
//  Serial.println(bsString);
  client.publish("wind/speed/force", bsString);
  
  // Convert the Gust-Speed to a char array
  char gsString[8];
  dtostrf(gustSpeed, 1, 0, gsString);
//  Serial.print("Gust: ");
//  Serial.println(gsString);
  client.publish("wind/gust/mph", gsString);

  // Convert the Gust-Speed-Force to a char array
  char bgString[8];
  dtostrf(Beaufort(gustSpeed), 1, 0, bgString);
//  Serial.print("Gust Force: ");
//  Serial.println(bgString);
  client.publish("wind/gust/force", bgString);
}
void sendDirectionMessage(int Dir){
  // Convert the Direction to a char array
  char dirString[8];
  dtostrf(Dir, 1, 0, dirString);
//  Serial.print("Direction: ");
//  Serial.println(dirString);
  client.publish("wind/direction", dirString);
}
void sendDirectionMessageInst(int Dir){
  // Convert the Direction to a char array
  char dirString[8];
  dtostrf(Dir, 1, 0, dirString);
//  Serial.print("Direction: ");
//  Serial.println(dirString);
  client.publish("wind/direction/inst", dirString);
}
/*  Debugging only
void sendNumberMessage(int N){
  // Convert the number to a char array
  char numString[8];
  dtostrf(N, 1, 0, numString);
  Serial.print("Number: ");
  Serial.println(numString);
  client.publish("wind/number", numString);
}
void sendNumberMessage2(int N){
  // Convert the number to a char array
  char numString[8];
  dtostrf(N, 1, 0, numString);
  Serial.print("Number: ");
  Serial.println(numString);
  client.publish("wind/number2", numString);
} 
*/
void do3sJobs (){
  byte instDir = readDirection();
  sendDirectionMessageInst(instDir); // send instantaneous direction
  windSpeed += PulseCount;  //  Accumulate mean speed
  if (PulseCount > windGust) {windGust = PulseCount;};  // Get max speed for gust
  PulseCount = 0;
  ++bin[instDir]; // increment appropriate bin
}
void do1mJobs(){
  // wind speed mean and gust ring arrays and report
  meanArray[ringIndex] = windSpeed; // put windSpeed into new array index
  gustArray[ringIndex] = windGust;  // put windGust into new array index
//  windSpeed /=13;  // /20 and *1.5 -- leave this for later
  meanSpeed = 0; gustSpeed = 0; windSpeed = 0; windGust = 0;
  for (int i = 0; i < 10; i++) { meanSpeed += meanArray[i];  // sum the windSpeeds 
    if (gustArray[i] > gustSpeed){gustSpeed = gustArray[i];}; // find maximum gust speed
  }
  meanSpeed /=133;  // the first sum was over 20 values and then the second over 10 values
  gustSpeed *= 1.5;  // Speed count over 3s rather than 4.5s
  sendSpeedMessages();
//  sendNumberMessage(ringIndex); debugging only
  ringIndex = (ringIndex+1)%10; // move ringIndex on to next location in the ring arrays
}
void do3mJobs(){
  // wind direction calculations and report
  int sum[16];
  int S=0,I=0,W=0;
  bin[16] = bin[0];
  bin[17] = bin[1];
  bin[18] = bin[2];
  bin[19] = bin[3];
  for (int i = 0; i < 16; i++) {
    sum[i] = bin[i] + bin[i+1] + bin[i+2] + bin[i+3] + bin[i+4];
    // find the index with the highest sum and save sum and index
    if (sum[i] > S){S = sum[i]; I = i;}; 
//    sendNumberMessage2(I);  //  send index for debugging
  }
  W = (bin[I+1] + 2 * bin[I+2] + 3 * bin[I+3] + 4 * bin[I+4]) * 45 / S;
  sendDirectionMessage((I * 45 + W)%720 /2);
  //Empty the bins ready for a new direction calculation
  for (int i = 0; i < 16; i++) {bin[i] = 0;};
}

void loop() {
  if (!client.connected()) {reconnect();}
  client.loop();
// time the various periods
  long now = millis();
  if(now - last3s > P3s) {do3sJobs(); last3s = now;}
  if(now - last1m > P1m) {do1mJobs(); last1m = now;}
  if(now - last3m > P3m) {do3mJobs(); last3m = now;}
}

 

Link to comment
Share on other sites

Somewhere in that code must be an error but I've been through it many times and can't see it.  It is probably a case of three sevens are twenty two - you can go over calculations or code many times and the error remains invisible.  Many years ago when I was programming I would go through the code bit by bit and explain what it was doing to my friend.  Sometimes I would then find the problem myself or she would.  She knew practically nothing about coding but was an enormous help.

Link to comment
Share on other sites

It seems to have got worse.  I may try copying the wind speed code onto another ESP32 and feeding it with varying frequency pulses and see what happens as the pulse rate is increased.  I can add in code to send various numbers to the MQTT network to see what's happening.

1182742818_Screenshotfrom2020-09-0222-24-49.png.31f836c53f1e84bf12b3bda4ea155200.png  1743428833_Screenshotfrom2020-09-0222-25-20.png.3ee2a166517aa0b973c96ccf944bde1e.png

Link to comment
Share on other sites

// MQTT for wind sensors

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
********
Modified and added to by Gina 2020-08-21 onward
********
*/

// periods or intervals in milliseconds
const int P3s = 3000;      // integer
const int P1m = 60000u;    // unsigned integer 
const int P3m = 180000ul;  // unsigned long
long last3s = 0;
long last1m = 0;
long last3m = 0;
// 10m averaging etc.
int meanArray[10] = {0,0,0,0,0,0,0,0,0,0};
int gustArray[10] = {0,0,0,0,0,0,0,0,0,0};
int ringIndex = 0;

// Output variables
int meanSpeed = 0; // 0-100mph
int gustSpeed = 0; // 0-100mph

// Set GPIO for Hall Sensor
const int HallSensorPin = 4;
int PulseCount = 0, windGust = 0;
float windSpeed = 0;

#include <WiFi.h>
#include <PubSubClient.h>

// Replace the next variables with your SSID/Password combination
const char* ssid = "Ubiquity";
const char* password = "********";

const char* mqtt_server = "192.168.1.140";

WiFiClient windClient;
PubSubClient client(windClient);

char msg[50];
int value = 0;

// Checks if Hall sensor was triggered - Interrupt Handler
void IRAM_ATTR HallTriggered() {
//  Serial.println("Hall Triggered");
  ++PulseCount; // Increment count
}

int Beaufort(int mph){
  if (mph < 1) return 0;
  else if (mph <= 3) return 1;
  else if (mph <= 7) return 2;
  else if (mph <= 12) return 3;
  else if (mph <= 18) return 4;
  else if (mph <= 24) return 5;
  else if (mph <= 31) return 6;
  else if (mph <= 38) return 7;
  else if (mph <= 46) return 8;
  else if (mph <= 54) return 9;
  else if (mph <= 63) return 10;
  else if (mph <= 72) return 11;
  else return 12;
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  
  // Hall Sensor mode INPUT_PULLUP
  pinMode(HallSensorPin, INPUT_PULLUP);
  // Set HallSensor pin as interrupt, assign interrupt function and set FALLING mode
  attachInterrupt(digitalPinToInterrupt(HallSensorPin), HallTriggered, FALLING);
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("windClient")) {
      Serial.println("connected");
      // Subscribe
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
//
void sendSpeedMessages(){
  // messages to send :-
  // wind/speed/mph -- meanSpeed
  // wind speed/force -- Beaufort(meanSpeed)
  // wind/gust/mph -- gustSpeed
  // wind/gust/force -- Beaufort(gustSpeed)
  // 
  // Convert the Mean Speed to a char array
  char msString[8];
  dtostrf(meanSpeed, 1, 1, msString);
  client.publish("wind/speed/mph", msString);
  
  // Convert the Mean-Speed-Force to a char array
  char bsString[8];
  dtostrf(Beaufort(meanSpeed), 1, 0, bsString);
  client.publish("wind/speed/force", bsString);
  
  // Convert the Gust-Speed to a char array
  char gsString[8];
  dtostrf(gustSpeed, 1, 0, gsString);
  client.publish("wind/gust/mph", gsString);

  // Convert the Gust-Speed-Force to a char array
  char bgString[8];
  dtostrf(Beaufort(gustSpeed), 1, 0, bgString);
  client.publish("wind/gust/force", bgString);
}
//  Debugging only
void sendNumberMessage(int N){
  // Convert the number to a char array
  char numString[8];
  dtostrf(N, 1, 0, numString);
  Serial.print("Number: ");
  Serial.println(numString);
  client.publish("wind/number", numString);
}
void sendNumberMessage2(int N){
  // Convert the number to a char array
  char numString[8];
  dtostrf(N, 1, 0, numString);
  Serial.print("Number: ");
  Serial.println(numString);
  client.publish("wind/number2", numString);
} 
//
void do3sJobs (){
  windSpeed += PulseCount;  //  Accumulate mean speed
  if (PulseCount > windGust) {windGust = PulseCount;};  // Get max speed for gust
  PulseCount = 0;
}
void do1mJobs(){
  // wind speed mean and gust ring arrays and report
  meanArray[ringIndex] = windSpeed; // put windSpeed into new array index
  gustArray[ringIndex] = windGust;  // put windGust into new array index
//  windSpeed /=13;  // /20 and *1.5 -- leave this for later
  meanSpeed = 0; gustSpeed = 0; windSpeed = 0; windGust = 0;
  for (int i = 0; i < 10; i++) { meanSpeed += meanArray[i];  // sum the windSpeeds 
    if (gustArray[i] > gustSpeed){gustSpeed = gustArray[i];}; // find maximum gust speed
  }
  meanSpeed /=133;  // the first sum was over 20 values and then the second over 10 values
  gustSpeed *= 1.5;  // Speed count over 3s rather than 4.5s
  sendSpeedMessages();
//  sendNumberMessage(ringIndex); debugging only
  ringIndex = (ringIndex+1)%10; // move ringIndex on to next location in the ring arrays
}
void do3mJobs(){
}

void loop() {
  if (!client.connected()) {reconnect();}
  client.loop();
// time the various periods
  long now = millis();
  if(now - last3s > P3s) {do3sJobs(); last3s = now;}
  if(now - last1m > P1m) {do1mJobs(); last1m = now;}
  if(now - last3m > P3m) {do3mJobs(); last3m = now;}
}

 

Link to comment
Share on other sites

In your do1mjobs routine you sum the contents of the meanArray irrespective of the number of entries in it. Then divide the total by a constant. That would explain why your mean value increments. I have no idea why it gets reset to zero - does the ESP32 get reset somehow?

 

As far as OTA uploads go, I would advise you to look into this. It saves a great deal of time and is well worth the effort. It also loads the code in faster :)

 

Link to comment
Share on other sites

Quote

void do1mJobs() {
 
  // wind speed mean and gust ring arrays and report
  meanArray[ringIndex] = windSpeed; // put windSpeed into new array index
  gustArray[ringIndex] = windGust;  // put windGust into new array index
  //  windSpeed /=13;  // /20 and *1.5 -- leave this for later
  meanSpeed = 0; gustSpeed = 0; windSpeed = 0; windGust = 0;
  for (int i = 0; i < 10; i++) {
    meanSpeed += meanArray;  // sum the windSpeeds
    if (gustArray > gustSpeed) {
      gustSpeed = gustArray;
    }; // find maximum gust speed
  }
  meanSpeed /= 133; // the first sum was over 20 values and then the second over 10 values
  gustSpeed *= 1.5;  // Speed count over 3s rather than 4.5s
  sendSpeedMessages();
  //  sendNumberMessage(ringIndex); debugging only
  ringIndex = (ringIndex + 1) % 10; // move ringIndex on to next location in the ring arrays

}

I auto formatted your code and spotted a superfluous semicolon in the summing loop.

Quote

    }; // find maximum gust speed

 

  • Thanks 1
Link to comment
Share on other sites

9 hours ago, pete_l said:

In your do1mjobs routine you sum the contents of the meanArray irrespective of the number of entries in it. Then divide the total by a constant. That would explain why your mean value increments. I have no idea why it gets reset to zero - does the ESP32 get reset somehow?

The meanArray should be fully loaded after the initial startup, with new entries simply overwriting the oldest entry.  It shouldn't be "reset to zero" (emptied) and nor should the new entries be zero.

9 hours ago, pete_l said:

As far as OTA uploads go, I would advise you to look into this. It saves a great deal of time and is well worth the effort. It also loads the code in faster :)

Found this :- ESP8266 Over The Air (OTA) Programming In Arduino IDE 

A couple of points. 

  1. I presume it's the same for the ESP32.
  2. I have a later Python on my machine.
  3. The tutorial shows the Windows version and I only have Linux (Mint)
Link to comment
Share on other sites

i use OTA updates - the point is that the OTA installs a web handler that can receive and blow new firmware images. Just browse to the URL in your browser, upload the firmware blob and hit submit. Key dependencies are that your device is on the network, is discoverable, etc,, so problematic if your device falls off the network for a programming reason, then you will need serial access .

I don't / haven't done it from the IDE though. 

 

  • Like 1
Link to comment
Share on other sites

This is the latest Wind display still showing the problem, which isn't surprising as the wind is still a moderate breeze - I estimate around Force 3-4, possibly gusting 5 looking at the trees.  This is the large oak trees at the bottom of the next field and a lot higher than my wind instruments so I'm not surprised that the Gusts are less strong at me anemometer.  I would say the Gust speed reading is reasonable.

723619425_Screenshotfrom2020-09-0313-29-59.png.aa9f9945690dfb073f5872eabb10b0a9.png

Link to comment
Share on other sites

I'm now looking into a way of simulating the anemometer in a test rig indoors.  Whilst I could do the testing all in one ESP32, I think it would be more realistic to use a separate source of pulses to feed the test ESP32.  One way is to use another ESP32 to generate the pulses either using a pot to vary the pulse rate or even set up as another client connected to the MQTT network where an input to the Node-RED Dashboard could set the frequency.  Using MQTT would mean I would have an exact control of the pulse rate.

Link to comment
Share on other sites

OTOH if the fault is in the code, generating a simulated interrupt within the same ESP32 should have the desired effect but if the problem is internal timing issues it might not.  The interrupt handler should have no problem with interrupts at the sort of rate we have here.  All it does is increment the PulseCount.

// Checks if Hall sensor was triggered - Interrupt Handler
void IRAM_ATTR HallTriggered() {
//  Serial.println("Hall Triggered");
  ++PulseCount; // Increment count
}

So if I produce code to increment the PulseCount at a variable rate it should do the same thing.  I think the easiest way would be to add another period to the list with the period set in millis.

void loop() {
  if (!client.connected()) {reconnect();}
  client.loop();
// time the various periods
  long now = millis();
  if(now - lastP > Ptest) {++PulseCount; lastP = now;}
  if(now - last3s > P3s) {do3sJobs(); last3s = now;}
  if(now - last1m > P1m) {do1mJobs(); last1m = now;}
  if(now - last3m > P3m) {do3mJobs(); last3m = now;}
}

 

Edited by Gina
Link to comment
Share on other sites

Realised that since I am running a test simulation with the ESP32 powered from the USB, I can use the Serial Monitor to see results - easier that setting up a load of Node_RED stuff.

  1. Testing at 1pps which is about 4.5 mph ATM.  Mean Speed reads 4.0mph.
  2. Testing at 2pps = 9mph.  Mean Speed reads 9.0mph.
  3. Testing at 12mph which is 375ms period.  Mean Speed reads 11.0mph.
Edited by Gina
Link to comment
Share on other sites

Problem showing.  Mean Speed rose to 11mph rather than 12 then dropped back to 10.  Continuing the test at this simulated wind speed.

131955198_Screenshotfrom2020-09-0315-41-05.thumb.png.adb80a4aa54d208bad847f31e044c9f1.png

Edited by Gina
Link to comment
Share on other sites

Well, I guess it isn't too bad but it isn't right so it fails the test.  Timing variations might explain the Gust speed varying between 12 and 13.  The Mean Speed is supposed to be displayed in tenths but I may have used int as speed to the nearest mph is good enough.  Think I'll try a large increase in wind speed and see if serious errors arise.  I'll go to 200ms next - 5pps = 5x4.5mph = 22.5mph.  I would expect the speed to show as 22 or 23.

84990726_Screenshotfrom2020-09-0315-51-12.thumb.png.0b123577cc26999a1be1a24595d00d5b.png

Link to comment
Share on other sites

Well, the test sketch is not showing the problem I'm getting with the real thing!!  That seems to prove the problem is not with the calculations but there is a problem none the less!!  The direction calculations are still running and everything is the same as the real thing except I'm simulating the anemometer pulses.  The only thing I can think of trying is to set up all the dials and graphs as the real thing in a Test tab on the Dashboard.

One other thing occurs to me - everything was fine with the display for a couple of days so I'm wondering if there is something time related.  I guess I could reset the real wind client by powering down and back up again.

Here's the current Wind display before I shut it down.

1964271613_Screenshotfrom2020-09-0316-38-47.png.7288c834522c586aaa488465728a6b52.png

Edited by Gina
Link to comment
Share on other sites

Hi Gina,

Quote

Mean Speed rose to 11mph rather than 12 then dropped back to 10. 

The maths within do1mjobs relies on do3sjobs being called 20 times between runs; you have a /133 (and the 133 = 10 * 20/1.5).  With connection issues causing 5 second waits between retries there may not always be 20 calls to do3sjobs and so your mean calculation will be too low (i.e dividing the sum of less than 20 speeds by 20 will lower the average speed).

You could solve this by incrementing a counter in do3sjobs which is then used in do1mjobs instead of the fixed 133 (i.e. use /(10*counter/1.5); and then reset it to zero after it's been used in do1mjobs.

I'm not sure why everything resets to zero though - it seems unlikely connection delays could last long enough to cause that. 

  • Thanks 1
Link to comment
Share on other sites

Can you get a ring buffer dump every time you have gone round the ring index. 

Is your buffer being written from somewhere else too ?

If you are happy that the individual values are in range, does the sum overflow ?

Are you getting a rash of spurious edges that cause it to occasionally overflow ? a la button damping ?

 

 

 

 

 

Link to comment
Share on other sites

Erm, good catch on the MQTT reconnect timeouts. Thats why I went to async reconnects handled through a separate timer handler. You dont want your device to be wrapped up and unresponsive to you becaase it can't see the MQTT server. Those periods will always be handled if you implement them using timer events. 

You can set the MQTT connection lifetime to be a longer value - the default is two minutes iirc. You should also watch out for the packets being within the MQTT header size - typically 120 bytes unless your redefine the limit in the library header. Also you need to go to the high capacity network model if your packets begin to get bigger than 350 bytes or so ( at least for the esp8266 version)

you can also drop this line as no longer required 

if (!client.connected()) {reconnect();}

since the Wifi object will auto reconnect if it detects a broken connection. 

 

Link to comment
Share on other sites

12 minutes ago, globular said:

Hi Gina,

The maths within do1mjobs relies on do3sjobs being called 20 times between runs; you have a /133 (and the 133 = 10 * 20/1.5).  With connection issues causing 5 second waits between retries there may not always be 20 calls to do3sjobs and so your mean calculation will be too low (i.e dividing the sum of less than 20 speeds by 20 will lower the average speed).

You could solve this by incrementing a counter in do3sjobs which is then used in do1mjobs instead of the fixed 133 (i.e. use /(10*counter/1.5); and then reset it to zero after it's been used in do1mjobs.

I'm not sure why everything resets to zero though - it seems unlikely connection delays could last long enough to cause that. 

Ah yes, lost connection delays could cause a problem and yes, using counting rather than timing would be better.  The actual timing of messages is not important but getting them right is.

Link to comment
Share on other sites

Things seem to work fine when there are no disconnects - I think this is the problem.  I need to take account of the ESP32 getting locked up by connection problems.  And I though using timing periods was a clever approach!!!  Guess I'm not as clever as I like to think!! 🤣

1446021449_Screenshotfrom2020-09-0318-03-52.thumb.png.3477389ffbea5df0fcbc7dc58fbd2586.png

Link to comment
Share on other sites

16 minutes ago, skybadger said:

Can you get a ring buffer dump every time you have gone round the ring index. 

I certainly could.

Quote

Is your buffer being written from somewhere else too ?

Pretty certain it isn't.

Quote

If you are happy that the individual values are in range, does the sum overflow ?

No, it doesn't.

Quote

Are you getting a rash of spurious edges that cause it to occasionally overflow ? a la button damping ?

No, I don't think so, the Hall device has considerable hysteresis and produces clean, square pulses.

Link to comment
Share on other sites

29 minutes ago, globular said:

I'm not sure why everything resets to zero though - it seems unlikely connection delays could last long enough to cause that. 

Yes, that's a puzzle.

Link to comment
Share on other sites

I can use the test setup to cause connection failures by interrupting the WiFi signal.

Or so I thought but I can't stop the connection.  I've completely shielded the WiFi with metal but it still connects.  Maybe it's because it's connected to my Mint box by USB.

Edited by Gina
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. By using this site, you agree to our Terms of Use.