From 353cfe723ca0caf78f259cce16a1fd5f4ed4d627 Mon Sep 17 00:00:00 2001 From: Harald Pichler Date: Tue, 6 Dec 2016 21:32:33 +0100 Subject: [PATCH] initial upload --- examples/osd/openvoting-box/ChainableLED.cpp | 175 +++++++++++++++ examples/osd/openvoting-box/ChainableLED.h | 69 ++++++ .../ChainableLED/ChainableLED.cpp | 175 +++++++++++++++ .../ChainableLED/ChainableLED.h | 69 ++++++ .../osd/openvoting-box/ChainableLED/LICENSE | 20 ++ .../osd/openvoting-box/ChainableLED/README.md | 34 +++ .../CycleThroughColors/CycleThroughColors.ino | 39 ++++ .../examples/FadeInOut/FadeInOut.ino | 34 +++ .../examples/SimpleCycle/SimpleCycle.ino | 33 +++ .../openvoting-box/ChainableLED/keywords.txt | 19 ++ examples/osd/openvoting-box/Makefile | 71 ++++++ examples/osd/openvoting-box/README.md | 11 + examples/osd/openvoting-box/arduino-example.c | 2 + examples/osd/openvoting-box/flash.sh | 2 + examples/osd/openvoting-box/project-conf.h | 106 +++++++++ .../osd/openvoting-box/resources/res-event.c | 117 ++++++++++ .../osd/openvoting-box/resources/res-led.c | 104 +++++++++ .../osd/openvoting-box/resources/res-rgb.c | 148 +++++++++++++ .../openvoting-box/resources/res-separate.c | 127 +++++++++++ examples/osd/openvoting-box/run.sh | 5 + examples/osd/openvoting-box/sketch.h | 16 ++ examples/osd/openvoting-box/sketch.pde | 206 ++++++++++++++++++ 22 files changed, 1582 insertions(+) create mode 100644 examples/osd/openvoting-box/ChainableLED.cpp create mode 100644 examples/osd/openvoting-box/ChainableLED.h create mode 100644 examples/osd/openvoting-box/ChainableLED/ChainableLED.cpp create mode 100644 examples/osd/openvoting-box/ChainableLED/ChainableLED.h create mode 100644 examples/osd/openvoting-box/ChainableLED/LICENSE create mode 100644 examples/osd/openvoting-box/ChainableLED/README.md create mode 100644 examples/osd/openvoting-box/ChainableLED/examples/CycleThroughColors/CycleThroughColors.ino create mode 100644 examples/osd/openvoting-box/ChainableLED/examples/FadeInOut/FadeInOut.ino create mode 100644 examples/osd/openvoting-box/ChainableLED/examples/SimpleCycle/SimpleCycle.ino create mode 100644 examples/osd/openvoting-box/ChainableLED/keywords.txt create mode 100644 examples/osd/openvoting-box/Makefile create mode 100644 examples/osd/openvoting-box/README.md create mode 100644 examples/osd/openvoting-box/arduino-example.c create mode 100755 examples/osd/openvoting-box/flash.sh create mode 100644 examples/osd/openvoting-box/project-conf.h create mode 100644 examples/osd/openvoting-box/resources/res-event.c create mode 100644 examples/osd/openvoting-box/resources/res-led.c create mode 100644 examples/osd/openvoting-box/resources/res-rgb.c create mode 100644 examples/osd/openvoting-box/resources/res-separate.c create mode 100755 examples/osd/openvoting-box/run.sh create mode 100644 examples/osd/openvoting-box/sketch.h create mode 100755 examples/osd/openvoting-box/sketch.pde diff --git a/examples/osd/openvoting-box/ChainableLED.cpp b/examples/osd/openvoting-box/ChainableLED.cpp new file mode 100644 index 000000000..7a1abbbd9 --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Information about the P9813 protocol obtained from: + * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED + * + * HSB to RGB routine adapted from: + * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + */ + + +// -------------------------------------------------------------------------------------- + +#include "ChainableLED.h" + +// Forward declaration +float hue2rgb(float p, float q, float t); + +// -------------------------------------------------------------------------------------- + +ChainableLED::ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds) : + _clk_pin(clk_pin), _data_pin(data_pin), _num_leds(number_of_leds) +{ + _led_state = (byte*) calloc(_num_leds*3, sizeof(byte)); +} + +ChainableLED::~ChainableLED() +{ + free(_led_state); +} + +// -------------------------------------------------------------------------------------- + +void ChainableLED::init() +{ + pinMode(_clk_pin, OUTPUT); + pinMode(_data_pin, OUTPUT); + + for (byte i=0; i<_num_leds; i++) + setColorRGB(i, 0, 0, 0); +} + +void ChainableLED::clk(void) +{ + digitalWrite(_clk_pin, LOW); + delayMicroseconds(_CLK_PULSE_DELAY); + digitalWrite(_clk_pin, HIGH); + delayMicroseconds(_CLK_PULSE_DELAY); +} + +void ChainableLED::sendByte(byte b) +{ + // Send one bit at a time, starting with the MSB + for (byte i=0; i<8; i++) + { + // If MSB is 1, write one and clock it, else write 0 and clock + if ((b & 0x80) != 0) + digitalWrite(_data_pin, HIGH); + else + digitalWrite(_data_pin, LOW); + clk(); + + // Advance to the next bit to send + b <<= 1; + } +} + +void ChainableLED::sendColor(byte red, byte green, byte blue) +{ + // Start by sending a byte with the format "1 1 /B7 /B6 /G7 /G6 /R7 /R6" + byte prefix = 0b11000000; + if ((blue & 0x80) == 0) prefix|= 0b00100000; + if ((blue & 0x40) == 0) prefix|= 0b00010000; + if ((green & 0x80) == 0) prefix|= 0b00001000; + if ((green & 0x40) == 0) prefix|= 0b00000100; + if ((red & 0x80) == 0) prefix|= 0b00000010; + if ((red & 0x40) == 0) prefix|= 0b00000001; + sendByte(prefix); + + // Now must send the 3 colors + sendByte(blue); + sendByte(green); + sendByte(red); +} + +void ChainableLED::setColorRGB(byte led, byte red, byte green, byte blue) +{ + // Send data frame prefix (32x "0") + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + + // Send color data for each one of the leds + for (byte i=0; i<_num_leds; i++) + { + if (i == led) + { + _led_state[i*3 + _CL_RED] = red; + _led_state[i*3 + _CL_GREEN] = green; + _led_state[i*3 + _CL_BLUE] = blue; + } + + sendColor(_led_state[i*3 + _CL_RED], + _led_state[i*3 + _CL_GREEN], + _led_state[i*3 + _CL_BLUE]); + } + + // Terminate data frame (32x "0") + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); +} + +void ChainableLED::setColorHSB(byte led, float hue, float saturation, float brightness) +{ + float r, g, b; + + hue=constrain(hue, 0.0, 1.0); + saturation=constrain(saturation, 0.0, 1.0); + brightness=constrain(brightness, 0.0, 1.0); + + if(saturation == 0.0) + { + r = g = b = brightness; + } + else + { + float q = brightness < 0.5 ? + brightness * (1.0 + saturation) : brightness + saturation - brightness * saturation; + float p = 2.0 * brightness - q; + r = hue2rgb(p, q, hue + 1.0/3.0); + g = hue2rgb(p, q, hue); + b = hue2rgb(p, q, hue - 1.0/3.0); + } + + setColorRGB(led, (byte)(255.0*r), (byte)(255.0*g), (byte)(255.0*b)); +} + +// -------------------------------------------------------------------------------------- + +float hue2rgb(float p, float q, float t) +{ + if (t < 0.0) + t += 1.0; + if(t > 1.0) + t -= 1.0; + if(t < 1.0/6.0) + return p + (q - p) * 6.0 * t; + if(t < 1.0/2.0) + return q; + if(t < 2.0/3.0) + return p + (q - p) * (2.0/3.0 - t) * 6.0; + + return p; +} diff --git a/examples/osd/openvoting-box/ChainableLED.h b/examples/osd/openvoting-box/ChainableLED.h new file mode 100644 index 000000000..9a471b2bb --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED.h @@ -0,0 +1,69 @@ +/* +Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Library for controlling a chain of RGB LEDs based on the P9813 protocol. + * E.g., supports the Grove Chainable RGB LED product. + * + * Information about the P9813 protocol obtained from: + * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED + */ + + + +#ifndef __ChainableLED_h__ +#define __ChainableLED_h__ + +#if defined (SPARK) + #include "application.h" +#else + #include "Arduino.h" +#endif + +#define _CL_RED 0 +#define _CL_GREEN 1 +#define _CL_BLUE 2 +#define _CLK_PULSE_DELAY 20 + +class ChainableLED +{ +public: + ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds); + ~ChainableLED(); + + void init(); + void setColorRGB(byte led, byte red, byte green, byte blue); + void setColorHSB(byte led, float hue, float saturation, float brightness); + +private: + byte _clk_pin; + byte _data_pin; + byte _num_leds; + + byte* _led_state; + + void clk(void); + void sendByte(byte b); + void sendColor(byte red, byte green, byte blue); +}; + +#endif + diff --git a/examples/osd/openvoting-box/ChainableLED/ChainableLED.cpp b/examples/osd/openvoting-box/ChainableLED/ChainableLED.cpp new file mode 100644 index 000000000..e63bec175 --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED/ChainableLED.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Information about the P9813 protocol obtained from: + * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED + * + * HSB to RGB routine adapted from: + * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + */ + + +// -------------------------------------------------------------------------------------- + +#include "ChainableLED.h" + +// Forward declaration +float hue2rgb(float p, float q, float t); + +// -------------------------------------------------------------------------------------- + +ChainableLED::ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds) : + _clk_pin(clk_pin), _data_pin(data_pin), _num_leds(number_of_leds) +{ + _led_state = (byte*) calloc(_num_leds*3, sizeof(byte)); +} + +ChainableLED::~ChainableLED() +{ + free(_led_state); +} + +// -------------------------------------------------------------------------------------- + +void ChainableLED::init() +{ + pinMode(_clk_pin, OUTPUT); + pinMode(_data_pin, OUTPUT); + + for (byte i=0; i<_num_leds; i++) + setColorRGB(i, 0, 0, 0); +} + +void ChainableLED::clk(void) +{ + digitalWrite(_clk_pin, LOW); + delayMicroseconds(_CLK_PULSE_DELAY); + digitalWrite(_clk_pin, HIGH); + delayMicroseconds(_CLK_PULSE_DELAY); +} + +void ChainableLED::sendByte(byte b) +{ + // Send one bit at a time, starting with the MSB + for (byte i=0; i<8; i++) + { + // If MSB is 1, write one and clock it, else write 0 and clock + if ((b & 0x80) != 0) + digitalWrite(_data_pin, HIGH); + else + digitalWrite(_data_pin, LOW); + clk(); + + // Advance to the next bit to send + b <<= 1; + } +} + +void ChainableLED::sendColor(byte red, byte green, byte blue) +{ + // Start by sending a byte with the format "1 1 /B7 /B6 /G7 /G6 /R7 /R6" + byte prefix = 0b11000000; + if ((blue & 0x80) == 0) prefix|= 0b00100000; + if ((blue & 0x40) == 0) prefix|= 0b00010000; + if ((green & 0x80) == 0) prefix|= 0b00001000; + if ((green & 0x40) == 0) prefix|= 0b00000100; + if ((red & 0x80) == 0) prefix|= 0b00000010; + if ((red & 0x40) == 0) prefix|= 0b00000001; + sendByte(prefix); + + // Now must send the 3 colors + sendByte(blue); + sendByte(green); + sendByte(red); +} + +void ChainableLED::setColorRGB(byte led, byte red, byte green, byte blue) +{ + // Send data frame prefix (32x "0") + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + + // Send color data for each one of the leds + for (byte i=0; i<_num_leds; i++) + { + if (i == led) + { + _led_state[i*3 + _CL_RED] = red; + _led_state[i*3 + _CL_GREEN] = green; + _led_state[i*3 + _CL_BLUE] = blue; + } + + sendColor(_led_state[i*3 + _CL_RED], + _led_state[i*3 + _CL_GREEN], + _led_state[i*3 + _CL_BLUE]); + } + + // Terminate data frame (32x "0") + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); + sendByte(0x00); +} + +void ChainableLED::setColorHSB(byte led, float hue, float saturation, float brightness) +{ + float r, g, b; + + constrain(hue, 0.0, 1.0); + constrain(saturation, 0.0, 1.0); + constrain(brightness, 0.0, 1.0); + + if(saturation == 0.0) + { + r = g = b = brightness; + } + else + { + float q = brightness < 0.5 ? + brightness * (1.0 + saturation) : brightness + saturation - brightness * saturation; + float p = 2.0 * brightness - q; + r = hue2rgb(p, q, hue + 1.0/3.0); + g = hue2rgb(p, q, hue); + b = hue2rgb(p, q, hue - 1.0/3.0); + } + + setColorRGB(led, (byte)(255.0*r), (byte)(255.0*g), (byte)(255.0*b)); +} + +// -------------------------------------------------------------------------------------- + +float hue2rgb(float p, float q, float t) +{ + if (t < 0.0) + t += 1.0; + if(t > 1.0) + t -= 1.0; + if(t < 1.0/6.0) + return p + (q - p) * 6.0 * t; + if(t < 1.0/2.0) + return q; + if(t < 2.0/3.0) + return p + (q - p) * (2.0/3.0 - t) * 6.0; + + return p; +} diff --git a/examples/osd/openvoting-box/ChainableLED/ChainableLED.h b/examples/osd/openvoting-box/ChainableLED/ChainableLED.h new file mode 100644 index 000000000..9a471b2bb --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED/ChainableLED.h @@ -0,0 +1,69 @@ +/* +Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + * Library for controlling a chain of RGB LEDs based on the P9813 protocol. + * E.g., supports the Grove Chainable RGB LED product. + * + * Information about the P9813 protocol obtained from: + * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Chainable_RGB_LED + */ + + + +#ifndef __ChainableLED_h__ +#define __ChainableLED_h__ + +#if defined (SPARK) + #include "application.h" +#else + #include "Arduino.h" +#endif + +#define _CL_RED 0 +#define _CL_GREEN 1 +#define _CL_BLUE 2 +#define _CLK_PULSE_DELAY 20 + +class ChainableLED +{ +public: + ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds); + ~ChainableLED(); + + void init(); + void setColorRGB(byte led, byte red, byte green, byte blue); + void setColorHSB(byte led, float hue, float saturation, float brightness); + +private: + byte _clk_pin; + byte _data_pin; + byte _num_leds; + + byte* _led_state; + + void clk(void); + void sendByte(byte b); + void sendColor(byte red, byte green, byte blue); +}; + +#endif + diff --git a/examples/osd/openvoting-box/ChainableLED/LICENSE b/examples/osd/openvoting-box/ChainableLED/LICENSE new file mode 100644 index 000000000..ccf9fda5c --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED/LICENSE @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2012 Paulo Marques (pjp.marques@gmail.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ diff --git a/examples/osd/openvoting-box/ChainableLED/README.md b/examples/osd/openvoting-box/ChainableLED/README.md new file mode 100644 index 000000000..a529875f0 --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED/README.md @@ -0,0 +1,34 @@ +ChainableLED +============ + +Arduino library compatible with Grove Chainable LED and the P9813 chip. It allows controlling a chain of LEDS individually. + +Supports both RGB and HSB color spaces for setting the color of each individual LED. + +Compatible with [Particle devices](https://www.particle.io/). + +[More information on the wiki](https://github.com/pjpmarques/ChainableLED/wiki) + + +Installation +============ +1. Grab the latest version from the release section of GitHub. +(https://github.com/pjpmarques/ChainableLED/releases) + +2. Unzip it to your Arduino "libraries" directory. + +3. It should be ready to use. Examples are included. + + +Library Interface +================= +```c++ +class ChainableLED { +public: + ChainableLED(byte clk_pin, byte data_pin, byte number_of_leds); + + void init(); + void setColorRGB(byte led, byte red, byte green, byte blue); + void setColorHSB(byte led, float hue, float saturation, float brightness); +} +``` diff --git a/examples/osd/openvoting-box/ChainableLED/examples/CycleThroughColors/CycleThroughColors.ino b/examples/osd/openvoting-box/ChainableLED/examples/CycleThroughColors/CycleThroughColors.ino new file mode 100644 index 000000000..285ee1285 --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED/examples/CycleThroughColors/CycleThroughColors.ino @@ -0,0 +1,39 @@ + +/* + * Example of using the ChainableRGB library for controlling a Grove RGB. + * This code cycles through all the colors in an uniform way. This is accomplished using a HSB color space. + */ + + +#include + +#define NUM_LEDS 5 + +ChainableLED leds(7, 8, NUM_LEDS); + +void setup() +{ + leds.init(); +} + +float hue = 0.0; +boolean up = true; + +void loop() +{ + for (byte i=0; i=1.0 && up) + up = false; + else if (hue<=0.0 && !up) + up = true; +} + diff --git a/examples/osd/openvoting-box/ChainableLED/examples/FadeInOut/FadeInOut.ino b/examples/osd/openvoting-box/ChainableLED/examples/FadeInOut/FadeInOut.ino new file mode 100644 index 000000000..9d2edae50 --- /dev/null +++ b/examples/osd/openvoting-box/ChainableLED/examples/FadeInOut/FadeInOut.ino @@ -0,0 +1,34 @@ + +/* + * Example of using the ChainableRGB library for controlling a Grove RGB. + * This code fades in an out colors in a strip of leds. + */ + + +#include + +#define NUM_LEDS 5 + +ChainableLED leds(7, 8, NUM_LEDS); + +void setup() +{ + leds.init(); +} + +byte power = 0; + +void loop() +{ + for (byte i=0; i + +#define NUM_LEDS 5 + +ChainableLED leds(7, 8, NUM_LEDS); + +void setup() +{ + leds.init(); +} + +byte pos = 0; + +void loop() +{ + for (byte i=0; i +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/openvoting-box/flash.sh b/examples/osd/openvoting-box/flash.sh new file mode 100755 index 000000000..e82962073 --- /dev/null +++ b/examples/osd/openvoting-box/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur-128 flash diff --git a/examples/osd/openvoting-box/project-conf.h b/examples/osd/openvoting-box/project-conf.h new file mode 100644 index 000000000..445f3a95e --- /dev/null +++ b/examples/osd/openvoting-box/project-conf.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * 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_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define LOOP_INTERVAL (CLOCK_SECOND/10) + +/* Seeping nodes are host nodes without routing features */ +#define UIP_CONF_ROUTER 0 + +/* For Debug: Dont allow MCU sleeping between channel checks */ +//#undef RDC_CONF_MCU_SLEEP +//#define RDC_CONF_MCU_SLEEP 0 + +/* Save energy */ +//#define RDC_CONF_PT_YIELD_OFF + +/* 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 8 + +/* 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 +*/ + +/* +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 +#undef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER noncoresec_framer +#undef NETSTACK_CONF_LLSEC +#define NETSTACK_CONF_LLSEC noncoresec_driver +#undef NONCORESEC_CONF_SEC_LVL +#define NONCORESEC_CONF_SEC_LVL 1 + +#define NONCORESEC_CONF_KEY { 0x00 , 0x01 , 0x02 , 0x03 , \ + 0x04 , 0x05 , 0x06 , 0x07 , \ + 0x08 , 0x09 , 0x0A , 0x0B , \ + 0x0C , 0x0D , 0x0E , 0x0F } + +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ + diff --git a/examples/osd/openvoting-box/resources/res-event.c b/examples/osd/openvoting-box/resources/res-event.c new file mode 100644 index 000000000..6470c311b --- /dev/null +++ b/examples/osd/openvoting-box/resources/res-event.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * 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 + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap.h" +#include "dev/button-sensor.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) +#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5]) +#else +#define PRINTF(...) +#define PRINT6ADDR(addr) +#define PRINTLLADDR(addr) +#endif + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_event_handler(void); + +/* + * Example for an event resource. + * Additionally takes a period parameter that defines the interval to call [name]_periodic_handler(). + * A default post_handler takes care of subscriptions and manages a list of subscribers to notify. + */ +EVENT_RESOURCE(res_event, + "title=\"Event demo\";obs", + res_get_handler, + NULL, + NULL, + NULL, + res_event_handler); + +/* + * Use local resource state that is accessed by res_get_handler() and altered by res_event_handler() or PUT or POST. + */ +static int32_t event_counter = 0; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int buttonstate = button_sensor.value(0); + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "EVENT %lu STATE %d", event_counter, buttonstate)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "{'EVENT':%lu ,'STATE': %d}", event_counter, buttonstate)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, buffer, snprintf((char *)buffer, preferred_size, "Supporting content-types text/plain and application/json")); + } + + /* A post_handler that handles subscriptions/observing will be called for periodic resources by the framework. */ + + // tell client when to schedule re-registration: 1 Hour + REST.set_header_max_age(response, /* uint32_t, Seconds */ 3600); +} +/* + * Additionally, res_event_handler must be implemented for each EVENT_RESOURCE. + * It is called through .trigger(), usually from the server process. + */ +static void +res_event_handler(void) +{ + /* Do the update triggered by the event here, e.g., sampling a sensor. */ + ++event_counter; + + /* Usually a condition is defined under with subscribers are notified, e.g., event was above a threshold. */ + if(1) { + PRINTF("TICK %u for /%s\n", event_counter, res_event.url); + + /* Notify the registered observers which will trigger the res_get_handler to create the response. */ + REST.notify_subscribers(&res_event); + } +} diff --git a/examples/osd/openvoting-box/resources/res-led.c b/examples/osd/openvoting-box/resources/res-led.c new file mode 100644 index 000000000..fb0fa138f --- /dev/null +++ b/examples/osd/openvoting-box/resources/res-led.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * 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 + * Door resource + * \author + * Harald Pichler + */ + +#include "contiki.h" + +#include +#include "rest-engine.h" +#include "Arduino.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_led, + "title=\"LED: , POST/PUT mode=on|off\";rt=\"Control\"", + res_get_handler, + res_post_put_handler, + res_post_put_handler, + NULL); + +extern uint8_t led_pin; +extern uint8_t led_status; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", led_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'led':%d}", led_status); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *mode = NULL; + int success = 1; + + if(success && (len = REST.get_post_variable(request, "mode", &mode))) { + if(strncmp(mode, "on", len) == 0) { + digitalWrite(led_pin, LOW); + led_status=1; + } else if(strncmp(mode, "off", len) == 0) { + digitalWrite(led_pin, HIGH); + led_status=0; + } else { + success = 0; + } + } else { + success = 0; + } if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} diff --git a/examples/osd/openvoting-box/resources/res-rgb.c b/examples/osd/openvoting-box/resources/res-rgb.c new file mode 100644 index 000000000..6390b5d9a --- /dev/null +++ b/examples/osd/openvoting-box/resources/res-rgb.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * 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 + * rgb resource + * \author + * Harald Pichler + */ + +#include "contiki.h" +#include +#include "rest-engine.h" +#include "generic_resource.h" +#include "Arduino.h" +#include "sketch.h" + +extern uint8_t color_rgb [3]; + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +/* A simple getter example. Returns the reading from the sensor with a simple etag */ +RESOURCE(res_rgb, + "title=\"LED: , POST/PUT r=10&g=11&b=12\";rt=\"Control\"", + res_get_handler, + res_post_put_handler, + res_post_put_handler, + NULL); + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "r=%d&g=%d&b=%d",color_rgb [0],color_rgb [1],color_rgb [2] ); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{'r':%d\n,'g':%d\n,'b':%d}",color_rgb [0],color_rgb [1],color_rgb [2]); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + const char *msg = "Supporting content-types text/plain and application/json"; + REST.set_response_payload(response, msg, strlen(msg)); + } +} + +static void +res_post_put_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + size_t len = 0; + const char *valr = NULL; + const char *valg = NULL; + const char *valb = NULL; + int success = 1; + + if(success && (len = REST.get_post_variable(request, "r", &valr))) { + if(len != 0) { + // printf("r= %s;",valr); + } else { + success = 0; + } + if(success && (len = REST.get_post_variable(request, "g", &valg))) { + if(len != 0) { + // printf("g= %s;",valg); + } else { + success = 0; + } + } + if(success && (len = REST.get_post_variable(request, "b", &valb))) { + if(len != 0) { + // printf("b= %s;\n",valb); + } else { + success = 0; + } + } + if((success) && !color_rgb_from_string (valr, valg, valb)) { + + } + } else { + success = 0; + } if(!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} + +#pragma GCC diagnostic ignored "-Wwrite-strings" +GENERIC_RESOURCE + ( red + , RED_LED + , s + , 1 + , color_from_string + , color_to_string + ); + +GENERIC_RESOURCE + ( green + , GREEN_LED + , s + , 1 + , color_from_string + , color_to_string + ); + +GENERIC_RESOURCE + ( blue + , BLUE_LED + , s + , 1 + , color_from_string + , color_to_string + ); +#pragma GCC diagnostic pop diff --git a/examples/osd/openvoting-box/resources/res-separate.c b/examples/osd/openvoting-box/resources/res-separate.c new file mode 100644 index 000000000..bb2248c92 --- /dev/null +++ b/examples/osd/openvoting-box/resources/res-separate.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich + * 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 + * Example resource + * \author + * Matthias Kovatsch + */ + +#include +#include "rest-engine.h" +#include "er-coap-separate.h" +#include "er-coap-transactions.h" + +static void res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void res_resume_handler(void); + +SEPARATE_RESOURCE(res_separate, + "title=\"Separate demo\"", + res_get_handler, + NULL, + NULL, + NULL, + res_resume_handler); + +/* A structure to store the information required for the separate handler */ +typedef struct application_separate_store { + + /* Provided by Erbium to store generic request information such as remote address and token. */ + coap_separate_t request_metadata; + + /* Add fields for addition information to be stored for finalizing, e.g.: */ + char buffer[16]; +} application_separate_store_t; + +#define COAP_MAX_OPEN_SEPARATE 2 + +static uint8_t separate_active = 0; +static application_separate_store_t separate_store[COAP_MAX_OPEN_SEPARATE]; + +static void +res_get_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + /* + * Example allows only one open separate response. + * For multiple, the application must manage the list of stores. + */ + if(separate_active >= COAP_MAX_OPEN_SEPARATE) { + coap_separate_reject(); + } else { + ++separate_active; + + /* Take over and skip response by engine. */ + coap_separate_accept(request, &separate_store->request_metadata); + /* Be aware to respect the Block2 option, which is also stored in the coap_separate_t. */ + + /* + * At the moment, only the minimal information is stored in the store (client address, port, token, MID, type, and Block2). + * Extend the store, if the application requires additional information from this handler. + * buffer is an example field for custom information. + */ + snprintf(separate_store->buffer, sizeof(separate_store->buffer), "StoredInfo"); + } +} +static void +res_resume_handler() +{ + if(separate_active) { + coap_transaction_t *transaction = NULL; + if((transaction = coap_new_transaction(separate_store->request_metadata.mid, &separate_store->request_metadata.addr, separate_store->request_metadata.port))) { + coap_packet_t response[1]; /* This way the packet can be treated as pointer as usual. */ + + /* Restore the request information for the response. */ + coap_separate_resume(response, &separate_store->request_metadata, REST.status.OK); + + coap_set_payload(response, separate_store->buffer, strlen(separate_store->buffer)); + + /* + * Be aware to respect the Block2 option, which is also stored in the coap_separate_t. + * As it is a critical option, this example resource pretends to handle it for compliance. + */ + coap_set_header_block2(response, separate_store->request_metadata.block2_num, 0, separate_store->request_metadata.block2_size); + + /* Warning: No check for serialization error. */ + transaction->packet_len = coap_serialize_message(response, transaction->packet); + coap_send_transaction(transaction); + /* The engine will clear the transaction (right after send for NON, after acked for CON). */ + + /* FIXME there could me more! */ + separate_active = 0; + } else { + /* + * Set timer for retry, send error message, ... + * The example simply waits for another button press. + */ + } + } /* if (separate_active) */ +} diff --git a/examples/osd/openvoting-box/run.sh b/examples/osd/openvoting-box/run.sh new file mode 100755 index 000000000..5d5cbbbb4 --- /dev/null +++ b/examples/osd/openvoting-box/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# For the ages-old bootloader (before 2014) you want to use +# BOOTLOADER_GET_MAC=0x0001f3a0 as parameter to make below. +make clean TARGET=osd-merkur-128 +make TARGET=osd-merkur-128 diff --git a/examples/osd/openvoting-box/sketch.h b/examples/osd/openvoting-box/sketch.h new file mode 100644 index 000000000..065d302d3 --- /dev/null +++ b/examples/osd/openvoting-box/sketch.h @@ -0,0 +1,16 @@ +#ifndef __SKETCH_h__ +#define __SKETCH_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +size_t color_to_string (const char *name, const char *uri, char *buf, size_t bsize); +int color_from_string (const char *name, const char *uri, const char *s); +int color_rgb_from_string (const char *r, const char *g, const char *b); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/osd/openvoting-box/sketch.pde b/examples/osd/openvoting-box/sketch.pde new file mode 100755 index 000000000..29f62d659 --- /dev/null +++ b/examples/osd/openvoting-box/sketch.pde @@ -0,0 +1,206 @@ +/* + * Sample arduino sketch using contiki features. + * We turn the LED off + * We allow read the moisture sensor + * Unfortunately sleeping for long times in loop() isn't currently + * possible, something turns off the CPU (including PWM outputs) if a + * Proto-Thread is taking too long. We need to find out how to sleep in + * a Contiki-compatible way. + * Note that for a normal arduino sketch you won't have to include any + * of the contiki-specific files here, the sketch should just work. + */ + +extern "C" { +#include "arduino-process.h" +#include "rest-engine.h" +#include "er-coap-engine.h" +#include "generic_resource.h" +#include "net/netstack.h" +#include "dev/button-sensor.h" +#include "ChainableLED.h" +#include "sketch.h" +} + +extern resource_t + res_led, + res_rgb, + res_red, + res_green, + res_blue, + res_battery, + res_cputemp, + res_event, + res_separate, + res_server; + +uint8_t led_pin=4; +uint8_t led_status; + +// coap_server_post +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +// should be the same :-) +#define UIP_NTOHS(x) UIP_HTONS(x) +#define SERVER_NODE(ip) uip_ip6addr(ip,0xaaaa,0,0,0,0,0,0,0x01) + +uip_ipaddr_t server_ipaddr, tmp_addr; + +#define NUM_LEDS 1 + +// Merkurboard grove i2c D8, D9 +ChainableLED leds(8, 9, NUM_LEDS); + +uint8_t color_rgb [3] = {0, 0, 0}; + + +static uint8_t +name_to_offset (const char * name) +{ + uint8_t offset = 0; + if (0 == strcmp (name, "green")) { + offset = 1; + } else if (0 == strcmp (name, "blue")) { + offset = 2; + } + return offset; +} + +extern "C" size_t +color_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + return snprintf (buf, bsize, "%d", color_rgb [name_to_offset (name)]); +} + +extern "C" int +color_from_string (const char *name, const char *uri, const char *s) +{ + color_rgb [name_to_offset (name)] = atoi (s); + leds.setColorRGB(0,color_rgb [0], color_rgb [1], color_rgb [2]); + return 0; +} + +extern "C" int +color_rgb_from_string (const char *r, const char *g, const char *b) +{ + // printf("rgb r=%s; g=%s; b=%s;\n",r,g,b); + color_rgb [0] = atoi (r); + color_rgb [1] = atoi (g); + color_rgb [2] = atoi (b); + leds.setColorRGB(0,color_rgb [0], color_rgb [1], color_rgb [2]); + return 0; +} + +static size_t +ip_to_string (const char *name, const char *uri, char *buf, size_t bsize) +{ + #define IP(x) UIP_NTOHS(server_ipaddr.u16[x]) + return snprintf + ( buf, bsize, "%x:%x:%x:%x:%x:%x:%x:%x" + , IP(0), IP(1), IP(2), IP(3), IP(4), IP(5), IP(6), IP(7) + ); +} + +int ip_from_string (const char *name, const char *uri, const char *s) +{ + /* Returns 1 if successful, only copy valid address */ + if (uiplib_ip6addrconv (s, &tmp_addr)) { + uip_ip6addr_copy (&server_ipaddr, &tmp_addr); + return 0; + } + return -1; +} + +#pragma GCC diagnostic ignored "-Wwrite-strings" +GENERIC_RESOURCE + ( server_ip + , ip + , ipv6_address + , 1 + , ip_from_string + , ip_to_string + ); +#pragma GCC diagnostic pop + +void setup (void) +{ + // switch off the led + pinMode(led_pin, OUTPUT); + digitalWrite(led_pin, HIGH); + led_status=0; + // init chainable led + leds.init(); + leds.setColorRGB(0,color_rgb [0], color_rgb [1], color_rgb [2]); + // sensors + SENSORS_ACTIVATE(button_sensor); + // init coap resourcen + rest_init_engine (); + SERVER_NODE (&server_ipaddr); + #pragma GCC diagnostic ignored "-Wwrite-strings" + rest_activate_resource (&res_led, "s/led"); + rest_activate_resource (&res_battery, "s/battery"); + rest_activate_resource (&res_cputemp, "s/cputemp"); + rest_activate_resource(&res_event, "s/button"); + rest_activate_resource (&res_server_ip,"button/ip"); + rest_activate_resource (&res_red, "led/R"); + rest_activate_resource (&res_green, "led/G"); + rest_activate_resource (&res_blue, "led/B"); + rest_activate_resource (&res_rgb, "led/RGB"); + #pragma GCC diagnostic pop + +// mcu_sleep_set(64); +// NETSTACK_MAC.off(1); +} + +int coap_server_post(void) +{ + char buf [25]; + static coap_packet_t request [1]; /* Array: treat as pointer */ + coap_transaction_t *transaction; + static int32_t levent_counter; + + char server_resource [20] = "button"; + int buttonstate = button_sensor.value(0); + + sprintf (buf, "state=%d&event=%lu",buttonstate,levent_counter++); +// printf("post\n"); +// printf ("%s\n", buf); + coap_init_message (request, COAP_TYPE_NON, 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)); + request->mid = coap_get_mid (); + transaction = coap_new_transaction + (request->mid, &server_ipaddr, REMOTE_PORT); + transaction->packet_len = coap_serialize_message + (request, transaction->packet); + coap_send_transaction (transaction); + return 0; +} + +void button (void) +{ + /* Call the event_handler for this application-specific event. */ + res_event.trigger(); + + /* Also call the separate response example handler. */ + res_separate.resume(); + + /* Call the Coap Server */ + coap_server_post(); +} + +void loop (void) +{ + +// test chainable led +/* + static byte power=0; + for (byte i=0; i