From 95263827d96f1a3c7aa745359991c261d8ec796c Mon Sep 17 00:00:00 2001 From: xkonni Date: Sun, 25 Nov 2012 17:52:45 +0100 Subject: [PATCH 1/3] dev: add arduino sketch ReceiveDemo --- ReceiveDemo/Makefile | 278 ++++++++++++++++++++++++++++++++++++ ReceiveDemo/ReceiveDemo.pde | 99 +++++++++++++ 2 files changed, 377 insertions(+) create mode 100644 ReceiveDemo/Makefile create mode 100644 ReceiveDemo/ReceiveDemo.pde diff --git a/ReceiveDemo/Makefile b/ReceiveDemo/Makefile new file mode 100644 index 0000000..0c25e35 --- /dev/null +++ b/ReceiveDemo/Makefile @@ -0,0 +1,278 @@ + +# +# Arduino 0023 Makefile +# Uno with DOGS102 Shield +# +# written by olikraus@gmail.com +# modified by xkonni +# +# Features: +# - boards.txt is used to derive parameters +# - All intermediate files are put into a separate directory (TMPDIRNAME) +# - Simple use: Copy Makefile into the same directory of the .pde file +# +# Limitations: +# - requires UNIX environment +# - TMPDIRNAME must be subdirectory of the current directory. +# +# Targets +# all build everything +# upload build and upload to arduino +# clean remove all temporary files (includes final hex file) +# +# History +# 001 28 Apr 2010 first release +# 002 05 Oct 2010 added 'uno' +# + +#=== user configuration === +# All ...PATH variables must have a '/' at the end + +# Board (and prozessor) information: see $(ARDUINO_PATH)hardware/arduino/boards.txt +# Some examples: +# BOARD DESCRIPTION +# uno Arduino Uno +# atmega328 Arduino Duemilanove or Nano w/ ATmega328 +# diecimila Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 +# mega Arduino Mega +# mini Arduino Mini +# lilypad328 LilyPad Arduino w/ ATmega328 +BOARD:=atmega328 + +# additional (comma separated) defines +# -DDOGM128_HW board is connected to DOGM128 display +# -DDOGM132_HW board is connected to DOGM132 display +# -DDOGS102_HW board is connected to DOGS102 display +# -DDOG_REVERSE 180 degree rotation +# -DDOG_SPI_SW_ARDUINO force SW shiftOut +DEFS=-DDOGS102_HW -DDOG_DOUBLE_MEMORY -DDOG_SPI_SW_ARDUINO + +# The location where the avr tools (e.g. avr-gcc) are located. Requires a '/' at the end. +# Can be empty if all tools are accessable through the search path +AVR_TOOLS_PATH:=/usr/bin/ + +# Install path of the arduino software. Requires a '/' at the end. +ARDUINO_PATH:=/extra/arduino/homecontrol4me/arduino-0023/ + +# Install path for avrdude. Requires a '/' at the end. Can be empty if avrdude is in the search path. +AVRDUDE_PATH:= + +# The unix device where we can reach the arduino board +# Uno: /dev/ttyACM0 +# Duemilanove: /dev/ttyUSB0 +AVRDUDE_PORT:=/dev/ttyUSB0 + +# List of all libaries which should be included. +EXTRA_DIRS=$(ARDUINO_PATH)libraries/SPI/ +EXTRA_DIRS+=$(ARDUINO_PATH)libraries/RCSwitch/ +#EXTRA_DIRS+=/home/kraus/src/arduino/dogm128/hg/libraries/Dogm/ + +#=== fetch parameter from boards.txt processor parameter === +# the basic idea is to get most of the information from boards.txt + +BOARDS_TXT:=$(ARDUINO_PATH)hardware/arduino/boards.txt + +# get the MCU value from the $(BOARD).build.mcu variable. For the atmega328 board this is atmega328p +MCU:=$(shell sed -n -e "s/$(BOARD).build.mcu=\(.*\)/\1/p" $(BOARDS_TXT)) +# get the F_CPU value from the $(BOARD).build.f_cpu variable. For the atmega328 board this is 16000000 +F_CPU:=$(shell sed -n -e "s/$(BOARD).build.f_cpu=\(.*\)/\1/p" $(BOARDS_TXT)) + +# avrdude +# get the AVRDUDE_UPLOAD_RATE value from the $(BOARD).upload.speed variable. For the atmega328 board this is 57600 +AVRDUDE_UPLOAD_RATE:=$(shell sed -n -e "s/$(BOARD).upload.speed=\(.*\)/\1/p" $(BOARDS_TXT)) +# get the AVRDUDE_PROGRAMMER value from the $(BOARD).upload.protocol variable. For the atmega328 board this is stk500 +# AVRDUDE_PROGRAMMER:=$(shell sed -n -e "s/$(BOARD).upload.protocol=\(.*\)/\1/p" $(BOARDS_TXT)) +# use stk500v1, because stk500 will default to stk500v2 +AVRDUDE_PROGRAMMER:=stk500v1 + +#=== identify user files === +PDESRC:=$(shell ls *.pde) +TARGETNAME=$(basename $(PDESRC)) + +CDIRS:=$(EXTRA_DIRS) $(addsuffix utility/,$(EXTRA_DIRS)) +CDIRS:=*.c utility/*.c $(addsuffix *.c,$(CDIRS)) $(ARDUINO_PATH)hardware/arduino/cores/arduino/*.c +CSRC:=$(shell ls $(CDIRS) 2>/dev/null) + +CCSRC:=$(shell ls *.cc 2>/dev/null) + +CPPDIRS:=$(EXTRA_DIRS) $(addsuffix utility/,$(EXTRA_DIRS)) +CPPDIRS:=*.cpp utility/*.cpp $(addsuffix *.cpp,$(CPPDIRS)) $(ARDUINO_PATH)hardware/arduino/cores/arduino/*.cpp +CPPSRC:=$(shell ls $(CPPDIRS) 2>/dev/null) + +#=== build internal variables === + +# the name of the subdirectory where everything is stored +TMPDIRNAME:=tmp +TMPDIRPATH:=$(TMPDIRNAME)/ + +AVRTOOLSPATH:=$(AVR_TOOLS_PATH) + +OBJCOPY:=$(AVRTOOLSPATH)avr-objcopy +OBJDUMP:=$(AVRTOOLSPATH)avr-objdump +SIZE:=$(AVRTOOLSPATH)avr-size + +CPPSRC:=$(addprefix $(TMPDIRPATH),$(PDESRC:.pde=.cpp)) $(CPPSRC) + +COBJ:=$(CSRC:.c=.o) +CCOBJ:=$(CCSRC:.cc=.o) +CPPOBJ:=$(CPPSRC:.cpp=.o) + +OBJFILES:=$(COBJ) $(CCOBJ) $(CPPOBJ) +DIRS:= $(dir $(OBJFILES)) + +DEPFILES:=$(OBJFILES:.o=.d) +# assembler files from avr-gcc -S +ASSFILES:=$(OBJFILES:.o=.s) +# disassembled object files with avr-objdump -S +DISFILES:=$(OBJFILES:.o=.dis) + + +LIBNAME:=$(TMPDIRPATH)$(TARGETNAME).a +ELFNAME:=$(TMPDIRPATH)$(TARGETNAME).elf +HEXNAME:=$(TMPDIRPATH)$(TARGETNAME).hex + +AVRDUDE_FLAGS = -V -F +AVRDUDE_FLAGS += -C $(ARDUINO_PATH)/hardware/tools/avrdude.conf +AVRDUDE_FLAGS += -p $(MCU) +AVRDUDE_FLAGS += -P $(AVRDUDE_PORT) +AVRDUDE_FLAGS += -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += -b $(AVRDUDE_UPLOAD_RATE) +AVRDUDE_FLAGS += -U flash:w:$(HEXNAME) + +AVRDUDE = avrdude + +#=== predefined variable override === +# use "make -p -f/dev/null" to see the default rules and definitions + +# Build C and C++ flags. Include path information must be placed here +COMMON_FLAGS = -DF_CPU=$(F_CPU) -mmcu=$(MCU) $(DEFS) +# COMMON_FLAGS += -gdwarf-2 +COMMON_FLAGS += -Os +COMMON_FLAGS += -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +COMMON_FLAGS += -I. +COMMON_FLAGS += -I$(ARDUINO_PATH)hardware/arduino/cores/arduino +COMMON_FLAGS += $(addprefix -I,$(EXTRA_DIRS)) +COMMON_FLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections +COMMON_FLAGS += -Wl,--relax +COMMON_FLAGS += -mcall-prologues +## VERSION ARDUINO +COMMON_FLAGS += -DARDUINO=23 + +CFLAGS = $(COMMON_FLAGS) -std=gnu99 -Wstrict-prototypes +CXXFLAGS = $(COMMON_FLAGS) + +# Replace standard build tools by avr tools +CC = $(AVRTOOLSPATH)avr-gcc +CXX = $(AVRTOOLSPATH)avr-g++ +AR = @$(AVRTOOLSPATH)avr-ar + + +# "rm" must be able to delete a directory tree +RM = rm -rf + +#=== rules === + +# add rules for the C/C++ files where the .o file is placed in the TMPDIRPATH +# reuse existing variables as far as possible + +$(TMPDIRPATH)%.o: %.c + @echo compile $< + @$(COMPILE.c) $(OUTPUT_OPTION) $< + +$(TMPDIRPATH)%.o: %.cc + @echo compile $< + @$(COMPILE.cc) $(OUTPUT_OPTION) $< + +$(TMPDIRPATH)%.o: %.cpp + @echo compile $< + @$(COMPILE.cpp) $(OUTPUT_OPTION) $< + +$(TMPDIRPATH)%.s: %.c + @$(COMPILE.c) $(OUTPUT_OPTION) -S $< + +$(TMPDIRPATH)%.s: %.cc + @$(COMPILE.cc) $(OUTPUT_OPTION) -S $< + +$(TMPDIRPATH)%.s: %.cpp + @$(COMPILE.cpp) $(OUTPUT_OPTION) -S $< + +$(TMPDIRPATH)%.dis: $(TMPDIRPATH)%.o + @$(OBJDUMP) -S $< > $@ + +.SUFFIXES: .elf .hex .pde + +.elf.hex: + @$(OBJCOPY) -O ihex -R .eeprom $< $@ + +$(TMPDIRPATH)%.cpp: %.pde + @cat $(ARDUINO_PATH)hardware/arduino/cores/arduino/main.cpp > $@ + @cat $< >> $@ + @echo >> $@ + @echo 'extern "C" void __cxa_pure_virtual() { while (1); }' >> $@ + + +.PHONY: all +all: tmpdir $(HEXNAME) assemblersource showsize + ls -al $(HEXNAME) $(ELFNAME) + +$(ELFNAME): $(LIBNAME)($(addprefix $(TMPDIRPATH),$(OBJFILES))) + $(LINK.o) $(COMMON_FLAGS) $(LIBNAME) $(LOADLIBES) $(LDLIBS) -o $@ + +$(LIBNAME)(): $(addprefix $(TMPDIRPATH),$(OBJFILES)) + +#=== create temp directory === +# not really required, because it will be also created during the dependency handling +.PHONY: tmpdir +tmpdir: + @test -d $(TMPDIRPATH) || mkdir $(TMPDIRPATH) + +#=== create assembler files for each C/C++ file === +.PHONY: assemblersource +assemblersource: $(addprefix $(TMPDIRPATH),$(ASSFILES)) $(addprefix $(TMPDIRPATH),$(DISFILES)) + + +#=== show the section sizes of the ELF file === +.PHONY: showsize +showsize: $(ELFNAME) + $(SIZE) $< + +#=== clean up target === +# this is simple: the TMPDIRPATH is removed +.PHONY: clean +clean: + $(RM) $(TMPDIRPATH) + +# Program the device. +# step 1: reset the arduino board with the stty command +# step 2: user avrdude to upload the software +.PHONY: upload +upload: $(HEXNAME) + stty -F $(AVRDUDE_PORT) hupcl + $(AVRDUDE) $(AVRDUDE_FLAGS) + + +# === dependency handling === +# From the gnu make manual (section 4.14, Generating Prerequisites Automatically) +# Additionally (because this will be the first executed rule) TMPDIRPATH is created here. +# Instead of "sed" the "echo" command is used +# cd $(TMPDIRPATH); mkdir -p $(DIRS) 2> /dev/null; cd .. +DEPACTION=test -d $(TMPDIRPATH) || mkdir $(TMPDIRPATH);\ +mkdir -p $(addprefix $(TMPDIRPATH),$(DIRS));\ +set -e; echo -n $@ $(dir $@) > $@; $(CC) -MM $(COMMON_FLAGS) $< >> $@ + + +$(TMPDIRPATH)%.d: %.c + @$(DEPACTION) + +$(TMPDIRPATH)%.d: %.cc + @$(DEPACTION) + + +$(TMPDIRPATH)%.d: %.cpp + @$(DEPACTION) + +# Include dependency files. If a .d file is missing, a warning is created and the .d file is created +# This warning is not a problem (gnu make manual, section 3.3 Including Other Makefiles) +-include $(addprefix $(TMPDIRPATH),$(DEPFILES)) + + diff --git a/ReceiveDemo/ReceiveDemo.pde b/ReceiveDemo/ReceiveDemo.pde new file mode 100644 index 0000000..374650f --- /dev/null +++ b/ReceiveDemo/ReceiveDemo.pde @@ -0,0 +1,99 @@ +/* + Example for receiving + + http://code.google.com/p/rc-switch/ + + If you want to visualize a telegram copy the raw data and + paste it into http://test.sui.li/oszi/ +*/ + +#include + +RCSwitch mySwitch = RCSwitch(); +void output(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int* raw); +static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength); +static char* bin2tristate(char* bin); + +void setup() { + + Serial.begin(9600); + mySwitch.enableReceive(0, output); + +} + +void loop() { + +} + +void output(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int* raw) { + + if (decimal == 0) { + Serial.print("Unknown encoding."); + } else { + char* b = dec2binWzerofill(decimal, length); + Serial.print("Decimal: "); + Serial.print(decimal); + Serial.print(" ("); + Serial.print( length ); + Serial.print("Bit) Binary: "); + Serial.print( b ); + Serial.print(" Tri-State: "); + Serial.print( bin2tristate( b) ); + Serial.print(" PulseLength: "); + Serial.print(delay); + Serial.println(" microseconds"); + } + + Serial.print("Raw data: "); + for (int i=0; i<= length*2; i++) { + Serial.print(raw[i]); + Serial.print(","); + } + Serial.println(); + Serial.println(); +} + + +static char* bin2tristate(char* bin) { + char returnValue[50]; + int pos = 0; + int pos2 = 0; + while (bin[pos]!='\0' && bin[pos+1]!='\0') { + if (bin[pos]=='0' && bin[pos+1]=='0') { + returnValue[pos2] = '0'; + } else if (bin[pos]=='1' && bin[pos+1]=='1') { + returnValue[pos2] = '1'; + } else if (bin[pos]=='0' && bin[pos+1]=='1') { + returnValue[pos2] = 'F'; + } else { + return "not applicable"; + } + pos = pos+2; + pos2++; + } + returnValue[pos2] = '\0'; + return returnValue; +} + + + +static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength){ + static char bin[64]; + unsigned int i=0; + + while (Dec > 0) { + bin[32+i++] = (Dec & 1 > 0) ? '1' : '0'; + Dec = Dec >> 1; + } + + for (unsigned int j = 0; j< bitLength; j++) { + if (j >= bitLength - i) { + bin[j] = bin[ 31 + i - (j - (bitLength - i)) ]; + }else { + bin[j] = '0'; + } + } + bin[bitLength] = '\0'; + + return bin; +} From 57d50cc614ae203689bea3d1fa69a1ede1907244 Mon Sep 17 00:00:00 2001 From: xkonni Date: Sun, 25 Nov 2012 17:55:41 +0100 Subject: [PATCH 2/3] dev: add octave script to evaluate received data --- codes.m | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 codes.m diff --git a/codes.m b/codes.m new file mode 100644 index 0000000..b6d5ae4 --- /dev/null +++ b/codes.m @@ -0,0 +1,27 @@ +% raw data received by arduino +remote=[10272 412 912 1064 276 400 932 1088 244 404 932 1088 248 416 920 392 952 384 940 1088 248 396 940 1080 248 424 912 400 944 392 952 1056 268 388 948 1060 268 408 932 1052 284 388 948 400 932 388 952 1040 296]; +hi1=[10152 428 952 1120 268 436 952 1124 256 504 876 1104 284 424 952 496 884 432 956 1084 288 460 928 1096 296 420 956 460 924 432 960 1096 276 436 944 1088 308 424 952 1104 280 424 956 420 952 476 912 1068 312]; +hi2=[11016 468 976 1136 296 448 972 1168 284 420 1012 1136 296 428 1012 404 1016 452 972 1140 296 428 1004 1176 260 436 992 408 1008 452 968 1136 292 416 1040 1180 304 380 1052 1132 300 420 1016 412 1028 424 1012 1140 316]; + +% calculate total timings per bit sent +for ii=2:2:48 + g(ii/2)=remote(ii)+remote(ii+1); + s1(ii/2)=hi1(ii)+hi1(ii+1); + s2(ii/2)=hi2(ii)+hi2(ii+1); +end + +% calculate factor +qh1=remote./hi1; +qh2=remote./hi2; + +% min and max values +mh1=[min(qh1) max(qh1)] +mh2=[min(qh2) max(qh2)] + +% plot +figure(1) +hold off +clf +hold on +plot(qh1, 'b'); +plot(qh2, 'r'); From cc5eec7cf345fbb204ab1039f1ca4d859701f001 Mon Sep 17 00:00:00 2001 From: xkonni Date: Thu, 29 Nov 2012 05:34:19 +0000 Subject: [PATCH 3/3] daemon: make sure sockets are properly handled Makefile: enabled all warnings --- Makefile | 2 +- daemon.cpp | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 39e3164..e11141c 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ CXXFLAGS += -lwiringPi default: daemon daemon: RCSwitch.o daemon.o - $(CXX) -pthread $+ -o $@ $(CXXFLAGS) $(LDFLAGS) + $(CXX) -Wall -pthread $+ -o $@ $(CXXFLAGS) $(LDFLAGS) send: RCSwitch.o send.o $(CXX) $+ -o $@ $(CXXFLAGS) $(LDFLAGS) diff --git a/daemon.cpp b/daemon.cpp index b694a28..53cc241 100644 --- a/daemon.cpp +++ b/daemon.cpp @@ -65,17 +65,24 @@ int main(int argc, char* argv[]) { char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) - error("ERROR opening socket"); + bzero((char *) &serv_addr, sizeof(serv_addr)); portno = PORT; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); + // receiving socket + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); + // sending socket + newsockfd = socket(AF_INET, SOCK_STREAM, 0); + if (newsockfd < 0) + error("ERROR opening socket"); + /* * start listening */ @@ -92,7 +99,6 @@ int main(int argc, char* argv[]) { if (n < 0) error("ERROR reading from socket"); - printf("message: %s\n", buffer); if (strlen(buffer) >= 8) { for (int i=0; i<5; i++) {