Jump to content

Gina

Beyond the Event Horizon
  • Posts

    45,326
  • Joined

  • Last visited

  • Days Won

    120

Everything posted by Gina

  1. Ah yes, That's one I've read about before but couldn't remember what it was called. I've posted in the DIY Observatories forum to see if others have used it and any experiences though I'm not sure this is the best place.
  2. I certainly wouldn't rely on a rain gauge to close the ROR - it would only be a backup if everything else failed. I'd rather have two different forms of rain detector though. I've asked for suggestions in the past but got no replies.
  3. I already have one of these :- Rain Sensor 12 V/DC but I do wonder if there's something better.
  4. The automatic Y range of the history graphs works quite well for the pressure but less well for temperatures but with the Node-RED system being so easy to use, it's easy to alter the ranges to suit current conditions manually, unlike physical gauges. Here is a new display with more suitable temperature ranges IMO.
  5. I like this system for displaying current conditions and recent history. Of course, standard weather data logging and display is another matter. That may come later as it's something I've always been interested in but there's lots to do before that. There are more sensors and data processing to add to the current system plus the ROR control. Although in some ways a weather station and control of the observatory roof are two distinct systems, they do relate to each other and covering both in one MQTT system makes sense.
  6. I was going to add the data from the rain gauge into the wind sensor unit with the gauge mounted on the same mast but now I'm having second thoughts and thinking it would be better fed to the ROR control unit as a second source for closing the roof, in addition to the rainfall information for the weather station - a "belt and braces" approach. I'm also thinking of adding a sky temperature sensor into the weather data somewhere and guess the ROR control unit would make sense for that too.
  7. Dashboard display still fine. Hoping to make progress on the sketch for the rain sensors today - lots of data processing.
  8. I think I may use different periods for the wind speed and direction. Although easier to have the same it isn't necessary and the ideal periods work out differently. I reckon ring arrays will work for both speed and direction and seems to me a better approach to consensus averaging for the direction.
  9. 6 hours later and the display is still good with no "lost connection" errors!! Seem to have cured the problem.
  10. This is the dashboard display. The pressure shows where I had rounding to integer (which seemed unsuitable). The wind sensor is awaiting development.
  11. Example of modulus % /* update one value in an array each time through a loop */ int values[10]; int i = 0; void setup() {} void loop() { values[i] = analogRead(0); i = (i + 1) % 10; // modulo operator rolls over variable }
  12. There are 3 periods or intervals. A 3s period used to count anemometer revolutions and to read the instantaneous wind direction then a 60s period used as the reporting (message sending) period and finally a 10m period for the mean direction.
  13. Since the atmospheric pressure often changes very slowly I've decided to round to one decimal place. Same for temperatures but pressures I've set to zero decimal places. Just a matter of setting the appropriate number of decimal places in the dtostrf function which converts numbers to a char array for MQTT.
  14. I'm still displaying readings to the default 2 decimal places when the readings are nothing like that accurate. In fact integer values would suit the reading accuracy better. I see no point in showing the atmospheric pressure more accurately than integer values but I may round temperature and humidity to tenths.
  15. I have now applied averaging in all the currently running clients. Taking readings every 5s as before but accumulating data over 12 intervals then dividing by 12, sending the messages to MQTT and resetting ready for the next 12 intervals. I have also reset the RPi to clear all old data and started again. Looking better so far but it's "early days"!
  16. I need to consider my various periods. ATM I'm using a 4.5s counting period for the anemometer speed count which would be good enough as the gust period since I'm not producing weather reports for publication. I think a one minute reporting period would suffice for wind speed. With a 10m period being standard for mean wind speed I could use a 10 integer ring buffer. With an integral number of 4.5s periods not fitting into a minute I think the irregular sampling could be a problem plus I would like to abide by the standard for gusts so I'm having second thoughts about the 4.5s counting period. I could use a 3s period and adjust the result by multiplying by 1.5. Only the very low speeds would be affected and accurate low wind speeds are not relevant. This would mean 20 counting periods to one reporting period and 10 reporting periods for the period over which the mean and gust wind speed would be calculated.
  17. I'm still having a problem displaying the dashboard. I'm wondering if I'm trying to display too much information. Or too much changing information. Most of my sensors are sending messages every 5s and several in quick succession. It really isn't necessary to have the data updated this often and generally the actual values don't change that quickly. The only reason for the rapidly changing data is noise. The only truly rapidly changing data is wind gusts and even that doesn't want displaying every few seconds. I think it would be better to average the data and send MQTT messages far less often. Or am I barking up the wrong tree here?
  18. Yes, I thought of doing that myself but not sure how easy it would be. I hadn't thought of subtracting the oldest value from the sum and adding the newest though. A ring buffer for the consensus averaging was something I hadn't thought of but it makes a lot of sense as the direction is a ring.
  19. I think the easiest way of making a running average and maximum is to push them down a queue. A10 = A9 A9 = A8 A8 = A7 etc. This can be simplified using an array and decreasing index. The average and maximum can also be derived from the array.
  20. The next stage in the wind sensors is mathematical. Rather than just the instantaneous direction and the wind speed taken over a few seconds, I want Mean and Gust wind speed and an average direction rather the a direction that varies all over the place with turbulence. The wind speed is straightforward. The highest rev count in an extended time is taken as the gust speed and the average in that period is the Mean. With the period being 10m and wanting readings more often than this I think I shall use a running average and maximum. For the wind direction there is a procedure called Consensus Averaging that collects a number of values in "bins" and then an average of the bins with the highest number of counts is taken. This uses an array of 20 integers where the direction counts are collected.
  21. Sent the Gray code as well and that's working so it's in the Gray code to direction in binary that's wrong. Edit - found my error! Working now. 16 discrete directions in sequence. Only thing is, it's going anti-clockwise instead of clockwise as seen from above. I can fix that easily enough. Now edited the sketch above. Direction fixed and all working fine (as far as it goes). This is just the instantaneous value and wants smoothing which I'll add next. This screenshot of MQTT Explorer shows the vane direction as I turned it (turned it a bit too far in the middle).
  22. Something wrong - wind direction isn't being displayed in the dashboard.
  23. Here is the full sketch for the wind sensors so far. This will read the rotary encoder on the vane and count revolution of the anemometer and send the instantaneous wind direction and wind speed to the MQTT network. // MQTT for wind sensors /********* Rui Santos Complete project details at https://randomnerdtutorials.com ******** Modified and added to by Gina 2020-08-21 onward ******** */ const int Interval = 4500; // Set sampling interval in milliseconds // 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; // Set GPIO for Hall Sensor const int HallSensorPin = 4; int PulseCount = 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); long lastMsg = 0; char msg[50]; int value = 0; // Checks if Hall sensor was triggered 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(); // Feel free to add more if statements to control more GPIOs with MQTT } 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 // client.subscribe("esp32/output"); // client.subscribe("esp32/roof"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); if(now - lastMsg > Interval) { // Serial.println("PulseCount :- "); lastMsg = now; // Convert the value to a char array char countString[8]; dtostrf(PulseCount, 1, 0, countString); Serial.print("mph: "); Serial.println(countString); client.publish("wind/speed/mph", countString); // Get Beaufort value // Convert the value to a char array char BeaufortString[8]; dtostrf(Beaufort(PulseCount), 1, 0, BeaufortString); Serial.print("Force: "); Serial.println(BeaufortString); client.publish("wind/speed/force", BeaufortString); PulseCount = 0; // Read wind vane optical sensor values dir1 = analogRead(An1); dir2 = analogRead(An2); dir3 = analogRead(An3); dir4 = analogRead(An4); /* Serial.print(dir1); Serial.print(" "); Serial.print(dir2); Serial.print(" "); Serial.print(dir3); Serial.print(" "); Serial.print(dir4); Serial.println(" ");*/ // Convert Gray bits to integer int Gray = 0; if (dir1 > 2000) {Gray = 8;}; if (dir2 > 2000) {Gray = Gray + 4;}; if (dir3 > 2000) {Gray = Gray + 2;}; if (dir4 > 2000) {Gray = Gray + 1;}; // Convert Gray to binary dirn = 15 - codeArray[Gray]; // Convert the value to a char array char dirString[8]; dtostrf(dirn, 1, 0, dirString); Serial.print("Direction: "); Serial.println(dirString); client.publish("wind/direction", dirString); } }
  24. Now added Gray to binary conversion. // 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 code logic levels bool dirBit1 = false; bool dirBit2 = false; bool dirBit3 = false; bool dirBit4 = false; // 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; // Convert to logic levels dirBit1 = (dir1 > 2000); dirBit2 = (dir2 > 2000); dirBit3 = (dir3 > 2000); dirBit4 = (dir4 > 2000); // Convert bits to integer int Gray = 0; if (dir1 > 2000) {Gray = 8;}; if (dir2 > 2000) {Gray = Gray + 4;}; if (dir3 > 2000) {Gray = Gray + 2;}; if (dir4 > 2000) {Gray = Gray + 1;}; // Convert Gray to binary dirn = codeArray[16]; The dirBitx set isn't needed with this shortcut.
×
×
  • 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.