-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathVLCB_long_message_example.ino
More file actions
195 lines (157 loc) · 6.08 KB
/
VLCB_long_message_example.ino
File metadata and controls
195 lines (157 loc) · 6.08 KB
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Copyright (C) Sven Rosvall (sven@rosvall.ie)
// This file is part of VLCB-Arduino project on https://github.com/SvenRosvall/VLCB-Arduino
// Licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
// The full licence can be found at: http://creativecommons.org/licenses/by-nc-sa/4.0
/*
3rd party libraries needed for compilation: (not for binary-only distributions)
Streaming -- C++ stream style output, v5, (http://arduiniana.org/libraries/streaming/)
ACAN2515 -- library to support the MCP2515/25625 CAN controller IC
*/
// 3rd party libraries
#include <Streaming.h>
// VLCB library header files
#include <VLCB.h>
#include <CAN2515.h> // Chosen CAN controller
// forward function declarations
void eventhandler(byte, const VLCB::VlcbMessage *);
void printConfig();
void longmessagehandler(void *, const unsigned int, const byte, const byte);
// constants
const byte VER_MAJ = 1; // code major version
const char VER_MIN = 'a'; // code minor version
const byte VER_BETA = 0; // code beta sub-version
const byte MODULE_ID = 99; // VLCB module type
const byte LED_GRN = 4; // VLCB green Unitialised LED pin
const byte LED_YLW = 7; // VLCB yellow Normal LED pin
const byte SWITCH0 = 8; // VLCB push button switch pin
// module name, must be 7 characters, space padded.
char mname[] = "LMSGEX";
// long message variables
byte streams[] = {1, 2, 3}; // streams to subscribe to
char lmsg_out[32], lmsg_in[32]; // message buffers
VLCB::CAN2515 can2515; // CAN transport object
// Service objects
VLCB::LEDUserInterface ledUserInterface(LED_GRN, LED_YLW, SWITCH0);
VLCB::SerialUserInterface serialUserInterface;
VLCB::MinimumNodeService mnService;
VLCB::CanService canService(&can2515);
VLCB::NodeVariableService nvService;
VLCB::LongMessageService lmsg; // Controller RFC0005 long message object
VLCB::EventConsumerService ecService;
VLCB::EventTeachingService etService;
VLCB::EventProducerService epService;
//
/// setup VLCB - runs once at power on from setup()
//
void setupVLCB()
{
VLCB::checkStartupAction(LED_GRN, LED_YLW, SWITCH0);
VLCB::setServices({
&mnService, &ledUserInterface, &serialUserInterface, &canService, &nvService, &lmsg,
&ecService, &epService, &etService});
// set config layout parameters
VLCB::setNumNodeVariables(10);
VLCB::setMaxEvents(32);
VLCB::setNumEventVariables(1);
// set module parameters
VLCB::setVersion(VER_MAJ, VER_MIN, VER_BETA);
VLCB::setModuleId(MANU_DEV, MODULE_ID);
// set module name
VLCB::setName(mname);
// register our VLCB event handler, to receive event messages of learned events
ecService.setEventHandler(eventhandler);
// subscribe to long message streams and register our handler function
lmsg.subscribe(streams, sizeof(streams) / sizeof(byte), lmsg_in, 32, longmessagehandler);
// configure and start CAN bus and VLCB message processing
can2515.setNumBuffers(4, 2); // more buffers = more memory used, fewer = less
can2515.setOscFreq(16000000UL); // select the crystal frequency of the CAN module
can2515.setPins(10, 2); // select pins for CAN bus CE and interrupt connections
can2515.begin();
// initialise and load configuration
VLCB::begin();
Serial << F("> mode = ") << VLCB::Configuration::modeString(VLCB::getCurrentMode()) << F(", CANID = ") << VLCB::getCANID();
Serial << F(", NN = ") << VLCB::getNodeNum() << endl;
// show code version and copyright notice
printConfig();
}
//
/// setup - runs once at power on
//
void setup()
{
Serial.begin (115200);
Serial << endl << endl << F("> ** VLCB Arduino long message example module ** ") << __FILE__ << endl;
setupVLCB();
// end of setup
Serial << F("> ready") << endl << endl;
}
//
/// loop - runs forever
//
void loop()
{
//
/// do VLCB message, switch and LED processing
//
VLCB::process();
//
/// do RFC0005 Controller long message processing
//
if (!lmsg.process()) {
Serial << F("> error in long message processing") << endl;
}
//
/// check CAN message buffers
//
if (can2515.canp->receiveBufferPeakCount() > can2515.canp->receiveBufferSize())
{
Serial << F("> receive buffer overflow") << endl;
}
if (can2515.canp->transmitBufferPeakCount(0) > can2515.canp->transmitBufferSize(0))
{
Serial << F("> transmit buffer overflow") << endl;
}
//
/// check CAN bus state
//
byte err;
if ((err = can2515.canp->errorFlagRegister()) != 0)
{
Serial << F("> error flag register = ") << err << endl;
}
// bottom of loop()
}
//
/// user-defined event processing function
/// called from the VLCB library when a learned event is received
/// it receives the event table index and the CAN frame
//
void eventhandler(byte index, const VLCB::VlcbMessage *msg)
{
// as an example, display the opcode and the first EV of this event, which is ev2 as ev1 defines produced event
Serial << F("> event handler: index = ") << index << F(", opcode = 0x") << _HEX(msg->data[0]) << endl;
Serial << F("> EV1 = ") << VLCB::getEventEVval(index, 1) << endl;
}
//
/// long message receive handler function
/// called once the user buffer is full, or the message has been completely received
//
void longmessagehandler(void *fragment, const unsigned int fragment_len, const byte stream_id, const byte status)
{
// display the message
// this will be the complete message if shorter than the provided buffer, or the final fragment if longer
if (status == VLCB::LONG_MESSAGE_COMPLETE) {
Serial << F("> received long message, stream = ") << stream_id << F(", len = ") << fragment_len << F(", msg = |") << (char *) fragment << F("|") << endl;
}
}
//
/// print code version config details and copyright notice
//
void printConfig()
{
// code version
Serial << F("> code version = ") << VER_MAJ << VER_MIN << F(" beta ") << VER_BETA << endl;
Serial << F("> compiled on ") << __DATE__ << F(" at ") << __TIME__ << F(", compiler ver = ") << __cplusplus << endl;
// copyright
Serial << F("> © Duncan Greenwood (MERG M5767) 2019") << endl;
}