From e6fc2331c1f536359629efde3a526fb8e0083537 Mon Sep 17 00:00:00 2001 From: Fernandez Lucas Date: Mon, 3 Sep 2012 16:01:21 +0200 Subject: [PATCH] add new sensor temp --- PolluxSensorTemp/Makefile | 448 ++++++++++++++++++++ PolluxSensorTemp/PolluxSensorTemp.ino | 89 ++++ PolluxSensorTemp/README.md | 2 + PolluxSensorTemp/Statistic/Statistic.cpp | 134 ++++++ PolluxSensorTemp/Statistic/Statistic.h | 53 +++ PolluxSensorTemp/TinyWire/TinyWire.cpp | 55 +++ PolluxSensorTemp/TinyWire/TinyWire.h | 45 ++ PolluxSensorTemp/TinyWire/buffer.h | 90 ++++ PolluxSensorTemp/TinyWire/usiTwiSlave.c | 497 +++++++++++++++++++++++ PolluxSensorTemp/TinyWire/usiTwiSlave.h | 51 +++ 10 files changed, 1464 insertions(+) create mode 100644 PolluxSensorTemp/Makefile create mode 100644 PolluxSensorTemp/PolluxSensorTemp.ino create mode 100644 PolluxSensorTemp/README.md create mode 100644 PolluxSensorTemp/Statistic/Statistic.cpp create mode 100644 PolluxSensorTemp/Statistic/Statistic.h create mode 100644 PolluxSensorTemp/TinyWire/TinyWire.cpp create mode 100644 PolluxSensorTemp/TinyWire/TinyWire.h create mode 100644 PolluxSensorTemp/TinyWire/buffer.h create mode 100644 PolluxSensorTemp/TinyWire/usiTwiSlave.c create mode 100644 PolluxSensorTemp/TinyWire/usiTwiSlave.h diff --git a/PolluxSensorTemp/Makefile b/PolluxSensorTemp/Makefile new file mode 100644 index 0000000..92f8dfd --- /dev/null +++ b/PolluxSensorTemp/Makefile @@ -0,0 +1,448 @@ +# Makefile for building Arduino sketches with Arduino 1.0. +# +# Makefile-arduino v0.8 by Bernard Pratz +# I release my changes under WTFPL2.0 licence, contact other authors for their favorite licences. +# Updates on : https://github.com/guyzmo/Arduino-Tools/blob/master/Makefile +# +# Makefile-arduino v0.7 by Akkana Peck +# Adapted from a long-ago Arduino 0011 Makefile by mellis, eighthave, oli.keller +# +# This Makefile allows you to build sketches from the command line +# without the Arduino environment (or Java). +# +# Detailed instructions for using this Makefile: +# +# 1. Copy this file into the folder with your sketch. +# There should be a file with the extension .pde (e.g. blink.pde). +# cd into this directory. Be sure your directory has the same name +# as the .pde file. +# +# 2. Modify the line containg "ARDUINO_DIR" to point to the directory that +# contains the Arduino installation (for example, under Mac OS X, this +# might be /Applications/arduino-1.0). If it's in your home directory, +# you can include $(HOME) as part of the path. +# +# 3. Set MODEL to your Arduino model. +# Tested so far on uno, atmega328, diecimila and mega. +# but there are lots of other options: +# Use the "make list" command to know all the available models +# +# 4. Run "make" to compile/verify your program. +# +# 5. Run "make upload" (and reset your Arduino if it requires it) +# to download your program to the Arduino. +# +# Nota Bene: +# if reset does not work, add RESET_MODE='python' or RESET_MODE='perl' to your env +# * Perl version needs libdevice-serialport-perl : +# * Python version needs python-serial : +# if you want to compile against ATTiny, see ATTINY_DIR below. + +############################################################################ +# Project's settings +############################################################################ + +VERSION = 0.1 + +# Standard Arduino libraries it will import, e.g. LiquidCrystal: +ARDLIBS = + +# User-specified (in ~/sketchbook/libraries/) libraries : +USERLIBS = + +# Libs in local directory +LOCALLIBS = $(patsubst applet/,,$(wildcard */)) + +# Arduino model: +# You can set this to be a string, such as uno, atmega328, diecimila and mega, +MODEL ?= attiny85at1 + +############################################################################ +# Platform's settings +############################################################################ + +# Determine operating system environment +ifneq "$(wildcard C:/Windows/)" "" + UNAME=Windows +else + UNAME=$(shell uname) +endif + +# Name of the program and source .pde file: +TARGET = $(shell basename $(PWD)) + +# Where do you keep the official Arduino software package? +ARDUINO_DIR = /Applications/Arduino.app/Contents/Resources/Java +HOME_LIB = $(HOME)/Documents/Arduino/libraries +# path to ATTiny files look at http://code.google.com/p/arduino-tiny/ +ATTINY_DIR=$(HOME)/Documents/Arduino/hardware/tiny + +USERDEF= +#'BUFFER_SIZE=64' + +############################################################################ +# Below here nothing should need to be changed. Cross your fingers! +############################################################################ + +# Where are tools like avr-gcc located on your system? +ifeq "$(UNAME)" "Darwin" + AVR_TOOLS_PATH = $(ARDUINO_DIR)/hardware/tools/avr/bin +else + AVR_TOOLS_PATH = /usr/bin +endif + +ifeq "$(UNAME)" "Windows" + PORT ?= COM1 #XXX needs to be checked ! +else + ifeq "$(UNAME)" "Darwin" + ifeq "$(MODEL)" "uno" + PORT ?= /dev/tty.usbmodem* + else + PORT ?= /dev/tty.usbserial* + endif + else + ifeq "$(UNAME)" "Linux" + ifeq "$(MODEL)" "uno" + PORT ?= /dev/ttyACM* + else + PORT ?= /dev/ttyUSB* + endif + endif + endif +endif + +# How to reset the device before downloading a new program. +# These don't always work; if the default one doesn't work, +# try uncommenting one of the others instead. +ifeq "$(RESET_MODE)" "python" + RESET_DEVICE = python -c "import serial; s = serial.SERIAL('/dev/ttyUSB0', 57600); s.setDTR(True); sleep(1); s.setDTR(False)" +else + ifeq "$(RESET_MODE)" "perl" + RESET_DEVICE = perl -MDevice::SerialPort -e 'Device::SerialPort->new("/dev/ttyUSB0")->pulse_dtr_on(1000)' + else + ifeq "$(UNAME)" "Windows" + RESET_DEVICE = echo "CAN'T RESET DEVICE ON WINDOWS !" + else + ifeq "$(UNAME)" "Linux" + RESET_DEVICE = stty -F $(PORT) hupcl + else + # BSD uses small f + RESET_DEVICE = stty -f $(PORT) hupcl + endif + endif + endif +endif + +# +# set up attiny boards.txt path +# +ifeq "$(wildcard $(ATTINY_DIR))" "" + ATTINY_BOARDS= +else + ATTINY_BOARDS=$(ATTINY_DIR)/boards.txt +endif + +# +# Set up values according to what the IDE uses: +# +UPLOAD_RATE ?= $(shell grep "^$(MODEL)\." $(ARDUINO_DIR)/hardware/arduino/boards.txt $(ATTINY_BOARDS) | grep upload.speed | sed 's/.*=//') +MCU = $(shell grep "^$(MODEL)\." $(ARDUINO_DIR)/hardware/arduino/boards.txt $(ATTINY_BOARDS) | grep build.mcu | sed 's/.*=//') +F_CPU = $(shell grep "^$(MODEL)\." $(ARDUINO_DIR)/hardware/arduino/boards.txt $(ATTINY_BOARDS) | grep build.f_cpu | sed 's/.*=//') + +# man avrdude says to use arduino, but the IDE mostly uses stk500. +# One rumor says that the difference is that arduino does an auto-reset, stk500 doesn't. +# Might want to grep for upload.protocol as with previous 3 values. +ifneq ($(findstring tiny,$(MODEL)),) + AVRDUDE_PROGRAMMER = $(shell grep "^$(MODEL)\." $(ARDUINO_DIR)/hardware/arduino/boards.txt $(ATTINY_BOARDS) | grep upload.using | sed 's/.*=\(.*\):.*/\1/') + ARDUINO_CORE=$(ATTINY_DIR)/cores/tiny + ARDUINO_VARIANT=$(ATTINY_DIR)/cores/tiny + ARDUINO_PROG_HEADER=WProgram.h + SRC=$(ARDUINO_CORE)/pins_arduino.c + ifeq ($(UPLOAD_RATE),) + UPLOAD_RATE=9600 + endif +else + AVRDUDE_PROGRAMMER = $(shell grep "^$(MODEL)\." $(ARDUINO_DIR)/hardware/arduino/boards.txt $(ATTINY_BOARDS) | grep upload.protocol | sed 's/.*=//') + ARDUINO_CORE=$(ARDUINO_DIR)/hardware/arduino/cores/arduino + ARDUINO_PROG_HEADER=Arduino.h + SRC= + + # This has only been tested on standard variants. I'm guessing + # at what mega and micro might need; other possibilities are + # leonardo and "eightanaloginputs". + ifeq "$(MODEL)" "mega" + ARDUINO_VARIANT=$(ARDUINO_DIR)/hardware/arduino/variants/mega + else + ifeq "$(MODEL)" "micro" + ARDUINO_VARIANT=$(ARDUINO_DIR)/hardware/arduino/variants/micro + else + ARDUINO_VARIANT=$(ARDUINO_DIR)/hardware/arduino/variants/standard + endif + endif +endif + +CWDBASE = $(shell basename $(PWD)) +TARFILE = $(TARGET)-$(VERSION).tar.gz + +# $(ARDUINO_DIR)/hardware/arduino/variants/standard/pins_arduino.c +SRC += \ + $(ARDUINO_CORE)/wiring.c \ + $(ARDUINO_CORE)/wiring_analog.c $(ARDUINO_CORE)/wiring_digital.c \ + $(ARDUINO_CORE)/wiring_pulse.c \ + $(ARDUINO_CORE)/wiring_shift.c $(ARDUINO_CORE)/WInterrupts.c \ + $(foreach l,$(ARDLIBS),$(wildcard $(ARDUINO_DIR)/libraries/$l/*.c)) \ + $(foreach l,$(USERLIBS),$(wildcard $(HOME_LIB)/$l/*.c)) \ + $(foreach l,$(LOCALLIBS),$(wildcard $l/*.c)) + +CXXSRC = $(ARDUINO_CORE)/HardwareSerial.cpp $(ARDUINO_CORE)/WMath.cpp \ + $(ARDUINO_CORE)/WString.cpp $(ARDUINO_CORE)/Print.cpp \ + $(foreach l,$(ARDLIBS),$(wildcard $(ARDUINO_DIR)/libraries/$l/*.cpp)) \ + $(foreach l,$(USERLIBS),$(wildcard $(HOME_LIB)/$l/*.cpp)) \ + $(foreach l,$(LOCALLIBS),$(wildcard $l/*.cpp)) + +FORMAT = ihex + +# Name of this Makefile (used for "make depend"). +MAKEFILE = Makefile + +# Debugging format. +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. +# AVR (extended) COFF requires stabs, plus an avr-objcopy run. +DEBUG = stabs + +OPT = s + +#DEFINE=$(foreach d,$(USERDEF), -D$d) +DEFINE=$(patsubst %,-D%,$(USERDEF)) + +# Place -D or -U options here +CDEFS = -DF_CPU=$(F_CPU) + +# Include directories +CINCS = -I$(ARDUINO_CORE) -I$(ARDUINO_VARIANT) \ + $(patsubst %,-I$(ARDUINO_DIR)/libraries/%,$(ARDLIBS)) \ + $(patsubst %,-I$(HOME_LIB)/%,$(USERLIBS)) \ + $(patsubst %,-I%/,$(LOCALLIBS)) + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +#CSTANDARD = -std=gnu99 +CDEBUG = -g$(DEBUG) +#CWARN = -Wall -Wstrict-prototypes +CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) + +# Extra flags to match what the Arduino 1.0 IDE is doing: +# Something about the -ffunction-sections -fdata-sections reduces +# final text size by roughly half! +CEXTRA= -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -DARDUINO=100 + +CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA) +CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA) +#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs +LDFLAGS = -Os -Wl,--gc-sections -mmcu=$(MCU) -lm + +# Programming support using avrdude. Settings and variables. +AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex +ifeq "$(UNAME)" "Darwin" +AVRDUDE_CONF = -V -F -C $(ARDUINO_DIR)/hardware/tools/avr/etc/avrdude.conf +else +AVRDUDE_CONF = -V -F -C /etc/avrdude.conf +endif +AVRDUDE_FLAGS = $(AVRDUDE_CONF) \ + -p $(MCU) -P $(PORT) -c $(AVRDUDE_PROGRAMMER) \ + -b $(UPLOAD_RATE) + +# Program settings +CC = $(AVR_TOOLS_PATH)/avr-gcc +CXX = $(AVR_TOOLS_PATH)/avr-g++ +OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy +OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump +AR = $(AVR_TOOLS_PATH)/avr-ar +SIZE = $(AVR_TOOLS_PATH)/avr-size +NM = $(AVR_TOOLS_PATH)/avr-nm +AVRDUDE = $(AVR_TOOLS_PATH)/avrdude +REMOVE = rm -f +MV = mv -f + +# Define all object files. +OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS) $(DEFINE) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + +# Default target. +all: applet_files build sizeafter + +test: + @echo CXXSRC = $(CXXSRC) + +build: elf hex + +ifneq "$(wildcard $(TARGET).pde)" "" +applet/$(TARGET).cpp: $(TARGET).pde + # Here is the "preprocessing". + # It creates a .cpp file based with the same name as the .pde file. + # On top of the new .cpp file comes the WProgram.h header. + # At the end there is a generic main() function attached, + # plus special magic to get around the pure virtual error + # undefined reference to `__cxa_pure_virtual' from Print.o. + # Then the .cpp file will be compiled. Errors during compile will + # refer to this new, automatically generated, file. + # Not the original .pde file you actually edit... + test -d applet || mkdir applet + echo '#include "$(ARDUINO_PROG_HEADER)"' > applet/$(TARGET).cpp + cat $(TARGET).pde >> applet/$(TARGET).cpp + echo 'extern "C" void __cxa_pure_virtual() { while (1) ; }' >> applet/$(TARGET).cpp + cat $(ARDUINO_CORE)/main.cpp >> applet/$(TARGET).cpp +else + ifneq "$(wildcard $(TARGET).ino)" "" +applet/$(TARGET).cpp: $(TARGET).ino + # Here is the "preprocessing". + # It creates a .cpp file based with the same name as the .ino file. + # On top of the new .cpp file comes the WProgram.h header. + # At the end there is a generic main() function attached, + # plus special magic to get around the pure virtual error + # undefined reference to `__cxa_pure_virtual' from Print.o. + # Then the .cpp file will be compiled. Errors during compile will + # refer to this new, automatically generated, file. + # Not the original .ino file you actually edit... + test -d applet || mkdir applet + echo '#include "$(ARDUINO_PROG_HEADER)"' > applet/$(TARGET).cpp + cat $(TARGET).ino >> applet/$(TARGET).cpp + echo 'extern "C" void __cxa_pure_virtual() { while (1) ; }' >> applet/$(TARGET).cpp + cat $(ARDUINO_CORE)/main.cpp >> applet/$(TARGET).cpp +else +applet/$(TARGET).cpp: + @echo "FAILURE: Missing .pde or .ino file in current directory !" + @exit 2 +endif +endif + +elf: applet/$(TARGET).elf +hex: applet/$(TARGET).hex +eep: applet/$(TARGET).eep +lss: applet/$(TARGET).lss +sym: applet/$(TARGET).sym + +# Program the device. +upload: applet/$(TARGET).hex + $(RESET_DEVICE) + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) + + # Display size of file. +HEXSIZE = $(SIZE) --target=$(FORMAT) applet/$(TARGET).hex +ELFSIZE = $(SIZE) applet/$(TARGET).elf +sizebefore: + @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi + +sizeafter: + @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ + --change-section-address .data-0x800000 \ + --change-section-address .bss-0x800000 \ + --change-section-address .noinit-0x800000 \ + --change-section-address .eeprom-0x810000 + +coff: applet/$(TARGET).elf + $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf $(TARGET).cof + + +extcoff: $(TARGET).elf + $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf $(TARGET).cof + +.SUFFIXES: .elf .hex .eep .lss .sym + +.elf.hex: + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +.elf.eep: + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +.elf.lss: + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +.elf.sym: + $(NM) -n $< > $@ + + # Link: create ELF output file from library. +applet/$(TARGET).elf: applet/$(TARGET).o applet/core.a + $(CC) -o $@ applet/$(TARGET).o -L. applet/core.a $(LDFLAGS) + +#applet/$(TARGET).elf: applet/$(TARGET).o applet/core.a +# $(CC) $(ALL_CFLAGS) -o $@ applet/$(TARGET).cpp -L. applet/core.a $(LDFLAGS) + +applet/core.a: $(OBJ) + @for i in $(OBJ); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done + +# Compile: create object files from C++ source files. +.cpp.o: + $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ + +# Compile: create object files from C source files. +.c.o: + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +.c.s: + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +.S.o: + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + +# Target: clean project. +clean: + $(REMOVE) applet/$(TARGET).eep applet/$(TARGET).cof applet/$(TARGET).elf \ + applet/$(TARGET).map applet/$(TARGET).sym applet/$(TARGET).lss applet/core.a \ + $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) + +flush: + $(REMOVE) -rf applet/ \ + $(REMOVE) $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) + +list: + # LIST OF ALL THE BOARDS AVAILABLE AS TARGETS FOR $$MODEL ENV VARIABLE + @cat $(ARDUINO_DIR)/hardware/arduino/boards.txt $(ATTINY_BOARDS) \ + | grep '.name' \ + | sed 's/\(.*\)\.name=\(.*\)/MODEL=\1;\2/' \ + | column -t -s';' + +tar: $(TARFILE) + +$(TARFILE): + ( cd .. && \ + tar czvf $(TARFILE) --exclude=applet --owner=root $(CWDBASE) && \ + mv $(TARFILE) $(CWD) && \ + echo Created $(TARFILE) \ + ) + +depend: + if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ + then \ + sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ + $(MAKEFILE).$$$$ && \ + $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ + fi + echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ + >> $(MAKEFILE); \ + $(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE) + +.PHONY: all build elf hex eep lss sym program coff extcoff clean depend applet_files sizebefore sizeafter + diff --git a/PolluxSensorTemp/PolluxSensorTemp.ino b/PolluxSensorTemp/PolluxSensorTemp.ino new file mode 100644 index 0000000..3e814e8 --- /dev/null +++ b/PolluxSensorTemp/PolluxSensorTemp.ino @@ -0,0 +1,89 @@ +/** + * Pollux'NZ City Project + * Copyright (c) 2012 CKAB, hackable:Devices + * Copyright (c) 2012 Bernard Pratz + * Copyright (c) 2012 Lucas Fernandez + * + * Pollux'NZ City 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. + * + * Pollux'NZ City 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 project. If not, see . + + +-\/-+ + (RESET) 1| |8 VCC (2.7-5.5V) + Temp Read 2| |7 I2C SCK -> Uno A5 + NA 3| |6 (PB1) NA + GND 4| |5 I2C SDA -> Uno A4 + +----+ +*/ +#include +#include + +#define I2C_SLAVE_ADDR 0x25 // I2C slave address + +#define TEMP_READ 3 // Dust read on pin 2 (ADC3) +#define DELAY_TIME 10 // Wait 10 ms before reread sensor value +#define NB_READ 100 + +TinyWire Wire; + +prog_uint32_t offset=(float)-0.5; + +void sensor_calibrate() { + offset = Wire.read(0x20); + offset = Wire.read(0x21); + offset = Wire.read(0x22); + offset = Wire.read(0x23); +} + +void sensor_meas() { + Statistic stat; + float result; + uint8_t* float_ptr; + + for(uint8_t i=0;i int overflows @32K samples +// +// 0.3 - branched from 0.2.01 version of Rob Tillaart's code +// Released to the public domain +// + +#include "Statistic.h" + +Statistic::Statistic() +{ + clear(); +} + +// resets all counters +void Statistic::clear() +{ + _cnt = 0; // count at N stored, becoming N+1 at a new iteration + _sum = 0; + _min = 0.0; + _max = 0.0; +#ifdef STAT_USE_STDEV + _ssqdif = 0.0; // not _ssq but sum of square differences + // which is SUM(from i = 1 to N) of + // (f(i)-_ave_N)**2 +#endif +} + +// adds a new value to the data-set +void Statistic::add(float f) +{ + if (_cnt == 0) + { + _min = f; + _max = f; + } else { + if (f < _min) _min = f; + if (f > _max) _max = f; + } // end of if (_cnt == 0) else + _sum += f; + _cnt++; +#ifdef STAT_USE_STDEV + if (_cnt >1) { + _store = (_sum / _cnt - f); + _ssqdif = _ssqdif + _cnt * _store * _store / (_cnt-1); + } // end if > 1 + +#endif + + +} + +// returns the number of values added +long Statistic::count() +{ + return _cnt; +} + +// returns the average of the data-set added sofar +float Statistic::average() +{ + if (_cnt == 0) return -1; // original code returned 0 + return _sum / _cnt; +} + +// returns the sum of the data-set (0 if no values added) +float Statistic::sum() +{ + return _sum; +} + +// returns the sum of the data-set (0 if no values added) +float Statistic::minimum() +{ + return _min; +} + +// returns the sum of the data-set (0 if no values added) +float Statistic::maximum() +{ + return _max; +} + + +// Population standard deviation = s = sqrt [ S ( Xi - µ )2 / N ] +// http://www.suite101.com/content/how-is-standard-deviation-used-a99084 +#ifdef STAT_USE_STDEV +float Statistic::pop_stdev() +{ + if (_cnt < 1) return -1; // otherwise DIV0 error + return sqrt( _ssqdif / _cnt); +} + +float Statistic::unbiased_stdev() +{ + if (_cnt < 2) return -1; // otherwise DIV0 error + return sqrt( _ssqdif / (_cnt - 1)); +} +#endif +// END OF FILE diff --git a/PolluxSensorTemp/Statistic/Statistic.h b/PolluxSensorTemp/Statistic/Statistic.h new file mode 100644 index 0000000..80d1686 --- /dev/null +++ b/PolluxSensorTemp/Statistic/Statistic.h @@ -0,0 +1,53 @@ +#ifndef Statistic_h +#define Statistic_h +// +// FILE: Statistic.h +// AUTHOR: Rob dot Tillaart at gmail dot com +// modified at 0.3 by Gil Ross at physics dot org +// PURPOSE: Recursive Statistical library for Arduino +// VERSION: 0.3.00 +// URL: http://www.arduino.cc/playground/Main/Statistics +// HISTORY: See Statistic.cpp +// +// Released to the public domain +// + +// the standard deviation increases the lib (<100 bytes) +// it can be in/excluded by un/commenting next line +#define STAT_USE_STDEV + +#ifdef STAT_USE_STDEV +#include +#endif + +class Statistic +{ + public: + Statistic(); + void clear(); + void add(float); + long count(); + float sum(); + float average(); + float minimum(); + float maximum(); + + +#ifdef STAT_USE_STDEV + float pop_stdev(); // population stdev + float unbiased_stdev(); +#endif + +protected: + long _cnt; + float _store; // store to minimise computation + float _sum; + float _min; + float _max; +#ifdef STAT_USE_STDEV + float _ssqdif; // sum of squares difference +#endif +}; + +#endif +// END OF FILE diff --git a/PolluxSensorTemp/TinyWire/TinyWire.cpp b/PolluxSensorTemp/TinyWire/TinyWire.cpp new file mode 100644 index 0000000..7434e58 --- /dev/null +++ b/PolluxSensorTemp/TinyWire/TinyWire.cpp @@ -0,0 +1,55 @@ +/** + * Pollux'NZ City Project + * Copyright (c) 2012 CKAB, hackable:Devices + * Copyright (c) 2012 Bernard Pratz + * Copyright (c) 2012 Lucas Fernandez + * + * Copyright (c) 2009 Andrew Rapp. For the XBee example origins. + * + * Pollux'NZ City 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. + * + * Pollux'NZ City 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 project. If not, see . + */ + +////////////////////////////////////////////////////////////////////////////////////////// +//// TinyWire.cpp + + +extern "C" { + #include +} +#include "TinyWire.h" + +prog_uint8_t mem_buffer[I2C_ADDR_SIZE]; + +void TinyWire::begin(uint8_t i2c_slave_address) { + usiTwiSlaveInit(i2c_slave_address, + _on_request_handler, + _on_receive_handler); + for (int i=0;i + * Copyright (c) 2012 Lucas Fernandez + * + * Copyright (c) 2009 Andrew Rapp. For the XBee example origins. + * + * Pollux'NZ City 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. + * + * Pollux'NZ City 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 project. If not, see . + */ +extern "C" { +#include "usiTwiSlave.h" +} +#define I2C_ADDR_SIZE 256 + +#include + +class TinyWire { + + static void _on_receive_handler(uint8_t reg, uint8_t value); + static uint8_t _on_request_handler(uint8_t reg); + + public: + void begin(uint8_t i2c_slave_address); + + uint8_t read(uint8_t reg); + void write(uint8_t reg, uint8_t value); + +}; + +#endif // __TINYWIRE_H__ diff --git a/PolluxSensorTemp/TinyWire/buffer.h b/PolluxSensorTemp/TinyWire/buffer.h new file mode 100644 index 0000000..94cb333 --- /dev/null +++ b/PolluxSensorTemp/TinyWire/buffer.h @@ -0,0 +1,90 @@ +#ifndef __BUFFER_H__ +#define __BUFFER_H__ + +/** + * Pollux'NZ City Project + * Copyright (c) 2012 CKAB, hackable:Devices + * Copyright (c) 2012 Bernard Pratz + * Copyright (c) 2012 Lucas Fernandez + * + * Copyright (c) 2009 Andrew Rapp. For the XBee example origins. + * + * Pollux'NZ City 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. + * + * Pollux'NZ City 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 project. If not, see . + */ +/* thanks to Akash Nath, akashnath{at}rediffmail{dot}com for this snippet, + taken from http://datastructures.itgo.com/staque/queues/circular */ + +#ifndef BUFFER_SIZE +# define BUFFER_SIZE 32 +#endif + +class Buffer { + uint8_t queue[BUFFER_SIZE]; + uint8_t front; + uint8_t rear; + + public: + Buffer() : front(0), rear(-1) { + for (int i=0;i BUFFER_SIZE) + return -1; + for (uint8_t i=0;i BUFFER_SIZE) + return 0; + return rear-front+1; + } + void clear() { + front = 0; + rear = -1; + for (int i=0;i +#include +#include +#include "usiTwiSlave.h" + + + +/******************************************************************************** + + device dependent defines + +********************************************************************************/ + +#if defined( __AVR_ATtiny2313__ ) +# define DDR_USI DDRB +# define PORT_USI PORTB +# define PIN_USI PINB +# define PORT_USI_SDA PB5 +# define PORT_USI_SCL PB7 +# define PIN_USI_SDA PINB5 +# define PIN_USI_SCL PINB7 +# define USI_START_COND_INT USISIF +# define USI_START_VECTOR USI_START_vect +# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect +#endif + +#if defined( __AVR_ATtiny25__ ) | \ + defined( __AVR_ATtiny45__ ) | \ + defined( __AVR_ATtiny85__ ) +# define DDR_USI DDRB +# define PORT_USI PORTB +# define PIN_USI PINB +# define PORT_USI_SDA PB0 +# define PORT_USI_SCL PB2 +# define PIN_USI_SDA PINB0 +# define PIN_USI_SCL PINB2 +# define USI_START_COND_INT USISIF +# define USI_START_VECTOR USI_START_vect +# define USI_OVERFLOW_VECTOR USI_OVF_vect +#endif + +#if defined( __AVR_ATtiny26__ ) +# define DDR_USI DDRB +# define PORT_USI PORTB +# define PIN_USI PINB +# define PORT_USI_SDA PB0 +# define PORT_USI_SCL PB2 +# define PIN_USI_SDA PINB0 +# define PIN_USI_SCL PINB2 +# define USI_START_COND_INT USISIF +# define USI_START_VECTOR USI_STRT_vect +# define USI_OVERFLOW_VECTOR USI_OVF_vect +#endif + +#if defined( __AVR_ATtiny261__ ) | \ + defined( __AVR_ATtiny461__ ) | \ + defined( __AVR_ATtiny861__ ) +# define DDR_USI DDRB +# define PORT_USI PORTB +# define PIN_USI PINB +# define PORT_USI_SDA PB0 +# define PORT_USI_SCL PB2 +# define PIN_USI_SDA PINB0 +# define PIN_USI_SCL PINB2 +# define USI_START_COND_INT USISIF +# define USI_START_VECTOR USI_START_vect +# define USI_OVERFLOW_VECTOR USI_OVF_vect +#endif + +#if defined( __AVR_ATmega165__ ) | \ + defined( __AVR_ATmega325__ ) | \ + defined( __AVR_ATmega3250__ ) | \ + defined( __AVR_ATmega645__ ) | \ + defined( __AVR_ATmega6450__ ) | \ + defined( __AVR_ATmega329__ ) | \ + defined( __AVR_ATmega3290__ ) +# define DDR_USI DDRE +# define PORT_USI PORTE +# define PIN_USI PINE +# define PORT_USI_SDA PE5 +# define PORT_USI_SCL PE4 +# define PIN_USI_SDA PINE5 +# define PIN_USI_SCL PINE4 +# define USI_START_COND_INT USISIF +# define USI_START_VECTOR USI_START_vect +# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect +#endif + +#if defined( __AVR_ATmega169__ ) +# define DDR_USI DDRE +# define PORT_USI PORTE +# define PIN_USI PINE +# define PORT_USI_SDA PE5 +# define PORT_USI_SCL PE4 +# define PIN_USI_SDA PINE5 +# define PIN_USI_SCL PINE4 +# define USI_START_COND_INT USISIF +# define USI_START_VECTOR USI_START_vect +# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect +#endif + +#define NO_CURRENT_REGISTER_SET 255 + +/******************************************************************************** + + functions implemented as macros + +********************************************************************************/ + +#define SET_USI_TO_SEND_ACK( ) \ +{ \ + /* prepare ACK */ \ + USIDR = 0; \ + /* set SDA as output */ \ + DDR_USI |= ( 1 << PORT_USI_SDA ); \ + /* clear all interrupt flags, except Start Cond */ \ + USISR = \ + ( 0 << USI_START_COND_INT ) | \ + ( 1 << USIOIF ) | ( 1 << USIPF ) | \ + ( 1 << USIDC )| \ + /* set USI counter to shift 1 bit */ \ + ( 0x0E << USICNT0 ); \ +} + +#define SET_USI_TO_READ_ACK( ) \ +{ \ + /* set SDA as input */ \ + DDR_USI &= ~( 1 << PORT_USI_SDA ); \ + /* prepare ACK */ \ + USIDR = 0; \ + /* clear all interrupt flags, except Start Cond */ \ + USISR = \ + ( 0 << USI_START_COND_INT ) | \ + ( 1 << USIOIF ) | \ + ( 1 << USIPF ) | \ + ( 1 << USIDC ) | \ + /* set USI counter to shift 1 bit */ \ + ( 0x0E << USICNT0 ); \ +} + +#define SET_USI_TO_TWI_START_CONDITION_MODE( ) \ +{ \ + USICR = \ + /* enable Start Condition Interrupt, disable Overflow Interrupt */ \ + ( 1 << USISIE ) | ( 0 << USIOIE ) | \ + /* set USI in Two-wire mode, no USI Counter overflow hold */ \ + ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | \ + /* Shift Register Clock Source = External, positive edge */ \ + /* 4-Bit Counter Source = external, both edges */ \ + ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | \ + /* no toggle clock-port pin */ \ + ( 0 << USITC ); \ + USISR = \ + /* clear all interrupt flags, except Start Cond */ \ + ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \ + ( 1 << USIDC ) | ( 0x0 << USICNT0 ); \ +} + +#define SET_USI_TO_SEND_DATA( ) \ +{ \ + /* set SDA as output */ \ + DDR_USI |= ( 1 << PORT_USI_SDA ); \ + /* clear all interrupt flags, except Start Cond */ \ + USISR = \ + ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \ + ( 1 << USIDC) | \ + /* set USI to shift out 8 bits */ \ + ( 0x0 << USICNT0 ); \ +} + +#define SET_USI_TO_READ_DATA( ) \ +{ \ + /* set SDA as input */ \ + DDR_USI &= ~( 1 << PORT_USI_SDA ); \ + /* clear all interrupt flags, except Start Cond */ \ + USISR = \ + ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | \ + ( 1 << USIPF ) | ( 1 << USIDC ) | \ + /* set USI to shift out 8 bits */ \ + ( 0x0 << USICNT0 ); \ +} + + + +/******************************************************************************** + + typedef's + +********************************************************************************/ + +typedef enum +{ + USI_SLAVE_CHECK_ADDRESS = 0x00, + USI_SLAVE_SEND_DATA = 0x01, + USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA = 0x02, + USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA = 0x03, + USI_SLAVE_REQUEST_DATA = 0x04, + USI_SLAVE_GET_DATA_AND_SEND_ACK = 0x05 +} overflowState_t; + + + +/******************************************************************************** + + local variables + +********************************************************************************/ + +static uint8_t (*_onI2CReadFromRegister)(uint8_t reg); +static void (*_onI2CWriteToRegister)(uint8_t reg, uint8_t value); + +static uint8_t slaveAddress; +static volatile overflowState_t overflowState; +static volatile uint8_t currentRegister = NO_CURRENT_REGISTER_SET; + +/******************************************************************************** + + public functions + +********************************************************************************/ + + + +// initialise USI for TWI slave mode + +void +usiTwiSlaveInit( + uint8_t ownAddress, + uint8_t (*onI2CReadFromRegister)(uint8_t reg), + void (*onI2CWriteToRegister)(uint8_t reg, uint8_t value) +) +{ + + slaveAddress = ownAddress; + _onI2CReadFromRegister = onI2CReadFromRegister; + _onI2CWriteToRegister = onI2CWriteToRegister; + + // In Two Wire mode (USIWM1, USIWM0 = 1X), the slave USI will pull SCL + // low when a start condition is detected or a counter overflow (only + // for USIWM1, USIWM0 = 11). This inserts a wait state. SCL is released + // by the ISRs (USI_START_vect and USI_OVERFLOW_vect). + + // Set SCL and SDA as output + DDR_USI |= ( 1 << PORT_USI_SCL ) | ( 1 << PORT_USI_SDA ); + + // set SCL high + PORT_USI |= ( 1 << PORT_USI_SCL ); + + // set SDA high + PORT_USI |= ( 1 << PORT_USI_SDA ); + + // Set SDA as input + DDR_USI &= ~( 1 << PORT_USI_SDA ); + + USICR = + // enable Start Condition Interrupt + ( 1 << USISIE ) | + // disable Overflow Interrupt + ( 0 << USIOIE ) | + // set USI in Two-wire mode, no USI Counter overflow hold + ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | + // Shift Register Clock Source = external, positive edge + // 4-Bit Counter Source = external, both edges + ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | + // no toggle clock-port pin + ( 0 << USITC ); + + // clear all interrupt flags and reset overflow counter + + USISR = ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | ( 1 << USIDC ); + +} // end usiTwiSlaveInit + + +/******************************************************************************** + + USI Start Condition ISR + +********************************************************************************/ + +ISR( USI_START_VECTOR ) +{ + // set default starting conditions for new TWI package + overflowState = USI_SLAVE_CHECK_ADDRESS; + + // set SDA as input + DDR_USI &= ~( 1 << PORT_USI_SDA ); + + // wait for SCL to go low to ensure the Start Condition has completed (the + // start detector will hold SCL low ) - if a Stop Condition arises then leave + // the interrupt to prevent waiting forever - don't use USISR to test for Stop + // Condition as in Application Note AVR312 because the Stop Condition Flag is + // going to be set from the last TWI sequence + while ( + // SCL his high + ( PIN_USI & ( 1 << PIN_USI_SCL ) ) && + // and SDA is low + !( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) ) + ); + + + if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) ) + { + // a Stop Condition did not occur + USICR = + // keep Start Condition Interrupt enabled to detect RESTART + ( 1 << USISIE ) | + // enable Overflow Interrupt + ( 1 << USIOIE ) | + // set USI in Two-wire mode, hold SCL low on USI Counter overflow + ( 1 << USIWM1 ) | ( 1 << USIWM0 ) | + // Shift Register Clock Source = External, positive edge + // 4-Bit Counter Source = external, both edges + ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | + // no toggle clock-port pin + ( 0 << USITC ); + + } + else + { + currentRegister = NO_CURRENT_REGISTER_SET; + + // a Stop Condition did occur + USICR = + // enable Start Condition Interrupt + ( 1 << USISIE ) | + // disable Overflow Interrupt + ( 0 << USIOIE ) | + // set USI in Two-wire mode, no USI Counter overflow hold + ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | + // Shift Register Clock Source = external, positive edge + // 4-Bit Counter Source = external, both edges + ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | + // no toggle clock-port pin + ( 0 << USITC ); + + } // end if + + USISR = + // clear interrupt flags - resetting the Start Condition Flag will + // release SCL + ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | + ( 1 << USIPF ) |( 1 << USIDC ) | + // set USI to sample 8 bits (count 16 external SCL pin toggles) + ( 0x0 << USICNT0); + +} // end ISR( USI_START_VECTOR ) + + + +/******************************************************************************** + + USI Overflow ISR + +Handles all the communication. + +Only disabled when waiting for a new Start Condition. + +********************************************************************************/ + +ISR( USI_OVERFLOW_VECTOR ) +{ + + switch ( overflowState ) + { + + // Address mode: check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK, + // else reset USI + case USI_SLAVE_CHECK_ADDRESS: + if ( ( USIDR == 0 ) || ( ( USIDR >> 1 ) == slaveAddress) ) + { + + if ( USIDR & 0x01 ) + { + overflowState = USI_SLAVE_SEND_DATA; + } + else + { + overflowState = USI_SLAVE_REQUEST_DATA; + } // end if + SET_USI_TO_SEND_ACK( ); + } + else + { + SET_USI_TO_TWI_START_CONDITION_MODE( ); + } + break; + + // Master write data mode: check reply and goto USI_SLAVE_SEND_DATA if OK, + // else reset USI + case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA: + if ( USIDR ) + { + // if NACK, the master does not want more data + SET_USI_TO_TWI_START_CONDITION_MODE( ); + return; + } + // from here we just drop straight into USI_SLAVE_SEND_DATA if the + // master sent an ACK + + // copy data from buffer to USIDR and set USI to shift byte + // next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA + case USI_SLAVE_SEND_DATA: + + USIDR = _onI2CReadFromRegister(currentRegister); + currentRegister = NO_CURRENT_REGISTER_SET; + overflowState = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA; + SET_USI_TO_SEND_DATA( ); + break; + + // set USI to sample reply from master + // next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA + case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA: + overflowState = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA; + SET_USI_TO_READ_ACK( ); + break; + + // Master read data mode: set USI to sample data from master, next + // USI_SLAVE_GET_DATA_AND_SEND_ACK + case USI_SLAVE_REQUEST_DATA: + overflowState = USI_SLAVE_GET_DATA_AND_SEND_ACK; + SET_USI_TO_READ_DATA( ); + break; + + // copy data from USIDR and send ACK + // next USI_SLAVE_REQUEST_DATA + case USI_SLAVE_GET_DATA_AND_SEND_ACK: + + // The master is writing a value. If we don't have a register yet, it + // must be writing the register value. + if (currentRegister == NO_CURRENT_REGISTER_SET) + { + // Store the value as the current register. + currentRegister = USIDR; + } + else + { + // We already have a register value, so it must be storing some data. + _onI2CWriteToRegister(currentRegister, USIDR); + + // Currently we only support writing a single value, so we assume that the + // transaction is over. + currentRegister = NO_CURRENT_REGISTER_SET; + } + + // next USI_SLAVE_REQUEST_DATA + overflowState = USI_SLAVE_REQUEST_DATA; + SET_USI_TO_SEND_ACK( ); + break; + + } // end switch + +} // end ISR( USI_OVERFLOW_VECTOR ) diff --git a/PolluxSensorTemp/TinyWire/usiTwiSlave.h b/PolluxSensorTemp/TinyWire/usiTwiSlave.h new file mode 100644 index 0000000..cf77642 --- /dev/null +++ b/PolluxSensorTemp/TinyWire/usiTwiSlave.h @@ -0,0 +1,51 @@ +/******************************************************************************** + +Header file for the USI TWI Slave driver. + +Created by Donald R. Blake +donblake at worldnet.att.net + +--------------------------------------------------------------------------------- + +Created from Atmel source files for Application Note AVR312: Using the USI Module +as an I2C slave. + +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 2 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. + +--------------------------------------------------------------------------------- + +Change Activity: + + Date Description + ------ ------------- + 15 Mar 2007 Created. + +********************************************************************************/ + + + +#ifndef _USI_TWI_SLAVE_H_ +#define _USI_TWI_SLAVE_H_ + + +/******************************************************************************** + + prototypes + +********************************************************************************/ + +#include +void usiTwiSlaveInit( + uint8_t, + uint8_t (*onI2CReadFromRegister)(uint8_t reg), + void (*onI2CWriteToRegister)(uint8_t reg, uint8_t value) + ); + +#endif // ifndef _USI_TWI_SLAVE_H_