Jump to content

Banner.jpg.b89429c566825f6ab32bcafbada449c9.jpg

Weather Station Ideas


Gina

Recommended Posts

The mention of a backtrace before the reboot suggests to me that something has been caught running out of bounds or something like that.  Perhaps run off the end of an array into memory you're not allowed to use?  Attempting to dereference a null pointer might be another favourite, but I don't recall you doing any pointery type stuff in your code.

James

  • Thanks 1
Link to comment
Share on other sites

All lines back except

  windSpeed += PulseCount;  //  Accumulate mean speed

Not sure why but windSpeed is a float whilst PulseCount is an integer.  I'll try changing that.

Link to comment
Share on other sites

Changed windSpeed to unsigned long int and it's working.  Except that the process that should occur every minute is running at 3s!

The speeds are zero because the sensors arn't connected.

1280372937_Screenshotfrom2020-09-0422-15-54.thumb.png.1181b6734fd83d6f185fc0a7d17d6f3e.png

Link to comment
Share on other sites

Found that error easily - forgot to reset the timerCount.

New code.

  if (timerCount >= 21) {speed21sum(); timerCount=0;};

 

Edited by Gina
Link to comment
Share on other sites

Looking at the code I would note that constant int xxxx = 1234ul will have unintended outcomes.

Also, dont sit and wait in the loop for things to fire. A loop happens  every 5ms or so, so loop should look for a timer  interrupt fired flag to indicate the desired event has happened rather than block. On do ding the flag you can then process the action. Otherwise,  while interrupts will keep on firing, your Wi-Fi may crap out due to missing carrier detects. 

Don't write debug code  in interrupts that write to serial.!

You are using the hardware timer, there are only a few available .  On the 8266 you can chain many more using the soft interrupt timer , I don't know if this is true for esp32.

You can use c_str() to convert strings to char [] . 

I haven't  run the code to work out where the issue is. 

  • Thanks 1
Link to comment
Share on other sites

42 minutes ago, JamesF said:

The mention of a backtrace before the reboot suggests to me that something has been caught running out of bounds or something like that.  Perhaps run off the end of an array into memory you're not allowed to use?  Attempting to dereference a null pointer might be another favourite, but I don't recall you doing any pointery type stuff in your code.

James

The problem was trying to increment a float.  Now fixed.

Link to comment
Share on other sites

11 minutes ago, skybadger said:

Looking at the code I would note that constant int xxxx = 1234ul will have unintended outcomes.

Got that from the Arduino Reference for Constants.

Quote

U & L formatters:

By default, an integer constant is treated as an int with the attendant limitations in values. To specify an integer constant with another data type, follow it with:

  • a 'u' or 'U' to force the constant into an unsigned data format. Example: 33u

  • a 'l' or 'L' to force the constant into a long data format. Example: 100000L

  • a 'ul' or 'UL' to force the constant into an unsigned long constant. Example: 32767ul

 

Link to comment
Share on other sites

12 minutes ago, skybadger said:

Also, dont sit and wait in the loop for things to fire. A loop happens  every 5ms or so, so loop should look for a timer  interrupt fired flag to indicate the desired event has happened rather than block. On do ding the flag you can then process the action. Otherwise,  while interrupts will keep on firing, your Wi-Fi may crap out due to missing carrier detects.

OK took that from elsewhere - changed it to

void loop() {
//  if (!client.connected()) {reconnect();}
  client.loop();
  if (interrupts == 0 ){
    // ISR has triggered - proceed and perform the jobs
    if (timerCount >= 21) {speed21sum(); timerCount=0;};
    // time the various periods
    long now = millis();
    if(now - last3s > P3s) {getDirection(); last3s = now;}
    if(now - last3m > P3m) {ConsensusAveraging(); last3m = now;}
    interrupts = 0; // Reset the flag
  }
}

 

Link to comment
Share on other sites

14 minutes ago, skybadger said:

Don't write debug code  in interrupts that write to serial.!

I'm not.

16 minutes ago, skybadger said:

You are using the hardware timer, there are only a few available .  On the 8266 you can chain many more using the soft interrupt timer , I don't know if this is true for esp32.

I'm only running one hardware timer - the ESP32 has 4.  All other timings are by counting or using millis and now.

Link to comment
Share on other sites

Grand.

While there are 4 hardware timers , how many of them are already in use by the os ? At least one for Wi-Fi and obedience the soft timer handler.

While the Arduino manual is right you cannot declare an int and stuff it with an unsigned long.

,you d really like the compiler to pick that float + int error up. 

  • Like 1
Link to comment
Share on other sites

The hardware timer works.

I don't quite understand "While the Arduino manual is right you cannot declare an int and stuff it with an unsigned long."  I've thought about this, it seems to work fine but I guess I could assign an unsigned long variable and preset it with the value I want and use it as a constant.  After all, a non-varying variable is a constant in effect.  Would that be better?

Yes, the compiler should have picked up that error.  Guess nothing is perfect and the error checking is pretty good.  Though sometimes the error message can be rather vague or unhelpful.

Link to comment
Share on other sites

2 minutes ago, Gina said:

I don't quite understand "While the Arduino manual is right you cannot declare an int and stuff it with an unsigned long."

On the Arduino an int type takes 2 bytes of memory. There will be other variables adjacent to it with their own data values. When you try to store a 4-byte value in the space allocated for an int, the other 2 bytes will overwrite data in the 2 bytes either above or below that int.
This is bad when done in global memory space. When done to local variables within a routine it can have even weirder effects. Especially if that ul data corrupts the routine's return address, which is also held on the same stack.

  • Thanks 1
Link to comment
Share on other sites

I thought adding U or L or UL allocated the extra space but to avoid any possible trouble I've declared as follows

// periods or intervals in milliseconds
const int P3s = 3000;       // integer
unsigned long P3m = 180000; // variable used as constant
unsigned long last3s = 0;
unsigned long last3m = 0;

 

Link to comment
Share on other sites

Working fine I think, though won't know for sure until I get the wind sensors connected and the wind blowing on it.  Looks like the UL constant(s) has been causing the problems all along and that the Arduino Reference is wrong!

648612023_Screenshotfrom2020-09-0509-58-12.png.874db2a15258abf3c902c4b1e5607d45.png

Edited by Gina
Link to comment
Share on other sites

Running test rig on the table with desk fan.  Seems reasonable.  Mean speed slightly below the Gust speed but speeds are just to the nearest mph, so Gust of 10mph and Mean of 9mph is reasonable.

926002206_Screenshotfrom2020-09-0512-26-58.thumb.png.fb29a4b2cc58d524ee01bdb71ec2fe4f.png

  • Like 1
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.