Karaburan: Difference between revisions
m (→Turbidity) |
|||
(87 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{Project | {{Project | ||
|Name=Karaburan | |Name=Karaburan | ||
|Picture= | |Picture=karaburan.png | ||
|Omschrijving=Monitoring water quality | |Omschrijving=Monitoring water quality | ||
|Status= | |Status=In progress | ||
|Contact=bertrik | |Contact=bertrik | ||
}} | }} | ||
== Next steps == | |||
* engage with PX4 community on getting a feel if this is useful to use and if so, how to get started | |||
* figure out how to duplicate an MQTT stream | |||
* write python scripts | |||
** arduino turbidity | |||
** turbidity-to-mqtt | |||
** HID-to-mqtt | |||
** position/velocity listener script: latitude, longitude, altitude, heading/bearing/track/whatever, velocity | |||
* hook things into systemd / udev | |||
* analoog in op de pi: | |||
** https://elektronicavoorjou.nl/product/adc-pi/ | |||
** https://www.123materialen.com/products/zeer-nauwkeurige-ads1256-dac8552-ad-da-board-voor-raspberry-pi_1676153 | |||
** FreeJoy project | |||
* UPS voor pi: https://elektronicavoorjou.nl/product/raspberry-pi-ups-hat/ | |||
* 1-wire stuff: | |||
** 1-wire adapter emulation on an stm32: https://github.com/alitekin2fx/stm32_ds2480_emu | |||
** owfs.org for easy interfacing with multiple 1-wire devices in a hierarchical way on linux | |||
Check: | |||
* https://www.rtvnoord.nl/natuur/1215705/vuilrobot-maakt-jachthaven-winschoten-schoon-beter-dan-met-een-schepnet | |||
=== USB HID as analog input === | |||
An stm32 based bluepill board can be flashed with firmware to allow its analog inputs to be exposed as USB HID sliders. | |||
Flashing the bluepill with openocd to the freejoy firmware: | |||
* install openocd | |||
sudo apt install openocd | |||
* connect an stlinkv2 to an stm32 bluepill, connect the stlinkv2 to USB | |||
* flash the freejoy firmware as follows: | |||
** download the firmware from https://github.com/FreeJoy-Team/FreeJoy | |||
** create a symlink to the hex file called firmware.hex | |||
** flash the firmware from the command line | |||
openocd -s /usr/share/openocd/scripts -f interface/stlink.cfg -f target/stm32f1x.cfg -c init -c "program firmware.hex verify reset exit" | |||
* watch the kernel logs | |||
sudo dmesg -w | |||
* connect the stm32 using a USB cable | |||
* download the freejoy configurator from https://github.com/FreeJoy-Team/FreeJoyConfiguratorQt | |||
* start the configurator and load the karaburan.cfg setting | |||
* Write config to device -> it should reboot now and come up with the new settings | |||
Verify that it works: | |||
* install the evtest package | |||
* run | |||
evtest /dev/input/by-id/usb-FreeJoy_FreeJoy_v1.7.1-event-if00 | |||
See also https://github.com/vostrenkov/EazyJoy | |||
=== influxdb === | |||
See https://hub.docker.com/_/influxdb | |||
See https://github.com/bertrik/karaburan/tree/master/influxdb | |||
=== ROS === | |||
Investigation: | |||
* Use ROS 2, not the old ROS 1 | |||
* Cannot work comfortably with debian, works best with ubuntu | |||
* Using gpsd: | |||
** install ros-jazzy-desktop | |||
** ros2 launch gpsd_client gpsd_client-launch.py | |||
== Introduction == | == Introduction == | ||
Line 24: | Line 84: | ||
** conductivity/total dissolved solids | ** conductivity/total dissolved solids | ||
** water properties by light reflection, hyperspectral/polarity | ** water properties by light reflection, hyperspectral/polarity | ||
** depth? | |||
* boat control | * boat control | ||
** trajectory -> steering | ** trajectory -> steering | ||
** idea: interface with the remote control, not with the boat | |||
** idea: find a boat with easily hackable remote control protocol | |||
** idea: can we get sensor data over this link too, e.g. GPS? | |||
* camera control | * camera control | ||
* post-processing | * post-processing | ||
Line 41: | Line 105: | ||
** processing platform selection | ** processing platform selection | ||
** communication platform selection | ** communication platform selection | ||
== Investigate RTK GPS == | |||
Goal: figure out if it is practically possible to achieve cm resolution with a 200-euro GPS and a free correction service: YES | |||
* https://www.nsgi.nl/referentiepunten-en-gnss-data/gnss-data/real-time-streams public correction data service | |||
* https://www.ardusimple.nl/rtk-in-5-minutes/ | |||
* RTK in action https://www.youtube.com/watch?v=Oc1LBFDj2MA | |||
* Use with Linux / gpsd: https://stackoverflow.com/questions/77314115/drotek-gpsd-and-ntrip-correction-data-for-precise-positioning ? | |||
* Chipsets | |||
** Quectel LC29H (default: 115200 bps) | |||
*** review: see https://rtklibexplorer.wordpress.com/2024/04/28/dual-frequency-rtk-for-less-than-60-with-the-quectel-lc29hea/ | |||
*** configuration: https://rtklibexplorer.wordpress.com/2024/05/06/configuring-the-quectel-lc29hea-receiver-for-real-time-rtk-solutions/ | |||
** uBLOX ZED-F9P | |||
* Boards | |||
** UM980 / UM982 | |||
Edit /etc/default/gpsd, set GPSD_OPTIONS: | |||
GPSD_OPTIONS="-Gn ntrip://user:pass@ntrip.kadaster.nl:2101/CBW100NLD0" | |||
Option -G exposes the control socket on all network interfaces, option -n keeps the GPS active if there is no one currently connected. | |||
Plotting live location on a map: | |||
* Configure gpsd to expose its socket to the outside world: last section of https://gpsd.gitlab.io/gpsd/troubleshooting.html | |||
* In QGIS, press ctrl+0 to show the GPS information tab, enter the name of the remote gpsd (port 2947) | |||
Station at Stolwijk (close to Gouda): https://gnss1.tudelft.nl/dpga/station/Stolwijk.html#STWK ? | |||
Starting from the command line: | |||
* stop gpsd.socket | |||
sudo systemctl stop gpsd.socket | |||
* run from command line | |||
sudo /usr/sbin/gpsd -Gn -D 1 -N /dev/ttyUSB0 .... (not sure yet) | |||
=== Validation === | |||
How to show that RTK GPS is actually accurate? | |||
* Relative positioning: with an "fix RTK" solution, place the antenna at 4 points 25cm apart, each point for 20 seconds or so -> you see 4 distinct clusters of points | |||
* Positioning over short time: put it in a fixed location, make sure that it has "fix RTK" solution, take 100 measurements or so -> determine the radius of the circle that contains 90% of the points | |||
* Positioning over longer time: do this for (say) an hour | |||
* Absolute positioning: look up a national reference point, for example "RD-punt 389346", located on the Sluisdijk between Gouda and Moordrecht. Technical data: https://www.nsgi.nl/iv-api/rdinfo/rdpoint/389346 | |||
** see https://www.nsgi.nl/referentiepunten-en-gnss-data/informatie-referentiepunten/rdinfo and enter 389346 | |||
** latitude: 51° 59' 49,64048" , longitude: 4° 41' 19,90765", or 51.99712236/4.68886324 | |||
==== Comparison with reference coordinate ==== | |||
On october 4th, we took the RTK GPS to a kernnet reference point at 51.99712236/4.68886324, results below: | |||
Differences between the reference point and the measurements are calculated to easting ('X') and northing ('Y'), unit meter. To calculate distance in meters, we use a linear approximation: | |||
* For dy: 40075km/360 = 111,319 m/deg | |||
* For dx: dy * cos(latitude) = 68,549 m/deg | |||
{| class="wikitable" style="margin:auto" | |||
|+ Measurements + deviations | |||
|- | |||
! Name !! Latitude !! Longitude !! dx (m) !! dy (m) !! absolute (m) !! Remark | |||
|- | |||
| Reference || 51.99712236 || 4.68886324 || - || - || 0 || by definition | |||
|- | |||
| Screenshot 1 || 51.99712217 || 4.68886567 || 0.167 || -0.021 || 0.168 || - | |||
|- | |||
| Screenshot 2 || 51.99712200 || 4.68886533 || 0.143 || -0.040 || 0.149 || - | |||
|- | |||
| Meting 1 || 51.9971220 || 4.6888663 || 0.210 || -0.040 || 0.214 || - | |||
|- | |||
| Meting 2 || 51.9971222 || 4.6888660 || 0.189 || -0.018 || 0.190 || - | |||
|- | |||
| Average || - || - || 0.177 || -0.030 || 0.180 || - | |||
|} | |||
According to [https://www.unavco.org/software/geodetic-utilities/plate-motion-calculator/plate-motion-calculator.html this page], the rate of movement is about | |||
15.75mm/year to the north and 17.45 mm/year to the east (ITRF2020 model). | |||
Over 12 years, that amounts to 0.189m north and 0.209m east. | |||
== Air quality sensors == | == Air quality sensors == | ||
Line 58: | Line 192: | ||
=== Turbidity / clarity === | === Turbidity / clarity === | ||
See https://en.wikipedia.org/wiki/Turbidity | See https://en.wikipedia.org/wiki/Turbidity | ||
Aliexpress sensor '''TS-300B''': https://nl.aliexpress.com/item/1005006732956937.html | |||
Has a range 0 ~ 1000 ± 30 NTU | |||
Order of magnitude for turbidity: | |||
* Drinking water upper limit: '''4 NTU''' (European turbidity standard for drinking water) | |||
* Ambient water: 10-150 NTU. The US state of Washington use a "background" value of '''50 NTU''' as reference. | |||
(see https://en.wikipedia.org/wiki/Turbidity#Standards_and_test_methods ) | |||
So the Aliexpress sensor is suited only for "dirty" water. | |||
== Boat control == | |||
Typically the wireless link looks like this: | |||
* 2.4 GHz working frequency | |||
* 500m range | |||
Interesting links: | |||
* Flytec-2011 remote control https://nl.aliexpress.com/item/1005002984723718.html | |||
* Replacement board for various boats with "18" in their type number: https://nl.aliexpress.com/item/1005006115484716.html | |||
* DIY Multi-protocol module: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module | |||
=== remote control === | |||
Image of remote control RF chip: | |||
[...] | |||
Parts: | |||
* 12.000 MHz crystal/oscillator | |||
* 16-pin control chip: 20_CL6L071 | |||
* 6-pin RF chip: 1110 / VKA3, could be an rx/tx switch, amplifier or filter circuit | |||
See also: https://www.open-tx.org/ | |||
Next steps: | |||
* map out the connections between the mainboard and the rf board, expected: VCC, GND, spi ? | |||
== Use cases == | == Use cases == | ||
Line 64: | Line 233: | ||
* https://iplo.nl/thema/water/oppervlaktewater/kaderrichtlijn-water | * https://iplo.nl/thema/water/oppervlaktewater/kaderrichtlijn-water | ||
* kaartje: https://krw-nutrend.netlify.app/ -> 2 meetpunten op de reeuwijkse plassen, tijdresolutie is 1 jaar? | * kaartje: https://krw-nutrend.netlify.app/ -> 2 meetpunten op de reeuwijkse plassen, tijdresolutie is 1 jaar? | ||
Useful distinction, typically used in documents/guidelines: | |||
* chemical quality, what substances are present in the water? | |||
* biological / ecology quality, what kind of living organisms live in the water? | |||
=== Reeuwijkse plassen === | === Reeuwijkse plassen === | ||
Line 71: | Line 244: | ||
potential applications: | potential applications: | ||
* | * inspect water sides (oever) over time | ||
* underwater camera: detect invasive cray fish | * underwater camera: detect invasive cray fish | ||
* sample water properties at high spatial resolution, high time resolution | * sample water properties at high spatial resolution, high time resolution | ||
* early detection of indicators for cyanobacteria: temperature and nutrients | * early detection of indicators for cyanobacteria: temperature and nutrients | ||
=== Detect/find pollution source === | |||
* ... | |||
== Implementation == | |||
=== reading temperature sensor === | |||
The idea is to to use a DB18B20 temperature sensor, read it using an arduino nano board acting as a 1-wire adapter. | |||
Use openwire-fs as user-side openwire software http://owfs.org | |||
Preparation: | |||
* Add the regular user to the 'dialout' group, so it can access serial ports | |||
sudo adduser <name> dialout | |||
Setting up the hardware: | |||
* connect the DS18B20 to the connector board with the pull-ups | |||
* wire the connector board to the arduino nano, see ... | |||
* plug the arduino nano in the pi | |||
Setting up the software: | |||
* Install openwire fs | |||
sudo apt install owfs | |||
* Create the openwire fs mountpoint | |||
sudo mkdir /mnt/1wire | |||
* Configure owfs, edit /etc/owfs.conf | |||
server: device = /dev/ttyUSB0 | |||
mountpoint = /mnt/1wire | |||
allow_other | |||
(comment out the line with the FAKE devices) | |||
* Configure systemd services | |||
sudo systemctl enable owserver owhttpd | |||
sudo systemctl disable owftpd | |||
* Start the systemd service | |||
sudo systemctl start owserver owhttpd | |||
* Check the logs | |||
sudo journalctl -xeu owserver -f | |||
* Open a browser to view the web interface | |||
http://localhost:2121 or | |||
http://raspberrypi.local:2121 |
Latest revision as of 23:33, 9 December 2024
Project Karaburan | |
---|---|
Monitoring water quality | |
Status | In progress |
Contact | bertrik |
Last Update | 2024-12-09 |
Next steps
- engage with PX4 community on getting a feel if this is useful to use and if so, how to get started
- figure out how to duplicate an MQTT stream
- write python scripts
- arduino turbidity
- turbidity-to-mqtt
- HID-to-mqtt
- position/velocity listener script: latitude, longitude, altitude, heading/bearing/track/whatever, velocity
- hook things into systemd / udev
- analoog in op de pi:
- UPS voor pi: https://elektronicavoorjou.nl/product/raspberry-pi-ups-hat/
- 1-wire stuff:
- 1-wire adapter emulation on an stm32: https://github.com/alitekin2fx/stm32_ds2480_emu
- owfs.org for easy interfacing with multiple 1-wire devices in a hierarchical way on linux
Check:
USB HID as analog input
An stm32 based bluepill board can be flashed with firmware to allow its analog inputs to be exposed as USB HID sliders.
Flashing the bluepill with openocd to the freejoy firmware:
- install openocd
sudo apt install openocd
- connect an stlinkv2 to an stm32 bluepill, connect the stlinkv2 to USB
- flash the freejoy firmware as follows:
- download the firmware from https://github.com/FreeJoy-Team/FreeJoy
- create a symlink to the hex file called firmware.hex
- flash the firmware from the command line
openocd -s /usr/share/openocd/scripts -f interface/stlink.cfg -f target/stm32f1x.cfg -c init -c "program firmware.hex verify reset exit"
- watch the kernel logs
sudo dmesg -w
- connect the stm32 using a USB cable
- download the freejoy configurator from https://github.com/FreeJoy-Team/FreeJoyConfiguratorQt
- start the configurator and load the karaburan.cfg setting
- Write config to device -> it should reboot now and come up with the new settings
Verify that it works:
- install the evtest package
- run
evtest /dev/input/by-id/usb-FreeJoy_FreeJoy_v1.7.1-event-if00
See also https://github.com/vostrenkov/EazyJoy
influxdb
See https://hub.docker.com/_/influxdb
See https://github.com/bertrik/karaburan/tree/master/influxdb
ROS
Investigation:
- Use ROS 2, not the old ROS 1
- Cannot work comfortably with debian, works best with ubuntu
- Using gpsd:
- install ros-jazzy-desktop
- ros2 launch gpsd_client gpsd_client-launch.py
Introduction
Topics:
- air quality sensors
- ammonia
- NOx
- water chemical analysis
- nitrates
- ammonia
- dissolved oxygen
- sulfide/sulfate
- phosphates?
- salinity (chlorides?)
- water physical analysis
- temperature
- clarity/turbidity -> investigate standard ways of measuring/expressing this
- conductivity/total dissolved solids
- water properties by light reflection, hyperspectral/polarity
- depth?
- boat control
- trajectory -> steering
- idea: interface with the remote control, not with the boat
- idea: find a boat with easily hackable remote control protocol
- idea: can we get sensor data over this link too, e.g. GPS?
- camera control
- post-processing
- data presentation
- video/photo stitching
- time lapse view
- map view of properties
- data presentation
- use cases
- verify with domain experts, how to engage?
- slootview, under/above water
- minimum viable prototype
- high-res measurement by location, by time
- materials
- boat selection
- processing platform selection
- communication platform selection
Investigate RTK GPS
Goal: figure out if it is practically possible to achieve cm resolution with a 200-euro GPS and a free correction service: YES
- https://www.nsgi.nl/referentiepunten-en-gnss-data/gnss-data/real-time-streams public correction data service
- https://www.ardusimple.nl/rtk-in-5-minutes/
- RTK in action https://www.youtube.com/watch?v=Oc1LBFDj2MA
- Use with Linux / gpsd: https://stackoverflow.com/questions/77314115/drotek-gpsd-and-ntrip-correction-data-for-precise-positioning ?
- Chipsets
- Quectel LC29H (default: 115200 bps)
- uBLOX ZED-F9P
- Boards
- UM980 / UM982
Edit /etc/default/gpsd, set GPSD_OPTIONS:
GPSD_OPTIONS="-Gn ntrip://user:pass@ntrip.kadaster.nl:2101/CBW100NLD0"
Option -G exposes the control socket on all network interfaces, option -n keeps the GPS active if there is no one currently connected.
Plotting live location on a map:
- Configure gpsd to expose its socket to the outside world: last section of https://gpsd.gitlab.io/gpsd/troubleshooting.html
- In QGIS, press ctrl+0 to show the GPS information tab, enter the name of the remote gpsd (port 2947)
Station at Stolwijk (close to Gouda): https://gnss1.tudelft.nl/dpga/station/Stolwijk.html#STWK ?
Starting from the command line:
- stop gpsd.socket
sudo systemctl stop gpsd.socket
- run from command line
sudo /usr/sbin/gpsd -Gn -D 1 -N /dev/ttyUSB0 .... (not sure yet)
Validation
How to show that RTK GPS is actually accurate?
- Relative positioning: with an "fix RTK" solution, place the antenna at 4 points 25cm apart, each point for 20 seconds or so -> you see 4 distinct clusters of points
- Positioning over short time: put it in a fixed location, make sure that it has "fix RTK" solution, take 100 measurements or so -> determine the radius of the circle that contains 90% of the points
- Positioning over longer time: do this for (say) an hour
- Absolute positioning: look up a national reference point, for example "RD-punt 389346", located on the Sluisdijk between Gouda and Moordrecht. Technical data: https://www.nsgi.nl/iv-api/rdinfo/rdpoint/389346
- see https://www.nsgi.nl/referentiepunten-en-gnss-data/informatie-referentiepunten/rdinfo and enter 389346
- latitude: 51° 59' 49,64048" , longitude: 4° 41' 19,90765", or 51.99712236/4.68886324
Comparison with reference coordinate
On october 4th, we took the RTK GPS to a kernnet reference point at 51.99712236/4.68886324, results below:
Differences between the reference point and the measurements are calculated to easting ('X') and northing ('Y'), unit meter. To calculate distance in meters, we use a linear approximation:
- For dy: 40075km/360 = 111,319 m/deg
- For dx: dy * cos(latitude) = 68,549 m/deg
Name | Latitude | Longitude | dx (m) | dy (m) | absolute (m) | Remark |
---|---|---|---|---|---|---|
Reference | 51.99712236 | 4.68886324 | - | - | 0 | by definition |
Screenshot 1 | 51.99712217 | 4.68886567 | 0.167 | -0.021 | 0.168 | - |
Screenshot 2 | 51.99712200 | 4.68886533 | 0.143 | -0.040 | 0.149 | - |
Meting 1 | 51.9971220 | 4.6888663 | 0.210 | -0.040 | 0.214 | - |
Meting 2 | 51.9971222 | 4.6888660 | 0.189 | -0.018 | 0.190 | - |
Average | - | - | 0.177 | -0.030 | 0.180 | - |
According to this page, the rate of movement is about 15.75mm/year to the north and 17.45 mm/year to the east (ITRF2020 model). Over 12 years, that amounts to 0.189m north and 0.209m east.
Air quality sensors
Nitrogen compounds in air
According to https://www.rivm.nl/stikstof/monitoren-advies-onderzoek/overzicht-stikstofmetingen/metingen-stikstof-in-de-lucht average (typical?) values of
- Ammonia (NH3): 6.7 ug/m3 (9.6 ppb)
- NOx: 27.3 ug/m3
- NO2: 18.6 ug/m3 (9.9 ppb)
(ppb-conversion using https://www.breeze-technologies.de/blog/air-pollution-how-to-convert-between-mgm3-%C2%B5gm3-ppm-ppb/ )
RIVM report on inexpensive nitrogen-in-air sensors: https://www.samenmeten.nl/sensoren-voor-no2 Conclusion: most sensors are not sensitive enough to be used in typical outdoor conditions, with perhaps one exception: alphasense NO2-B43F
Water physical analysis
Turbidity / clarity
See https://en.wikipedia.org/wiki/Turbidity
Aliexpress sensor TS-300B: https://nl.aliexpress.com/item/1005006732956937.html Has a range 0 ~ 1000 ± 30 NTU
Order of magnitude for turbidity:
- Drinking water upper limit: 4 NTU (European turbidity standard for drinking water)
- Ambient water: 10-150 NTU. The US state of Washington use a "background" value of 50 NTU as reference.
(see https://en.wikipedia.org/wiki/Turbidity#Standards_and_test_methods )
So the Aliexpress sensor is suited only for "dirty" water.
Boat control
Typically the wireless link looks like this:
- 2.4 GHz working frequency
- 500m range
Interesting links:
- Flytec-2011 remote control https://nl.aliexpress.com/item/1005002984723718.html
- Replacement board for various boats with "18" in their type number: https://nl.aliexpress.com/item/1005006115484716.html
- DIY Multi-protocol module: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module
remote control
Image of remote control RF chip: [...]
Parts:
- 12.000 MHz crystal/oscillator
- 16-pin control chip: 20_CL6L071
- 6-pin RF chip: 1110 / VKA3, could be an rx/tx switch, amplifier or filter circuit
See also: https://www.open-tx.org/
Next steps:
- map out the connections between the mainboard and the rf board, expected: VCC, GND, spi ?
Use cases
material:
- https://www.youtube.com/watch?v=cMk0bGvIU1E
- https://iplo.nl/thema/water/oppervlaktewater/kaderrichtlijn-water
- kaartje: https://krw-nutrend.netlify.app/ -> 2 meetpunten op de reeuwijkse plassen, tijdresolutie is 1 jaar?
Useful distinction, typically used in documents/guidelines:
- chemical quality, what substances are present in the water?
- biological / ecology quality, what kind of living organisms live in the water?
Reeuwijkse plassen
See
- https://www.rijnland.net/wat-doet-rijnland/in-uw-buurt/reeuwijkse-plassen/ their stated goal: CLEAR WATER
- https://www.rijnland.net/regels-op-een-rij/subsidies-en-andere-financi%C3%ABle-bijdragen/
potential applications:
- inspect water sides (oever) over time
- underwater camera: detect invasive cray fish
- sample water properties at high spatial resolution, high time resolution
- early detection of indicators for cyanobacteria: temperature and nutrients
Detect/find pollution source
- ...
Implementation
reading temperature sensor
The idea is to to use a DB18B20 temperature sensor, read it using an arduino nano board acting as a 1-wire adapter. Use openwire-fs as user-side openwire software http://owfs.org
Preparation:
- Add the regular user to the 'dialout' group, so it can access serial ports
sudo adduser <name> dialout
Setting up the hardware:
- connect the DS18B20 to the connector board with the pull-ups
- wire the connector board to the arduino nano, see ...
- plug the arduino nano in the pi
Setting up the software:
- Install openwire fs
sudo apt install owfs
- Create the openwire fs mountpoint
sudo mkdir /mnt/1wire
- Configure owfs, edit /etc/owfs.conf
server: device = /dev/ttyUSB0 mountpoint = /mnt/1wire allow_other (comment out the line with the FAKE devices)
- Configure systemd services
sudo systemctl enable owserver owhttpd sudo systemctl disable owftpd
- Start the systemd service
sudo systemctl start owserver owhttpd
- Check the logs
sudo journalctl -xeu owserver -f
- Open a browser to view the web interface
http://localhost:2121 or http://raspberrypi.local:2121