-
Notifications
You must be signed in to change notification settings - Fork 0
/
main_n2k_signalk.cpp
152 lines (124 loc) · 5.13 KB
/
main_n2k_signalk.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <Arduino.h>
#include "sensesp/signalk/signalk_output.h"
#include "sensesp/sensors/system_info.h"
#include "sensesp_app_builder.h"
// CAN bus (NMEA 2000) pins on SH-ESP32
#include <N2kMessages.h>
#include <NMEA2000_esp32.h>
#define CAN_RX_PIN GPIO_NUM_34
#define CAN_TX_PIN GPIO_NUM_32
#define RECOVERY_RETRY_MS 1000 // How long to attempt CAN bus recovery
#define MAX_RX_WAIT_TIME_MS 30000 // Time after which we should reboot if we haven't received any CAN messages
// MAX6675
#include <max6675.h>
#define thermoDO GPIO_NUM_18
#define thermoCLK GPIO_NUM_25
#define thermo1CS GPIO_NUM_26
#define thermo2CS GPIO_NUM_27
// Serial console debugging disable
// #define SERIAL_DEBUG_DISABLED
using namespace sensesp;
tNMEA2000* nmea2000;
ReactESP app;
// MAX6675 setup
MAX6675 thermocouple0(thermoCLK, thermo1CS, thermoDO);
MAX6675 thermocouple1(thermoCLK, thermo2CS, thermoDO);
float temp0 = 0;
float temp1 = 0;
float temp0_callback() {
temp0 = thermocouple0.readCelsius() + 273.15;
return (temp0);
}
float temp1_callback() {
temp1 = thermocouple1.readCelsius() + 273.15;
return (temp1);
}
void setup() {
#ifndef SERIAL_DEBUG_DISABLED
SetupSerialDebug(115200);
#endif
SensESPAppBuilder builder;
sensesp_app = (&builder)
// Set a custom hostname for the app.
->set_hostname("egt-temp")
// Optionally, hard-code the WiFi and Signal K server
// settings. This is normally not needed.
->set_wifi("Off Hand 2.4G", "2222222222")
//->set_wifi("kitty3", "2222222222")
//->set_sk_server("192.168.8.10", 3443)
->get_app();
auto* engine_0_egt_temperature = new RepeatSensor<float>(1000, temp0_callback);
auto* engine_1_egt_temperature = new RepeatSensor<float>(1000, temp1_callback);
// define metadata for sensors
auto engine_egt_temperature_metadata =
new SKMetadata("K", // units
"Exhaust Gas Temperature", // display name
"Exhaust Gas Temperature", // description
"EGT", // short name
10. // timeout, in seconds
);
// connect the sensors to Signal K output paths
engine_0_egt_temperature->connect_to(
new SKOutput<float>("propulsion.0.exhaustTemperature",
engine_egt_temperature_metadata));
engine_1_egt_temperature->connect_to(
new SKOutput<float>("propulsion.1.exhaustTemperature",
engine_egt_temperature_metadata));
// initialize the NMEA 2000 subsystem
// instantiate the NMEA2000 object
nmea2000 = new tNMEA2000_esp32(CAN_TX_PIN, CAN_RX_PIN);
// Reserve enough buffer for sending all messages. This does not work on small
// memory devices like Uno or Mega
nmea2000->SetN2kCANSendFrameBufSize(250);
nmea2000->SetN2kCANReceiveFrameBufSize(250);
// Set Product information
nmea2000->SetProductInformation(
"7630101", // Manufacturer's Model serial code (max 32 chars)
103, // Manufacturer's product code
"SME EGT Interface", // Manufacturer's Model ID (max 33 chars)
"0.1 (2024-03-22)", // Manufacturer's Software version code (max 40
// chars)
"0.1 (2024-03-22)" // Manufacturer's Model version (max 24 chars)
);
// Set device information
nmea2000->SetDeviceInformation(
7630101.01, // Unique number. Use e.g. Serial number.
160, // Device function=Engine Gateway
50, // Device class=Propulsion
// https://manualzz.com/doc/12647142/nmea2000-class-and-function-codes
2012 // Manufacture code, free number taken from
// https://ttlappalainen.github.io/NMEA2000/md_7_glossary.html#secRefMfgCodes
);
nmea2000->SetMode(tNMEA2000::N2km_NodeOnly, 22);
// Disable all msg forwarding to USB (=Serial)
nmea2000->EnableForward(false);
nmea2000->Open();
// No need to parse the messages at every single loop iteration; 1 ms will do
app.onRepeat(1, []() { nmea2000->ParseMessages(); });
// Implement the N2K PGN sending.
engine_0_egt_temperature->connect_to(
new LambdaConsumer<float>([](float temperature) {
tN2kMsg N2kMsg;
SetN2kPGN130316(N2kMsg,
1, // SID
0, // TempInstance
N2kts_ExhaustGasTemperature, // TempSource
temperature // actual temperature
);
nmea2000->SendMsg(N2kMsg);
}));
engine_1_egt_temperature->connect_to(
new LambdaConsumer<float>([](float temperature) {
tN2kMsg N2kMsg;
SetN2kPGN130316(N2kMsg,
1, // SID
1, // TempInstance
N2kts_ExhaustGasTemperature, // TempSource
temperature // actual temperature
);
nmea2000->SendMsg(N2kMsg);
}));
sensesp_app->start();
}
// main program loop
void loop() { app.tick(); }