From 3e740fba89327c4fb02a0d3ba1ddf8d10ef664f4 Mon Sep 17 00:00:00 2001 From: jpunkt Date: Sun, 19 Dec 2021 19:21:09 +0100 Subject: [PATCH] Implementing serial communication (interim commit). --- include/Commands.h | 20 ++++++++ include/Serial_Comm.h | 66 +++++++++++++++++++++++++ platformio.ini | 1 + src/Serial_Comm.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 50 ++++++++----------- src/scratch.cpp | 50 +++++++++++++++++++ 6 files changed, 269 insertions(+), 29 deletions(-) create mode 100644 include/Commands.h create mode 100644 include/Serial_Comm.h create mode 100644 src/Serial_Comm.cpp create mode 100644 src/scratch.cpp diff --git a/include/Commands.h b/include/Commands.h new file mode 100644 index 0000000..1234c0b --- /dev/null +++ b/include/Commands.h @@ -0,0 +1,20 @@ +enum Command { + HELLO = 0, + ALREADY_CONNECTED = 1, + ERROR = 2, + RECEIVED = 3, + + MOTOR_H = 'H', + MOTOR_V = 'M', + + BACKLIGHT = 'B', + FRONTLIGHT = 'F', + + USER_INTERACT = 'U', + + RECORD = 'C', + REWIND = 'R', + EOT = '\n' +}; + +typedef enum Command Command; \ No newline at end of file diff --git a/include/Serial_Comm.h b/include/Serial_Comm.h new file mode 100644 index 0000000..c207c5a --- /dev/null +++ b/include/Serial_Comm.h @@ -0,0 +1,66 @@ +#include +#include "Commands.h" + +/** + * @brief Read one byte from Serial and cast it to a Command + * + * @return Command + */ +Command read_command(HardwareSerial &serial); + +/** + * @brief Wait for the number of bytes to be available on Serial + * + * @param num_bytes + * @param timeout_ms + */ +void wait_for_bytes(HardwareSerial &serial, int num_bytes, unsigned long timeout_ms); + +/** + * @brief Read one byte + * + * @return int8_t + */ +int8_t read_i8(HardwareSerial &serial); + +/** + * @brief Read two bytes and convert to signed 16bit integer + * + * @return int16_t + */ +int16_t read_i16(HardwareSerial &serial); + +/** + * @brief Read four bytes and convert to signed 32bit integer + * + * @return int32_t + */ +int32_t read_i32(HardwareSerial &serial); + +/** + * @brief Write one byte corresponding to a Command + * + * @param cmd + */ +void write_command(HardwareSerial &serial, Command cmd); + +/** + * @brief Write a signed 8bit integer + * + * @param num + */ +void write_i8(HardwareSerial &serial, int8_t num); + +/** + * @brief Write a signed 16bit integer + * + * @param num + */ +void write_i16(HardwareSerial &serial, int16_t num); + +/** + * @brief Write a signed 32bit integer + * + * @param num + */ +void write_i32(HardwareSerial &serial, int32_t num); diff --git a/platformio.ini b/platformio.ini index 8825a94..cd5ff41 100644 --- a/platformio.ini +++ b/platformio.ini @@ -14,3 +14,4 @@ board = teensy41 framework = arduino upload_protocol = teensy-cli lib_deps = adafruit/Adafruit NeoPixel@^1.10.1 +src_filter = +<*> -<.git/> -<.svn/> - - - - - diff --git a/src/Serial_Comm.cpp b/src/Serial_Comm.cpp new file mode 100644 index 0000000..9b46e61 --- /dev/null +++ b/src/Serial_Comm.cpp @@ -0,0 +1,111 @@ +#include "Serial_Comm.h" + +/** + * @brief Read one byte from Serial and cast it to a Command + * + * @return Command + */ +Command read_command(HardwareSerial &serial) { + return (Command) serial.read(); +} + +/** + * @brief Wait for the number of bytes to be available on Serial + * + * @param num_bytes + * @param timeout_ms + */ +void wait_for_bytes(HardwareSerial &serial, int num_bytes, unsigned long timeout_ms) { + uint32_t startTime = millis(); + // Wait for incoming bytes or exit if timeout + while ((serial.available() < num_bytes) && (millis() - startTime < timeout_ms)){ + // NOOP. + } +} + +void read_signed_bytes(HardwareSerial &serial, int8_t* buffer, size_t n) +{ + size_t i = 0; + int c; + while (i < n) + { + c = serial.read(); + if (c < 0) break; + *buffer++ = (int8_t) c; // buffer[i] = (int8_t)c; + i++; + } +} + +/** + * @brief Read one byte + * + * @return int8_t + */ +int8_t read_i8(HardwareSerial &serial) { + wait_for_bytes(serial, 1, 500); + return (int8_t) serial.read(); +} + +/** + * @brief Read two bytes and convert to signed 16bit integer + * + * @return int16_t + */ +int16_t read_i16(HardwareSerial &serial) { + int8_t buffer[2]; + wait_for_bytes(serial, 2, 500); + read_signed_bytes(serial, buffer, 2); + return (((int16_t) buffer[0]) & 0xff) | (((int16_t) buffer[1]) << 8 & 0xff00); +} + +/** + * @brief Read four bytes and convert to signed 32bit integer + * + * @return int32_t + */ +int32_t read_i32(HardwareSerial &serial) { + int8_t buffer[4]; + wait_for_bytes(serial, 4, 200); // Wait for 4 bytes with a timeout of 200 ms + read_signed_bytes(serial, buffer, 4); + return (((int32_t) buffer[0]) & 0xff) | (((int32_t) buffer[1]) << 8 & 0xff00) | (((int32_t) buffer[2]) << 16 & 0xff0000) | (((int32_t) buffer[3]) << 24 & 0xff000000); + +} + +/** + * @brief Write one byte corresponding to a Command + * + * @param cmd + */ +void write_command(HardwareSerial &serial, Command cmd) { + uint8_t* c = (uint8_t*) &cmd; + serial.write(c, sizeof(uint8_t)); +} + +/** + * @brief Write a signed 8bit integer + * + * @param num + */ +void write_i8(HardwareSerial &serial, int8_t num) { + serial.write(num); +} + +/** + * @brief Write a signed 16bit integer + * + * @param num + */ +void write_i16(HardwareSerial &serial, int16_t num) { + int8_t buffer[2] = {(int8_t) (num & 0xff), (int8_t) (num >> 8)}; + serial.write((uint8_t*)&buffer, 2*sizeof(int8_t)); +} + +/** + * @brief Write a signed 32bit integer + * + * @param num + */ +void write_i32(HardwareSerial &serial, int32_t num) { + int8_t buffer[4] = {(int8_t) (num & 0xff), (int8_t) (num >> 8 & 0xff), (int8_t) (num >> 16 & 0xff), (int8_t) (num >> 24 & 0xff)}; + serial.write((uint8_t*)&buffer, 4*sizeof(int8_t)); +} diff --git a/src/main.cpp b/src/main.cpp index 9d478c5..3815961 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include "Motor.h" +#include "Serial_Comm.h" // Vertical motor top #define VERT_UP_PWM 3 @@ -95,6 +96,7 @@ void mot_control(Motor mot1, Motor mot2, int32_t pos, int32_t aim) { void setup() { Serial.begin(115200); + Serial1.begin(115200); pinMode(LED_BUILTIN, OUTPUT); @@ -143,36 +145,26 @@ void setup() { } void loop() { - // led_front.setPixelColor(led_n, 0, 0, 0, led_on ? 255 : 0); - uint32_t c = led_back.Color((color == 0 || color == 1 || color == 2 || color == 9) ? brightness : 0, - (color == 2 || color == 3 || color == 4 || color == 8) ? brightness : 0, - (color == 4 || color == 5 || color == 6 || color == 9) ? brightness : 0, - (color == 6 || color == 7 || color == 0 || color == 8) ? brightness : 0); - if (back) { - led_back.fill(c); - led_back.show(); - } else { - led_front.fill(c); - led_front.show(); - } - delay(10); - - if (led_on && (brightness < 255)) { - brightness++; - } else if (!led_on && (brightness > 0)) { - brightness--; - } else { - if (!led_on) { - if (color < 9) color++; - else { - color = 0; - back = !back; + if (Serial1.available() > 0) { + Serial.printf("Serial1.available = %i \n", Serial1.available()); + Command cmd = read_command(Serial1); + switch (cmd) + { + case HELLO: + { + Serial.println("Received HELLO"); + break; + } + case MOTOR_H: + { + Serial.println("Received MOTOR_H"); + break; + } + default: + { + Serial.println("Received something."); + break; } } - led_on = !led_on; - } - - if (brightness % 8 == 0) { - Serial.printf("hor_pos %i | \t vert_pos %i \n", hor_pos, vert_pos); } } \ No newline at end of file diff --git a/src/scratch.cpp b/src/scratch.cpp new file mode 100644 index 0000000..db82b83 --- /dev/null +++ b/src/scratch.cpp @@ -0,0 +1,50 @@ +#include +#include + +// Lights +#define LED_FRONT 41 +#define LED_COUNT_FRONT 26 + +#define LED_BACK 14 +#define LED_COUNT_BACK 72 + +Adafruit_NeoPixel led_front(LED_COUNT_FRONT, LED_FRONT, NEO_GBRW + NEO_KHZ800); +Adafruit_NeoPixel led_back(LED_COUNT_BACK, LED_BACK, NEO_GBRW + NEO_KHZ800); + +bool back; +bool led_on; +int led_n; +u_int8_t brightness; +u_int8_t color; + +void led_loop() { + // LED test loop, for reference.. + + uint32_t c = led_back.Color((color == 0 || color == 1 || color == 2 || color == 9) ? brightness : 0, + (color == 2 || color == 3 || color == 4 || color == 8) ? brightness : 0, + (color == 4 || color == 5 || color == 6 || color == 9) ? brightness : 0, + (color == 6 || color == 7 || color == 0 || color == 8) ? brightness : 0); + if (back) { + led_back.fill(c); + led_back.show(); + } else { + led_front.fill(c); + led_front.show(); + } + delay(10); + + if (led_on && (brightness < 255)) { + brightness++; + } else if (!led_on && (brightness > 0)) { + brightness--; + } else { + if (!led_on) { + if (color < 9) color++; + else { + color = 0; + back = !back; + } + } + led_on = !led_on; + } +} \ No newline at end of file