commit 2a71ea379724ed628b3634b186454e0c97e66a60 Author: Dominik SzymaƄski Date: Sat Feb 3 02:46:44 2024 +0100 Initial code, screwed up diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/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/lib/PixelBydgoszcz/src/Pixel.cpp b/lib/PixelBydgoszcz/src/Pixel.cpp new file mode 100644 index 0000000..372d422 --- /dev/null +++ b/lib/PixelBydgoszcz/src/Pixel.cpp @@ -0,0 +1,157 @@ +#include +#include + +PixelClass::PixelClass(Stream& serial, int txEnPin, int rxEnPin) : + _serial(&serial), + _txEnPin(txEnPin), + _rxEnPin(rxEnPin) +{ + digitalWrite(_rxEnPin, HIGH); + digitalWrite(_txEnPin, LOW); + pinMode(_rxEnPin, OUTPUT); + pinMode(_txEnPin, OUTPUT); + pinMode(D4, OUTPUT); +} + +void PixelClass::begin() { + digitalWrite(_rxEnPin, LOW); + digitalWrite(_txEnPin, LOW); +} + +void PixelClass::end() { + digitalWrite(_rxEnPin, HIGH); + digitalWrite(_txEnPin, LOW); +} + +void PixelClass::sendSpace(bool autoEnd) { + beginTransmit(); + uint8_t bfr[2] = {0x20, 0x04}; + _serial->write(bfr, 2); + if (autoEnd) + endTransmit(); +} + +void PixelClass::sendDblSpace(bool autoEnd) { + beginTransmit(); + uint8_t bfr[3] = {0x20, 0x20, 0x04}; + _serial->write(bfr, 2); + if (autoEnd) + endTransmit(); +} + +void PixelClass::sendCommand(byte displayNo, char *command) { + if (displayNo > 7) + return; + + digitalWrite(D4, HIGH); + + sendSpace(false); + _serial->write('_'); + _serial->write(0x01); + _serial->write('2'); + _serial->write(displayNo + 0x30); + _serial->print(command); + _serial->write(0x0a); + _serial->write(0x0d); + _serial->write(0x04); + endTransmit(); + digitalWrite(D4, LOW); +} + +size_t PixelClass::readResponse(byte buffer[], uint16_t length, uint32_t timeout) { + unsigned long orig_timeout = _serial->getTimeout(); + _serial->setTimeout(timeout); + size_t readCnt = _serial->readBytesUntil(0x04, buffer, length); + _serial->setTimeout(orig_timeout); + return readCnt; +} + +/// @brief Checks response code and finds response start +/// @param buffer buffer to check +/// @param msgLength Length of buffer +/// @param start message start or 0xFFFF if start byte not found +/// @return error code, possibly 0xFF is start byte not found or wrong code met +uint8_t PixelClass::checkResponse(byte buffer[], uint16_t msgLength, uint16_t &start) +{ + for (start = 0; start < msgLength; start++) + { + if (buffer[start] == 0x02) + break; + } + + if (start == msgLength) + { + start = 0xFFFF; + return 0xFF; + } + + char nibble1 = buffer[start + 8]; + char nibble2 = buffer[start + 9]; + + uint8_t errorCode = 0x00; + + if (nibble1 >= 0x30 && nibble1 <= 0x39) { + errorCode |= (nibble1 - 0x30) << 4; + } + else if (nibble1 >= 'A' && nibble1 <= 'F') { + errorCode |= (nibble1 - 0x37) << 4; + } + else if (nibble1 >= 'a' && nibble2 <= 'f') { + errorCode |= (nibble1 - 0x57) << 4; + } + else { + return 0xFF; + } + + if (nibble2 >= 0x30 && nibble2 <= 0x39) { + errorCode |= (nibble2 - 0x30); + } + else if (nibble2 >= 'A' && nibble2 <= 'F') { + errorCode |= (nibble2 - 0x37); + } + else if (nibble2 >= 'a' && nibble2 <= 'f') { + errorCode |= (nibble2 - 0x57); + } + return errorCode; +} + +/// @brief Reads string response for command +/// @param displayNo display number +/// @param command command string to send to display +/// @param buffer buffer for response +/// @param length length of buffer +/// @param responseMsgLength Length of resulting string, or 0xFFFF if failed to parse response +/// @return display response code or 0xFF if parsing error occured +uint8_t PixelClass::readStringCommand(uint8_t displayNo, char *command, char buffer[], uint16_t length, uint16_t& responseMsgLength) { + sendCommand(displayNo, command); + byte respBuffer[length + 32]; + size_t responseLength = readResponse(respBuffer, length + 32); + uint16_t responseStart = 0; + uint8_t errorCode = checkResponse(respBuffer, responseLength, responseStart); + if (responseStart == 0xFFFF) { + responseMsgLength = 0xFFFF; + return 0xFF; + } + + responseMsgLength = responseLength - responseStart - 11; + + for (uint16_t ix = 0; ix < responseMsgLength - 1; ix++) { + buffer[ix] = respBuffer[ix + responseStart + 11]; + } + + buffer[responseMsgLength - 1] = 0x00; + + return errorCode; +} + +void PixelClass::beginTransmit() +{ + digitalWrite(_rxEnPin, HIGH); + digitalWrite(_txEnPin, HIGH); +} + +void PixelClass::endTransmit() +{ + digitalWrite(_txEnPin, LOW); + digitalWrite(_rxEnPin, LOW); +} diff --git a/lib/PixelBydgoszcz/src/Pixel.hpp b/lib/PixelBydgoszcz/src/Pixel.hpp new file mode 100644 index 0000000..2a88852 --- /dev/null +++ b/lib/PixelBydgoszcz/src/Pixel.hpp @@ -0,0 +1,35 @@ +#ifndef __PIXEL_BYDGOSZCZ__ +#define __PIXEL_BYDGOSZCZ__ + +#include + +class PixelClass { + public: + /// @brief Constructor for Pixel class + /// @param serial Stream object for serial. Idk, make it hardware or software, just make sure it's initialized to 4800 baud, 8E1. + /// @param txEnPin + /// @param rxEnPin + PixelClass(Stream& serial, int txEnPin, int rxEnPin); + void begin(); + void end(); + + void sendSpace(bool autoEnd = true); + void sendDblSpace(bool autoEnd = true); + + void sendCommand(byte displayNo, char *command); + size_t readResponse(byte buffer[], uint16_t length, uint32_t timeout = 3000); + uint8_t checkResponse(byte buffer[], uint16_t msgLength, uint16_t& start); + uint8_t readStringCommand(uint8_t displayNo, char *command, char buffer[], uint16_t length, uint16_t& responseMsgLength); + + private: + Stream* _serial; + int _txEnPin; + int _rxEnPin; + + void beginTransmit(); + void endTransmit(); +}; + +extern PixelClass Pixel; + +#endif \ No newline at end of file diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/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 a 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/platformio.ini b/platformio.ini new file mode 100644 index 0000000..6a29f27 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,20 @@ +; 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:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 +framework = arduino + +build_type = debug + +monitor_speed = 115200 +monitor_filters = + esp8266_exception_decoder diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..7f0ff48 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,25 @@ +#include +#include +#include + +SoftwareSerial pixelSerial(D7, D8); +PixelClass Pixel(pixelSerial, D6, D5); + +void setup() { + Serial.begin(115200); + pixelSerial.begin(4800, SoftwareSerialConfig::SWSERIAL_8E1); + Pixel.begin(); + Serial.println("Sleeping for a moment..."); + delay(2000); + Serial.println("Checking GID..."); + char respMsg[2137]; + uint16_t respMsgLen; + uint8_t errCode = Pixel.readStringCommand(0, "GID", respMsg, 2137, respMsgLen); + Serial.print("Got response code: "); + Serial.println(errCode); + Serial.println(respMsg); +} + +void loop() { + // put your main code here, to run repeatedly: +} \ No newline at end of file diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/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