From c7e7044c767446146d50dfa739e6cb453f9d0c25 Mon Sep 17 00:00:00 2001 From: elopes Date: Tue, 20 Feb 2018 22:58:31 +0100 Subject: [PATCH] put all files --- RIOT/drivers/include/robotcar.h | 2 +- RIOT/drivers/robotcar/robotcar.c | 28 +++++++++++----------------- RIOT/examples/network_app_rtt_1/Makefile | 67 ------------------------------------------------------------------- RIOT/examples/network_app_rtt_1/main.c | 343 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- RIOT/examples/network_app_rtt_1/udp.c | 174 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ RIOT/examples/network_app_sntp/Makefile | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RIOT/examples/network_app_sntp/main.c | 343 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RIOT/examples/network_app_sntp/udp.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RIOT/examples/robot_app_dynamic/main.c | 38 +++++++++++++++++++++++++------------- RIOT/examples/robot_app_dynamic/motor.c | 5 +++-- 10 files changed, 624 insertions(+), 617 deletions(-) delete mode 100755 RIOT/examples/network_app_rtt_1/Makefile delete mode 100755 RIOT/examples/network_app_rtt_1/main.c delete mode 100755 RIOT/examples/network_app_rtt_1/udp.c create mode 100755 RIOT/examples/network_app_sntp/Makefile create mode 100755 RIOT/examples/network_app_sntp/main.c create mode 100755 RIOT/examples/network_app_sntp/udp.c diff --git a/RIOT/drivers/include/robotcar.h b/RIOT/drivers/include/robotcar.h index afec485..100ee67 100644 --- a/RIOT/drivers/include/robotcar.h +++ b/RIOT/drivers/include/robotcar.h @@ -10,7 +10,7 @@ extern "C" { #endif #define WHEEL_DIAM 65 //mm -#define STEP_COUNT 20 +#define STEP_COUNT 19 typedef struct { pwm_t device; /**< the PWM device driving the robot */ diff --git a/RIOT/drivers/robotcar/robotcar.c b/RIOT/drivers/robotcar/robotcar.c index d434815..eecc604 100644 --- a/RIOT/drivers/robotcar/robotcar.c +++ b/RIOT/drivers/robotcar/robotcar.c @@ -74,7 +74,7 @@ void robot_rev( robot_t *dev, uint16_t speed){ void robot_drive( robot_t *dev, uint16_t speed, int direction){ gpio_set(dev->stby); - if(direction > 0) robot_fw(dev,speed); + if(direction < 0) robot_fw(dev,speed); else robot_rev(dev,speed); } @@ -84,12 +84,13 @@ void robot_stop(robot_t *dev1, robot_t *dev2){ gpio_clear(dev1->in2); gpio_clear(dev2->in1); gpio_clear(dev2->in2); + dev1->counter = 0; + dev2->counter = 0; } void robot_move_forward( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps){ - dev1->counter = 0; - dev2->counter = 0; + while((steps > dev1->counter)&&(steps > dev2->counter)) { @@ -98,15 +99,13 @@ void robot_move_forward( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps } robot_stop(dev1,dev2); - dev1->counter = 0; - dev2->counter = 0; + } void robot_move_reverse( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps){ - dev1->counter = 0; - dev2->counter = 0; + while((steps > dev1->counter)&&(steps > dev2->counter)) { @@ -116,14 +115,12 @@ void robot_move_reverse( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps } robot_stop(dev2,dev1); - dev1->counter = 0; - dev2->counter = 0; + } void robot_spin_right( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps){ - dev1->counter = 0; - dev2->counter = 0; + while((steps > dev1->counter)&&(steps > dev2->counter)) { @@ -133,14 +130,12 @@ void robot_spin_right( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps){ } robot_stop(dev1,dev2); - dev1->counter = 0; - dev2->counter = 0; + } void robot_spin_left( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps){ - dev1->counter = 0; - dev2->counter = 0; + while((steps > dev1->counter)&&(steps > dev2->counter)) { @@ -150,6 +145,5 @@ void robot_spin_left( robot_t *dev1, robot_t *dev2, uint16_t speed,int steps){ } robot_stop(dev1,dev2); - dev1->counter = 0; - dev2->counter = 0; + } diff --git a/RIOT/examples/network_app_rtt_1/Makefile b/RIOT/examples/network_app_rtt_1/Makefile deleted file mode 100755 index a5011f6..0000000 --- a/RIOT/examples/network_app_rtt_1/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# name of your application -APPLICATION = network_app_rtt - -# If no BOARD is found in the environment, use this default: -BOARD ?= stm32f4discovery - -# This has to be the absolute path to the RIOT base directory: -RIOTBASE ?= $(CURDIR)/../.. - -BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \ - nrf6310 nucleo-f103 nucleo-f334 pca10000 pca10005 spark-core \ - stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \ - yunjia-nrf51822 z1 nucleo-f072 nucleo-f030 nucleo-f070 \ - microbit calliope-mini - -# Include packages that pull up and auto-init the link layer. -USEMODULE += gnrc_sock_udp -USEMODULE += sntp -# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present -USEMODULE += gnrc_netdev_default -USEMODULE += auto_init_gnrc_netif -# Specify the mandatory networking modules for IPv6 and UDP -USEMODULE += gnrc_ipv6_router_default -USEMODULE += gnrc_udp -# This application dumps received packets to STDIO using the pktdump module -#USEMODULE += gnrc_pktdump -# Additional networking modules that can be dropped if not needed -USEMODULE += gnrc_icmpv6_echo -# Add a routing protocol -USEMODULE += gnrc_rpl -# Add also the shell, some shell commands -USEMODULE += shell -USEMODULE += shell_commands -USEMODULE += ps -USEMODULE += netstats_l2 -USEMODULE += netstats_ipv6 -USEMODULE += netstats_rpl -#include our RF module -USEMODULE += at86rf231 -# Comment this out to disable code in RIOT that does safety checking -# which is not needed in a production environment but helps in the -# development process: -CFLAGS += -DDEVELHELP -USEMODULE += printf_float - -# Comment this out to join RPL DODAGs even if DIOs do not contain -# DODAG Configuration Options (see the doc for more info) -# CFLAGS += -DGNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN - -# Change this to 0 show compiler invocation lines by default: -QUIET ?= 1 - -include $(RIOTBASE)/Makefile.include - -# Set a custom channel if needed -ifneq (,$(filter cc110x,$(USEMODULE))) # radio is cc110x sub-GHz - DEFAULT_CHANNEL ?= 0 - CFLAGS += -DCC110X_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL) -else - ifneq (,$(filter at86rf212b,$(USEMODULE))) # radio is IEEE 802.15.4 sub-GHz - DEFAULT_CHANNEL ?= 5 - FLAGS += -DIEEE802154_DEFAULT_SUBGHZ_CHANNEL=$(DEFAULT_CHANNEL) - else # radio is IEEE 802.15.4 2.4 GHz - DEFAULT_CHANNEL ?= 26 - CFLAGS += -DIEEE802154_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL) - endif -endif diff --git a/RIOT/examples/network_app_rtt_1/main.c b/RIOT/examples/network_app_rtt_1/main.c deleted file mode 100755 index e2041f2..0000000 --- a/RIOT/examples/network_app_rtt_1/main.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2015 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup examples - * @{ - * - * @file - * @brief Example application for demonstrating the RIOT network stack - * - * @author Hauke Petersen - * - * @} - */ -#include -#include -#include -#include -#include -#include -#include - -#include "board.h" -#include "periph_conf.h" -#include "periph/gpio.h" -#include "net/sock/udp.h" -#include "net/gnrc/ipv6.h" -#include "net/af.h" -#include "net/sixlowpan.h" -#include "net/gnrc/pktdump.h" -#include "shell.h" -#include "shell_commands.h" -#include "msg.h" -#include "thread.h" -#include "sched.h" -#include "kernel_types.h" -#include "net/netstats.h" -#include "net/ipv6/addr.h" -#include "periph/timer.h" -#include "net/gnrc/ipv6/netif.h" -#include "net/gnrc/netif.h" -#include "net/gnrc/netapi.h" -#include "net/netopt.h" -#include "net/gnrc/pkt.h" -#include "net/gnrc/pktbuf.h" -#include "net/gnrc/netif/hdr.h" -#include "net/gnrc/sixlowpan/netif.h" -#include "net/fib.h" -#include "net/gnrc/udp.h" -#include "periph/pwm.h" -#include "od.h" -#include "net/sntp.h" -#include "net/ntp_packet.h" -#ifdef MODULE_SCHEDSTATISTICS -#include "xtimer.h" -#endif - -#ifdef MODULE_TLSF -#include "tlsf.h" -#endif - -#define MAIN_QUEUE_SIZE (8) -/** - * @brief The maximal expected link layer address length in byte - */ -#define MAX_ADDR_LEN (8U) - -/** - * @brief The default IPv6 prefix length if not specified. - */ -#define SC_NETIF_IPV6_DEFAULT_PREFIX_LEN (64) - -#define _STACKSIZE (THREAD_STACKSIZE_DEFAULT + THREAD_EXTRA_STACKSIZE_PRINTF) -#define MSG_TYPE_ISR (0x3456) - -#define MAXPAC 100 -#define MAXLEN 1024 -#define ECHOLEN 1 - -//addr ipv6 link local node 1: fe80::1210:642c:1432:1702 -uint8_t node1[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x64,0x2c,0x14,0x32,0x17,0x02}; -// addr ipv6 link local node 2: fe80::1210:6432:140f:1732 -//uint8_t node2[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x64,0x32,0x14,0x0f,0x17,0x32}; -//addr ipv6 link local node 3: fe80::1210:642d:1439:1736 -uint8_t node3[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x64,0x2d,0x14,0x39,0x17,0x36}; - - -char sock_server_stack[THREAD_STACKSIZE_MAIN]; -char sock_client_stack[THREAD_STACKSIZE_MAIN]; -char sock_time_server_stack[THREAD_STACKSIZE_MAIN]; - -kernel_pid_t server, client,time_server; - -sock_udp_ep_t local = SOCK_IPV6_EP_ANY; -sock_udp_t sock; - -sock_udp_ep_t local_ntp = SOCK_IPV6_EP_ANY; -sock_udp_t sock_ntp; -static ntp_packet_t sntp_packet; - -void *sock_time_server_thread(void *arg) -{ - (void) arg; - local_ntp.port = NTP_PORT; - - if (sock_udp_create(&sock_ntp, &local_ntp, NULL, 0) < 0) { - puts("Error creating UDP sock"); - return NULL; - } - - while (1) { - sock_udp_ep_t remote; - ssize_t res; - - if ((res = sock_udp_recv(&sock_ntp,&sntp_packet, sizeof(sntp_packet), SOCK_NO_TIMEOUT, - &remote)) >= 0) { - sntp_packet.receive.seconds=byteorder_htonl( xtimer_now_usec()); - sntp_packet.origin.seconds=sntp_packet.transmit.seconds; - sntp_packet.transmit.seconds=byteorder_htonl( xtimer_now_usec()); - - if (sock_udp_send(&sock_ntp, &sntp_packet, sizeof(sntp_packet), &remote) < 0) { - puts("Error sending reply"); - } - } - } - return NULL; -} - - -typedef struct list { - uint32_t send_time; - char packet[MAXLEN]; -}Data; - -// calculate the time diff between start and end (in us) -uint32_t delay(uint32_t send_time, uint32_t recv_time) -{ - return(recv_time-send_time); -} - -// calculate the min/max/average value from an array -void rttd(float t[], int size, uint32_t time) -{ - float avg; - float min = t[0]; - float max = 0.0; - float sum=0.0; - int i; - - for(i=0; i< size; i++){ - sum += t[i]; - if(t[i] > max) {max = t[i];} - if(t[i] < min) {min = t[i];} - } - avg = sum/(float)size; - if(size!=0)printf("Round-trip delay: min/avg/max = %f/%f/%f ms, time = %f s\n",min*1000,avg*1000,max*1000,(float)time/1000000); -} - - -void *sock_server_thread(void *arg) -{ - (void) arg; - local.port = 1234; - Data buf; - int64_t offset = 0; - int deadline; - - sock_udp_ep_t server = { .port = NTP_PORT, .family = AF_INET6 }; - ipv6_addr_from_str((ipv6_addr_t *)&server.addr, "baad:a555::1702"); - - if (sock_udp_create(&sock, &local, NULL, 0) < 0) - { - puts("Error creating UDP sock"); - return NULL; - } - - if (sntp_sync(&server, SOCK_NO_TIMEOUT) < 0) { - puts("Error in synchronization"); - return NULL; - } - offset = sntp_get_offset(); - printf("offset: %i \n",(int)offset); - - while (1) - { - sock_udp_ep_t remote; - size_t res; - - if ((res = sock_udp_recv(&sock,&buf, sizeof(buf),SOCK_NO_TIMEOUT ,&remote)) < 0) - { - puts("Can't receive datagram\n"); - } - deadline = xtimer_now_usec() + offset - buf.send_time; - printf("tps de transmission : %i\n",deadline); - - //puts("Got a UDP datagram\n"); - //send ack - if (sock_udp_send(&sock,&buf,sizeof(buf), &remote) != res) - { - puts("Error sending reply"); - } - - - } - return NULL; -} - -void *sock_client_thread(void *arg) -{ - (void) arg; - ssize_t res; - Data data; - Data data2; - //int i; - //uint32_t timebuf; - sock_udp_ep_t remote = { .family = AF_INET6 }; - - remote.port = 1234; - remote.addr.ipv6[0] = 0xba; - remote.addr.ipv6[1] = 0xad; - remote.addr.ipv6[2] = 0xa5; - remote.addr.ipv6[3] = 0x55; - remote.addr.ipv6[14] = 0x17; - remote.addr.ipv6[15] = 0x36; - - /* fill up the echo message - for (i = 0; i < ECHOLEN; i++) { - - data.donnees[i] = 'e'; - }*/ - - for (;;) - { - - - data.send_time = xtimer_now_usec(); - //test=xtimer_now_usec(); - printf("Heure server: %" PRIu32 "\n",data.heure_actuelle); - if (sock_udp_send(&sock,&data,sizeof(data), &remote) < 0) - { - puts("Error sending message"); - } - if ((res = sock_udp_recv(&sock,&data2,sizeof(data2),1 * US_PER_SEC,NULL)) < 0) - { - if (res == -ETIMEDOUT) - { - puts("Timedout"); - } - else - { - puts("Error receiving message"); - } - } - else{ - //end = xtimer_now_usec(); - //timebuf = delay(test,end); - // printf("latency: %" PRIu32 "\n",timebuf); - //printf("heure reception: %" PRIu32 "\n",end); - xtimer_sleep(1); - - } - - } - return NULL; -} - -static void init_interface(void) -{ - kernel_pid_t ifs[GNRC_NETIF_NUMOF]; - ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED; - ipv6_addr_t tmp_addr= IPV6_ADDR_UNSPECIFIED; - uint8_t hwaddr[MAX_ADDR_LEN]; - int res; - - gnrc_netif_get(ifs); - - //addresses gobales - addr.u8[0] = 0xba; - addr.u8[1] = 0xad; - addr.u8[2] = 0xa5; - addr.u8[3] = 0x55; - - res = gnrc_netapi_get(ifs[0], NETOPT_ADDRESS, 0, hwaddr, sizeof(hwaddr)); - - if (res >= 0) { - addr.u8[14] = *hwaddr; - addr.u8[15] = *(hwaddr+1); - } - memcpy(tmp_addr.u8,addr.u8,IPV6_ADDR_BIT_LEN); - - gnrc_ipv6_netif_add_addr(ifs[0], &addr, 64, GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST); - - /* model ipv6 addr: baad:a555::Hwaddr */ - if((addr.u8[14]==0x17)&&(addr.u8[15]==0x02)) - { - - tmp_addr.u8[14] = 0x17; - tmp_addr.u8[15] = 0x36; - fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node3, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); - client=thread_create(sock_client_stack,sizeof(sock_client_stack),8,THREAD_CREATE_STACKTEST,sock_client_thread,NULL,"sock_client_thread"); - time_server=thread_create(sock_time_server_stack,sizeof(sock_time_server_stack),6,THREAD_CREATE_STACKTEST,sock_time_server_thread,NULL,"sock_time_server_thread"); - } - else if((addr.u8[14]==0x17)&&(addr.u8[15]==0x36)) - { - - tmp_addr.u8[14] = 0x17; - tmp_addr.u8[15] = 0x02; - fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node1, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); - server=thread_create(sock_server_stack,sizeof(sock_server_stack),6,THREAD_CREATE_STACKTEST,sock_server_thread,NULL,"sock_server_thread"); - } - else - { - puts("new node?"); - } -} - -static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; - -static const shell_command_t shell_commands[] = { - { NULL, NULL, NULL } -}; - - -int main(void) -{ - - msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); - puts("RIOT network stack example application"); - init_interface(); - - /* start shell */ - puts("All up, running the shell now"); - char line_buf[SHELL_DEFAULT_BUFSIZE]; - shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); - - /* should be never reached */ - return 0; -} diff --git a/RIOT/examples/network_app_rtt_1/udp.c b/RIOT/examples/network_app_rtt_1/udp.c deleted file mode 100755 index 74189c1..0000000 --- a/RIOT/examples/network_app_rtt_1/udp.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2015 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup examples - * @{ - * - * @file - * @brief Demonstrating the sending and receiving of UDP data - * - * @author Hauke Petersen - * - * @} - */ - -#include -#include - -#include "net/gnrc.h" -#include "net/gnrc/ipv6.h" -#include "net/gnrc/udp.h" -#include "net/gnrc/pktdump.h" -#include "timex.h" -#include "xtimer.h" - -//static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL, - // KERNEL_PID_UNDEF); - - -static void send(char *addr_str, char *port_str, char *data, unsigned int num, - unsigned int delay) -{ - uint16_t port; - ipv6_addr_t addr; - - /* parse destination address */ - if (ipv6_addr_from_str(&addr, addr_str) == NULL) { - puts("Error: unable to parse destination address"); - return; - } - /* parse port */ - port = (uint16_t)atoi(port_str); - if (port == 0) { - puts("Error: unable to parse destination port"); - return; - } - - for (unsigned int i = 0; i < num; i++) { - gnrc_pktsnip_t *payload, *udp, *ip; - unsigned payload_size; - /* allocate payload */ - payload = gnrc_pktbuf_add(NULL, data, strlen(data), GNRC_NETTYPE_UNDEF); - if (payload == NULL) { - puts("Error: unable to copy data to packet buffer"); - return; - } - /* store size for output */ - payload_size = (unsigned)payload->size; - /* allocate UDP header, set source port := destination port */ - udp = gnrc_udp_hdr_build(payload, port, port); - if (udp == NULL) { - puts("Error: unable to allocate UDP header"); - gnrc_pktbuf_release(payload); - return; - } - /* allocate IPv6 header */ - ip = gnrc_ipv6_hdr_build(udp, NULL, &addr); - if (ip == NULL) { - puts("Error: unable to allocate IPv6 header"); - gnrc_pktbuf_release(udp); - return; - } - /* send packet */ - if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) { - puts("Error: unable to locate UDP thread"); - gnrc_pktbuf_release(ip); - return; - } - /* access to `payload` was implicitly given up with the send operation above - * => use temporary variable for output */ - printf("Success: send %u byte to [%s]:%u\n", payload_size, addr_str, - port); - xtimer_usleep(delay); - } -} - -static void start_server(char *port_str) -{ -// uint16_t port; -// -// /* check if server is already running */ -// if (server.target.pid != KERNEL_PID_UNDEF) { -// printf("Error: server already running on port %" PRIu32 "\n", -// server.demux_ctx); -// return; -// } -// /* parse port */ -// port = (uint16_t)atoi(port_str); -// if (port == 0) { -// puts("Error: invalid port specified"); -// return; -// } -// /* start server (which means registering pktdump for the chosen port) */ -// server.target.pid = gnrc_pktdump_pid; -// server.demux_ctx = (uint32_t)port; -// gnrc_netreg_register(GNRC_NETTYPE_UDP, &server); -// printf("Success: started UDP server on port %" PRIu16 "\n", port); -} - -static void stop_server(void) -{ -// /* check if server is running at all */ -// if (server.target.pid == KERNEL_PID_UNDEF) { -// printf("Error: server was not running\n"); -// return; -// } -// /* stop server */ -// gnrc_netreg_unregister(GNRC_NETTYPE_UDP, &server); -// server.target.pid = KERNEL_PID_UNDEF; -// puts("Success: stopped UDP server"); -} - -int udp_cmd(int argc, char **argv) -{ - if (argc < 2) { - printf("usage: %s [send|server]\n", argv[0]); - return 1; - } - - if (strcmp(argv[1], "send") == 0) { - uint32_t num = 1; - uint32_t delay = 1000000; - if (argc < 5) { - printf("usage: %s send [ []]\n", - argv[0]); - return 1; - } - if (argc > 5) { - num = (uint32_t)atoi(argv[5]); - } - if (argc > 6) { - delay = (uint32_t)atoi(argv[6]); - } - send(argv[2], argv[3], argv[4], num, delay); - } - else if (strcmp(argv[1], "server") == 0) { - if (argc < 3) { - printf("usage: %s server [start|stop]\n", argv[0]); - return 1; - } - if (strcmp(argv[2], "start") == 0) { - if (argc < 4) { - printf("usage %s server start \n", argv[0]); - return 1; - } - start_server(argv[3]); - } - else if (strcmp(argv[2], "stop") == 0) { - stop_server(); - } - else { - puts("error: invalid command"); - } - } - else { - puts("error: invalid command"); - } - return 0; -} diff --git a/RIOT/examples/network_app_sntp/Makefile b/RIOT/examples/network_app_sntp/Makefile new file mode 100755 index 0000000..a5011f6 --- /dev/null +++ b/RIOT/examples/network_app_sntp/Makefile @@ -0,0 +1,67 @@ +# name of your application +APPLICATION = network_app_rtt + +# If no BOARD is found in the environment, use this default: +BOARD ?= stm32f4discovery + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \ + nrf6310 nucleo-f103 nucleo-f334 pca10000 pca10005 spark-core \ + stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \ + yunjia-nrf51822 z1 nucleo-f072 nucleo-f030 nucleo-f070 \ + microbit calliope-mini + +# Include packages that pull up and auto-init the link layer. +USEMODULE += gnrc_sock_udp +USEMODULE += sntp +# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present +USEMODULE += gnrc_netdev_default +USEMODULE += auto_init_gnrc_netif +# Specify the mandatory networking modules for IPv6 and UDP +USEMODULE += gnrc_ipv6_router_default +USEMODULE += gnrc_udp +# This application dumps received packets to STDIO using the pktdump module +#USEMODULE += gnrc_pktdump +# Additional networking modules that can be dropped if not needed +USEMODULE += gnrc_icmpv6_echo +# Add a routing protocol +USEMODULE += gnrc_rpl +# Add also the shell, some shell commands +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps +USEMODULE += netstats_l2 +USEMODULE += netstats_ipv6 +USEMODULE += netstats_rpl +#include our RF module +USEMODULE += at86rf231 +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +CFLAGS += -DDEVELHELP +USEMODULE += printf_float + +# Comment this out to join RPL DODAGs even if DIOs do not contain +# DODAG Configuration Options (see the doc for more info) +# CFLAGS += -DGNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +include $(RIOTBASE)/Makefile.include + +# Set a custom channel if needed +ifneq (,$(filter cc110x,$(USEMODULE))) # radio is cc110x sub-GHz + DEFAULT_CHANNEL ?= 0 + CFLAGS += -DCC110X_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL) +else + ifneq (,$(filter at86rf212b,$(USEMODULE))) # radio is IEEE 802.15.4 sub-GHz + DEFAULT_CHANNEL ?= 5 + FLAGS += -DIEEE802154_DEFAULT_SUBGHZ_CHANNEL=$(DEFAULT_CHANNEL) + else # radio is IEEE 802.15.4 2.4 GHz + DEFAULT_CHANNEL ?= 26 + CFLAGS += -DIEEE802154_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL) + endif +endif diff --git a/RIOT/examples/network_app_sntp/main.c b/RIOT/examples/network_app_sntp/main.c new file mode 100755 index 0000000..9bd3890 --- /dev/null +++ b/RIOT/examples/network_app_sntp/main.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Example application for demonstrating the RIOT network stack + * + * @author Hauke Petersen + * + * @} + */ +#include +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "periph_conf.h" +#include "periph/gpio.h" +#include "net/sock/udp.h" +#include "net/gnrc/ipv6.h" +#include "net/af.h" +#include "net/sixlowpan.h" +#include "net/gnrc/pktdump.h" +#include "shell.h" +#include "shell_commands.h" +#include "msg.h" +#include "thread.h" +#include "sched.h" +#include "kernel_types.h" +#include "net/netstats.h" +#include "net/ipv6/addr.h" +#include "periph/timer.h" +#include "net/gnrc/ipv6/netif.h" +#include "net/gnrc/netif.h" +#include "net/gnrc/netapi.h" +#include "net/netopt.h" +#include "net/gnrc/pkt.h" +#include "net/gnrc/pktbuf.h" +#include "net/gnrc/netif/hdr.h" +#include "net/gnrc/sixlowpan/netif.h" +#include "net/fib.h" +#include "net/gnrc/udp.h" +#include "periph/pwm.h" +#include "od.h" +#include "net/sntp.h" +#include "net/ntp_packet.h" +#ifdef MODULE_SCHEDSTATISTICS +#include "xtimer.h" +#endif + +#ifdef MODULE_TLSF +#include "tlsf.h" +#endif + +#define MAIN_QUEUE_SIZE (8) +/** + * @brief The maximal expected link layer address length in byte + */ +#define MAX_ADDR_LEN (8U) + +/** + * @brief The default IPv6 prefix length if not specified. + */ +#define SC_NETIF_IPV6_DEFAULT_PREFIX_LEN (64) + +#define _STACKSIZE (THREAD_STACKSIZE_DEFAULT + THREAD_EXTRA_STACKSIZE_PRINTF) +#define MSG_TYPE_ISR (0x3456) + +#define MAXPAC 100 +#define MAXLEN 1024 +#define ECHOLEN 1 + +//addr ipv6 link local node 1: fe80::1210:642c:1432:1702 +uint8_t node1[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x64,0x2c,0x14,0x32,0x17,0x02}; +// addr ipv6 link local node 2: fe80::1210:6432:140f:1732 +//uint8_t node2[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x64,0x32,0x14,0x0f,0x17,0x32}; +//addr ipv6 link local node 3: fe80::1210:642d:1439:1736 +uint8_t node3[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x10,0x64,0x2d,0x14,0x39,0x17,0x36}; + + +char sock_server_stack[THREAD_STACKSIZE_MAIN]; +char sock_client_stack[THREAD_STACKSIZE_MAIN]; +char sock_time_server_stack[THREAD_STACKSIZE_MAIN]; + +kernel_pid_t server, client,time_server; + +sock_udp_ep_t local = SOCK_IPV6_EP_ANY; +sock_udp_t sock; + +sock_udp_ep_t local_ntp = SOCK_IPV6_EP_ANY; +sock_udp_t sock_ntp; +static ntp_packet_t sntp_packet; + +void *sock_time_server_thread(void *arg) +{ + (void) arg; + local_ntp.port = NTP_PORT; + + if (sock_udp_create(&sock_ntp, &local_ntp, NULL, 0) < 0) { + puts("Error creating UDP sock"); + return NULL; + } + + while (1) { + sock_udp_ep_t remote; + ssize_t res; + + if ((res = sock_udp_recv(&sock_ntp,&sntp_packet, sizeof(sntp_packet), SOCK_NO_TIMEOUT, + &remote)) >= 0) { + sntp_packet.receive.seconds=byteorder_htonl( xtimer_now_usec()); + sntp_packet.origin.seconds=sntp_packet.transmit.seconds; + sntp_packet.transmit.seconds=byteorder_htonl( xtimer_now_usec()); + + if (sock_udp_send(&sock_ntp, &sntp_packet, sizeof(sntp_packet), &remote) < 0) { + puts("Error sending reply"); + } + } + } + return NULL; +} + + +typedef struct list { + uint32_t send_time; + char packet[MAXLEN]; +}Data; + +// calculate the time diff between start and end (in us) +uint32_t delay(uint32_t send_time, uint32_t recv_time) +{ + return(recv_time-send_time); +} + +// calculate the min/max/average value from an array +void rttd(float t[], int size, uint32_t time) +{ + float avg; + float min = t[0]; + float max = 0.0; + float sum=0.0; + int i; + + for(i=0; i< size; i++){ + sum += t[i]; + if(t[i] > max) {max = t[i];} + if(t[i] < min) {min = t[i];} + } + avg = sum/(float)size; + if(size!=0)printf("Round-trip delay: min/avg/max = %f/%f/%f ms, time = %f s\n",min*1000,avg*1000,max*1000,(float)time/1000000); +} + + +void *sock_server_thread(void *arg) +{ + (void) arg; + local.port = 1234; + Data buf; + int64_t offset = 0; + int latency; + + sock_udp_ep_t server = { .port = NTP_PORT, .family = AF_INET6 }; + ipv6_addr_from_str((ipv6_addr_t *)&server.addr, "baad:a555::1702"); + + if (sock_udp_create(&sock, &local, NULL, 0) < 0) + { + puts("Error creating UDP sock"); + return NULL; + } + + if (sntp_sync(&server, SOCK_NO_TIMEOUT) < 0) { + puts("Error in synchronization"); + return NULL; + } + offset = sntp_get_offset(); + printf("offset: %i \n",(int)offset); + + while (1) + { + sock_udp_ep_t remote; + size_t res; + + if ((res = sock_udp_recv(&sock,&buf, sizeof(buf),SOCK_NO_TIMEOUT ,&remote)) < 0) + { + puts("Can't receive datagram\n"); + } + latency = xtimer_now_usec() + offset - buf.send_time; + printf("latency : %i\n",latency); + + //puts("Got a UDP datagram\n"); + //send ack + if (sock_udp_send(&sock,&buf,sizeof(buf), &remote) != res) + { + puts("Error sending reply"); + } + + + } + return NULL; +} + +void *sock_client_thread(void *arg) +{ + (void) arg; + ssize_t res; + Data data; + Data data2; + //int i; + //uint32_t timebuf; + sock_udp_ep_t remote = { .family = AF_INET6 }; + + remote.port = 1234; + remote.addr.ipv6[0] = 0xba; + remote.addr.ipv6[1] = 0xad; + remote.addr.ipv6[2] = 0xa5; + remote.addr.ipv6[3] = 0x55; + remote.addr.ipv6[14] = 0x17; + remote.addr.ipv6[15] = 0x36; + + /* fill up the echo message */ + for (i = 0; i < ECHOLEN; i++) { + + data.donnees[i] = 'e'; + } + + for (;;) + { + + + data.send_time = xtimer_now_usec(); + //test=xtimer_now_usec(); + printf("Heure server: %" PRIu32 "\n",data.heure_actuelle); + if (sock_udp_send(&sock,&data,sizeof(data), &remote) < 0) + { + puts("Error sending message"); + } + if ((res = sock_udp_recv(&sock,&data2,sizeof(data2),1 * US_PER_SEC,NULL)) < 0) + { + if (res == -ETIMEDOUT) + { + puts("Timedout"); + } + else + { + puts("Error receiving message"); + } + } + else{ + //end = xtimer_now_usec(); + //timebuf = delay(test,end); + // printf("latency: %" PRIu32 "\n",timebuf); + //printf("heure reception: %" PRIu32 "\n",end); + xtimer_sleep(1); + + } + + } + return NULL; +} + +static void init_interface(void) +{ + kernel_pid_t ifs[GNRC_NETIF_NUMOF]; + ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED; + ipv6_addr_t tmp_addr= IPV6_ADDR_UNSPECIFIED; + uint8_t hwaddr[MAX_ADDR_LEN]; + int res; + + gnrc_netif_get(ifs); + + //addresses gobales + addr.u8[0] = 0xba; + addr.u8[1] = 0xad; + addr.u8[2] = 0xa5; + addr.u8[3] = 0x55; + + res = gnrc_netapi_get(ifs[0], NETOPT_ADDRESS, 0, hwaddr, sizeof(hwaddr)); + + if (res >= 0) { + addr.u8[14] = *hwaddr; + addr.u8[15] = *(hwaddr+1); + } + memcpy(tmp_addr.u8,addr.u8,IPV6_ADDR_BIT_LEN); + + gnrc_ipv6_netif_add_addr(ifs[0], &addr, 64, GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST); + + /* model ipv6 addr: baad:a555::Hwaddr */ + if((addr.u8[14]==0x17)&&(addr.u8[15]==0x02)) + { + + tmp_addr.u8[14] = 0x17; + tmp_addr.u8[15] = 0x36; + fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node3, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); + client=thread_create(sock_client_stack,sizeof(sock_client_stack),8,THREAD_CREATE_STACKTEST,sock_client_thread,NULL,"sock_client_thread"); + time_server=thread_create(sock_time_server_stack,sizeof(sock_time_server_stack),6,THREAD_CREATE_STACKTEST,sock_time_server_thread,NULL,"sock_time_server_thread"); + } + else if((addr.u8[14]==0x17)&&(addr.u8[15]==0x36)) + { + + tmp_addr.u8[14] = 0x17; + tmp_addr.u8[15] = 0x02; + fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node1, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); + server=thread_create(sock_server_stack,sizeof(sock_server_stack),6,THREAD_CREATE_STACKTEST,sock_server_thread,NULL,"sock_server_thread"); + } + else + { + puts("new node?"); + } +} + +static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; + +static const shell_command_t shell_commands[] = { + { NULL, NULL, NULL } +}; + + +int main(void) +{ + + msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); + puts("RIOT network stack example application"); + init_interface(); + + /* start shell */ + puts("All up, running the shell now"); + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + + /* should be never reached */ + return 0; +} diff --git a/RIOT/examples/network_app_sntp/udp.c b/RIOT/examples/network_app_sntp/udp.c new file mode 100755 index 0000000..74189c1 --- /dev/null +++ b/RIOT/examples/network_app_sntp/udp.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief Demonstrating the sending and receiving of UDP data + * + * @author Hauke Petersen + * + * @} + */ + +#include +#include + +#include "net/gnrc.h" +#include "net/gnrc/ipv6.h" +#include "net/gnrc/udp.h" +#include "net/gnrc/pktdump.h" +#include "timex.h" +#include "xtimer.h" + +//static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL, + // KERNEL_PID_UNDEF); + + +static void send(char *addr_str, char *port_str, char *data, unsigned int num, + unsigned int delay) +{ + uint16_t port; + ipv6_addr_t addr; + + /* parse destination address */ + if (ipv6_addr_from_str(&addr, addr_str) == NULL) { + puts("Error: unable to parse destination address"); + return; + } + /* parse port */ + port = (uint16_t)atoi(port_str); + if (port == 0) { + puts("Error: unable to parse destination port"); + return; + } + + for (unsigned int i = 0; i < num; i++) { + gnrc_pktsnip_t *payload, *udp, *ip; + unsigned payload_size; + /* allocate payload */ + payload = gnrc_pktbuf_add(NULL, data, strlen(data), GNRC_NETTYPE_UNDEF); + if (payload == NULL) { + puts("Error: unable to copy data to packet buffer"); + return; + } + /* store size for output */ + payload_size = (unsigned)payload->size; + /* allocate UDP header, set source port := destination port */ + udp = gnrc_udp_hdr_build(payload, port, port); + if (udp == NULL) { + puts("Error: unable to allocate UDP header"); + gnrc_pktbuf_release(payload); + return; + } + /* allocate IPv6 header */ + ip = gnrc_ipv6_hdr_build(udp, NULL, &addr); + if (ip == NULL) { + puts("Error: unable to allocate IPv6 header"); + gnrc_pktbuf_release(udp); + return; + } + /* send packet */ + if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) { + puts("Error: unable to locate UDP thread"); + gnrc_pktbuf_release(ip); + return; + } + /* access to `payload` was implicitly given up with the send operation above + * => use temporary variable for output */ + printf("Success: send %u byte to [%s]:%u\n", payload_size, addr_str, + port); + xtimer_usleep(delay); + } +} + +static void start_server(char *port_str) +{ +// uint16_t port; +// +// /* check if server is already running */ +// if (server.target.pid != KERNEL_PID_UNDEF) { +// printf("Error: server already running on port %" PRIu32 "\n", +// server.demux_ctx); +// return; +// } +// /* parse port */ +// port = (uint16_t)atoi(port_str); +// if (port == 0) { +// puts("Error: invalid port specified"); +// return; +// } +// /* start server (which means registering pktdump for the chosen port) */ +// server.target.pid = gnrc_pktdump_pid; +// server.demux_ctx = (uint32_t)port; +// gnrc_netreg_register(GNRC_NETTYPE_UDP, &server); +// printf("Success: started UDP server on port %" PRIu16 "\n", port); +} + +static void stop_server(void) +{ +// /* check if server is running at all */ +// if (server.target.pid == KERNEL_PID_UNDEF) { +// printf("Error: server was not running\n"); +// return; +// } +// /* stop server */ +// gnrc_netreg_unregister(GNRC_NETTYPE_UDP, &server); +// server.target.pid = KERNEL_PID_UNDEF; +// puts("Success: stopped UDP server"); +} + +int udp_cmd(int argc, char **argv) +{ + if (argc < 2) { + printf("usage: %s [send|server]\n", argv[0]); + return 1; + } + + if (strcmp(argv[1], "send") == 0) { + uint32_t num = 1; + uint32_t delay = 1000000; + if (argc < 5) { + printf("usage: %s send [ []]\n", + argv[0]); + return 1; + } + if (argc > 5) { + num = (uint32_t)atoi(argv[5]); + } + if (argc > 6) { + delay = (uint32_t)atoi(argv[6]); + } + send(argv[2], argv[3], argv[4], num, delay); + } + else if (strcmp(argv[1], "server") == 0) { + if (argc < 3) { + printf("usage: %s server [start|stop]\n", argv[0]); + return 1; + } + if (strcmp(argv[2], "start") == 0) { + if (argc < 4) { + printf("usage %s server start \n", argv[0]); + return 1; + } + start_server(argv[3]); + } + else if (strcmp(argv[2], "stop") == 0) { + stop_server(); + } + else { + puts("error: invalid command"); + } + } + else { + puts("error: invalid command"); + } + return 0; +} diff --git a/RIOT/examples/robot_app_dynamic/main.c b/RIOT/examples/robot_app_dynamic/main.c index 03390c6..b7108e0 100644 --- a/RIOT/examples/robot_app_dynamic/main.c +++ b/RIOT/examples/robot_app_dynamic/main.c @@ -112,8 +112,15 @@ void *robot_thread(void *arg) { msg_receive(&msg); cmd[0] = msg.content.value; - if((cmd[0]&0xff) == 4) {send_to_robot_auto();xtimer_sleep(3);} //mode auto - else {send_to_robot_manu(cmd[0]);xtimer_sleep(1);} //mode manu + if((cmd[0]&0xff) == 4) + { + send_to_robot_auto(); + } //mode auto + else + { + send_to_robot_manu(cmd[0]); + xtimer_sleep(1); + } //mode manu } return NULL; } @@ -133,7 +140,7 @@ void *sock_client_thread(void *arg) remote.addr.ipv6[2] = 0xa5; remote.addr.ipv6[3] = 0x55; remote.addr.ipv6[14] = 0x17; - remote.addr.ipv6[15] = 0x2a; + remote.addr.ipv6[15] = 0x36; for (;;) { @@ -144,7 +151,7 @@ void *sock_client_thread(void *arg) { puts("Error sending message"); } - if ((res = sock_udp_recv(&sock,message,MAX_MESSAGE_LENGTH, 14 * MS_PER_SEC,&remote)) < 0) + if ((res = sock_udp_recv(&sock,message,MAX_MESSAGE_LENGTH, 20 * SEC_PER_MIN,&remote)) < 0) { if (res == -ETIMEDOUT) { @@ -166,8 +173,9 @@ void *sock_server_thread(void *arg) { (void) arg; local.port = 1234; + int count = 0; uint32_t server_msg[1]; - //uint32_t auto_r; + uint32_t auto_r; msg_t msg; if (sock_udp_create(&sock, &local, NULL, 0) < 0) @@ -183,18 +191,23 @@ void *sock_server_thread(void *arg) /* wait for incoming packets */ if ((sock_udp_recv(&sock,server_msg, sizeof(server_msg), 5 * SEC_PER_MIN,&remote) >= 0)){ - msg.content.value = server_msg[0]; + //send ack if (sock_udp_send(&sock,"ok",sizeof("ok"), &remote) < 0) { puts("Error sending reply"); } + msg.content.value = server_msg[0]; + count = 0; msg_send(&msg, robot_pid); } else{ - //auto_r = 4; - // msg.content.value = auto_r; - //msg_send(&msg, robot_pid);//auto + auto_r = 4; + msg.content.value = auto_r; + if(count < 3) { + msg_send(&msg, robot_pid); + count++; + }//auto } @@ -231,13 +244,12 @@ static void _init_interface(void) { crea_rpl_dodag_root(1, addr); client=thread_create(sock_client_stack,sizeof(sock_client_stack),8,THREAD_CREATE_STACKTEST,sock_client_thread,NULL,"sock_client_thread"); - } else if((addr.u8[14]==0x17)&&(addr.u8[15]==0x36)){ - } - else if((addr.u8[14]==0x17)&&(addr.u8[15]==0x2a)) + } + else if((addr.u8[14]==0x17)&&(addr.u8[15]==0x36)) { server=thread_create(sock_server_stack,sizeof(sock_server_stack),6,THREAD_CREATE_STACKTEST,sock_server_thread,NULL,"sock_server_thread"); - robot_pid=thread_create(robot_stack,sizeof(robot_stack),5,THREAD_CREATE_STACKTEST,robot_thread,NULL,"robot_thread"); + robot_pid=thread_create(robot_stack,sizeof(robot_stack),7,THREAD_CREATE_STACKTEST,robot_thread,NULL,"robot_thread"); } else { diff --git a/RIOT/examples/robot_app_dynamic/motor.c b/RIOT/examples/robot_app_dynamic/motor.c index af9a209..9a76e75 100644 --- a/RIOT/examples/robot_app_dynamic/motor.c +++ b/RIOT/examples/robot_app_dynamic/motor.c @@ -44,7 +44,7 @@ #define MOTOR2_IN2 GPIO_PIN(PORT_E,3) #define MOTOR2_ECD GPIO_PIN(PORT_A,9) -#define STDBY GPIO_PIN(PORT_D,4) +#define STDBY GPIO_PIN(PORT_D,5) robot_t motor_1; robot_t motor_2; @@ -150,7 +150,8 @@ void send_to_robot_manu(uint32_t msg) void send_to_robot_auto(void) { - robot_spin_right(&motor_1,&motor_2,700,60); + robot_spin_right(&motor_1,&motor_2,600,60); + xtimer_sleep(1); } int init_robot(robot_t *dev1, robot_t *dev2) -- libgit2 0.21.2