ESPHome 2025.5.0
Loading...
Searching...
No Matches
canbus.h
Go to the documentation of this file.
1#pragma once
2
6
7#include <cinttypes>
8#include <vector>
9
10namespace esphome {
11namespace canbus {
12
21
45
46class CanbusTrigger;
47template<typename... Ts> class CanbusSendAction;
48
49/* CAN payload length definitions according to ISO 11898-1 */
50static const uint8_t CAN_MAX_DATA_LENGTH = 8;
51
52/*
53Can Frame describes a normative CAN Frame
54The RTR = Remote Transmission Request is implemented in every CAN controller but rarely used
55So currently the flag is passed to and from the hardware but currently ignored to the user application.
56*/
57struct CanFrame {
58 bool use_extended_id = false;
60 uint32_t can_id; /* 29 or 11 bit CAN_ID */
61 uint8_t can_data_length_code; /* frame payload length in byte (0 .. CAN_MAX_DATA_LENGTH) */
62 uint8_t data[CAN_MAX_DATA_LENGTH] __attribute__((aligned(8)));
63};
64
65class Canbus : public Component {
66 public:
67 Canbus(){};
68 void setup() override;
69 void dump_config() override;
70 float get_setup_priority() const override { return setup_priority::HARDWARE; }
71 void loop() override;
72
73 void send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request,
74 const std::vector<uint8_t> &data);
75 void send_data(uint32_t can_id, bool use_extended_id, const std::vector<uint8_t> &data) {
76 // for backwards compatibility only
77 this->send_data(can_id, use_extended_id, false, data);
78 }
79 void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
80 void set_use_extended_id(bool use_extended_id) { this->use_extended_id_ = use_extended_id; }
81 void set_bitrate(CanSpeed bit_rate) { this->bit_rate_ = bit_rate; }
82
83 void add_trigger(CanbusTrigger *trigger);
95 std::function<void(uint32_t can_id, bool extended_id, bool rtr, const std::vector<uint8_t> &data)> callback) {
96 this->callback_manager_.add(std::move(callback));
97 }
98
99 protected:
100 template<typename... Ts> friend class CanbusSendAction;
101 std::vector<CanbusTrigger *> triggers_{};
102 uint32_t can_id_;
105 CallbackManager<void(uint32_t can_id, bool extended_id, bool rtr, const std::vector<uint8_t> &data)>
107
108 virtual bool setup_internal();
109 virtual Error send_message(struct CanFrame *frame);
110 virtual Error read_message(struct CanFrame *frame);
111};
112
113template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public Parented<Canbus> {
114 public:
115 void set_data_template(const std::function<std::vector<uint8_t>(Ts...)> func) {
116 this->data_func_ = func;
117 this->static_ = false;
118 }
119 void set_data_static(const std::vector<uint8_t> &data) {
120 this->data_static_ = data;
121 this->static_ = true;
122 }
123
124 void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
125
126 void set_use_extended_id(bool use_extended_id) { this->use_extended_id_ = use_extended_id; }
127
128 void set_remote_transmission_request(bool remote_transmission_request) {
129 this->remote_transmission_request_ = remote_transmission_request;
130 }
131
132 void play(Ts... x) override {
133 auto can_id = this->can_id_.has_value() ? *this->can_id_ : this->parent_->can_id_;
134 auto use_extended_id =
135 this->use_extended_id_.has_value() ? *this->use_extended_id_ : this->parent_->use_extended_id_;
136 if (this->static_) {
137 this->parent_->send_data(can_id, use_extended_id, this->remote_transmission_request_, this->data_static_);
138 } else {
139 auto val = this->data_func_(x...);
140 this->parent_->send_data(can_id, use_extended_id, this->remote_transmission_request_, val);
141 }
142 }
143
144 protected:
148 bool static_{false};
149 std::function<std::vector<uint8_t>(Ts...)> data_func_{};
150 std::vector<uint8_t> data_static_{};
151};
152
153class CanbusTrigger : public Trigger<std::vector<uint8_t>, uint32_t, bool>, public Component {
154 friend class Canbus;
155
156 public:
157 explicit CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const std::uint32_t can_id_mask,
158 const bool use_extended_id)
159 : parent_(parent), can_id_(can_id), can_id_mask_(can_id_mask), use_extended_id_(use_extended_id){};
160
161 void set_remote_transmission_request(bool remote_transmission_request) {
162 this->remote_transmission_request_ = remote_transmission_request;
163 }
164
165 void setup() override { this->parent_->add_trigger(this); }
166
167 protected:
169 uint32_t can_id_;
170 uint32_t can_id_mask_;
173};
174
175} // namespace canbus
176} // namespace esphome
Helper class to easily give an object a parent of type T.
Definition helpers.h:538
CallbackManager< void(uint32_t can_id, bool extended_id, bool rtr, const std::vector< uint8_t > &data)> callback_manager_
Definition canbus.h:106
void loop() override
Definition canbus.cpp:67
void send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request, const std::vector< uint8_t > &data)
Definition canbus.cpp:25
void set_use_extended_id(bool use_extended_id)
Definition canbus.h:80
void setup() override
Definition canbus.cpp:9
void add_trigger(CanbusTrigger *trigger)
Definition canbus.cpp:58
virtual Error send_message(struct CanFrame *frame)
void add_callback(std::function< void(uint32_t can_id, bool extended_id, bool rtr, const std::vector< uint8_t > &data)> callback)
Add a callback to be called when a CAN message is received.
Definition canbus.h:94
void set_bitrate(CanSpeed bit_rate)
Definition canbus.h:81
void set_can_id(uint32_t can_id)
Definition canbus.h:79
float get_setup_priority() const override
Definition canbus.h:70
void dump_config() override
Definition canbus.cpp:17
void send_data(uint32_t can_id, bool use_extended_id, const std::vector< uint8_t > &data)
Definition canbus.h:75
virtual bool setup_internal()
virtual Error read_message(struct CanFrame *frame)
std::vector< CanbusTrigger * > triggers_
Definition canbus.h:101
std::function< std::vector< uint8_t >(Ts...)> data_func_
Definition canbus.h:149
void set_data_template(const std::function< std::vector< uint8_t >(Ts...)> func)
Definition canbus.h:115
void set_remote_transmission_request(bool remote_transmission_request)
Definition canbus.h:128
void set_data_static(const std::vector< uint8_t > &data)
Definition canbus.h:119
void play(Ts... x) override
Definition canbus.h:132
optional< uint32_t > can_id_
Definition canbus.h:145
void set_use_extended_id(bool use_extended_id)
Definition canbus.h:126
optional< bool > use_extended_id_
Definition canbus.h:146
std::vector< uint8_t > data_static_
Definition canbus.h:150
void set_can_id(uint32_t can_id)
Definition canbus.h:124
optional< bool > remote_transmission_request_
Definition canbus.h:172
CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const std::uint32_t can_id_mask, const bool use_extended_id)
Definition canbus.h:157
void set_remote_transmission_request(bool remote_transmission_request)
Definition canbus.h:161
bool has_value() const
Definition optional.h:87
mopeka_std_values val[4]
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.cpp:18
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
uint8_t can_data_length_code
Definition canbus.h:61
uint8_t data[CAN_MAX_DATA_LENGTH] __attribute__((aligned(8)))
uint16_t x
Definition tt21100.cpp:5