Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to latest, add speed messages example #9

Merged
merged 3 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions examples/SpeedMessages/SpeedMessages.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <AgIsoStack.hpp>

using namespace isobus;

auto can0 = std::make_shared<FlexCANT4Plugin>(0);
std::shared_ptr<InternalControlFunction> ISOBUSControlFunction = nullptr;
std::shared_ptr<DiagnosticProtocol> ISOBUSDiagnostics = nullptr;
std::shared_ptr<SpeedMessagesInterface> ISOBUSSpeedInterface = nullptr;

// A log sink for the CAN stack
class CustomLogger : public CANStackLogger
{
public:
void sink_CAN_stack_log(CANStackLogger::LoggingLevel level, const std::string &text) override
{
switch (level)
{
case LoggingLevel::Debug:
{
Serial.print("[Debug]: ");
}
break;

case LoggingLevel::Info:
{
Serial.print("[Info]: ");
}
break;

case LoggingLevel::Warning:
{
Serial.print("[Warning]: ");
}
break;

case LoggingLevel::Error:
{
Serial.print("[Error]: ");
}
break;

case LoggingLevel::Critical:
{
Serial.print("[Critical]: ");
}
break;
}
Serial.println(text.c_str());
}
};

static CustomLogger logger;

// These are optional callbacks you can use to do something as soon as new speed information is received.
static void test_mss_callback(const std::shared_ptr<SpeedMessagesInterface::MachineSelectedSpeedData> machineSpeedData, bool)
{
if (nullptr != machineSpeedData)
{
Serial.write(("[MSS] " + isobus::to_string(machineSpeedData->get_machine_speed()) + "mm/s\n").c_str());
}
}

static void test_wbs_callback(const std::shared_ptr<SpeedMessagesInterface::WheelBasedMachineSpeedData> wheelSpeedData, bool)
{
if (nullptr != wheelSpeedData)
{
Serial.write(("[WBS] " + isobus::to_string(wheelSpeedData->get_machine_speed()) + "mm/s\n").c_str());
}
}

static void test_gbs_callback(const std::shared_ptr<SpeedMessagesInterface::GroundBasedSpeedData> groundSpeedData, bool)
{
if (nullptr != groundSpeedData)
{
Serial.write(("[GBS] " + isobus::to_string(groundSpeedData->get_machine_speed()) + "mm/s\n").c_str());
}
}

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
CANStackLogger::set_can_stack_logger_sink(&logger);
CANStackLogger::set_log_level(isobus::CANStackLogger::LoggingLevel::Debug);
// Optional, add delay() here to give you time to connect to the serial logger
CANHardwareInterface::set_number_of_can_channels(1);
CANHardwareInterface::assign_can_channel_frame_handler(0, can0);
CANHardwareInterface::start();
CANHardwareInterface::update();

NAME deviceNAME(0);
// Make sure you change these for your device
// This is an example device that is using a manufacturer code that is currently unused at time of writing
deviceNAME.set_arbitrary_address_capable(true);
deviceNAME.set_industry_group(0);
deviceNAME.set_device_class(0);
deviceNAME.set_function_code(static_cast<std::uint8_t>(isobus::NAME::Function::IOController));
deviceNAME.set_identity_number(2);
deviceNAME.set_ecu_instance(0);
deviceNAME.set_function_instance(0);
deviceNAME.set_device_class_instance(0);
deviceNAME.set_manufacturer_code(1407); // This is the Open-Agriculture manufacturer code. You are welcome to use it if you want.
// If you want to set a preferred address, you can add another parameter below, like (deviceNAME, 0, 0x81), otherwise the CAN stack will choose one automatically.
ISOBUSControlFunction = CANNetworkManager::CANNetwork.create_internal_control_function(deviceNAME, 0);
ISOBUSDiagnostics = std::make_shared<DiagnosticProtocol>(ISOBUSControlFunction);
ISOBUSDiagnostics->initialize();

// Change these to be specific to your device
ISOBUSDiagnostics->set_product_identification_brand("Arduino");
ISOBUSDiagnostics->set_product_identification_code("123456789");
ISOBUSDiagnostics->set_product_identification_model("Example");
ISOBUSDiagnostics->set_software_id_field(0, "0.0.1");
ISOBUSDiagnostics->set_ecu_id_field(DiagnosticProtocol::ECUIdentificationFields::HardwareID, "Hardware ID");
ISOBUSDiagnostics->set_ecu_id_field(DiagnosticProtocol::ECUIdentificationFields::Location, "The Aether");
ISOBUSDiagnostics->set_ecu_id_field(DiagnosticProtocol::ECUIdentificationFields::ManufacturerName, "None");
ISOBUSDiagnostics->set_ecu_id_field(DiagnosticProtocol::ECUIdentificationFields::PartNumber, "1234");
ISOBUSDiagnostics->set_ecu_id_field(DiagnosticProtocol::ECUIdentificationFields::SerialNumber, "1");
ISOBUSDiagnostics->set_ecu_id_field(DiagnosticProtocol::ECUIdentificationFields::Type, "AgISOStack");

