From 42f985a297fa04ebc847ba92b03b3b491c7eba40 Mon Sep 17 00:00:00 2001 From: Ralf Schlatterbeck Date: Mon, 26 Jan 2015 17:27:12 +0100 Subject: [PATCH] Add potentiometer app for setting led intensity --- examples/osd/led-strip/led-strip.c | 2 +- examples/osd/poti/Makefile | 94 ++++++++++++ examples/osd/poti/README.md | 14 ++ examples/osd/poti/flash.sh | 2 + examples/osd/poti/poti.c | 220 +++++++++++++++++++++++++++++ examples/osd/poti/project-conf.h | 106 ++++++++++++++ examples/osd/poti/run.sh | 5 + 7 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 examples/osd/poti/Makefile create mode 100644 examples/osd/poti/README.md create mode 100755 examples/osd/poti/flash.sh create mode 100644 examples/osd/poti/poti.c create mode 100644 examples/osd/poti/project-conf.h create mode 100755 examples/osd/poti/run.sh diff --git a/examples/osd/led-strip/led-strip.c b/examples/osd/led-strip/led-strip.c index 1c2743e25..15efa8218 100644 --- a/examples/osd/led-strip/led-strip.c +++ b/examples/osd/led-strip/led-strip.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-15, Ralf Schlatterbeck Open Source Consulting + * Copyright (c) 2015, Ralf Schlatterbeck Open Source Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/examples/osd/poti/Makefile b/examples/osd/poti/Makefile new file mode 100644 index 000000000..536488828 --- /dev/null +++ b/examples/osd/poti/Makefile @@ -0,0 +1,94 @@ +SERIAL=/dev/ttyUSB0 +ifeq ($(TARGET), osd-merkur) +PLATFORM_FILES= avr-size poti.osd-merkur.hex \ + poti.osd-merkur.eep +endif + +all: poti $(PLATFORM_FILES) + +CONTIKI=../../.. + +# Contiki IPv6 configuration +WITH_UIP6=1 +UIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6=1 +CFLAGS += -DUIP_CONF_IPV6_RPL=1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +# automatically build RESTful resources +REST_RESOURCES_DIR = ./resources +REST_RESOURCES_DIR_COMMON = ../resources-common +REST_RESOURCES_FILES= $(notdir \ + $(shell find $(REST_RESOURCES_DIR_COMMON) -name '*.c') \ + ) + +PROJECTDIRS += $(REST_RESOURCES_DIR_COMMON) +PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) + +# linker optimizations +SMALL=1 + +# REST Engine shall use Erbium CoAP implementation +APPS += er-coap +APPS += rest-engine +APPS += json json-resource + +# optional rules to get assembly +#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 + +include $(CONTIKI)/Makefile.include + +# minimal-net target is currently broken in Contiki +ifeq ($(TARGET), minimal-net) +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=1300 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=176 +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +endif + +# optional rules to get assembly +#$(OBJECTDIR)/%.o: asmdir/%.S +# $(CC) $(CFLAGS) -MMD -c $< -o $@ +# @$(FINALIZE_DEPENDENCY) +# +#asmdir/%.S: %.c +# $(CC) $(CFLAGS) -MMD -S $< -o $@ + +# border router rules +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 + +avr-size: poti.osd-merkur + avr-size -C --mcu=MCU=atmega128rfa1 poti.osd-merkur + +poti.osd-merkur.hex: poti.osd-merkur + avr-objcopy -j .text -j .data -O ihex poti.osd-merkur \ + poti.osd-merkur.hex + +poti.osd-merkur.eep: poti.osd-merkur + avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O ihex \ + poti.osd-merkur poti.osd-merkur.eep + +flash: poti.osd-merkur.hex poti.osd-merkur.eep + avrdude -pm128rfa1 -c arduino -P$(SERIAL) -b57600 -e -U \ + flash:w:poti.osd-merkur.hex:a -U \ + eeprom:w:poti.osd-merkur.eep:a + +.PHONY: flash avr-size diff --git a/examples/osd/poti/README.md b/examples/osd/poti/README.md new file mode 100644 index 000000000..0a02cf8e6 --- /dev/null +++ b/examples/osd/poti/README.md @@ -0,0 +1,14 @@ +Potentiometer Driver +==================== + +This App allows sending potentiometer values to a remote node. This is +currently used to change colors of the led-strip app but the resource +used and the IP address are configurable -- so we can use it for any +other destination. + +The app sends its value to the remote only if the value has changed. In +addition it has a retransmit interval (in seconds) that can retransmit +the value after a timeout if the value has not changed. Setting this +retransmit interval to 0 will turn off the retransmit feature. Note that +we sample the value only every second: We don't want to use up the whole +bandwidth for this app alone. diff --git a/examples/osd/poti/flash.sh b/examples/osd/poti/flash.sh new file mode 100755 index 000000000..2b14c43f4 --- /dev/null +++ b/examples/osd/poti/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make flash TARGET=osd-merkur diff --git a/examples/osd/poti/poti.c b/examples/osd/poti/poti.c new file mode 100644 index 000000000..b33813600 --- /dev/null +++ b/examples/osd/poti/poti.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2015, Ralf Schlatterbeck Open Source Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +/** + * \file + * Potentiometer for regulating LED-strip brightness per color + * \author + * Ralf Schlatterbeck + */ + +#include +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "rest-engine.h" +#include "er-coap-engine.h" +#include "uiplib.h" +#include "generic_resource.h" +#include "Arduino.h" + +/* + * Resources to be activated need to be imported through the extern keyword. + * The build system automatically compiles the resources in the + * corresponding sub-directory. + */ + +#if PLATFORM_HAS_BATTERY +#include "dev/battery-sensor.h" +extern resource_t res_battery; +#endif + +#if PLATFORM_HAS_RADIO +#include "dev/radio-sensor.h" +extern resource_t res_radio; +#endif + +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +#define SERVER_NODE(ip) \ + uip_ip6addr(ip,0xfe80,0,0,0,0x22e,0xffff,0x34,0xa600) + /*uip_ip6addr(ip,0x2001,0xdb8,0xc001,0xf00d,0x22e,0xffff,0x34,0xa600)*/ +#define LOOP_INTERVAL (1 * CLOCK_SECOND) + +uip_ipaddr_t server_ipaddr, tmp_addr; +char server_resource [20] = "led/G"; +int interval = 10; /* Retransmit interval after no change in value */ + +static size_t +ip_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +{ + #define IP(x) server_ipaddr.u16[x] + char *q = "\""; + if (!is_json) { + q = ""; + } + return snprintf + ( buf, bsize, "%s%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x%s" + , q, IP(0), IP(1), IP(2), IP(3), IP(4), IP(5), IP(6), IP(7), q + ); +} + +void ip_from_string (const char *name, const char *s) +{ + /* Returns 1 if successful, only copy valid address */ + if (uiplib_ip6addrconv (s, &tmp_addr)) { + uip_ip6addr_copy (&server_ipaddr, &tmp_addr); + } +} + +GENERIC_RESOURCE + ( server_ip + , ip + , ipv6_address + , ip_from_string + , ip_to_string + ); + +static size_t +resource_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +{ + char *q = "\""; + if (!is_json) { + q = ""; + } + return snprintf (buf, bsize, "%s%s%s", q, server_resource, q); +} + +void resource_from_string (const char *name, const char *s) +{ + strncpy (server_resource, s, sizeof (server_resource)); + server_resource [sizeof (server_resource) - 1] = 0; +} + +GENERIC_RESOURCE + ( server_resource + , led-resource + , resource-name + , resource_from_string + , resource_to_string + ); + +static size_t +interval_to_string (const char *name, uint8_t is_json, char *buf, size_t bsize) +{ + return snprintf (buf, bsize, "%d", interval); +} + +void interval_from_string (const char *name, const char *s) +{ + interval = atoi (s); +} + +GENERIC_RESOURCE + ( interval + , interval + , s + , interval_from_string + , interval_to_string + ); + +/* Passed to COAP_BLOCKING_REQUEST to handle responses */ +void chunk_handler (void *response) +{ + const uint8_t *chunk; + int len = coap_get_payload (response, &chunk); + printf ("|%.*s", len, (char *)chunk); +} + +PROCESS(poti, "Potentiometer"); +AUTOSTART_PROCESSES(&poti); + +PROCESS_THREAD(poti, ev, data) +{ + + static struct etimer loop_timer; + PROCESS_BEGIN(); + + /* Initialize the REST engine. */ + rest_init_engine (); + SERVER_NODE (&server_ipaddr); + adc_init (); + coap_init_connection (0); + + /* Activate the application-specific resources. */ +#if PLATFORM_HAS_BATTERY + SENSORS_ACTIVATE(battery_sensor); + rest_activate_resource (&res_battery, "s/battery"); +#endif + rest_activate_resource (&res_server_ip, "poti/ip"); + rest_activate_resource (&res_server_resource, "poti/resource"); + rest_activate_resource (&res_interval, "poti/interval"); + + etimer_set (&loop_timer, LOOP_INTERVAL); + /* Define application-specific events here. */ + while(1) { + static int count = 0; + static int lastval = -1; + static coap_packet_t request [1]; /* Array: treat as pointer */ + uint8_t val = 127; + + PROCESS_WAIT_EVENT(); + if (etimer_expired (&loop_timer)) { + uint16_t sum = 0; + int i; + count++; + adc_setup (ADC_DEFAULT, A5); + for (i=0; i<5; i++) { + sum += adc_read (); + clock_delay_usec (50); + } + adc_fin (); + val = (sum / 5) >> 2; + if ((interval > 0 && count > interval) || (val != lastval)) { + char buf [4]; + sprintf (buf, "%d", val); + lastval = val; + printf ("Sending Value: %d\n", val); + coap_init_message (request, COAP_TYPE_CON, COAP_PUT, 0); + coap_set_header_uri_path (request, server_resource); + coap_set_header_content_format (request, REST.type.TEXT_PLAIN); + coap_set_payload (request, buf, strlen (buf)); + COAP_BLOCKING_REQUEST + (&server_ipaddr, REMOTE_PORT, request, chunk_handler); + count = 0; + } + etimer_reset (&loop_timer); + } + } /* while (1) */ + + PROCESS_END(); +} diff --git a/examples/osd/poti/project-conf.h b/examples/osd/poti/project-conf.h new file mode 100644 index 000000000..ab46b9879 --- /dev/null +++ b/examples/osd/poti/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, Matthias Kovatsch + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + */ + +#ifndef PROJECT_ERBIUM_CONF_H_ +#define PROJECT_ERBIUM_CONF_H_ + +#define PLATFORM_HAS_INFO 1 +#define PLATFORM_HAS_BATTERY 1 +#define PLATFORM_HAS_DS1820 1 +#define PLATFORM_HAS_DHT11HUM 1 +//#define PLATFORM_HAS_DHT11TEMP 1 +#define PLATFORM_HAS_LEDS 1 + + +/* Some platforms have weird includes. */ +#undef IEEE802154_CONF_PANID + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +/* For Debug: Dont allow MCU sleeping between channel checks */ +#undef RDC_CONF_MCU_SLEEP +#define RDC_CONF_MCU_SLEEP 0 + +#endif /* PROJECT_ERBIUM_CONF_H_ */ diff --git a/examples/osd/poti/run.sh b/examples/osd/poti/run.sh new file mode 100755 index 000000000..295a9ab1d --- /dev/null +++ b/examples/osd/poti/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the new bootloader (using a jump-table) you want to use +# BOOTLOADER_GET_MAC=0x0001ff80 (which is the current default) +make clean TARGET=osd-merkur +make TARGET=osd-merkur BOOTLOADER_GET_MAC=0x0001f3a0