diff --git a/firmware/mini_v/motor_driver/.gitignore b/firmware/mini_v/motor_driver/.gitignore new file mode 100644 index 000000000..89cc49cbd --- /dev/null +++ b/firmware/mini_v/motor_driver/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/firmware/mini_v/motor_driver/include/README b/firmware/mini_v/motor_driver/include/README new file mode 100644 index 000000000..194dcd432 --- /dev/null +++ b/firmware/mini_v/motor_driver/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/firmware/mini_v/motor_driver/lib/README b/firmware/mini_v/motor_driver/lib/README new file mode 100644 index 000000000..2593a33f9 --- /dev/null +++ b/firmware/mini_v/motor_driver/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.pb.c b/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.pb.c new file mode 100644 index 000000000..811d4141c --- /dev/null +++ b/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.pb.c @@ -0,0 +1,20 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-1.0.0-dev */ + +#include "proto/hardware_communication_msgs__MotorControl.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl, protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl, AUTO) + + + +#ifndef PB_CONVERT_DOUBLE_FLOAT +/* On some platforms (such as AVR), double is really float. + * To be able to encode/decode double on these platforms, you need. + * to define PB_CONVERT_DOUBLE_FLOAT in pb.h or compiler command line. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) +#endif + diff --git a/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.pb.h b/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.pb.h new file mode 100644 index 000000000..c923da4e5 --- /dev/null +++ b/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.pb.h @@ -0,0 +1,48 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-1.0.0-dev */ + +#ifndef PB_PROTOLINK__HARDWARE_COMMUNICATION_MSGS__MOTORCONTROL_PROTO_HARDWARE_COMMUNICATION_MSGS__MOTORCONTROL_PB_H_INCLUDED +#define PB_PROTOLINK__HARDWARE_COMMUNICATION_MSGS__MOTORCONTROL_PROTO_HARDWARE_COMMUNICATION_MSGS__MOTORCONTROL_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl { + double motor_speed; +} protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_init_default {0} +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_init_zero {0} + +/* Field tags (for use in manual encoding/decoding) */ +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_motor_speed_tag 1 + +/* Struct field encoding specification for nanopb */ +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, DOUBLE, motor_speed, 1) +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_CALLBACK NULL +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_DEFAULT NULL + +extern const pb_msgdesc_t protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_fields &protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_msg + +/* Maximum encoded size of messages (where known) */ +#define PROTOLINK__HARDWARE_COMMUNICATION_MSGS__MOTORCONTROL_PROTO_HARDWARE_COMMUNICATION_MSGS__MOTORCONTROL_PB_H_MAX_SIZE protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_size +#define protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_size 9 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.proto b/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.proto new file mode 100644 index 000000000..3f4c5f1fa --- /dev/null +++ b/firmware/mini_v/motor_driver/lib/protolink_msgs/proto/hardware_communication_msgs__MotorControl.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package protolink__hardware_communication_msgs__MotorControl; + +message hardware_communication_msgs__MotorControl { +double motor_speed = 1; +} \ No newline at end of file diff --git a/firmware/mini_v/motor_driver/platformio.ini b/firmware/mini_v/motor_driver/platformio.ini new file mode 100644 index 000000000..f0929d9de --- /dev/null +++ b/firmware/mini_v/motor_driver/platformio.ini @@ -0,0 +1,16 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:teensy41] +platform = teensy +board = teensy41 +framework = arduino +lib_deps = nanopb/Nanopb@^0.4.91 +lib_dir=lib diff --git a/firmware/mini_v/motor_driver/src/main.cpp b/firmware/mini_v/motor_driver/src/main.cpp new file mode 100644 index 000000000..c0c3c70c6 --- /dev/null +++ b/firmware/mini_v/motor_driver/src/main.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include "pb_encode.h" +#include "pb_decode.h" +#include +#include + +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +}; +IPAddress ip(192, 168, 1, 100); +unsigned int localPort = 8888; // local port to listen on +// An EthernetUDP instance to let us send and receive packets over UDP +EthernetUDP Udp; + +// buffers for receiving and sending data +uint8_t packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet, + +byte servoPin = 41; +Servo servo; + +void setup() { + servo.attach(servoPin); + + servo.writeMicroseconds(1500); // send "stop" signal to ESC. + + delay(7000); // delay to allow the ESC to recognize the stopped signal + + Ethernet.begin(mac, ip); + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // start UDP + Udp.begin(localPort); + +} + +void loop() { + int packetSize = Udp.parsePacket(); + if (packetSize) { + const size_t num_bytes = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); + pb_istream_t pb_stream = pb_istream_from_buffer(packetBuffer, num_bytes); + protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl msg + = protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_init_zero; + if(pb_decode(&pb_stream, protolink__hardware_communication_msgs__MotorControl_hardware_communication_msgs__MotorControl_fields, &msg)) { + int signal = (int)(constrain(msg.motor_speed, -1.0, 1.0) * 400.0 + 1500.0); + servo.writeMicroseconds(constrain(signal, 1100, 1900)); + } + } +} diff --git a/firmware/mini_v/motor_driver/test/README b/firmware/mini_v/motor_driver/test/README new file mode 100644 index 000000000..9b1e87bc6 --- /dev/null +++ b/firmware/mini_v/motor_driver/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html