From bf6f3886914b5e8bee9cf03ea1f567ea1c91ec98 Mon Sep 17 00:00:00 2001 From: Marcus Priesch Date: Wed, 12 Mar 2014 12:29:33 +0100 Subject: [PATCH] initial check in --- examples/osd/dual-rgbw-actor/Makefile | 93 ++++++ examples/osd/dual-rgbw-actor/README | 76 +++++ .../doc/ledStripe_board_btm.pdf | Bin 0 -> 18271 bytes .../doc/ledStripe_schematics.pdf | Bin 0 -> 42489 bytes .../osd/dual-rgbw-actor/er-example-server.c | 265 ++++++++++++++++++ examples/osd/dual-rgbw-actor/flash.sh | 2 + examples/osd/dual-rgbw-actor/project-conf.h | 99 +++++++ examples/osd/dual-rgbw-actor/run.sh | 6 + .../osd/dual-rgbw-actor/server-client.csc | 227 +++++++++++++++ examples/osd/dual-rgbw-actor/server-only.csc | 189 +++++++++++++ .../osd/dual-rgbw-actor/t4-servo-config.h | 65 +++++ .../osd/dual-rgbw-actor/t4-servo-hardware.h | 48 ++++ .../osd/dual-rgbw-actor/t4-servo-sensors.h | 78 ++++++ 13 files changed, 1148 insertions(+) create mode 100644 examples/osd/dual-rgbw-actor/Makefile create mode 100644 examples/osd/dual-rgbw-actor/README create mode 100644 examples/osd/dual-rgbw-actor/doc/ledStripe_board_btm.pdf create mode 100644 examples/osd/dual-rgbw-actor/doc/ledStripe_schematics.pdf create mode 100644 examples/osd/dual-rgbw-actor/er-example-server.c create mode 100755 examples/osd/dual-rgbw-actor/flash.sh create mode 100644 examples/osd/dual-rgbw-actor/project-conf.h create mode 100755 examples/osd/dual-rgbw-actor/run.sh create mode 100644 examples/osd/dual-rgbw-actor/server-client.csc create mode 100644 examples/osd/dual-rgbw-actor/server-only.csc create mode 100644 examples/osd/dual-rgbw-actor/t4-servo-config.h create mode 100644 examples/osd/dual-rgbw-actor/t4-servo-hardware.h create mode 100644 examples/osd/dual-rgbw-actor/t4-servo-sensors.h diff --git a/examples/osd/dual-rgbw-actor/Makefile b/examples/osd/dual-rgbw-actor/Makefile new file mode 100644 index 000000000..87efba905 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/Makefile @@ -0,0 +1,93 @@ +all: er-example-server +# use this target explicitly if requried: er-plugtest-server + +# variable for this Makefile +# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) +WITH_COAP=13 + +# for some platforms +UIP_CONF_IPV6=1 +# IPv6 make config disappeared completely +CFLAGS += -DUIP_CONF_IPV6=1 + +CONTIKI=../../.. +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + +# REST framework, requires WITH_COAP +ifeq ($(WITH_COAP), 13) +${info INFO: compiling with CoAP-13} +CFLAGS += -DWITH_COAP=13 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-13 +else ifeq ($(WITH_COAP), 12) +${info INFO: compiling with CoAP-12} +CFLAGS += -DWITH_COAP=12 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-12 +else ifeq ($(WITH_COAP), 7) +${info INFO: compiling with CoAP-08} +CFLAGS += -DWITH_COAP=7 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-07 +else ifeq ($(WITH_COAP), 3) +${info INFO: compiling with CoAP-03} +CFLAGS += -DWITH_COAP=3 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-03 +else +${info INFO: compiling with HTTP} +CFLAGS += -DWITH_HTTP +CFLAGS += -DREST=http_rest_implementation +CFLAGS += -DUIP_CONF_TCP=1 +APPS += er-http-engine +endif + +APPS += erbium + +# optional rules to get assembly +#CUSTOM_RULE_C_TO_OBJECTDIR_O = 1 +#CUSTOM_RULE_S_TO_OBJECTDIR_O = 1 + +include $(CONTIKI)/Makefile.include + +# 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 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 diff --git a/examples/osd/dual-rgbw-actor/README b/examples/osd/dual-rgbw-actor/README new file mode 100644 index 000000000..84d7dd2f4 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/README @@ -0,0 +1,76 @@ +A Quick Introduction to the Erbium (Er) REST Engine +=================================================== +Compile the Example +------------------- +./run.sh + +OSD-Merkur Board +---------------------- +write the images to the OSD-Merkur Board: + +./flash.sh + +EXAMPLE FILES +------------- +er-example-server.c: A RESTful server example showing how to use the REST layer to develop server-side applications (at the moment only CoAP is implemented for the REST Engine). +er-example-client.c: A CoAP client that polls the /actuators/toggle resource every 10 seconds and cycles through 4 resources on button press (target address is hard-coded). +er-plugtest-server.c: The server used for draft compliance testing at ETSI IoT CoAP Plugtest in Paris, France, March 2012 (configured for minimal-net). + +PRELIMINARIES +------------- +- Make sure rpl-border-router has the same stack and fits into mote memory: + You can disable RDC in border-router project-conf.h (not really required as BR keeps radio turned on). + #undef NETSTACK_CONF_RDC + #define NETSTACK_CONF_RDC nullrdc_driver +- For convenience, define the Cooja addresses in /etc/hosts + aaaa::0212:7401:0001:0101 cooja1 + aaaa::0212:7402:0002:0202 cooja2 + ... +- Get the Copper (Cu) CoAP user-agent from https://addons.mozilla.org/en-US/firefox/addon/copper-270430/ +- Optional: Save your target as default target + $ make TARGET=sky savetarget + +COOJA HOWTO +----------- +Server only: +1) $ make TARGET=cooja server-only.csc +2) Open new terminal +3) $ make connect-router-cooja +4) Start Copper and discover resources at coap://cooja2:5683/ +- Choose "Click button on Sky 2" from the context menu of mote 2 (server) after requesting /test/separate +- Do the same when observing /test/event + +With client: +1) $ make TARGET=cooja server-client.csc +2) Open new terminal +3) $ make connect-router-cooja +4) Wait until red LED toggles on mote 2 (server) +5) Choose "Click button on Sky 3" from the context menu of mote 3 (client) and watch serial output + +DETAILS +------- +Erbium currently implements draft 08 (name "er-coap-07" stems from last technical draft changes). +Central features are commented in er-example-server.c. +In general, apps/er-coap-07 supports: +* All draft 08 header options +* CON Retransmissions (note COAP_MAX_OPEN_TRANSACTIONS) +* Blockwise Transfers (note REST_MAX_CHUNK_SIZE, see er-plugtest-server.c for Block1 uploads) +* Separate Responses (no rest_set_pre_handler() required anymore, note coap_separate_accept(), _reject(), and _resume()) +* Resource Discovery +* Observing Resources (see EVENT_ and PRERIODIC_RESOURCE, note COAP_MAX_OBSERVERS) + +REST IMPLEMENTATIONS +-------------------- +The Makefile uses WITH_COAP to configure different implementations for the Erbium (Er) REST Engine. +* WITH_COAP=7 uses Erbium CoAP 08 apps/er-coap-07/. + The default port for coap-07/-08 is 5683. +* WITH_COAP=3 uses Erbium CoAP 03 apps/er-coap-03/. + The default port for coap-03 is 61616. + er-coap-03 produces some warnings, as it not fully maintained anymore. +* WITH_COAP=0 is a stub to link an Erbium HTTP engine that uses the same resource abstraction (REST.x() functions and RESOURCE macros. + +TODOs +----- +* Observe client +* Multiple If-Match ETags +* (Message deduplication) diff --git a/examples/osd/dual-rgbw-actor/doc/ledStripe_board_btm.pdf b/examples/osd/dual-rgbw-actor/doc/ledStripe_board_btm.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a54f23313adef176b876b0e0cae51c7e45211fab GIT binary patch literal 18271 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 literal 0 HcmV?d00001 diff --git a/examples/osd/dual-rgbw-actor/doc/ledStripe_schematics.pdf b/examples/osd/dual-rgbw-actor/doc/ledStripe_schematics.pdf new file mode 100644 index 0000000000000000000000000000000000000000..12556862d0feb47880d8bea0d65a74f814ce85b4 GIT binary patch literal 42489 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 z zJ%RaibbI~ixz0w;kU3|^3{Yx`#FH^E3m!b1H)F4#v(km=C}ZrIG2Yu6M|&%YCc4ZG z?+aMrC=7~+=##lyj&nD&123A!JuK8x76$3|!GniNp-T5LMDIWOzL9zFv6WkXK8K^Y%$wM!W%YBKCl+mRsUp zvcAxe*Rqywg;3U~)dVJ~1oJjh^ z*pt@7M`R25)Nvk{`?(!{u)W0+C`}8;7u~@|d(LjHXa`l#K!-<3I(vq@nlmzKSH8)M zJ3bH7wb)uM+Z_1$8S|?VW4}p^w5_?L9}2gXVS{z>zRG_UwJzk>e)b9XYrt9}Zvp;5 zMa?#OmagUGwwq{H@v56#xa)Z~{H1`*jCynNnABRyD4!AIBl zpIO}GNO`nGsxF8XoraKt=?lG)?wbQ{>dyS)GLN z&$W2aE#?{;kH3kt=$p(E+T)$?{7roVO~ms=&LaG1BDyaaStvhQu=JTdo2eEoD*VC3 z8a^O=ZN-_WyK`FfvxNdZ?N!8p@SibTi6vLjO>vPdIx zHsy$UF%D;NX=E3rMN4|jwz)>HE2;V8+x;nVHqs75vcIYPV_D9cRfW{WZ0@kIbuODa zgjmWXYyH@AVUJSEFGqEkGRfZtbo!)a=N`&d@bq1*bP2{c3xSVpHm2P8i-)JO$R=?F zI-XCR8ERT4CmCwYw05~A4_&5rz8mjUv@+Bjgt9cpyi+T1OCJC66S$r#DdXzqmMpE1 z4QH9^>Wv9C?9Rn*5e#e+9muOyHebpjc3emp$D?el0NJ)+NKD@(kivtPLQiO3y`+mvA(olT0e#ozqLKbu@ ze6vHgY%YrTr@w=%?A@}Pm7N6T;I}M!sfR;KyJ8nXlxhly%F?Fzc%l$Z+iU{Wl(<;+2=X%r2x0v5BjGE9EKabzD zZGVJLbjti=Y4eh+82yqIfsp*hokQbI1PhIQERkNVM)Xh;e7>Y>L*?=?>)<2jZ=PZ6-Q)zkCAMLUgw8;eGmQr2^#i0-84A6L(he<{BREo!DT#5+5eS=Y}qA`I1{%$w4(3O#s^p8W`$I)9TO5WhGQTh>Fj7S7D!aro4J5P}LtDVgag4Vg0-JL&laKHkp=)UHO<&8G} zipcDhfY16?efj(2p<>0Wk#qJ}?$0fHv`w_W9=Wgge;#k-A${4`Lj`H}Egs=SZi^>L ztpsz^pUHq@!qPZOe#!~oi10pU(pD$mUZo845@9w}SVla7(M@f~^wR%~@Ciy_SnrF} zA7Q%B%grCq6Do6MZY&=4P@|l;Ay1ex5{DHE74&{a ztG};*YA$)YX}JJA#%`bZ^6QXp-J%uw=HQFJctc>V7wm(sgX=67G!2GcuRWjdYGRQG zs}}dE^D61uN3i(|+)SP7)C|#hkvVMOd+RQFeHkbtV;*?WqROwx{q@yH8=gl4K5MBl z?){Hx<$q0BKib^<=-#L_LW*IS(jO`D^?7o_2)sm*o3Zsbn$maaI_m3U-Ia}@mAE5T zPkXUAFK#idE)KIC*Uo-BAycN0>=fId<@S^QJbCQ<>v-CMI!1p%>TnbNmFK*oKg9X9 zw&x|g+Ur-I7n%`rXpi;fo8Bn!7};}zVc%#)OeLMoOLId5a{qk3m!v^K^~l^=Ijb(W zBBQ}kv_wb}t?}B2*5J%j#dft#uR188oq=*`0^LAZCrMZX$*ys+e-aFvy%s~J(rJEg z?U6Y^u))V(3FroZL>y1n%7?IQJ5x@Oq_%L z7UoCaN$U+lJN;s+`!=88bc+n*WQv}>Amjcf`4|7njcVh5bb7uhlU>b7R^8W*hxd9Y zBKcJh!f(><*_e3W>VBhoc2%zWN|5UNBYl$7XGXzUk3mBtj0Mc~nJbSM*+RQI-Y0yW zvx{BHulBi6(!p;uQH84n859 z9+}9VenTRNi0cLocDSS+MD7Z1J%%xxi-Rw`gT~wOMRa09$&*WI`d|VyL)I!4Azeh~ z`dZP)%JXt(CC9oZ`Dl}2A!N!|JnP6*kRJvMK~lg6bxQc5SsegA-q4L~V5U3x8E5Rei$L#63myo@9(DcAmi@ z_0+JWTY82S2)bP5y(hvZYNjt(7Wqm61kQA%ehz)UE7X@m`&_(@1O+)N$S zfQQ?*(-Q*!TpaCl#tnI%mgJ4g91P{aj=S~K@-nG+!u5_mHy?m3TXL_Bh?T#?daAwmO)AyW=H&Ziu3sWs(M%#GX#wS0wP1HVavvzIX&L)WygRXi_ zCuOG^G&*ndHL_jATs5^^?+1Iy&-WcKD)Fl-ZPCl-lz^iHx^Kr+#AcLfOmxVdptB0iV;p)MOW`Vi z;?oWBiLUbB)ug(d$8Y{Hz{IC=rKi|BOWbIN+Ff`v^CLNmS#*ro*72Dr*rJKI!d%$m zo2)b*bBn3qlZ8DcowW)>&wYH`{pdNhoxs5IcDyW--1Vv1$oFi_4Z0}8r8mJYpWgIu zGtPY5Fn9>Og$)rGZ4u%~(j2xGOhhba!}TAz5aYkn_SNAR58Eg$EPFe!bqsa>UP_xP zmX}Uxy{tMs|9ZWcZ|x`7B(rzH*yqp8q3P}#<>Q^1T`N2Z@NUI~i1Y4wlD$ZpZaI-J z`T1!jQcS=6xeBjhP6y=Pu}8cs#C}+B9!u@vG>-nHK_knRLcE|_K!)$pRpKRkXG(3q zJV-ryMeFN#P<~OFvNZv09@oj{G;m#>ld!v%qA-lsh9J_ETg*TY{R7>GqLOpTFyp%F zlb+nL%-B=c<}PY{mwa<9*^obs4Bf9eB&wVb@=9!rk{1upc?}F|_D1x1%_=ftVa37Bl51{UlHY&iSxrT)tA+6$q(jyboP2_#RT(PTnejJ;2|AMvKlBbtUsDQ_*O!-h|udHupG5-=1yiOMk93@Yqab77T|*Hve^QCRrO+QMf3jOTSmh{lJKi$}a_ zkUq(o<`|BL>FdnrEDkvbD$7FF2R|T+SN(py2>A>7G*(}yoUYAi&u6p`v-Q-X9h%i1 zJ$F|ALc991q$FkXbK&pGQ=>0&=_zTFq!6dfKFeWT)y*L+?t6SKSOZa~+h~?L$@ELM zipBghJ#-1BR9}JzUK6>48A~x=`KwQ&zf#Iy{FJ2WlAjWvPupPH^Gz?K%uai;NP`Nl zg^OSMaRi+`LzA3KJ0XAiuc_D2ME=|AbT+y2NsKR^)hr&O)4>DNdvSU*v!8P7n5Auh zNi{=k1{0FLF6w+v5@qzJ5~O7P+Sq;dRnfYz`=xHJA!+cpr04n!JjII2h6?n0b!#Kf z(vrXDqDwIiP0+=BMW;GvBo1nQ?G#l}asAf$p6=kRAB_MymAY+ik_<_e6%F2)OAt;N z_2O1~DyQ>mdfYrB1#^dtcdh zo~X0vcm1H}73bCw#~85qXkPHQU*Rp=RZOgL~%6=)K4i4sw{5w7#L zPL9@Hs|q_nHkbQ;_cr%=mcIWb@p^H#9_xbk;PKqE(Z>fboXjpooJR^6uyOLmo}z5;s@QuIg`F8*c-CdfwDk8&vT@(L#7=Hrebvy6JUu54Pu z{#UER-6y=B{%xwyR(a0$elPLy?c#_`4f7mv2#mje8xHr44SreB4Eg(1 z`;(X#v$YA^BaO-0;!jK^A_(S}7*7Ia!!vQ^@;^Z^$&IjZ`R<3Nb_Av^lapJNXlsAv z=^QH4jK@L~nNj>zXq%#a%kVT`Gx<8Vrd`sZ{Oy${F5Y}U|3mwNtH%LY-=7sXKG5CM zXqR>hyl+xi+PLG5cjL44E06E@&4@!4wXtyd!Tk5Nn~sKo_p6Ottr^)p>YJJizr#h| zcYDbm5cuZ7FV4C8U{K5BW6SnG3ipd^JNAD?_I=ZJr`Dej-5J;M1_!;;mP zWEs_THQ$oqUOT$VJ}{Xk{H3R~Z~KX<+W)V%Gl7RX>Kgx3iL$h)R3u{^+w5a73}wxl zE!o$Zv5jqvolw~+B1^Uq5~*xi6Old3C?qK&&_5 z+;isMd+ulEGrun%Bo9w|zJ7#D&vl=O>_OkGt58wbl+SyW@^DsCUV60US(2kq)$=G3 z%an|;{)@$&mXB4zPmIOt8|^WLCc7_}*^GLgk`!VqzDA7R_nfCW|mPj2S;wcoWQ*BRNyG?_I!YO$Wa^+mhwNEXv! zZI^{Ygo17zUfjK?R2Y*$mk?zuY%Ag=wMu!{RgbFF&y!c5ab}JUH%1LdK%d#(Tdk zP3ykO7nkJ)hZ5;-!S*1R zQ$+_$FR;NJV}mEXnW&3wo_8!v1Mh9LL`9ZVxmOXB1@m90=lf!Yx_U}p>QX{7vbf8h zOlm6^9Km32@y9YP-m+yMF*G8Tp&a-iiZkYQ{aR@6;h7;5Vh#7oW>Ctd<)@j(8Ft%S zMO@!3n^BLQUoSS?=UDCYCWb~NKm{X*Lq*>DGk@6Ra;SdzWzm`g_>({ZFFn_m6V1Jo zXT8gL8hZjdEt-7~fEYTeC^q|*S)7QT!D~82A)mz-M1_VYp{`SfN(E_0;Kg2hTb;T& zV1`4{LP>Cees3{xd*)XAg@GFtQJeT_3#MxMoM*6c#E537S*}viO^?!!D3d|?kD%pL z`n}19ACbdl?6#lrxU?R0fUHzg>igSM4Ti{azE3AyV%VCY${mM2=MPw&mwTFiis;MA zxf0{in0026enPvH3lzY*pr=g%WBSG~fT;+-FY&=&_HU8R+~KuyNjlslsu-{TRAHnP zw0r}6-N1;~2G*p&_vlebFxRUsGKpFmX^2+iF0t)+D!@5$j4pz|_+*e(ucp;qp?BvV z)8A)iv8r-+SmpHRxMVO?yB%V9P;X!Dl?>dQwWT9hm|AD=KkoFOU#Y*Mmq)s?D^z-e zZFj&c#T(-tCO0a*z5s6ur5-uf#uS@YwlE1vXN*;6H^xkuLtDdCly(y0Vkr9o=vR$3wC zlp0hlMdw<(Pe#y!LS;$c)8u9o?oihPK-2Xj5Wzz3IvC( zE;e&NU+g=Oqcs|u*@zNc@Oe#_4!Ph*&L55Q^|XNA^7Xrzm1S(&}Lb$Dis zJ!~pg?0#&3N6t;QJh#9!$Km1OuUywTH<4)v1J*HTPP^3mYj&M!O@_i3SuWUxCvxTI zrDo(XuRe5?CG87WQ93ta;H=lzVTlli#z;m^K4_4Pjf*bjXdIhNmuYQL3CSMcGfi=k z@hnLnPzW%(t)P7H8>x~XB-YK6sbR5ySHkVLEJ8e8Of?1q=RXF=Na&d7)g>E02uRt~ zicdf6s>Q6vZCWXzS%mIHzg%3lO4Ealycpq`jxj$x@@|Cne0YXx!1227oS`M3pbuU= z5jR9XgLpnuxK&EkZnP};o$DUjd-egtiFqvZ2a&KF2TFJKF5(8V+IDvxfE2r<6J{BV zW6zO32z!@b+3&M(RXjhM`FW!VyZpXbJXGb=4TX!hviYte49?uN73i=E48?}z^9CnN zPg71J__#TARi~%vCXBxn>zvGWA%rsmck=(nRg@DO|8D$0V1`+bfW;lGG=l z_mfPlmhmE1^h!FEV^xgT);W2$@Ook|+XlcRorebr#R-8v_V*bM6_?0Vf=WzY5s3O> zOE@{AB%QOzhGF;NZq4N>OV2&Nr{cZhM4oSA_k0Wte4@#~^7gY{n$-iDx>;ie33dMTK5A^jMd|r5feL=tQa%=l4qmAK5K?q-Iyp;(mx+ z%Aw<426IbSsR?I{SdAH}_4dQzE?n%lN8Xv39F(oAI8Dqg3}s(J`x+<0%j5E{FL-^C zMrO8kGjHo$P;x(sE6RKwbyCh@TidP2vZ^5E36GkADAyIj^i$fiHSsJcl~}W5G4V$BNH)L}o{~u+@XJ4}+R6D~75#BRM(~lOUgtE)!2mz?%hNLl zgq(!F{(Rd0aRt4}ou;z(V{XfpUdNRqsGKV9@6HMDQ`YIn4pgLlE;lOEUiWcR{C3Q( z>6TT|e7N?MuA{kF08!$mTeMJQIPqyJL7;>Gq{}jDD5Mr~Z@SL*nS???VgDpQ4lHb0 zVEf`JTP?)0eatx*17ntna@-hbOlB{!8Bl7iT5esQ!_1`TOjIvACzY>k`mOcUib1H6 zPFyBxvz2xiUOszp@bqpM{pRzFm4SPYkUy-hDdu`7tRz#n9Ha#2tnw`_lq~Pj>FFJ&qjyJ9IKNC}- zk(VcpoYLXv1MV*<6&c#T8nNw@s;$8XxSt z#+T0{f?p`SZEosa`3tq1HI4ycjk__O(=_!PgWrK0`(s%3?vC1Zn7ccX$% zyZysiQ?4ad;hLnYs`1`^%1WqV#i0Q!D}2lXvgP3-Q{&36mX=RtSAvv+@A=IUr|86Y3U<-xhRakhA)kRr^Q7&ir;$?>?;`j`Gf~k5?|T)= z%USWe)U~ifOqqSPTFcbc?WNTL*CDPsDMVkuZMV<3G*jbpj~nRJ&37T0s|?q-7i3-7 zFtyu}{Q=8V^BN_wbvAg2`K~^L9`MxF26W-PL`&j)+C!|JF3!XW0>LW{2*s3l42Zj~NC~(;Vge(=|xK zjqx}ALL8@J9}MZG>aceeN$!0er-|FxyQhR9_REz1;*9cy&?x(x7JWP1TMxE*j!Va_ z_|>bWs(ARAyyz+0>ns_}jLbNcv+uJhOBH?P*%1p{I3`JdO218HS%gI-T0~>`{j7sSxY~Oxt`0;*Do1;D_qEblebvaAj=~4!)8OoB=*3>1vxF&KI>8;Za;ll3=Jr?@7`)SchT8 z%UIho2`%zC-jU6mIi($NEjZth$@frX2Io|_Vvi<=6{3WfbH+<~vrn~52{H)2k^9(J zee`SjBlnHLqcg{}K_)2Pb#`G^yPUiVA&#wWvD@!Jh11T2x!ZSdx~ZPT2d%IPFR(J| zYlwN`^|c-zzj{AHLq%5tF*Me7hMXQB6de1GFv!ggXFzFrbmRM?yKUapm>9y8)|kh1 zk&_#$b-@MQ(ko`-vc=wu#CR*$9)GJ3O?1NX`k%V>?42Y$j|xFfw!eT_8oqi`uJV}r zOvr|<=cr3XF_k>$n1V?Nd9vPiE&0NSFLj936)wob=TQz9Nk)?{M~QFz*Lo%*E;`As zNcjb?hKO~(yhvx7nI$6LmE@zA4nxkA6N)5R+}bX`?Lhl$y1vW}*(>#6eV1)o>Y5Fo z`9M%=MNQlFD4`7P6VUaqpLk$7^Hz)xLhTMQQ#q|NZtYP|;aHhhiaYJrlG$=N(v0FI zc}1~RX>fqD5Ur(CKUn%;qHp>x1mEbYa*?+mtpd?WDK#BEELvH8C#et2nWzw+uC8+* zs{Q8Ca_W=Byw|3^Z)N#UtPszX^p-Z6h&?2jsuxb)>fu?wakC}3*~8@9G2UeVoB5nP zX;|a>x5rrY4cd1}H#M~t2yvNSO?|z|WJU@+vAa@UyNT_VkS<+}#1!aK)K(h_F*aY-PM-WF2b%vuS&9$=x)J$Gp_nh@n<} z#qo!bnNskzz$4?AG)i%Q-m<6(J|y69fx1MIyJKA8gZu&^>-y>b6<Bcqg*a2?@Q6 zEh1}fV*>99D;Ji~Vqp?I7xwKwo5eT3#Pwd~*jLSK{t90Yy?*gTdzM?$v?_rC%_;3a z|K_$%rlb$$Y-a`{ds685R_R)VJi~#7@oU8gqk0AcCSL^(UAweBB6VZetZlEW!?&J= zx=#TR(RCY5M(w;5VOV!H3pF}U1EqoL}?ww7lY+qs)2nQnc|_z}W0& zUeR1}^)$4)efEFwYcrtp(FjB!+#FfXdu^-x5yLq;;=*)3^;5qofvI0#nP`UlaBJe! zY+Gl7j>E}~Zy!c`PJLP|4WNIsAhDLTv1B7sZyrU=&bMX1b$zP)LQ6=)UA7C^`)-97 zDWST>1Q}P|CR9sL8fpm@XCXcEqPH2KPs5kS-`{&xXh7lJ#Gz|AN2>x#2S_06~A6C;k+!u2S# z%*o3EuG&%I&Fok!U*F?K!rQs+-DlRvLMzwNe*Pmw%B8t?$dA}zQdpac`ZnyQe7Nqv zk~llm)bC))PoCfi zG~gO8@&sGEb3SB(u8*dkwU2|fBpxg)!ze9l3D9ci5Xf#IfHcAJ$m^&p z@z4ysuwITXjsVsL@^U0OxnaF<;2jq%Ak)+^Flfhw;(!AiXlQ{b&dwwUI|>L1m4qT7 z2$U#@NCr?CPiL|N2m!@_fg#CwB31|B*S-%3Ji~!)DHInh4Cd+S3H3xloyj&ZgruY- z432~$kr2QF;^yr{vGjsCx$y$=b`r5O_~qv02HnXCYVGU@vonAppm5mFKtHh@J7*^l zEwH7PvpWR`c6YbKW5p$qC~-Ie0g;dt$3qYZ0tx~LE{HfDBPnSKx3&_K6#p5{<+n8d zhzE240Z~9eX+XpRgdX1Ann0FO)=~#4+d8{ZzH?I`Nhn-g8uo_?P*%Hc9aajJMQ!Y_?bSi zNolKzfQmzZME%jVWBGqRXO=D+8vpNEb9AIt1fVx@ReqR!joy>P(#~Jp| z0RhRHwo9DJ-^bJ?xc(emMqcMH=bcWP^Dh@b#{Ym5fpq_M2wGXu%IH`8Uqk%i_HRmU zM+KZzz-qvLor5xrp#RYIpBw0(hd%&!;=rD?qy1kn&)>+}pNEv-zdNLa0Qiu$9KdAK z%2rSTORIS}0x1rcfJ^R_I~WcJ17^Un@ZVURb*I=mlLbvs;uzo|ZUUUH^0Y?hXOO=- zwP>9Rv_|QdEtw_}XpJSUq0kyvuqDlI+X2)bl=SF*KM{9QMoM_UH9fBr7Y0XY5 zI}#j7<>!ej2*?2PX-}}G&_q4jhW{gZ63urf5S}LK(wd!wcH-`YbophnGyG02)-;{1 zkc`X^n%av@ATq*12s9(0|8apZVqz#U5E1lUhs2;T0G~;_Ku$k&XaoiWVAOx;06RFa zvVZ9iVgRE0hYomx0C?~}bVv*W1;D?5>crvVfBPaa5-0$f{mTx41{m)@br>`f;Nbt% ziKEbezYZh@jrltlG#rll&5lC01ejGaqqH;#rfcT|K*negK*&1-R5}e}1;JFDh|ZuL z@R$*%q5v|MmXH$@S3&{%Qvs=f7FWP1O2{J>(Qx1gj+BstE6V)$7N#`d-Hl>NrtB;b Q8VMH@W8~*oJg>y~U*>v{5dZ)H literal 0 HcmV?d00001 diff --git a/examples/osd/dual-rgbw-actor/er-example-server.c b/examples/osd/dual-rgbw-actor/er-example-server.c new file mode 100644 index 000000000..9fb587974 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/er-example-server.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2011-2014, Matthias Kovatsch and other contributors. + * 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 + * Erbium (Er) Dual RGBW Led REST Engine example (with CoAP-specific code) + * \author + * Matthias Kovatsch + * Harald Pichler + * Marcus Priesch + */ + +#include +#include +#include +#include "contiki.h" +#include "contiki-net.h" +#include "erbium.h" + +#include "dev/t4-servo-sensor.h" + +/* For CoAP-specific example: not required for normal RESTful Web service. */ +#if WITH_COAP == 3 +#include "er-coap-03.h" +#elif WITH_COAP == 7 +#include "er-coap-07.h" +#elif WITH_COAP == 12 +#include "er-coap-12.h" +#elif WITH_COAP == 13 +#include "er-coap-13.h" +#else +#warning "Erbium example without CoAP-specifc functionality" +#endif /* CoAP-specific example */ + +#define DEBUG 1 +#if DEBUG +#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 + +/******************************************************************************/ +/* + * Resources are defined by the RESOURCE macro. + * Signature: resource name, the RESTful methods it handles, and its URI path (omitting the leading slash). + */ +RESOURCE(info, METHOD_GET, "info", "title=\"Info\";rt=\"text\""); + +/* + * A handler function named [resource name]_handler must be implemented for each RESOURCE. + * A buffer for the response payload is provided through the buffer pointer. Simple resources can ignore + * preferred_size and offset, but must respect the REST_MAX_CHUNK_SIZE limit for the buffer. + * If a smaller block size is requested for CoAP, the REST framework automatically splits the data. + */ +void +info_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + char message[100]; + int index = 0; + int length = 0; /* |<-------->| */ + + /* Some data that has the length up to REST_MAX_CHUNK_SIZE. For more, see the chunk resource. */ + // jSON Format + index += sprintf(message + index,"{\n \"Version\" : \"V1.0pre1\",\n"); + index += sprintf(message + index," \"name\" : \"Dual RGBW Led Actor\"\n"); + index += sprintf(message + index,"}\n"); + + length = strlen(message); + memcpy(buffer, message,length ); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); +} + +RESOURCE(t4_servo, METHOD_GET | METHOD_PUT , "a/dual_rgbw_led", "title=\"Dual RGBW Led Actor\";rt=\"dual_rgbw_led\""); +void +t4_servo_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int success = 1; + + char temp[100]; + int index = 0; + int length = 0; + const char *value = NULL; + size_t len = 0; + + int r1 = t4_servo_sensor.value(0); + int g1 = t4_servo_sensor.value(1); + int b1 = t4_servo_sensor.value(2); + int w1 = t4_servo_sensor.value(3); + int r2 = t4_servo_sensor.value(4); + int g2 = t4_servo_sensor.value(5); + int b2 = t4_servo_sensor.value(6); + int w2 = t4_servo_sensor.value(7); + + switch(REST.get_method_type(request)){ + case METHOD_GET: + // jSON Format + index += sprintf(temp + index,"{\"r1\":%d,", r1); + index += sprintf(temp + index, "\"g1\":%d,", g1); + index += sprintf(temp + index, "\"b1\":%d,", b1); + index += sprintf(temp + index, "\"w1\":%d,", w1); + index += sprintf(temp + index, "\"r2\":%d,", r2); + index += sprintf(temp + index, "\"g2\":%d,", g2); + index += sprintf(temp + index, "\"b2\":%d,", b2); + index += sprintf(temp + index, "\"w2\":%d,", w2); + index += sprintf(temp + index,"}\n"); + + length = strlen(temp); + memcpy(buffer, temp, length); + + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + REST.set_response_payload(response, buffer, length); + + break; + + case METHOD_POST: + success = 0; + break; + + case METHOD_PUT: + // Note that we have to set all at once: + // red=255&green=255&blue=255&white=255 + // otherwise we get "bad request" + if (success && (len=REST.get_post_variable(request, "r1", &value))) { + t4_servo_sensor.configure(0,(unsigned char) atoi(value)); + } else { + success = 0; + } + + if (success && (len=REST.get_post_variable(request, "g1", &value))) { + t4_servo_sensor.configure(1,(unsigned char) atoi(value)); + } else { + success = 0; + } + + if (success && (len=REST.get_post_variable(request, "b1", &value))) { + t4_servo_sensor.configure(2,(unsigned char) atoi(value)); + } else { + success = 0; + } + + if (success && (len=REST.get_post_variable(request, "w1", &value))) { + t4_servo_sensor.configure(3,(unsigned char) atoi(value)); + } else { + success = 0; + } + + if (success && (len=REST.get_post_variable(request, "r2", &value))) + { + t4_servo_sensor.configure(4,(unsigned char) atoi(value)); + } else { + success = 0; + } + + if (success && (len=REST.get_post_variable(request, "g2", &value))) { + t4_servo_sensor.configure(5,(unsigned char) atoi(value)); + } else { + success = 0; + } + + if (success && (len=REST.get_post_variable(request, "b2", &value))) { + t4_servo_sensor.configure(6,(unsigned char) atoi(value)); + } else { + success = 0; + } + + if (success && (len=REST.get_post_variable(request, "w2", &value))) { + t4_servo_sensor.configure(7,(unsigned char) atoi(value)); + } else { + success = 0; + } + break; + + default: + success = 0; + } + + if (!success) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + } +} + +void +hw_init() +{ +} + +PROCESS(rest_server_example, "Erbium Example Server"); + +AUTOSTART_PROCESSES(&rest_server_example, &sensors_process); + +PROCESS_THREAD(rest_server_example, ev, data) +{ + PROCESS_BEGIN(); + PRINTF("Starting Erbium Example Server\n"); + +#ifdef RF_CHANNEL + PRINTF("RF channel: %u\n", RF_CHANNEL); +#endif +#ifdef IEEE802154_PANID + PRINTF("PAN ID: 0x%04X\n", IEEE802154_PANID); +#endif + + PRINTF("uIP buffer: %u\n", UIP_BUFSIZE); + PRINTF("LL header: %u\n", UIP_LLH_LEN); + PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN); + PRINTF("REST max chunk: %u\n", REST_MAX_CHUNK_SIZE); + +/* if static routes are used rather than RPL */ +#if !UIP_CONF_IPV6_RPL && !defined (CONTIKI_TARGET_MINIMAL_NET) && !defined (CONTIKI_TARGET_NATIVE) + set_global_address(); + configure_routing(); +#endif + + /* Initialize the OSD Hardware. */ + hw_init(); + /* Initialize the REST engine. */ + rest_init_engine(); + + /* Activate the application-specific resources. */ + rest_activate_resource(&resource_info); + + SENSORS_ACTIVATE(t4_servo_sensor); + rest_activate_resource(&resource_t4_servo); + + /* Define application-specific events here. */ + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} diff --git a/examples/osd/dual-rgbw-actor/flash.sh b/examples/osd/dual-rgbw-actor/flash.sh new file mode 100755 index 000000000..060c0bb39 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +avrdude -V -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U flash:w:er-example-server.osd-merkur.hex:a -U eeprom:w:er-example-server.osd-merkur.eep:a diff --git a/examples/osd/dual-rgbw-actor/project-conf.h b/examples/osd/dual-rgbw-actor/project-conf.h new file mode 100644 index 000000000..b5ef8c215 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/project-conf.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2010-2014, 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 SICSLOWPAN_CONF_FRAG 1 + +/* Dont allow MCU sleeping between channel checks */ +#undef RDC_CONF_MCU_SLEEP +#define RDC_CONF_MCU_SLEEP 0 + +/* 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 512 + + +/* 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 +*/ + +/* 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 +*/ +#endif /* PROJECT_ERBIUM_CONF_H_ */ diff --git a/examples/osd/dual-rgbw-actor/run.sh b/examples/osd/dual-rgbw-actor/run.sh new file mode 100755 index 000000000..b2cd87d5e --- /dev/null +++ b/examples/osd/dual-rgbw-actor/run.sh @@ -0,0 +1,6 @@ +#!/bin/bash +#make clean TARGET=osd-merkur +make -j TARGET=osd-merkur +#avr-size -C --mcu=MCU=atmega128rfa1 er-example-server.osd-merkur +avr-objcopy -j .text -j .data -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.hex +avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex er-example-server.osd-merkur er-example-server.osd-merkur.eep diff --git a/examples/osd/dual-rgbw-actor/server-client.csc b/examples/osd/dual-rgbw-actor/server-client.csc new file mode 100644 index 000000000..8c45fdf02 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/server-client.csc @@ -0,0 +1,227 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + client + Erbium Client + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.c + make er-example-client.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-client.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 46.57186415376375 + 40.35946215910942 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + + se.sics.cooja.interfaces.Position + 18.638049428485125 + 47.55034515769599 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 3 + + client + + + + se.sics.cooja.plugins.SimControl + 259 + 0 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 3.61568947862321 0.0 0.0 3.61568947862321 15.610600779367 -85.92728269158351 + + 300 + 2 + 178 + 261 + 1 + + + se.sics.cooja.plugins.LogListener + + + + + 762 + 3 + 491 + 2 + 182 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 4 + 74 + 578 + 18 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + 2 + + + + + 125 + 25.49079397896416 + + 1624 + 5 + 252 + 6 + 712 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 2 + + Serial port + 0,0 + + 853 + 1 + 491 + 765 + 182 + + + diff --git a/examples/osd/dual-rgbw-actor/server-only.csc b/examples/osd/dual-rgbw-actor/server-only.csc new file mode 100644 index 000000000..d5eee34d6 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/server-only.csc @@ -0,0 +1,189 @@ + + + [CONTIKI_DIR]/tools/cooja/apps/mrm + [CONTIKI_DIR]/tools/cooja/apps/mspsim + [CONTIKI_DIR]/tools/cooja/apps/avrora + [CONTIKI_DIR]/tools/cooja/apps/serial_socket + [CONTIKI_DIR]/tools/cooja/apps/collect-view + + REST with RPL router + -2147483648 + 123456 + 1000000 + + se.sics.cooja.radiomediums.UDGM + 50.0 + 50.0 + 1.0 + 1.0 + + + 40000 + + + se.sics.cooja.mspmote.SkyMoteType + rplroot + Sky RPL Root + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.sky TARGET=sky + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + se.sics.cooja.mspmote.SkyMoteType + server + Erbium Server + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.c + make er-example-server.sky TARGET=sky + [CONTIKI_DIR]/examples/er-rest-example/er-example-server.sky + se.sics.cooja.interfaces.Position + se.sics.cooja.interfaces.RimeAddress + se.sics.cooja.interfaces.IPAddress + se.sics.cooja.interfaces.Mote2MoteRelations + se.sics.cooja.interfaces.MoteAttributes + se.sics.cooja.mspmote.interfaces.MspClock + se.sics.cooja.mspmote.interfaces.MspMoteID + se.sics.cooja.mspmote.interfaces.SkyButton + se.sics.cooja.mspmote.interfaces.SkyFlash + se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem + se.sics.cooja.mspmote.interfaces.SkyByteRadio + se.sics.cooja.mspmote.interfaces.MspSerial + se.sics.cooja.mspmote.interfaces.SkyLED + se.sics.cooja.mspmote.interfaces.MspDebugOutput + se.sics.cooja.mspmote.interfaces.SkyTemperature + + + + + se.sics.cooja.interfaces.Position + 33.260163187353555 + 30.643217359962595 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 1 + + rplroot + + + + + se.sics.cooja.interfaces.Position + 35.100895239785295 + 39.70574552287428 + 0.0 + + + se.sics.cooja.mspmote.interfaces.MspMoteID + 2 + + server + + + + se.sics.cooja.plugins.SimControl + 259 + 5 + 179 + 0 + 0 + + + se.sics.cooja.plugins.Visualizer + + se.sics.cooja.plugins.skins.IDVisualizerSkin + se.sics.cooja.plugins.skins.UDGMVisualizerSkin + se.sics.cooja.plugins.skins.MoteTypeVisualizerSkin + se.sics.cooja.plugins.skins.AttributeVisualizerSkin + se.sics.cooja.plugins.skins.LEDVisualizerSkin + se.sics.cooja.plugins.skins.AddressVisualizerSkin + 7.9849281638410705 0.0 0.0 7.9849281638410705 -133.27812697619663 -225.04752569190535 + + 300 + 4 + 175 + 263 + 3 + + + se.sics.cooja.plugins.LogListener + + + + + 560 + 1 + 326 + 1 + 293 + + + se.sics.cooja.plugins.RadioLogger + + 150 + + + 451 + -1 + 305 + 73 + 140 + true + + + SerialSocketServer + 0 + 422 + 2 + 74 + 39 + 199 + + + se.sics.cooja.plugins.TimeLine + + 0 + 1 + + + + + 125 + 25.49079397896416 + + 1624 + 3 + 252 + 4 + 622 + + + se.sics.cooja.plugins.MoteInterfaceViewer + 1 + + Serial port + 0,0 + + 702 + 0 + 646 + 564 + 2 + + + diff --git a/examples/osd/dual-rgbw-actor/t4-servo-config.h b/examples/osd/dual-rgbw-actor/t4-servo-config.h new file mode 100644 index 000000000..1c5ee8b26 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/t4-servo-config.h @@ -0,0 +1,65 @@ +// Copyright (C) 2014 Marcus Priesch, All rights reserved +// In Prandnern 31, A--2122 Riedenthal, Austria. office@priesch.co.at +// **************************************************************************** +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// **************************************************************************** +// +//++ +// Name +// t4-servo-config +// +// Purpose +// configuration for t4-servo +// +// Revision Dates +// 10-Mar-2014 (MPR) Creation +// ««revision-date»»··· +//-- + +#include + +#ifndef __T4_SERVO_CONFIG_H__ +#define __T4_SERVO_CONFIG_H__ 1 + +// timing: (X:pwm, _:zero) +// +// X_______________XXXXXXXXXXXXX_______________XXXXXXXXXXXXX +// +// |<------------->|<--------->|<------------->|<--------->| ... +// SERVO_OFFSET SERVO_MAX SERVO_OFFSET SERVO_MAX +// +// within SERVO_MAX you get the PWM set with servo_set (id, pwm) +// if you set SERVO_OFFSET to zero, you get a pwm from 0 to 100% duty cycle +// +// the period of the smallest tick is derived from the timer4 prescaler +// plus the ISR overhead. however, the latter one should be constant +// regardless of the pwm signal generated + +#define SERVO_OFFSET 0 +#define SERVO_MIN 0 +#define SERVO_MAX 64 + +// Counter value for timer 4 without any prescaler for a single tick +#define PWMFREQ 200 + +#define T4_VALUE F_CPU/SERVO_MAX/PWMFREQ + +#define SERVO_COUNT 8 + +#define T4_SENSOR_NAME "Dual RGBW Led" + +#endif + + diff --git a/examples/osd/dual-rgbw-actor/t4-servo-hardware.h b/examples/osd/dual-rgbw-actor/t4-servo-hardware.h new file mode 100644 index 000000000..98d3c01d7 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/t4-servo-hardware.h @@ -0,0 +1,48 @@ +// Copyright (C) 2014 Marcus Priesch, All rights reserved +// In Prandnern 31, A--2122 Riedenthal, Austria. office@priesch.co.at +// **************************************************************************** +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// **************************************************************************** +// +//++ +// Name +// t4-servo-hardware +// +// Purpose +// configuration for t4-servo +// +// Revision Dates +// 10-Mar-2014 (MPR) Creation +// ««revision-date»»··· +//-- + +#include + +#ifndef __T4_SERVO_HARDWARE_H__ +#define __T4_SERVO_HARDWARE_H__ 1 + +static servo_channel_type servo_channels [] = +{ /* PORTx, DDRx, PINxn, PWM */ + {0x05, 0x04, PINB7, 0} // r +, {0x0E, 0x0D, PINE2, 0} // g +, {0x05, 0x04, PINB6, 0} // b +, {0x05, 0x04, PINB5, 0} // w +, {0x05, 0x04, PINB1, 0} // r +, {0x05, 0x04, PINB0, 0} // g +, {0x05, 0x04, PINB2, 0} // b +, {0x05, 0x04, PINB3, 0} // w +}; + +#endif diff --git a/examples/osd/dual-rgbw-actor/t4-servo-sensors.h b/examples/osd/dual-rgbw-actor/t4-servo-sensors.h new file mode 100644 index 000000000..b07b5a677 --- /dev/null +++ b/examples/osd/dual-rgbw-actor/t4-servo-sensors.h @@ -0,0 +1,78 @@ +//os_fname_map// t4-servo-config:h:h +// Copyright (C) 2014 Marcus Priesch, All rights reserved +// In Prandnern 31, A--2122 Riedenthal, Austria. office@priesch.co.at +// **************************************************************************** +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// **************************************************************************** +// +//++ +// Name +// t4-servo-config +// +// Purpose +// configuration for t4-servo +// +// Revision Dates +// 10-Mar-2014 (MPR) Creation +// ««revision-date»»··· +//-- + +#include + +#ifndef __T4_SERVO_CONFIG_H__ +#define __T4_SERVO_CONFIG_H__ 1 + +// timing: (X:pwm, _:zero) +// +// X_______________XXXXXXXXXXXXX_______________XXXXXXXXXXXXX +// +// |<------------->|<--------->|<------------->|<--------->| ... +// SERVO_OFFSET SERVO_MAX SERVO_OFFSET SERVO_MAX +// +// within SERVO_MAX you get the PWM set with servo_set (id, pwm) +// if you set SERVO_OFFSET to zero, you get a pwm from 0 to 100% duty cycle +// +// the period of the smallest tick is derived from the timer4 prescaler +// plus the ISR overhead. however, the latter one should be constant +// regardless of the pwm signal generated + +#define SERVO_OFFSET 0 +#define SERVO_MIN 0 +#define SERVO_MAX 255 + +// Counter value for timer 4 without any prescaler for a single tick +#define PWMFREQ 500 +#define T4_VALUE F_CPU/SERVO_MAX/PWMFREQ + +#define SERVO_COUNT 8 + +#define T4_SENSOR_NAME "Dual RGBW Led" + +#ifndef servo_channels_defined +#define servo_channels_defined +static servo_channel_type servo_channels [SERVO_COUNT] = +{ {0x0E, 0x0D, PINE2, 0} +, {0x0B, 0x0D, PINB7, 0} +, {0x0B, 0x0D, PINB6, 0} +, {0x0B, 0x0D, PINB5, 0} +, {0x0B, 0x0D, PINB0, 0} +, {0x0B, 0x0D, PINB1, 0} +, {0x0B, 0x0D, PINB2, 0} +, {0x0B, 0x0D, PINB3, 0} +}; +#endif +#endif + +