// Set up to receive speed messages.
ISOBUSSpeedInterface = std::make_shared<SpeedMessagesInterface>(nullptr);
ISOBUSSpeedInterface->initialize();
ISOBUSSpeedInterface->get_machine_selected_speed_data_event_publisher().add_listener(test_mss_callback);
ISOBUSSpeedInterface->get_ground_based_machine_speed_data_event_publisher().add_listener(test_gbs_callback);
ISOBUSSpeedInterface->get_wheel_based_machine_speed_data_event_publisher().add_listener(test_wbs_callback);
}

void loop() {
// put your main code here, to run repeatedly:
static std::uint32_t bestSpeedPrintTimestamp = SystemTiming::get_timestamp_ms();

ISOBUSDiagnostics->update(); // Update diagnostics interface
ISOBUSSpeedInterface->update();
CANHardwareInterface::update(); // Update CAN stack

// Every 1 second, print the "best speed".
if (SystemTiming::time_expired_ms(bestSpeedPrintTimestamp, 1000))
{
std::uint32_t bestSpeed = 0;

if (ISOBUSSpeedInterface->get_number_received_machine_selected_speed_sources() > 0)
{
bestSpeed = ISOBUSSpeedInterface->get_received_machine_selected_speed(0)->get_machine_speed();
Serial.write("Best speed is MSS: ");
Serial.write((isobus::to_string(bestSpeed) + "mm/s\n").c_str());
}
else if (ISOBUSSpeedInterface->get_number_received_ground_based_speed_sources() > 0)
{
bestSpeed = ISOBUSSpeedInterface->get_received_ground_based_speed(0)->get_machine_speed();
Serial.write("Best speed is GBS: ");
Serial.write((isobus::to_string(bestSpeed) + "mm/s\n").c_str());
}
else if (ISOBUSSpeedInterface->get_number_received_wheel_based_speed_sources() > 0)
{
bestSpeed = ISOBUSSpeedInterface->get_received_wheel_based_speed(0)->get_machine_speed();
Serial.write("Best speed is WBS: ");
Serial.write((isobus::to_string(bestSpeed) + "mm/s\n").c_str());
}
else
{
Serial.write("No valid speed sources.\n");
}
bestSpeedPrintTimestamp = SystemTiming::get_timestamp_ms();
}
}
10 changes: 5 additions & 5 deletions examples/VirtualTerminal/VirtualTerminal.ino
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ void setup() {
deviceNAME.set_ecu_instance(0);
deviceNAME.set_function_instance(0);
deviceNAME.set_device_class_instance(0);
deviceNAME.set_manufacturer_code(64);
// Change 0x81 to be your preferred address, but 0x81 is the base arbitrary address
ISOBUSControlFunction = InternalControlFunction::create(deviceNAME, 0x81, 0);
deviceNAME.set_manufacturer_code(1407); // This is the Open-Agriculture manufacturer code. You are welcome to use it if you want.
// If you want to set a preferred address, you can add another parameter below, like (deviceNAME, 0, 0x81), otherwise the CAN stack will choose one automatically.
ISOBUSControlFunction = CANNetworkManager::CANNetwork.create_internal_control_function(deviceNAME, 0);
ISOBUSDiagnostics = std::make_shared<DiagnosticProtocol>(ISOBUSControlFunction);
ISOBUSDiagnostics->initialize();

Expand All @@ -142,11 +142,11 @@ void setup() {
// Set up virtual terminal client
const NAMEFilter filterVirtualTerminal(NAME::NAMEParameters::FunctionCode, static_cast<std::uint8_t>(NAME::Function::VirtualTerminal));
const std::vector<NAMEFilter> vtNameFilters = { filterVirtualTerminal };
auto TestPartnerVT = PartneredControlFunction::create(0, vtNameFilters);
auto TestPartnerVT = CANNetworkManager::CANNetwork.create_partnered_control_function(0, vtNameFilters);
ExampleVirtualTerminalClient = std::make_shared<VirtualTerminalClient>(TestPartnerVT, ISOBUSControlFunction);
ExampleVirtualTerminalClient->set_object_pool(0, VT3TestPool, sizeof(VT3TestPool), "AIS1");
ExampleVirtualTerminalClient->get_vt_button_event_dispatcher().add_listener(handleVTKeyEvents);
ExampleVirtualTerminalClient->get_vt_button_event_dispatcher().add_listener(handleVTKeyEvents);
ExampleVirtualTerminalClient->get_vt_soft_key_event_dispatcher().add_listener(handleVTKeyEvents);
ExampleVirtualTerminalClient->initialize(false);
}

Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=AgIsoStack
version=0.1.4
version=0.1.5
license=MIT
author=Adrian Del Grosso <[email protected]>
maintainer=Adrian Del Grosso <[email protected]>
Expand Down
93 changes: 47 additions & 46 deletions src/AgIsoStack.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*******************************************************************************
** @file AgIsoStack.hpp
** @author Automatic Code Generation
** @date February 08, 2024 at 19:36:28
** @date October 19, 2024 at 23:45:04
** @brief Includes all important files in the AgIsoStack library.
**
** Copyright 2024 The AgIsoStack++ Developers
Expand All @@ -10,62 +10,63 @@
#ifndef AG_ISO_STACK_HPP
#define AG_ISO_STACK_HPP

#include <can_address_claim_state_machine.hpp>
#include <can_badge.hpp>
#include <can_hardware_plugin.hpp>
#include <flex_can_t4_plugin.hpp>
#include <can_callbacks.hpp>
#include <can_constants.hpp>
#include <isobus_language_command_interface.hpp>
#include <isobus_virtual_terminal_client.hpp>
#include <can_NAME.hpp>
#include <event_dispatcher.hpp>
#include <can_partnered_control_function.hpp>
#include <isobus_time_date_interface.hpp>
#include <circular_buffer.hpp>
#include <can_network_configuration.hpp>
#include <can_network_manager.hpp>
#include <isobus_maintain_power_interface.hpp>
#include <can_message_frame.hpp>
#include <nmea2000_message_definitions.hpp>
#include <can_control_function.hpp>
#include <can_extended_transport_protocol.hpp>
#include <can_general_parameter_group_numbers.hpp>
#include <can_hardware_abstraction.hpp>
#include <can_hardware_interface_single_thread.hpp>
#include <can_hardware_plugin.hpp>
#include <can_identifier.hpp>
#include <isobus_shortcut_button_interface.hpp>
#include <kinetis_flexcan.hpp>
#include <isobus_guidance_interface.hpp>
#include <isobus_functionalities.hpp>
#include <isobus_task_controller_client_objects.hpp>
#include <isobus_device_descriptor_object_pool.hpp>
#include <nmea2000_message_interface.hpp>
#include <isobus_virtual_terminal_objects.hpp>
#include <can_internal_control_function.hpp>
#include <can_message.hpp>
#include <isobus_virtual_terminal_base.hpp>
#include <isobus_data_dictionary.hpp>
#include <can_message_data.hpp>
#include <can_message_frame.hpp>
#include <can_NAME.hpp>
#include <can_NAME_filter.hpp>
#include <can_network_configuration.hpp>
#include <can_network_manager.hpp>
#include <isobus_standard_data_description_indices.hpp>
#include <isobus_virtual_terminal_client_state_tracker.hpp>
#include <thread_synchronization.hpp>
#include <isobus_task_controller_client.hpp>
#include <processing_flags.hpp>
#include <nmea2000_fast_packet_protocol.hpp>
#include <isobus_preferred_addresses.hpp>
#include <to_string.hpp>
#include <can_parameter_group_number_request_protocol.hpp>
#include <can_partnered_control_function.hpp>
#include <can_protocol.hpp>
#include <can_stack_logger.hpp>
#include <platform_endianness.hpp>
#include <can_extended_transport_protocol.hpp>
#include <imxrt_flexcan.hpp>
#include <can_transport_protocol.hpp>
#include <can_transport_protocol_base.hpp>
#include <circular_buffer.hpp>
#include <can_NAME_filter.hpp>
#include <data_span.hpp>
#include <event_dispatcher.hpp>
#include <can_identifier.hpp>
#include <FlexCAN_T4.hpp>
#include <flex_can_t4_plugin.hpp>
#include <imxrt_flexcan.hpp>
#include <isobus_data_dictionary.hpp>
#include <isobus_device_descriptor_object_pool.hpp>
#include <isobus_diagnostic_protocol.hpp>
#include <isobus_functionalities.hpp>
#include <isobus_guidance_interface.hpp>
#include <isobus_language_command_interface.hpp>
#include <isobus_maintain_power_interface.hpp>
#include <isobus_preferred_addresses.hpp>
#include <isobus_shortcut_button_interface.hpp>
#include <isobus_speed_distance_messages.hpp>
#include <isobus_standard_data_description_indices.hpp>
#include <isobus_task_controller_client.hpp>
#include <isobus_task_controller_client_objects.hpp>
#include <isobus_virtual_terminal_client.hpp>
#include <isobus_virtual_terminal_client_state_tracker.hpp>
#include <isobus_heartbeat.hpp>
#include <isobus_virtual_terminal_client_update_helper.hpp>
#include <isobus_virtual_terminal_objects.hpp>
#include <kinetis_flexcan.hpp>
#include <nmea2000_fast_packet_protocol.hpp>
#include <nmea2000_message_definitions.hpp>
#include <nmea2000_message_interface.hpp>
#include <platform_endianness.hpp>
#include <processing_flags.hpp>
#include <can_hardware_abstraction.hpp>
#include <system_timing.hpp>
#include <thread_synchronization.hpp>
#include <to_string.hpp>
#include <can_constants.hpp>
#include <can_badge.hpp>
#include <can_stack_logger.hpp>
#include <can_message.hpp>
#include <isobus_speed_distance_messages.hpp>
#include <isobus_diagnostic_protocol.hpp>
#include <can_hardware_interface_single_thread.hpp>

#endif // AG_ISO_STACK_HPP
16 changes: 8 additions & 8 deletions src/can_NAME.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/// @brief A class that represents a control function's NAME
/// @author Adrian Del Grosso
///
/// @copyright 2022 Adrian Del Grosso
/// @copyright 2022 The Open-Agriculture Developers
//================================================================================================
#include "can_NAME.hpp"
#include "can_stack_logger.hpp"
Expand Down Expand Up @@ -41,7 +41,7 @@ namespace isobus
{
if (value > 0x07)
{
CANStackLogger::error("[NAME]: Industry group out of range, must be between 0 and 7");
LOG_ERROR("[NAME]: Industry group out of range, must be between 0 and 7");
}
rawName &= ~static_cast<std::uint64_t>(0x7000000000000000);
rawName |= (static_cast<std::uint64_t>(value & 0x07) << 60);
Expand All @@ -56,7 +56,7 @@ namespace isobus
{
if (value > 0x0F)
{
CANStackLogger::error("[NAME]: Device class instance out of range, must be between 0 and 15");
LOG_ERROR("[NAME]: Device class instance out of range, must be between 0 and 15");
}
rawName &= ~static_cast<std::uint64_t>(0xF00000000000000);
rawName |= (static_cast<std::uint64_t>(value & 0x0F) << 56);
Expand All @@ -71,7 +71,7 @@ namespace isobus
{
if (value > 0x7F)
{
CANStackLogger::error("[NAME]: Device class out of range, must be between 0 and 127");
LOG_ERROR("[NAME]: Device class out of range, must be between 0 and 127");
}
rawName &= ~static_cast<std::uint64_t>(0xFE000000000000);
rawName |= (static_cast<std::uint64_t>(value & 0x7F) << 49);
Expand All @@ -97,7 +97,7 @@ namespace isobus
{
if (value > 0x1F)
{
CANStackLogger::error("[NAME]: Function instance out of range, must be between 0 and 31");
LOG_ERROR("[NAME]: Function instance out of range, must be between 0 and 31");
}
rawName &= ~static_cast<std::uint64_t>(0xF800000000);
rawName |= (static_cast<std::uint64_t>(value & 0x1F) << 35);
Expand All @@ -112,7 +112,7 @@ namespace isobus
{
if (value > 0x07)
{
CANStackLogger::error("[NAME]: ECU instance out of range, must be between 0 and 7");
LOG_ERROR("[NAME]: ECU instance out of range, must be between 0 and 7");
}
rawName &= ~static_cast<std::uint64_t>(0x700000000);
rawName |= (static_cast<std::uint64_t>(value & 0x07) << 32);
Expand All @@ -127,7 +127,7 @@ namespace isobus
{
if (value > 0x07FF)
{
CANStackLogger::error("[NAME]: Manufacturer code out of range, must be between 0 and 2047");
LOG_ERROR("[NAME]: Manufacturer code out of range, must be between 0 and 2047");
}
rawName &= ~static_cast<std::uint64_t>(0xFFE00000);
rawName |= (static_cast<std::uint64_t>(value & 0x07FF) << 21);
Expand All @@ -142,7 +142,7 @@ namespace isobus
{
if (value > 0x001FFFFF)
{
CANStackLogger::error("[NAME]: Identity number out of range, must be between 0 and 2097151");
LOG_ERROR("[NAME]: Identity number out of range, must be between 0 and 2097151");
}
rawName &= ~static_cast<std::uint64_t>(0x1FFFFF);
rawName |= static_cast<std::uint64_t>(value & 0x1FFFFF);
Expand Down
Loading
Loading