Code:
/******************************************************
knotmeter esp8266 devboard
Digital input GPIO12 /D6
Output signalK navigation.speedThroughWater m/s
David Delorme 05/4/20
Openplotter rpi
*****************************************************/
#include <FS.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
const float paddleCir = .0515; // half the cir in meters of paddle
const char * udpAddress = "10.10.10.1"; // address of signalK server
const byte WSPD_PIN = 12; // pin of ws D6 esp8266
volatile unsigned int rotation_count; //knotmeter counter
volatile uint16_t lastperiod; // time since last reading
boolean connected = false;
WiFiUDP udp;
void ICACHE_RAM_ATTR isr_knotmeter_count();
void WiFiEvent(WiFiEvent_t event);
void read_knotmeter();
void setup()
{
// Setup needed for OTA
Serial.begin(115200);
Serial.println("Booting");
WiFiManager wm;
bool res;
res = wm.autoConnect(); // auto generated AP name from chipid
if (!res) {
Serial.println("Failed to connect");
ESP.restart();
}
else {
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
}
ArduinoOTA.setHostname("knotmeter");
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
pinMode(WSPD_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(WSPD_PIN), isr_knotmeter_count, FALLING);
}
void loop()
{
ArduinoOTA.handle();
yield();
// Serial.println ("made it to main loop");
read_knotmeter();
//delay(1);
}
// stuff done durring windspeed Interrupts
void ICACHE_RAM_ATTR isr_knotmeter_count()
{
static uint16_t lastt; // lastmills
uint32_t t = millis();// current mills
uint16_t period = t - lastt;
if (period < 6) // debounce, greater then 10m/s
return;
lastt = t;
lastperiod += period;
rotation_count++;
}
void read_knotmeter()
{
uint32_t time = millis();
static uint32_t last_time;
uint32_t dt = time - last_time;
//delay(1000);
if (dt >= 500) { // output every 500ms
last_time += 500;
uint16_t period = lastperiod;
uint16_t count = rotation_count;
// reset the lastperiod and counter to 0
rotation_count = 0;
lastperiod = 0;
static uint16_t nospeedcount;
static float stw = 0;
const int nospeedtimeout = 1;
if (count) {
if (nospeedcount != nospeedtimeout)
stw = paddleCir * count / period * 1000; // meters/sec
nospeedcount = 0;
} else {
if (nospeedcount < nospeedtimeout)
nospeedcount++;
else
stw = 0;
}
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
char buf3 [128];
snprintf(buf3, sizeof buf3, "{\"updates\":[{ \"$source\": \"OPwifi.Knotmeter\",\"values\":[{\"path\": \"navigation.speedThroughWater\",\"value\":\"%f\" }]}]}\n", stw);
udp.beginPacket(udpAddress, 55562); //use openplotter wifi port
udp.printf(buf3);
Serial.println(buf3);
udp.endPacket();
// Serial.println("Connected to server successful!");
} else {
Serial.println("Error not connected");
}
// Serial.println(knots);
}
}
It is basically counting ticks when ever the magnet passes the coil? i dont know what is inside the plastic though hull, just the paddle. I did see an ac voltage but it is very low current so i ignored it...