From 7d10a1e8c93af788094d62b6411367752022c039 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Sun, 28 Sep 2025 21:13:08 +0100 Subject: [PATCH] First commit with SRs 165N and 595N functionality --- .gitignore | 6 ++++++ 165_pinout.webp | Bin 0 -> 33704 bytes 595n_pinout.webp | Bin 0 -> 14490 bytes Makefile | 22 +++++++++++++++++++++ check.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++ include/README | 39 ++++++++++++++++++++++++++++++++++++ platformio.ini | 21 ++++++++++++++++++++ src/165.cpp | 35 +++++++++++++++++++++++++++++++++ src/165.h | 17 ++++++++++++++++ src/595n.cpp | 22 +++++++++++++++++++++ src/595n.h | 15 ++++++++++++++ src/main.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++ test/README | 11 +++++++++++ 13 files changed, 286 insertions(+) create mode 100644 .gitignore create mode 100644 165_pinout.webp create mode 100644 595n_pinout.webp create mode 100644 Makefile create mode 100644 check.py create mode 100644 include/README create mode 100644 platformio.ini create mode 100644 src/165.cpp create mode 100644 src/165.h create mode 100644 src/595n.cpp create mode 100644 src/595n.h create mode 100644 src/main.cpp create mode 100644 test/README diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a8ac1ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.pio +.clang_complete +.gcc-flags.json +.ccls +.cache +compile_commands.json diff --git a/165_pinout.webp b/165_pinout.webp new file mode 100644 index 0000000000000000000000000000000000000000..fb4e7fb34aefaf716c579add41aeab21ce9d5b40 GIT binary patch literal 33704 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 float(env.GetProjectOption("max_ram_perc")): + print("RAM USAGE EXCEEDS LIMIT") + sys.exit(1) + + except FileNotFoundError: + print("Coult not find map_file %s" % map_file) + sys.exit(1) + + +env.AddPreAction("upload", check_ram_usage) 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/platformio.ini b/platformio.ini new file mode 100644 index 0000000..e3950a5 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,21 @@ +; 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:sparkfun_promicro16] +platform = atmelavr +board = sparkfun_promicro16 +framework = arduino +# upload_port = /dev/ttyACM0 +build_flags = -Wl,-Map=${BUILD_DIR}/${PROGNAME}.map +extra_scripts = post:check.py +max_ram = 2560 +max_ram_perc = 80 +max_flash = 28672 +max_flash_perc = 90 diff --git a/src/165.cpp b/src/165.cpp new file mode 100644 index 0000000..6d5deaa --- /dev/null +++ b/src/165.cpp @@ -0,0 +1,35 @@ +#include "Arduino.h" +#include +#include "165.h" + +SR165 NewSR165(uint8_t pl, uint8_t ce, uint8_t cp, uint8_t q7) { + SR165 newSr = { + .parallelLoadIn = pl, + .clockEnable = ce, + .complementaryOut = q7, + .clockIn = cp + }; + + pinMode(newSr.clockIn, OUTPUT); + pinMode(newSr.clockEnable, OUTPUT); + pinMode(newSr.parallelLoadIn, OUTPUT); + pinMode(newSr.complementaryOut, INPUT); + + return newSr; +} + +byte SR165_read(SR165 *sr) { + // Write pulse to load pin + digitalWrite(sr->parallelLoadIn, LOW); + delayMicroseconds(5); + digitalWrite(sr->parallelLoadIn, HIGH); + delayMicroseconds(5); + + // Get data from 74HC165 + digitalWrite(sr->clockIn, HIGH); + digitalWrite(sr->clockEnable, LOW); + byte incoming = shiftIn(sr->complementaryOut, sr->clockIn, LSBFIRST); + digitalWrite(sr->clockEnable, HIGH); + + return incoming; +} diff --git a/src/165.h b/src/165.h new file mode 100644 index 0000000..aed6aae --- /dev/null +++ b/src/165.h @@ -0,0 +1,17 @@ +#ifndef __165__ +#define __165__ + +#include "Arduino.h" +#include + +typedef struct SR165 { + uint8_t parallelLoadIn; + uint8_t clockEnable; + uint8_t complementaryOut; + uint8_t clockIn; +} SR165; + +SR165 NewSR165(uint8_t pl, uint8_t ce, uint8_t cp, uint8_t q7); +byte SR165_read(SR165 *sr); + +#endif diff --git a/src/595n.cpp b/src/595n.cpp new file mode 100644 index 0000000..2ccc7c0 --- /dev/null +++ b/src/595n.cpp @@ -0,0 +1,22 @@ +#include "Arduino.h" +#include "595n.h" + +SR595N NewSR595N(uint8_t ser, uint8_t rclk, uint8_t srclk) { + struct SR595N newSR = { + .ser = ser, + .rclk = rclk, + .srclk = srclk + }; + + pinMode(newSR.ser, OUTPUT); + pinMode(newSR.rclk, OUTPUT); + pinMode(newSR.srclk, OUTPUT); + + return newSR; +} + +void SR595N_write(SR595N *sr, uint8_t value) { + digitalWrite(sr->rclk, LOW); + shiftOut(sr->ser, sr->srclk, MSBFIRST, value); + digitalWrite(sr->rclk, HIGH); +} diff --git a/src/595n.h b/src/595n.h new file mode 100644 index 0000000..b02620b --- /dev/null +++ b/src/595n.h @@ -0,0 +1,15 @@ +#ifndef __595N__ +#define __595N__ + +#include + +typedef struct SR595N { + uint8_t ser; + uint8_t rclk; + uint8_t srclk; +} SR595N; + +SR595N NewSR595N(uint8_t ser, uint8_t rclkh, uint8_t srclk); +void SR595N_write(SR595N *sr, uint8_t value); + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..b619ec8 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,48 @@ +/* BtnBOX by Eduardo Silva + * Notes: + * calling Wire.begin() will take use of the pins 2 and 3. Maybe try not using + * them from the getgo + */ + +#include +#include "595n.h" +#include "165.h" +// #include "Wire.h" + +// NOTES - 595N +// On the board, the first output pin on the SR595 is Qb +// Which means that our outputs go from 0b00000010 to 0b01111110 +#define IN_SERIAL_PIN 4 // SER - pin14 (Serial Pin) +#define IN_LATCH_PIN 5 // RCLK - pin12 (Latch Pin) +#define IN_CLOCK_PIN 6 // SRCLK - pin11 (Clock Pin) +/* ++-- --+ +|P5 P4 P3 P2 P1 P0| ++-----------------+ +P0 0b00000010 +P1 +*/ + +// NOTES - 165 +#define OUT_PARALLEL_LOAD_IN 10 // PL - pin1 (Async Parallel Load In) +#define OUT_CLOCK_IN 9 // CP - pin2 (Clock In) +#define OUT_COMPLEMENTARY_OUT 8 // Q7 - pin7 (Complementary Output) +#define OUT_CLOCK_ENABLE 7 // CE - pin15 (Clock Enable) + +SR595N input = NewSR595N(IN_SERIAL_PIN, IN_LATCH_PIN, IN_CLOCK_PIN); +SR165 output = NewSR165(OUT_PARALLEL_LOAD_IN, OUT_CLOCK_ENABLE, + OUT_CLOCK_IN, OUT_COMPLEMENTARY_OUT); + +void setup() { + Serial.begin(115200); + + SR595N_write(&input, 0b10101010); +} + +void loop(void) { + delay(200); + + byte srOutput = SR165_read(&output); + + Serial.println(srOutput, BIN); +} 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