Skip to content

Commit d6b7400

Browse files
authored
Merge pull request #407 from OUXT-Polaris/Feat/add_check_heartbeat
feat: check heart beat for estop system and phsical power cutoff
2 parents 26f7141 + 91cb314 commit d6b7400

File tree

8 files changed

+205
-5
lines changed

8 files changed

+205
-5
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef __HEART_BEAT_HPP__
2+
#define __HEART_BEAT_HPP__
3+
4+
5+
#include <NativeEthernet.h>
6+
#include <NativeEthernetUdp.h>
7+
8+
#include "proto/hardware_communication_msgs__HeartBeat.pb.h"
9+
#include "pb_decode.h"
10+
11+
12+
class UDPHeartBeat {
13+
public:
14+
UDPHeartBeat(uint16_t port, unsigned long timeout);
15+
void begin(); // After define Ethernet.begin
16+
17+
bool verify_survival();
18+
19+
auto get_msgs() -> protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat;
20+
21+
private:
22+
const uint16_t port;
23+
EthernetUDP Udp;
24+
uint8_t packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet,
25+
26+
protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat msg
27+
= protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_init_zero;
28+
29+
unsigned long preTime = 0;
30+
unsigned long timeout; // ms
31+
32+
33+
bool update_msgs();
34+
};
35+
36+
#endif
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* Automatically generated nanopb constant definitions */
2+
/* Generated by nanopb-1.0.0-dev */
3+
4+
#include "proto/hardware_communication_msgs__HeartBeat.pb.h"
5+
#if PB_PROTO_HEADER_VERSION != 40
6+
#error Regenerate this file with the current version of nanopb generator.
7+
#endif
8+
9+
PB_BIND(protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat, protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat, AUTO)
10+
11+
12+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* Automatically generated nanopb header */
2+
/* Generated by nanopb-1.0.0-dev */
3+
4+
#ifndef PB_PROTOLINK__HARDWARE_COMMUNICATION_MSGS__HEARTBEAT_PROTO_HARDWARE_COMMUNICATION_MSGS__HEARTBEAT_PB_H_INCLUDED
5+
#define PB_PROTOLINK__HARDWARE_COMMUNICATION_MSGS__HEARTBEAT_PROTO_HARDWARE_COMMUNICATION_MSGS__HEARTBEAT_PB_H_INCLUDED
6+
#include <pb.h>
7+
8+
#if PB_PROTO_HEADER_VERSION != 40
9+
#error Regenerate this file with the current version of nanopb generator.
10+
#endif
11+
12+
/* Struct definitions */
13+
typedef struct _protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat {
14+
uint64_t sequence;
15+
} protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat;
16+
17+
18+
#ifdef __cplusplus
19+
extern "C" {
20+
#endif
21+
22+
/* Initializer values for message structs */
23+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_init_default {0}
24+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_init_zero {0}
25+
26+
/* Field tags (for use in manual encoding/decoding) */
27+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_sequence_tag 1
28+
29+
/* Struct field encoding specification for nanopb */
30+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_FIELDLIST(X, a) \
31+
X(a, STATIC, SINGULAR, UINT64, sequence, 1)
32+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_CALLBACK NULL
33+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_DEFAULT NULL
34+
35+
extern const pb_msgdesc_t protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_msg;
36+
37+
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
38+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_fields &protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_msg
39+
40+
/* Maximum encoded size of messages (where known) */
41+
#define PROTOLINK__HARDWARE_COMMUNICATION_MSGS__HEARTBEAT_PROTO_HARDWARE_COMMUNICATION_MSGS__HEARTBEAT_PB_H_MAX_SIZE protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_size
42+
#define protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat_size 11
43+
44+
#ifdef __cplusplus
45+
} /* extern "C" */
46+
#endif
47+
48+
#endif
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
syntax = "proto3";
2+
package protolink__hardware_communication_msgs__HeartBeat;
3+
4+
message hardware_communication_msgs__HeartBeat {
5+
uint64 sequence = 1;
6+
}

