diff --git a/.github/workflows/CompileTests.yml b/.github/workflows/CompileTests.yml
new file mode 100644
index 0000000..73f8d42
--- /dev/null
+++ b/.github/workflows/CompileTests.yml
@@ -0,0 +1,109 @@
+# This is the name of the workflow, visible on GitHub UI.
+name: 'Compile tests'
+
+#description: 'Run the Arduino CLI to compile the sketch and check if it compiles fine for multiple boards'
+#author: 'Jorge Rivera'
+
+# Controls when the action will run.
+# Here we tell GitHub to run the workflow when a commit.
+on:
+ # Triggers the workflow on push or pull request events but only for the "arduino" branch
+ push:
+ branches: [ arduino ]
+ paths:
+ - '*.ino'
+ - '.github/workflows/*.yml'
+
+ pull_request:
+ branches: [ arduino ]
+ paths:
+ - '*.ino'
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# This is the list of jobs that will be run concurrently.
+# Since we use a build matrix, the actual number of jobs
+# started depends on how many configurations the matrix
+# will produce.
+jobs:
+ boards:
+
+ # This is the name of the job
+ name: "Compile test for ${{ matrix.config.board }}"
+
+ # This is the platform GitHub will use to run our workflow, we
+ # pick Linux for no particular reason.
+ runs-on: ubuntu-latest
+
+ # Here we tell GitHub that the jobs must be determined
+ # dynamically depending on a matrix configuration.
+ strategy:
+
+ # Set to false so that GitHub does not cancel all jobs
+ # in progress if any array job fails.
+ fail-fast: false
+
+ # The matrix will produce one job for each configuration:
+ matrix:
+ config:
+ - board: "Arduino Nano"
+ fqbn: "arduino:avr:nano"
+ platform: "arduino:avr"
+
+ - board: "Arduino UNO"
+ fqbn: "arduino:avr:uno"
+ platform: "arduino:avr"
+
+ - board: "Arduino Leonardo"
+ fqbn: "arduino:avr:leonardo"
+ platform: "arduino:avr"
+
+ - board: "Arduino Due (Native USB Port)"
+ fqbn: "arduino:sam:arduino_due_x"
+ platform: "arduino:sam"
+
+ - board: "Arduino M0"
+ fqbn: "arduino:samd:mzero_bl"
+ platform: "arduino:samd"
+
+ - board: "ESP8266 NodeMCUv2"
+ fqbn: "esp8266:esp8266:nodemcuv2"
+ platform: "esp8266:esp8266"
+ additional-url: "--additional-urls https://arduino.esp8266.com/stable/package_esp8266com_index.json"
+
+ - board: "ESP32 NodeMCU-32S"
+ fqbn: "esp32:esp32:nodemcu-32s"
+ platform: "esp32:esp32"
+ additional-url: "--additional-urls https://dl.espressif.com/dl/package_esp32_index.json"
+
+ # This is the list of steps this job will run.
+ steps:
+ # First of all, we clone the repo using the "checkout" action.
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ # We use the "arduino/setup-arduino-cli" action to install and
+ # configure the Arduino CLI on the system.
+ - name: Setup Arduino CLI
+ uses: arduino/setup-arduino-cli@v2
+
+ # We then install the platform, which one will be determined
+ # dynamically by the build matrix.
+ - name: Install platform ${{ matrix.config.platform }}
+ run: |
+ arduino-cli config init -v ${{ matrix.config.additional-url }}
+ arduino-cli core update-index -v
+ arduino-cli core install -v ${{ matrix.config.platform }} --run-post-install
+
+ # Finally, we compile the sketch, using the FQBN that was set in the build matrix.
+ - name: Compile sketch for ${{ matrix.config.board }}
+ run: arduino-cli compile -v --fqbn ${{ matrix.config.fqbn }} --export-binaries --warnings none --log-level info
+
+ # Upload binary (.hex) files to artifacts
+ - name: Upload compiled binaries files to Artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: "Binaries for ${{ matrix.config.board }}"
+ path: ./
diff --git a/.gitignore b/.gitignore
index edf6645..6ff2b5e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,35 @@
+# Compiler outputs
+build/*
+
+# Visual Studio Code
+.vscode/
+*.code-workspace
+.history/
+
+# OS generated files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+Thumbs.db
+
+# Prerequisites
+*.d
+
+# Precompiled Headers
+*.gch
+*.pch
+
# Object files
*.o
*.ko
*.obj
*.elf
+*.bin
+*.eep
+*.lo
+*.slo
# Precompiled Headers
*.gch
@@ -12,7 +39,7 @@
*.lib
*.a
*.la
-*.lo
+*.lai
# Shared objects (inc. Windows DLLs)
*.dll
diff --git a/README.md b/README.md
index f0a6f32..0db45fc 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,50 @@
-# pilight USB Nano
+# pilight USB Nano v2 (Arduino compatible)
-The pilight Arduino Nano software allows any computer with an USB port to work with pilight.
+The pilight USB Nano software allows any computer with an USB port to work with pilight.
+
+[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0)
+[![Compile tests](https://github.com/latchdevel/pilight-usb-nano/actions/workflows/CompileTests.yml/badge.svg?branch=arduino)](https://github.com/latchdevel/pilight-usb-nano/actions/workflows/CompileTests.yml)
+
+## New v2 firmware features:
+ - Can run on any AVR Arduino compatible board, like Arduino UNO, Nano, MEGA, Leonardo, etc. any clock speed allowed.
+ - Can run on other platforms like Arduino SAMD boards (DUE, M0, etc.), ESP8266, ESP32, Teensy, even Raspberry Pico.
+ - Works using the MCU's internal USB-Serial COM port (CDC/ACM device class) or any onboard/external USB-Serial adapter.
+ - Fully Arduino IDE compiler environment compatible. Arduino PRO IDE and Arduino CLI also supported.
+ - Configurable RF receiver output (RX_PIN); must be interrupt attachable, depends board (D2 as default).
+ - Configurable RF transmitter input (TX_PIN); can be any digital pin, depends board (D5 as default).
+ - Support to configure a digital output so that a led blinks at valid RF code reception.
+ - Support to configure send of every 'space' before 'pulse', which stripped in previous version firmware.
+ - Support to configure initial RX settings at boot, like as 's:22,200,3000,51000@'.
+ - Support to configure show settings at boot, like as: 'v:20,200,4000,82000,2,1,1600@'.
+ - Support to configure add line feed '\n' each line output.
+ - Support to configure a tx enable pin (PTT_PIN), useful for use transceivers.
+ - Fix TX pulse generator drift from 9.95µS to 0.69µS (AVR@16Mhz).
+ - Improve RX pulse meter resolution from 10µS to 4µS (AVR@16Mhz).
+
+## Usage:
1. Compile the firmware:
-```
-avr-gcc -Os -Wall -DF_CPU=16000000UL -mmcu=atmega328p -c -o pilight_usb_nano.o pilight_usb_nano.c -lm -I.
-avr-gcc -mmcu=atmega328p pilight_usb_nano.o -o pilight_usb_nano
-avr-objcopy -O ihex -R .eeprom pilight_usb_nano pilight_usb_nano.hex
-```
-2. Flash the firmware on the Arduino Nano:
-`avrdude -b 57600 -p atmega328p -c arduino -P COM5 -U flash:w:pilight_usb_nano.hex`
-3. Connect the receiver data pin to D2 and the sender to D5.
-4. Connect the Arduino Nano to your computer.
-5. Check what COM port the Arduino Nano is using.
-6. Configure pilight to interface with the Arduino Nano (see below).
+ ```
+ - Open Arduino IDE application
+ - File> Open> Select file "pilight-usb-nano.ino"
+ - Tools> Board> Select your board
+ - Sketch> Verify/Compile
+ ```
+2. Flash the firmware on the board:
+ ```
+ - Tools> Port> Select your USB/Serial COM port
+ - Sketch> Upload
+ ```
+3. Connect the receiver data pin to configured RX_PIN (D2 as default) and the transmitter data pin to configured TX_PIN (D5 as default).
+4. Connect the Arduino to your computer.
+5. Check what Serial/COM port the Arduino is using.
+6. Configure pilight to interface with the Arduino (see below).
7. Start pilight normally and it should work OOTB.
-pilight USB nano hardware configuration:
+## pilight USB Arduino hardware configuration:
Linux example:
-```
+```json
"hardware": {
"433nano": {
"comport": "/dev/ttyUSB0"
@@ -27,10 +52,76 @@ Linux example:
}
```
Windows Example:
-```
+```json
"hardware": {
"433nano": {
"comport": "COM5"
}
}
-```
\ No newline at end of file
+```
+
+## Example:
+Transmitter code:
+```
+c:011010100101011010100110101001100110010101100110101010101010101012;p:1400,600,6800;r:4@
+```
+ * Receive with spaces:
+ ```
+ c:011010100101011010100110101001100110010101100110101010101010101012;p:1400,600,6800@
+ ```
+
+ * Receive without spaces:
+ ```
+ c:100011100010001010111010000000002;p:1400,600,6800@
+ ```
+
+## Decoding:
+You can decode and encode any code using an external tool **"picoder"** from https://github.com/latchdevel/picoder
+
+Decode example:
+```
+$ picoder decode -s "c:011010100101011010100110101001100110010101100110101010101010101012;p:1400,600,6800@"
+```
+return:
+```json
+ [{
+ "conrad_rsl_switch": {
+ "id": 1,
+ "unit": 2,
+ "state": "on"
+ }
+ }]
+```
+
+Encode example:
+```json
+$ picoder encode -f '{ "conrad_rsl_switch" : {"id":1,"unit":2,"on":1} }' -r 5
+```
+return:
+```
+c:011010100101011010100110101001100110010101100110101010101010101012;p:1400,600,6800;r:5@
+```
+
+## To do:
+- [ ] Support to measure RSSI of receivers that provide it.
+
+# License
+
+Copyright (C) 2015 CurlyMo. This file is part of pilight. GPLv3.
+
+Copyright (C) 2021 Jorge Rivera. GNU General Public License v3.0.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+
+
diff --git a/diff b/diff
deleted file mode 100644
index 48ba9d9..0000000
--- a/diff
+++ /dev/null
@@ -1,377 +0,0 @@
-diff --git a/README.md b/README.md
-index 5c180cc..e669d2e 100644
---- a/README.md
-+++ b/README.md
-@@ -1,2 +1,31 @@
--# pilight-usb-nano
--pilight Arduino Nano USB interface
-+# pilight USB Nano
-+
-+The pilight Arduino Nano software allows any computer with an USB port to work with pilight.
-+
-+1. Compile the firmware:
-+`avr-gcc -Os -Wall -DF_CPU=16000000UL -mmcu=atmega328p -c -o usbto433.o usbto433.c -lm -I.`
-+`avr-gcc -mmcu=atmega328p usbto433.o -o usbto433`
-+`avr-objcopy -O ihex -R .eeprom usbto433 usbto433.hex`
-+2. Flash the firmware on the Arduino Nano:
-+`avrdude -b 57600 -p atmega328p -c arduino -P COM5 -U flash:w:usbto433.hex`
-+3. Connect the receiver data pin to D2 and the sender to D5.
-+4. Connect the Arduino Nano to your computer.
-+5. Check what COM port the Arduino Nano is using.
-+6. Configure pilight to interface with the Arduino Nano:
-+Linux example:
-+```
-+ "hardware": {
-+ "433nano": {
-+ "comport": "/dev/ttyUSB0"
-+ }
-+ }
-+```
-+Windows Example:
-+```
-+ "hardware": {
-+ "433nano": {
-+ "comport": "COM5"
-+ }
-+ }
-+```
-+7. Start pilight normally and it should work OOTB.
-\ No newline at end of file
-diff --git a/usbto433.c b/usbto433.c
-new file mode 100644
-index 0000000..ce83dcf
---- /dev/null
-+++ b/usbto433.c
-@@ -0,0 +1,332 @@
-+/*
-+ Copyright (C) 2015 CurlyMo
-+
-+ This file is part of pilight.
-+
-+ pilight is free software: you can redistribute it and/or modify it under the
-+ terms of the GNU General Public License as published by the Free Software
-+ Foundation, either version 3 of the License, or (at your option) any later
-+ version.
-+
-+ pilight is distributed in the hope that it will be useful, but WITHOUT ANY
-+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with pilight. If not, see
-+*/
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#define BUFFER_SIZE 256
-+#define MAX_PULSE_TYPES 10
-+#define BAUD 57600
-+#define MIN_PULSELENGTH 8 //tested to work down to 30us pulsewidth (=2)
-+#define MAX_PULSELENGTH 1600
-+#define MIN_FOOTER_LENGTH 510 // 5100 deviced by 10
-+#define MIN_STREAM_LENGTH 25
-+
-+#include
-+
-+// Code formatting meant for sending
-+// on c:102020202020202020220202020020202200202200202020202020220020202203;p:279,2511,1395,9486;r:5@
-+// off c:102020202020202020220202020020202200202200202020202020202020202203;p:279,2511,1395,9486;r:5@
-+
-+
-+// Code formatting outputted by receiver
-+// on c:102020202020202020220202020020202200202200202020202020220020202203;p:279,2511,1395,9486@
-+// off c:102020202020202020220202020020202200202200202020202020202020202203;p:279,2511,1395,9486@
-+
-+char data[BUFFER_SIZE];
-+volatile unsigned long ten_us_counter1 = 0;
-+volatile uint16_t ten_us_counter = 0, codes[BUFFER_SIZE], plstypes[MAX_PULSE_TYPES];
-+volatile uint8_t state = 0, codelen = 0, repeats = 0, pos = 0;
-+volatile uint8_t valid_buffer = 0x00, r = 0, q = 0, plslen = 0, nrpulses = 0;
-+
-+void initUART(void) {
-+ DDRD |= _BV(PD1);
-+ DDRD &= ~_BV(PD0);
-+
-+ UBRR0H = UBRRH_VALUE;
-+ UBRR0L = UBRRL_VALUE;
-+
-+#if USE_2X
-+ UCSR0A |= _BV(U2X0);
-+#else
-+ UCSR0A &= ~_BV(U2X0);
-+#endif
-+
-+ UCSR0B |= _BV(RXEN0);
-+ UCSR0B |= _BV(RXCIE0);
-+ // UCSR0B = UCSR0B | (1 << TXEN0);
-+
-+ UCSR0C |= _BV(USBS0);
-+ UCSR0C |= _BV(UCSZ01) | _BV(UCSZ00);
-+}
-+
-+void setup() {
-+ uint8_t oldSREG = SREG;
-+
-+ cli();
-+
-+ /* We initialize our array to zero
-+ * here to spare resources while
-+ * running.
-+ */
-+ for(r=0;r 0 && spulse > 0 && srepeat > 0) {
-+ z = strlen(&data[spulse]);
-+ s = spulse;
-+ nrpulses = 0;
-+ for(i = spulse; i < spulse + z; i++) {
-+ if(data[i] == ',') {
-+ data[i] = '\0';
-+ plstypes[nrpulses++] = atoi(&data[s]);
-+ s = i+1;
-+ }
-+ }
-+ plstypes[nrpulses++] = atoi(&data[s]);
-+
-+ codelen = strlen(&data[scode]);
-+ repeats = atoi(&data[srepeat]);
-+ cli();
-+ for(i=0;i 100000) {
-+ putByte('\n');
-+ ten_us_counter1 = 0;
-+ }
-+ sei();
-+}
-+
-+void broadcast() {
-+ int i = 0, x = 0, match = 0, p = 0;
-+
-+ putByte('c');
-+ putByte(':');
-+ for(i=0;i MIN_PULSELENGTH) {
-+ if(ten_us_counter < MAX_PULSELENGTH) {
-+ /* All codes are buffered */
-+ codes[nrpulses++] = ten_us_counter;
-+ if(nrpulses > BUFFER_SIZE) {
-+ nrpulses = 0;
-+ }
-+ /* Let's match footers */
-+ if(ten_us_counter > MIN_FOOTER_LENGTH) {
-+ /* Only match minimal length pulse streams */
-+ if(nrpulses >= MIN_STREAM_LENGTH) {
-+ /*
-+ * Sending pulses over serial requires
-+ * a lot of cpu ticks. We therefor have
-+ * to be sure that we send valid codes.
-+ * Therefor, only streams we at least
-+ * received twice communicated.
-+ */
-+ if(plslen == nrpulses) {
-+ broadcast();
-+ }
-+ plslen = nrpulses;
-+ }
-+ nrpulses = 0;
-+ }
-+ }
-+ }
-+ ten_us_counter = 0;
-+ TCNT1 = 0;
-+ sei();
-+}
-+
-+int main(void) {
-+ setup();
-+ while(1);
-+}
diff --git a/pilight-usb-nano.ino b/pilight-usb-nano.ino
new file mode 100644
index 0000000..f72650e
--- /dev/null
+++ b/pilight-usb-nano.ino
@@ -0,0 +1,396 @@
+/*
+ Copyright (C) 2015 CurlyMo
+ This file is part of pilight. GNU General Public License v3.0.
+
+ You should have received a copy of the GNU General Public License
+ along with pilight. If not, see
+
+ Copyright (C) 2021 Jorge Rivera. GNU General Public License v3.0.
+
+ New v2 firmware features:
+ - Can run on any AVR Arduino compatible board, like Arduino UNO, Nano, Mega, Leonardo, etc.
+ - Can run on other platforms like Arduino SAMD boards (DUE, M0, etc.), ESP8266, ESP32, Teensy, even Raspberry Pico.
+ - Fully Arduino IDE compiler environment compatible. Arduino PRO IDE and Arduino CLI also supported.
+ - Configurable RF receiver output (RX_PIN); must be interrupt attachable, depends board (D2 as default).
+ - Configurable RF transmitter input (TX_PIN); can be any digital pin, depends board (D5 as default).
+ - Support to configure a digital output so that a led blinks at valid RF code reception.
+ - Support to configure send of every 'space' before 'pulse', which stripped in previous version firmware.
+ - Support to configure initial RX settings at boot, like as 's:20,200,4000,82000@'.
+ - Support to configure show settings at boot, like as: 'v:20,200,4000,82000,2,1,1600@'.
+ - Support to configure add line feed '\n' each line output.
+ - Support to configure a tx enable pin (PTT_PIN), useful for use transceivers.
+
+*/
+
+/* Configurable RX & TX pins */
+#define RX_PIN 2 // Pin for ASK/OOK pulse input from RF receiver module data output.
+#define TX_PIN 5 // Pin for ASK/OOK pulse output to RF transmitter module data input.
+#define PTT_PIN 4 // If a pin is defined, it will set to high state during transmissions.
+
+#define EVERY_SEC_LINE_FEED // If defined, print line feed '\n' every second, to emulate legacy firmware.
+//#define SEND_STRIPPED_SPACES // If defined, send every 'space' before 'pulse' in broadcast(), which stripped in legacy firmware.
+//#define LED_BLINK_RX LED_BUILTIN // If defined, sets the digital output to blink on valid RF code reception.
+//#define DEFAULT_RX_SETTINGS // If defined, sets valid RX settings at boot, like sets 's:20,200,4000,82000@'
+//#define BOOT_SHOW_SETTINGS // If defined, show settings at boot, like as: 'v:20,200,4000,82000,2,1,1600@'
+//#define ADD_LINE_FEED // If defined, add line feed '\n' each line output.
+
+#define BUFFER_SIZE 256 // Warning: 256 max because buffer indexes "nrpulses" and "q" are "uint8_t" type
+#define MAX_PULSE_TYPES 10 // From 0 to 9
+#define BAUD 57600
+
+/* Show numbers devided by 10 */
+#define MIN_PULSELENGTH 6 // v2 change from 8 to 6 and show devided by 10
+#define MAX_PULSELENGTH 8200 // v2 change from 1600 to 8200 (for quigg_gt7000 protocol footer pulse around 81000 usecs)
+
+#define VERSION 2 // Version 2 (Arduino compatible)
+
+#ifdef DEFAULT_RX_SETTINGS
+uint8_t minrawlen = 20; // Minimum number of pulses
+uint8_t maxrawlen = 200; // Maximum number of pulses
+uint16_t mingaplen = 400; // Minimum length of footer pulse and maximum length of previous pulses. Used and showing multiplied by 10
+#else
+uint8_t minrawlen = UINT8_MAX; // Maximum value for uint8_t from (stdint.h)
+uint8_t maxrawlen = 0;
+uint16_t mingaplen = 10000; // Used and showing multiplied by 10
+#endif
+
+uint16_t maxgaplen = MAX_PULSELENGTH; // v2 used and change from 5100 to MAX_PULSELENGTH, set and show multiplied by 10
+
+// Code formatting meant for sending
+// on c:102020202020202020220202020020202200202200202020202020220020202203;p:279,2511,1395,9486;r:5@
+// off c:102020202020202020220202020020202200202200202020202020202020202203;p:279,2511,1395,9486;r:5@
+
+// Code formatting outputted by receiver
+// on c:102020202020202020220202020020202200202200202020202020220020202203;p:279,2511,1395,9486@
+// off c:102020202020202020220202020020202200202200202020202020202020202203;p:279,2511,1395,9486@
+
+char data[BUFFER_SIZE] = {0}; // Fill to 0 // Buffer for serial uart inputs and outputs
+volatile uint16_t codes[BUFFER_SIZE] = {0}; // Fill to 0 // Buffer to store pulses length
+ uint32_t plstypes[MAX_PULSE_TYPES] = {0}; // Fill to 0 // Buffer to store pulse types (RX and TX)
+volatile uint32_t new_counter = 0; // Global time counter to store initial pulse micros(). Replaces global ten_us_counter.
+
+volatile uint8_t q = 0; // Index of data buffer
+volatile uint8_t rawlen = 0; // Flag to ensure to call broadcast() after reveive two same lenght pulse train
+volatile uint8_t nrpulses = 0; // Index of pulse lenght buffer
+volatile uint8_t broadcast_flag = 0; // Flag to call broadcast with nrpulses value
+volatile uint8_t receive_flag = 0; // Flag to call receive() in loop()
+
+void ISR_RX(); // Generic ISR function declaration for RF RX pulse interrupt handler instead specific AVR ISR(vector, attributes)
+
+void setup() {
+
+ pinMode(TX_PIN, OUTPUT);
+
+#ifdef LED_BLINK_RX
+ pinMode(LED_BLINK_RX, OUTPUT);
+#endif
+
+#ifdef PTT_PIN
+ // If defined PTT PIN set output low
+ pinMode(PTT_PIN,OUTPUT);
+ digitalWrite(PTT_PIN,LOW);
+#endif
+
+ // Arduino built-in function to attach Interrupt Service Routines (depends board)
+ attachInterrupt(digitalPinToInterrupt(RX_PIN), ISR_RX, CHANGE);
+
+ // Arduino build-in function to set serial UART data baud rate (depends board)
+ Serial.begin(BAUD);
+
+#ifdef BOOT_SHOW_SETTINGS
+ // Show settings at boot, like as: 'v:20,200,4000,82000,2,1,1600@'
+ sprintf(data, "v:%u,%u,%lu,%lu,%d,%d,%d@", minrawlen, maxrawlen, uint32_t(mingaplen)*10, uint32_t(maxgaplen)*10, VERSION, MIN_PULSELENGTH/10, MAX_PULSELENGTH);
+#ifdef ADD_LINE_FEED
+ Serial.println(data);
+#else
+ Serial.print(data);
+#endif
+#endif
+
+}
+
+/* Everything is parsed on-the-fly to preserve memory */
+void receive() {
+ unsigned int scode = 0, spulse = 0, srepeat = 0, sstart = 0;
+ unsigned int i = 0, s = 0, z = 0, x = 0;
+
+ nrpulses = 0;
+
+ z = strlen(data);
+ for(i = 0; i < z; i++) {
+ if(data[i] == 's') {
+ sstart = i + 2;
+ break;
+ }
+ if(data[i] == 'c') {
+ scode = i + 2;
+ }
+ if(data[i] == 'p') {
+ spulse = i + 2;
+ }
+ if(data[i] == 'r') {
+ srepeat = i + 2;
+ }
+ if(data[i] == ';') {
+ data[i] = '\0';
+ }
+ }
+ /*
+ * Tune the firmware with pilight-daemon values
+ */
+ if(sstart > 0) {
+ z = strlen(&data[sstart]);
+ s = sstart;
+ x = 0;
+ for(i = sstart; i < sstart + z; i++) {
+ if(data[i] == ',') {
+ data[i] = '\0';
+ if(x == 0) {
+ minrawlen = uint8_t(atoi(&data[s]));
+ }
+ if(x == 1) {
+ maxrawlen = uint8_t(atoi(&data[s]));
+ }
+ if(x == 2) {
+ mingaplen = uint16_t(atol(&data[s])/10);
+ }
+ x++;
+ s = i+1;
+ }
+ }
+ if(x == 3) {
+ maxgaplen = uint16_t(atol(&data[s])/10);
+ }
+ /*
+ * Once we tuned our firmware send back our settings + fw version
+ */
+ sprintf(data, "v:%u,%u,%lu,%lu,%d,%d,%d@", minrawlen, maxrawlen, uint32_t(mingaplen)*10, uint32_t(maxgaplen)*10, VERSION, MIN_PULSELENGTH/10, MAX_PULSELENGTH);
+#ifdef ADD_LINE_FEED
+ Serial.println(data);
+#else
+ Serial.print(data);
+#endif
+ } else if(scode > 0 && spulse > 0 && srepeat > 0) {
+ z = strlen(&data[spulse]);
+ s = spulse;
+ nrpulses = 0;
+ for(i = spulse; i < spulse + z; i++) {
+ if(data[i] == ',') {
+ data[i] = '\0';
+ plstypes[nrpulses++] = atol(&data[s]);
+ s = i+1;
+ }
+ }
+ plstypes[nrpulses++] = atol(&data[s]);
+ s = strlen(&data[scode]);
+ x = (unsigned int)atoi(&data[srepeat]);
+
+ // Check for maxgaplen
+ for(z = scode; z < scode + s; z++) {
+ if (plstypes[data[z] - '0'] >= uint32_t(maxgaplen*10)){
+ // Clear pulse types array
+ for(i=0;i MIN_PULSELENGTH) {
+ if(ten_us_counter < MAX_PULSELENGTH) {
+ /* All codes are buffered */
+ codes[nrpulses++] = ten_us_counter;
+ if(nrpulses >= BUFFER_SIZE-1) {
+ nrpulses = 0;
+ }
+ /* Let's match footers */
+ if((ten_us_counter > mingaplen) and (ten_us_counter < maxgaplen)) {
+ /* Only match minimal length pulse streams */
+ if(nrpulses >= minrawlen && nrpulses <= maxrawlen) {
+ /*
+ * Sending pulses over serial requires
+ * a lot of cpu ticks. We therefor have
+ * to be sure that we send valid codes.
+ * Therefor, only streams we at least
+ * received twice communicated.
+ */
+ if(rawlen == nrpulses) {
+ broadcast_flag = nrpulses;
+ }
+ rawlen = nrpulses;
+ }
+ nrpulses = 0;
+ }
+ }
+ }
+}
+
+void loop(){
+
+ // Workaround for Leonardo, Micro, and others MCUs like ESP8266 and ESP32
+#ifndef HAVE_HWSERIAL0
+ if (Serial.available()) serialEvent();
+#endif
+
+ // if receive flag is set
+ if (receive_flag){
+ // Call to receive()
+ receive();
+ // Clear flag
+ receive_flag = 0;
+ }
+
+ // if broadcast flag is set
+ if (broadcast_flag > 0){
+
+#ifdef LED_BLINK_RX
+ digitalWrite(LED_BLINK_RX, HIGH); // Led blink on RF RX
+#endif
+
+ // Call to broadcast()
+ broadcast(broadcast_flag);
+ // Clear flag
+ broadcast_flag = 0;
+
+#ifdef LED_BLINK_RX
+ digitalWrite(LED_BLINK_RX, LOW); // Led blink on RF RX
+#endif
+ }
+
+#ifdef EVERY_SEC_LINE_FEED
+ static unsigned long line_feed_counter = 0;
+ if (millis() > line_feed_counter){
+ line_feed_counter = millis()+1000;
+ Serial.println();
+ }
+#endif
+}
diff --git a/pilight_usb_nano.c b/pilight_usb_nano.c
deleted file mode 100644
index 30481b6..0000000
--- a/pilight_usb_nano.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- Copyright (C) 2015 CurlyMo
-
- This file is part of pilight.
-
- pilight is free software: you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation, either version 3 of the License, or (at your option) any later
- version.
-
- pilight is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with pilight. If not, see
-*/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define BUFFER_SIZE 256
-#define MAX_PULSE_TYPES 10
-#define BAUD 57600
-/* Number devided by 10 */
-#define MIN_PULSELENGTH 8 //tested to work down to 30us pulsewidth (=2)
-#define MAX_PULSELENGTH 1600
-#define VERSION 1
-
-volatile uint32_t minrawlen = 1000;
-volatile uint32_t maxrawlen = 0;
-volatile uint32_t mingaplen = 10000;
-volatile uint32_t maxgaplen = 5100;
-
-const uint16_t MIN_2X_BAUD = F_CPU / (4 * (2 * 0XFFF + 1)) + 1;
-
-#include
-
-// Code formatting meant for sending
-// on c:102020202020202020220202020020202200202200202020202020220020202203;p:279,2511,1395,9486;r:5@
-// off c:102020202020202020220202020020202200202200202020202020202020202203;p:279,2511,1395,9486;r:5@
-
-// Code formatting outputted by receiver
-// on c:102020202020202020220202020020202200202200202020202020220020202203;p:279,2511,1395,9486@
-// off c:102020202020202020220202020020202200202200202020202020202020202203;p:279,2511,1395,9486@
-
-char data[BUFFER_SIZE];
-volatile unsigned long ten_us_counter1 = 0;
-volatile uint16_t ten_us_counter = 0, codes[BUFFER_SIZE], plstypes[MAX_PULSE_TYPES];
-volatile uint8_t state = 0, codelen = 0, repeats = 0, pos = 0;
-volatile uint8_t valid_buffer = 0x00, r = 0, q = 0, rawlen = 0, nrpulses = 0;
-
-void initUART(void) {
- uint16_t x = 0;
-
- if((F_CPU != 16000000UL || BAUD != 57600) && BAUD > MIN_2X_BAUD) {
- UCSR0A = 1 << U2X0;
- x = (F_CPU / 4 / BAUD - 1) / 2;
- } else {
- UCSR0A = 0;
- x = (F_CPU / 8 / BAUD - 1) / 2;
- }
-
- UBRR0H = x >> 8;
- UBRR0L = x;
-
- UCSR0B |= _BV(RXEN0);
- UCSR0B |= _BV(RXCIE0);
- UCSR0B |= _BV(TXEN0);
-
- UCSR0C |= _BV(USBS0);
- UCSR0C |= _BV(UCSZ01) | _BV(UCSZ00);
-}
-
-/* From the Arduino library */
-void delayMicroseconds(unsigned int us) {
- if(--us == 0)
- return;
-
- us <<= 2;
- us -= 2;
-
- __asm__ __volatile__ (
- "1: sbiw %0,1" "\n\t" // 2 cycles
- "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
- );
-}
-
-uint8_t getByte(void) {
- /* Wait for data to be buffer */
- while(!(UCSR0A & (1 << RXC0)));
- return (uint8_t)UDR0;
-}
-
-void putByte(unsigned char data) {
- /* Wait for empty transmit buffer */
- while(!(UCSR0A & (1 << UDRE0)));
- UDR0 = (unsigned char) data;
-}
-
-/*! \brief Writes an ASCII string to the TX buffer */
-void writeString(char *line) {
- while(*line != '\0') {
- putByte(*line);
- ++line;
- }
-}
-
-char *readString(void) {
- static char rxstr[32];
- static char *temp;
- temp = rxstr;
-
- while((*temp = getByte()) != '\n') {
- ++temp;
- }
-
- return rxstr;
-}
-
-void setup() {
- uint8_t oldSREG = SREG;
-
- cli();
-
- /* We initialize our array to zero
- * here to spare resources while
- * running.
- */
- for(r=0;r 0) {
- z = strlen(&data[sstart]);
- s = sstart;
- x = 0;
- for(i = sstart; i < sstart + z; i++) {
- if(data[i] == ',') {
- data[i] = '\0';
- if(x == 0) {
- minrawlen = atol(&data[s]);
- }
- if(x == 1) {
- maxrawlen = atol(&data[s]);
- }
- if(x == 2) {
- mingaplen = atoi(&data[s])/10;
- }
- x++;
- s = i+1;
- }
- }
- if(x == 3) {
- maxgaplen = atol(&data[s])/10;
- }
- /*
- * Once we tuned our firmware send back our settings + fw version
- */
- sprintf(data, "v:%lu,%lu,%lu,%lu,%d,%d,%d@", minrawlen, maxrawlen, mingaplen*10, maxgaplen*10, VERSION, MIN_PULSELENGTH, MAX_PULSELENGTH);
- writeString(data);
- } else if(scode > 0 && spulse > 0 && srepeat > 0) {
- z = strlen(&data[spulse]);
- s = spulse;
- nrpulses = 0;
- for(i = spulse; i < spulse + z; i++) {
- if(data[i] == ',') {
- data[i] = '\0';
- plstypes[nrpulses++] = atoi(&data[s]);
- s = i+1;
- }
- }
- plstypes[nrpulses++] = atoi(&data[s]);
-
- codelen = strlen(&data[scode]);
- repeats = atoi(&data[srepeat]);
- cli();
- for(i=0;i 100000) {
- putByte('\n');
- ten_us_counter1 = 0;
- }
- sei();
-}
-
-void broadcast() {
- int i = 0, x = 0, match = 0, p = 0;
-
- putByte('c');
- putByte(':');
- for(i=0;i MIN_PULSELENGTH) {
- if(ten_us_counter < MAX_PULSELENGTH) {
- /* All codes are buffered */
- codes[nrpulses++] = ten_us_counter;
- if(nrpulses > BUFFER_SIZE) {
- nrpulses = 0;
- }
- /* Let's match footers */
- if(ten_us_counter > mingaplen) {
- /* Only match minimal length pulse streams */
- if(nrpulses >= minrawlen && nrpulses <= maxrawlen) {
- /*
- * Sending pulses over serial requires
- * a lot of cpu ticks. We therefor have
- * to be sure that we send valid codes.
- * Therefor, only streams we at least
- * received twice communicated.
- */
- if(rawlen == nrpulses) {
- broadcast();
- }
- rawlen = nrpulses;
- }
- nrpulses = 0;
- }
- }
- }
- ten_us_counter = 0;
- TCNT1 = 0;
- sei();
-}
-
-int main(void) {
- setup();
- while(1);
-}