Arduino Nano 33 IoT to read Peet Bros. anemometer and publish over MQTT
The Ultimeter Pro anemometer/wind vane from Peet Bros. is a reliable and inexpensive wind sensor, but it doesn't have a brain of any sort. In fact, it's a super-simple device with two reed switches that are activated by a magnet that gets blocked by metal plates when the cups spin. The timing of the switching indicates the speed of the wind and the direction. Much has been written about this, so I won't repeat it here. Additional reading available at https://mechinations.net/2014/12/27/building-a-nmea-0183-wind-instrument/
I sealed the circuitry up before drawing the diagram, but I believe the file "schematic.svg" shows the proper final result. Basically, the anemometer yellow and green wires are attached to the red and black wires via the reed switches. When the switch closes, the circuit grounds and the Arduino input drops to low. The capacitors help to reduce the bounce giving a cleaner signal.
Set up your WiFi and MQTT server information in the arduino_secrets.h file.
The data published to MQTT is a valid NMEA1083 string. I used Node Red to modify that string to push the data into SignalK, which expects the wind direction in radians rather than degrees and negative values for port-side, positive for starboard. Below is the code used for Node Red.
[{"id":"78875c66.8818ac","type":"mqtt in","z":"c9a8613c.509128","name":"","topic":"windNanoDir","qos":"0","datatype":"auto","broker":"4d32915d.41a748","x":110,"y":360,"wires":[["5a653fcc.8c21f","353bc820.696488","db1eb00a.678a7"]]},{"id":"5a653fcc.8c21f","type":"debug","z":"c9a8613c.509128","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":370,"y":320,"wires":[]},{"id":"4ce04ec6.b09c78","type":"change","z":"c9a8613c.509128","name":"environment.wind.angleApparent","rules":[{"t":"set","p":"topic","pt":"msg","to":"environment.wind.angleApparent","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":360,"wires":[["eaae67fb.da7168"]]},{"id":"eaae67fb.da7168","type":"signalk-send-pathvalue","z":"c9a8613c.509128","name":"","source":"NanoWind","meta":"","x":1190,"y":360,"wires":[]},{"id":"353bc820.696488","type":"string","z":"c9a8613c.509128","name":"Angle String","methods":[{"name":"between","params":[{"type":"str","value":"$WIMWV,"},{"type":"str","value":",R"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":370,"y":360,"wires":[["ede5154.ce2d668"]]},{"id":"ede5154.ce2d668","type":"function","z":"c9a8613c.509128","name":"Convert Degrees to Radians","func":"// SignalK requires the angle in radians, with anything to port\n// being negative\n\nfunction degrees_to_radians(degrees)\n{\n var pi = Math.PI;\n return degrees * (pi/180);\n}\nif (msg.payload < 180) { \n msg.payload = degrees_to_radians(-1 * msg.payload);\n} else {\n msg.payload = degrees_to_radians(360 - msg.payload);\n}\n\n//msg.payload = degrees_to_radians(msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":620,"y":360,"wires":[["4ce04ec6.b09c78"]]},{"id":"db1eb00a.678a7","type":"string","z":"c9a8613c.509128","name":"Speed String","methods":[{"name":"between","params":[{"type":"str","value":"R,"},{"type":"str","value":",N"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":370,"y":400,"wires":[["54b2bff3.4f71f"]]},{"id":"ce094c26.4a47d","type":"signalk-send-pathvalue","z":"c9a8613c.509128","name":"","source":"NanoWind","meta":"","x":1190,"y":400,"wires":[]},{"id":"199e8c26.9a2a34","type":"change","z":"c9a8613c.509128","name":"environment.wind.speedApparent","rules":[{"t":"set","p":"topic","pt":"msg","to":"environment.wind.speedApparent","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":400,"wires":[["ce094c26.4a47d"]]},{"id":"54b2bff3.4f71f","type":"function","z":"c9a8613c.509128","name":"Convert Knots to m/s","func":"function knots_to_ms(knots)\n{\n return knots * 0.514444;\n}\nmsg.payload = knots_to_ms(msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":600,"y":400,"wires":[["199e8c26.9a2a34"]]},{"id":"4d32915d.41a748","type":"mqtt-broker","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""}]