From 065835767dd877d8b0e2ccdbe5b915c5e22bd62a Mon Sep 17 00:00:00 2001 From: dakkar Date: Sat, 9 Jun 2018 12:55:53 +0100 Subject: working CHIP sender --- trasmitter/.gitignore | 4 +- trasmitter/Makefile | 21 ++---- trasmitter/README.rst.txt | 11 +--- trasmitter/arduino/Makefile | 19 ++++++ trasmitter/arduino/sender.ino | 93 +++++++++++++++++++++++++++ trasmitter/clock.c | 146 ------------------------------------------ trasmitter/sender-chip.c | 146 ++++++++++++++++++++++++++++++++++++++++++ trasmitter/sender.ino | 93 --------------------------- 8 files changed, 269 insertions(+), 264 deletions(-) create mode 100644 trasmitter/arduino/Makefile create mode 100644 trasmitter/arduino/sender.ino delete mode 100644 trasmitter/clock.c create mode 100644 trasmitter/sender-chip.c delete mode 100644 trasmitter/sender.ino (limited to 'trasmitter') diff --git a/trasmitter/.gitignore b/trasmitter/.gitignore index cebbcdf..bd6f3a9 100644 --- a/trasmitter/.gitignore +++ b/trasmitter/.gitignore @@ -1 +1,3 @@ -/build-*/ +/arduino/build-*/ +/sender-chip + diff --git a/trasmitter/Makefile b/trasmitter/Makefile index 9815090..b31025b 100644 --- a/trasmitter/Makefile +++ b/trasmitter/Makefile @@ -1,19 +1,10 @@ -ARDMK_DIR = /home/dakkar/src/Arduino-Makefile -ARDUINO_DIR = /usr/share/arduino -MONITOR_PORT = /dev/ttyACM* -CURRENT_DIR = $(basename $(CURDIR)) -AVR_TOOLS_DIR = /usr -AVRDUDE_CONF = /etc/avrdude.conf +CFLAGS = -Wall -PROJECT_DIR = $(CURDIR) -BOARD_TAG = uno -MONITOR_BAUDRATE = 115200 +all: sender-chip setcap -CFLAGS_STD = -std=gnu11 -CXXFLAGS_STD = -std=gnu++11 -CXXFLAGS += -pedantic -Wall -Wextra +sender-chip: sender-chip.c -include $(ARDMK_DIR)/Arduino.mk +setcap: sender-chip + sudo setcap CAP_SYS_NICE=eip $< -check-syntax: - $(CXX) -c -include Arduino.h -x c++ $(CXXFLAGS) $(CPPFLAGS) -fsyntax-only $(CHK_SOURCES) +.PHONY: setcap diff --git a/trasmitter/README.rst.txt b/trasmitter/README.rst.txt index d2fd957..78200a4 100644 --- a/trasmitter/README.rst.txt +++ b/trasmitter/README.rst.txt @@ -38,12 +38,5 @@ sysfs interface`_, seem to be fast enough for our purposes. See the ``sender-chip.pl`` test program. -The timing via the sysfs interface is awful. - -It looks like we can drive the pins (not the XIO ones) via -memory-mapped registers: the sunxi-tools ``pio.c`` has most of the -code needed. - -We could write a C program to just send the signal train. Look at -``clock.c`` for a way to handle fast / real-time scheduling and -delays. +If we keep the ``*/value`` file open, we get good enough timing. The +``sender-chip.c`` program works. diff --git a/trasmitter/arduino/Makefile b/trasmitter/arduino/Makefile new file mode 100644 index 0000000..9815090 --- /dev/null +++ b/trasmitter/arduino/Makefile @@ -0,0 +1,19 @@ +ARDMK_DIR = /home/dakkar/src/Arduino-Makefile +ARDUINO_DIR = /usr/share/arduino +MONITOR_PORT = /dev/ttyACM* +CURRENT_DIR = $(basename $(CURDIR)) +AVR_TOOLS_DIR = /usr +AVRDUDE_CONF = /etc/avrdude.conf + +PROJECT_DIR = $(CURDIR) +BOARD_TAG = uno +MONITOR_BAUDRATE = 115200 + +CFLAGS_STD = -std=gnu11 +CXXFLAGS_STD = -std=gnu++11 +CXXFLAGS += -pedantic -Wall -Wextra + +include $(ARDMK_DIR)/Arduino.mk + +check-syntax: + $(CXX) -c -include Arduino.h -x c++ $(CXXFLAGS) $(CPPFLAGS) -fsyntax-only $(CHK_SOURCES) diff --git a/trasmitter/arduino/sender.ino b/trasmitter/arduino/sender.ino new file mode 100644 index 0000000..9373875 --- /dev/null +++ b/trasmitter/arduino/sender.ino @@ -0,0 +1,93 @@ +const uint16_t pulseScale = 520; // usec per sample unit + +// alternate HIGH and LOW, first one of each array is HIGH +const uint8_t prologue[] = { + 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, + 2,3, 1,1, 2,2, 1,1, 1,1, 2,1, + 1,1, 1,1, 1,2, 1,1, 1,1, 1,1, + 1,1, 1,1, +}; +const size_t prologueSize = sizeof(prologue) / sizeof(uint8_t); + +const uint8_t epilogue[] = { + 1,2, 2,2, 1,3, // the last value doesn't much matter +}; +const size_t epilogueSize = sizeof(epilogue) / sizeof(uint8_t); + +const uint8_t onSignal[] = { + 2,2, 1,1, 1,1, 1,1, 1,1, 2,1, 1,1, +}; +const size_t onSize = sizeof(onSignal) / sizeof(uint8_t); + +const uint8_t offSignal[] = { + 1,1, 1,1, 1,1, 1,1, 1,1, 2,2, 2,1, +}; +const size_t offSize = sizeof(offSignal) / sizeof(uint8_t); + +const int nTxPin = 7; // Arduino digital pin you're using for radio data. + +void transmitArray(const uint8_t pulses[], size_t pulseCount) { + for(size_t idx = 0; idx < pulseCount; idx+=2) { + digitalWrite(nTxPin, HIGH); + delayMicroseconds(pulseScale*pulses[idx]); + + digitalWrite(nTxPin, LOW); + delayMicroseconds(pulseScale*pulses[idx+1]); + } +} + +void transmitSignal(const uint8_t signal[], size_t signalSize) { + transmitArray(prologue,prologueSize); + transmitArray(signal,signalSize); + transmitArray(epilogue,epilogueSize); +} + +void sendTrain(const uint8_t signal[], size_t signalSize) { + transmitSignal(signal,signalSize); + delay(1000); + transmitSignal(signal,signalSize); + delay(2000); + transmitSignal(signal,signalSize); +} + + +/** + * The setup() function is called when a sketch starts. Used to initialize + * variables, pin modes, start using libraries, etc. The setup function will + * only run once, after each powerup or reset of the Arduino board. + */ +void setup() +{ + pinMode(nTxPin, OUTPUT); + digitalWrite(nTxPin, LOW); + + Serial.begin(9600); + Serial.println("Press 0 to turn off heating"); + Serial.println("Press 1 to turn on heating"); + +} + + +/** + * The loop() function loops consecutively, allowing the program to change and + * respond. Used to actively control the Arduino board. + */ +void loop() +{ + if (Serial.available() > 0) + { + int nIncomming = Serial.read(); + if (nIncomming == 49) { // char code for 1 + Serial.println("ON"); + sendTrain(onSignal,onSize); + } + + if (nIncomming == 48) { // char code for 0 + Serial.println("OFF"); + sendTrain(offSignal,offSize); + } + + Serial.println("Press 0 to turn off heating"); + Serial.println("Press 1 to turn on heating"); + } +} \ No newline at end of file diff --git a/trasmitter/clock.c b/trasmitter/clock.c deleted file mode 100644 index 7ada0cf..0000000 --- a/trasmitter/clock.c +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define PIN "132" - -void init_pin() { - int fd = open("/sys/class/gpio/export",O_WRONLY); - char buf[16]; - int len = sprintf(buf,"%s\n",PIN); - write(fd,buf,len); - close(fd); - fd = open("/sys/class/gpio/gpio" PIN "/direction",O_WRONLY); - write(fd,"out\n",4); - close(fd); -} - -void deinit_pin() { - int fd = open("/sys/class/gpio/unexport",O_WRONLY); - char buf[16]; - int len = sprintf(buf,"%s\n",PIN); - write(fd,buf,len); - close(fd); -} - -int pin_fd; -void write_pin(uint8_t value) { - if (!pin_fd) { - pin_fd = open("/sys/class/gpio/gpio" PIN "/value",O_WRONLY); - } - char buf[16]; - int len = sprintf(buf,"%d\n",value); - write(pin_fd,buf,len); -} - -void init_sched() { - struct sched_param sp; - sp.sched_priority=99; - - // to make this work, sudo setcap CAP_SYS_NICE=eip clock - sched_setscheduler(0,SCHED_RR,&sp); -} - -const int width=520000; -struct timespec next_step; -void send_array(const uint8_t values[],size_t len) { - if (next_step.tv_sec == 0) { - clock_gettime(CLOCK_REALTIME,&next_step); - } - uint8_t pin_value = 1; - for (int i=0; i 1000000000UL) { - next_step.tv_nsec -= 1000000000UL; - ++next_step.tv_sec; - } - - int rc = clock_nanosleep(CLOCK_REALTIME, - TIMER_ABSTIME, - &next_step, - NULL); - if (rc) { - printf("problems: %d\n",rc); - } - } -} -void my_sleep(uint8_t seconds) { - next_step.tv_sec += seconds; - - int rc = clock_nanosleep(CLOCK_REALTIME, - TIMER_ABSTIME, - &next_step, - NULL); - if (rc) { - printf("problems: %d\n",rc); - } -} - -// alternate HIGH and LOW, first one of each array is HIGH -const uint8_t prologue[] = { - 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, - 2,3, 1,1, 2,2, 1,1, 1,1, 2,1, - 1,1, 1,1, 1,2, 1,1, 1,1, 1,1, - 1,1, 1,1, -}; -const size_t prologueSize = sizeof(prologue) / sizeof(uint8_t); - -const uint8_t epilogue[] = { - 1,2, 2,2, 1,3, // the last value doesn't much matter -}; -const size_t epilogueSize = sizeof(epilogue) / sizeof(uint8_t); - -const uint8_t onSignal[] = { - 2,2, 1,1, 1,1, 1,1, 1,1, 2,1, 1,1, -}; -const size_t onSize = sizeof(onSignal) / sizeof(uint8_t); - -const uint8_t offSignal[] = { - 1,1, 1,1, 1,1, 1,1, 1,1, 2,2, 2,1, -}; -const size_t offSize = sizeof(offSignal) / sizeof(uint8_t); - -void transmitSignal(const uint8_t signal[], size_t signalSize) { - send_array(prologue,prologueSize); - send_array(signal,signalSize); - send_array(epilogue,epilogueSize); -} - -void sendTrain(const uint8_t signal[], size_t signalSize) { - transmitSignal(offSignal,offSize); - my_sleep(1); - transmitSignal(signal,signalSize); - my_sleep(2); - transmitSignal(offSignal,offSize); -} - -int main(int argc,char **argv) { - if (argc != 2) { - fprintf(stderr,"thing 0/1\n"); - return 1; - } - - init_sched(); - init_pin(); - write_pin(0); - - if (argv[1][0] == '1') { - sendTrain(onSignal,onSize); - } - else { - sendTrain(offSignal,offSize); - } - - deinit_pin(); - - return 0; -} diff --git a/trasmitter/sender-chip.c b/trasmitter/sender-chip.c new file mode 100644 index 0000000..7ada0cf --- /dev/null +++ b/trasmitter/sender-chip.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIN "132" + +void init_pin() { + int fd = open("/sys/class/gpio/export",O_WRONLY); + char buf[16]; + int len = sprintf(buf,"%s\n",PIN); + write(fd,buf,len); + close(fd); + fd = open("/sys/class/gpio/gpio" PIN "/direction",O_WRONLY); + write(fd,"out\n",4); + close(fd); +} + +void deinit_pin() { + int fd = open("/sys/class/gpio/unexport",O_WRONLY); + char buf[16]; + int len = sprintf(buf,"%s\n",PIN); + write(fd,buf,len); + close(fd); +} + +int pin_fd; +void write_pin(uint8_t value) { + if (!pin_fd) { + pin_fd = open("/sys/class/gpio/gpio" PIN "/value",O_WRONLY); + } + char buf[16]; + int len = sprintf(buf,"%d\n",value); + write(pin_fd,buf,len); +} + +void init_sched() { + struct sched_param sp; + sp.sched_priority=99; + + // to make this work, sudo setcap CAP_SYS_NICE=eip clock + sched_setscheduler(0,SCHED_RR,&sp); +} + +const int width=520000; +struct timespec next_step; +void send_array(const uint8_t values[],size_t len) { + if (next_step.tv_sec == 0) { + clock_gettime(CLOCK_REALTIME,&next_step); + } + uint8_t pin_value = 1; + for (int i=0; i 1000000000UL) { + next_step.tv_nsec -= 1000000000UL; + ++next_step.tv_sec; + } + + int rc = clock_nanosleep(CLOCK_REALTIME, + TIMER_ABSTIME, + &next_step, + NULL); + if (rc) { + printf("problems: %d\n",rc); + } + } +} +void my_sleep(uint8_t seconds) { + next_step.tv_sec += seconds; + + int rc = clock_nanosleep(CLOCK_REALTIME, + TIMER_ABSTIME, + &next_step, + NULL); + if (rc) { + printf("problems: %d\n",rc); + } +} + +// alternate HIGH and LOW, first one of each array is HIGH +const uint8_t prologue[] = { + 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, + 2,3, 1,1, 2,2, 1,1, 1,1, 2,1, + 1,1, 1,1, 1,2, 1,1, 1,1, 1,1, + 1,1, 1,1, +}; +const size_t prologueSize = sizeof(prologue) / sizeof(uint8_t); + +const uint8_t epilogue[] = { + 1,2, 2,2, 1,3, // the last value doesn't much matter +}; +const size_t epilogueSize = sizeof(epilogue) / sizeof(uint8_t); + +const uint8_t onSignal[] = { + 2,2, 1,1, 1,1, 1,1, 1,1, 2,1, 1,1, +}; +const size_t onSize = sizeof(onSignal) / sizeof(uint8_t); + +const uint8_t offSignal[] = { + 1,1, 1,1, 1,1, 1,1, 1,1, 2,2, 2,1, +}; +const size_t offSize = sizeof(offSignal) / sizeof(uint8_t); + +void transmitSignal(const uint8_t signal[], size_t signalSize) { + send_array(prologue,prologueSize); + send_array(signal,signalSize); + send_array(epilogue,epilogueSize); +} + +void sendTrain(const uint8_t signal[], size_t signalSize) { + transmitSignal(offSignal,offSize); + my_sleep(1); + transmitSignal(signal,signalSize); + my_sleep(2); + transmitSignal(offSignal,offSize); +} + +int main(int argc,char **argv) { + if (argc != 2) { + fprintf(stderr,"thing 0/1\n"); + return 1; + } + + init_sched(); + init_pin(); + write_pin(0); + + if (argv[1][0] == '1') { + sendTrain(onSignal,onSize); + } + else { + sendTrain(offSignal,offSize); + } + + deinit_pin(); + + return 0; +} diff --git a/trasmitter/sender.ino b/trasmitter/sender.ino deleted file mode 100644 index 9373875..0000000 --- a/trasmitter/sender.ino +++ /dev/null @@ -1,93 +0,0 @@ -const uint16_t pulseScale = 520; // usec per sample unit - -// alternate HIGH and LOW, first one of each array is HIGH -const uint8_t prologue[] = { - 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, - 2,3, 1,1, 2,2, 1,1, 1,1, 2,1, - 1,1, 1,1, 1,2, 1,1, 1,1, 1,1, - 1,1, 1,1, -}; -const size_t prologueSize = sizeof(prologue) / sizeof(uint8_t); - -const uint8_t epilogue[] = { - 1,2, 2,2, 1,3, // the last value doesn't much matter -}; -const size_t epilogueSize = sizeof(epilogue) / sizeof(uint8_t); - -const uint8_t onSignal[] = { - 2,2, 1,1, 1,1, 1,1, 1,1, 2,1, 1,1, -}; -const size_t onSize = sizeof(onSignal) / sizeof(uint8_t); - -const uint8_t offSignal[] = { - 1,1, 1,1, 1,1, 1,1, 1,1, 2,2, 2,1, -}; -const size_t offSize = sizeof(offSignal) / sizeof(uint8_t); - -const int nTxPin = 7; // Arduino digital pin you're using for radio data. - -void transmitArray(const uint8_t pulses[], size_t pulseCount) { - for(size_t idx = 0; idx < pulseCount; idx+=2) { - digitalWrite(nTxPin, HIGH); - delayMicroseconds(pulseScale*pulses[idx]); - - digitalWrite(nTxPin, LOW); - delayMicroseconds(pulseScale*pulses[idx+1]); - } -} - -void transmitSignal(const uint8_t signal[], size_t signalSize) { - transmitArray(prologue,prologueSize); - transmitArray(signal,signalSize); - transmitArray(epilogue,epilogueSize); -} - -void sendTrain(const uint8_t signal[], size_t signalSize) { - transmitSignal(signal,signalSize); - delay(1000); - transmitSignal(signal,signalSize); - delay(2000); - transmitSignal(signal,signalSize); -} - - -/** - * The setup() function is called when a sketch starts. Used to initialize - * variables, pin modes, start using libraries, etc. The setup function will - * only run once, after each powerup or reset of the Arduino board. - */ -void setup() -{ - pinMode(nTxPin, OUTPUT); - digitalWrite(nTxPin, LOW); - - Serial.begin(9600); - Serial.println("Press 0 to turn off heating"); - Serial.println("Press 1 to turn on heating"); - -} - - -/** - * The loop() function loops consecutively, allowing the program to change and - * respond. Used to actively control the Arduino board. - */ -void loop() -{ - if (Serial.available() > 0) - { - int nIncomming = Serial.read(); - if (nIncomming == 49) { // char code for 1 - Serial.println("ON"); - sendTrain(onSignal,onSize); - } - - if (nIncomming == 48) { // char code for 0 - Serial.println("OFF"); - sendTrain(offSignal,offSize); - } - - Serial.println("Press 0 to turn off heating"); - Serial.println("Press 1 to turn on heating"); - } -} \ No newline at end of file -- cgit v1.2.3