firmware/mini_v/estop_driver/platformio.ini

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@
1212
platform = teensy
1313
board = teensy41
1414
framework = arduino
15-
lib_deps = adafruit/Adafruit NeoPixel@^1.12.4
15+
lib_deps =
16+
adafruit/Adafruit NeoPixel@^1.12.4
17+
nanopb/Nanopb@^0.4.91
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef __CONFIG_HPP__
2+
#define __CONFIG_HPP__
3+
4+
5+
const unsigned long TIMEOUT = 1000;
6+
7+
8+
byte MAC[] = {
9+
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAD
10+
};
11+
const IPAddress IP(192, 168, 0, 103);
12+
const unsigned int LOCALPORT_HEART = 4000; // local port to listen on
13+
14+
15+
#endif
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include "heart_beat.hpp"
2+
3+
UDPHeartBeat::UDPHeartBeat(u_int16_t _port, unsigned long _timeout = 1000) : port(_port), timeout(_timeout) {
4+
5+
}
6+
7+
void UDPHeartBeat::begin(){
8+
Udp.begin(port);
9+
}
10+
11+
bool UDPHeartBeat::update_msgs()
12+
{
13+
int packetSize = Udp.parsePacket();
14+
if (packetSize) {
15+
Serial.print("Received packet of size ");
16+
Serial.print(packetSize);
17+
Serial.print(" From ");
18+
IPAddress remote = Udp.remoteIP();
19+
for (int i=0; i < 4; i++) {
20+
Serial.print(remote[i], DEC);
21+
if (i < 3) Serial.print(".");
22+
}
23+
Serial.print(", port ");
24+
Serial.print(Udp.remotePort());
25+
Serial.print(" heart");
26+
const size_t num_bytes = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
27+
28+
for (auto c : packetBuffer){
29+
Serial.print(" ");
30+
Serial.print(c);
31+
}
32+
Serial.println();
33+
return true;
34+
}
35+
return false;
36+
}
37+
38+
bool UDPHeartBeat::verify_survival()
39+
{
40+
if (update_msgs()) {
41+
preTime = millis();
42+
return true;
43+
}
44+
else if (timeout > millis() - preTime) {
45+
return true;
46+
}
47+
return false;
48+
}
49+
50+
protolink__hardware_communication_msgs__HeartBeat_hardware_communication_msgs__HeartBeat UDPHeartBeat::get_msgs()
51+
{
52+
return msg;
53+
}

firmware/mini_v/estop_driver/src/main.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
#include <Arduino.h>
2-
2+
#include <NativeEthernet.h>
3+
#include <NativeEthernetUdp.h>
34
#include <Adafruit_NeoPixel.h>
45

5-
#define ESTOP_BUTTON_PIN 41
6+
#include "config.hpp"
7+
#include "heart_beat.hpp"
8+
9+
#define ESTOP_BUTTON_IN_PIN 41
10+
#define ESTOP_BUTTON_OUT_PIN 37
611

712
#define NUMPIXELS 60
813
#define BRIGHTNESS 100
@@ -17,6 +22,9 @@ Adafruit_NeoPixel pixels[pixels_n] = {
1722
Adafruit_NeoPixel(NUMPIXELS, 17, NEO_GRB + NEO_KHZ800),
1823
};
1924

25+
// Heart Beat
26+
UDPHeartBeat UdpHeart(LOCALPORT_HEART, TIMEOUT);
27+
2028
unsigned long pre_time = 0;
2129
unsigned long pre_saver_time = 0;
2230
bool pre_estop_state = false;
@@ -42,7 +50,8 @@ void setup()
4250
{
4351
Serial.begin(9600);
4452

45-
pinMode(ESTOP_BUTTON_PIN, INPUT);
53+
pinMode(ESTOP_BUTTON_IN_PIN, INPUT);
54+
pinMode(ESTOP_BUTTON_OUT_PIN, OUTPUT);
4655

4756
// Neopixel initalize
4857
for (int i = 0; i < pixels_n; i++)
@@ -52,13 +61,32 @@ void setup()
5261
pixels[i].clear();
5362
pixels[i].show();
5463
}
64+
65+
Ethernet.begin(MAC, IP);
66+
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
67+
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
68+
while (true) {
69+
delay(1); // do nothing, no point running without Ethernet hardware
70+
}
71+
}
72+
if (Ethernet.linkStatus() == LinkOFF) {
73+
Serial.println("Ethernet cable is not connected.");
74+
}
75+
// start UDP
76+
UdpHeart.begin();
5577
}
5678

5779

5880
void loop()
5981
{
60-
bool estop_state = !digitalRead(ESTOP_BUTTON_PIN);
82+
// Check heart beat and signal on/off
83+
if (UdpHeart.verify_survival()) digitalWrite(ESTOP_BUTTON_OUT_PIN, HIGH);
84+
else digitalWrite(ESTOP_BUTTON_OUT_PIN, LOW);
85+
86+
// Check e-stop button state
87+
bool estop_state = !digitalRead(ESTOP_BUTTON_IN_PIN);
6188

89+
// Determination state
6290
if (estop_state == true && millis() - pre_saver_time < SAVER)
6391
state = 2;
6492
else if (millis() - pre_time > INTERVAL)

0 commit comments

Comments
 (0)