1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
23 // Do not remove the include below
32 #include "oic_lanLib.h"
39 #define ARDUINO_AVR_MEGA2560 1
40 /// This is the port which Arduino Server will use for all unicast communication with it's peers
41 #define OC_WELL_KNOWN_PORT 5683
43 PROGMEM const char TAG[] = "TrackeeSensor";
45 OCResourceHandle m_handle;
48 #include "proximity.h"
50 #define JSON_BASE "{\"href\":\"\",\"rep\":{"
51 #define JSON_BASE00 "\"0\":\"trackeeID\",\"1\":\"string\",\"2\":\""
52 #define JSON_BASE01 "\",\"3\":\"things\",\"4\":\"int\",\"5\":\""
53 #define JSON_BASE02 "\",\"6\":\"ID\",\"7\":\"string\",\"8\":\""
54 #define JSON_BASE03 "\",\"9\":\"distance\",\"10\":\"float\",\"11\":\""
55 #define JSON_BASE04 "\",\"12\":\"proximity\",\"13\":\"int\",\"14\":\""
56 #define JSON_BASE05 "\",\"15\":\"SD\",\"16\":\"float\",\"17\":\""
57 #define JSON_BASE06 "\",\"18\":\"ID\",\"19\":\"string\",\"20\":\""
58 #define JSON_BASE07 "\",\"21\":\"distance\",\"22\":\"float\",\"23\":\""
59 #define JSON_BASE08 "\",\"24\":\"proximity\",\"25\":\"int\",\"26\":\""
60 #define JSON_BASE09 "\",\"27\":\"SD\",\"28\":\"float\",\"29\":\""
61 #define JSON_BASE10 "\"}}"
63 typedef struct PROXIRESOURCE
65 float m_distance[SLAVER_EA];
66 float m_proximity[SLAVER_EA];
71 int rssi[SLAVER_EA][arraysize];
72 int rssicnt[SLAVER_EA] = {0,};
73 int startindex[SLAVER_EA] = {0,};
74 int flag[SLAVER_EA] = {0,};
76 //bool bleWrite = true;
80 //char trackeeID[13] = "9059AF170C1D";
81 char trackeeID[13] = "9059AF16FEF7";
83 //char slaveList[SLAVER_EA][13]={"9059AF1704D7"};
84 char slaveList[SLAVER_EA][13] = {"9059AF1700EE", "34B1F7D004D2"};
85 int g_PROXIUnderObservation = 0;
89 const char *getResult(OCStackResult result);
90 void createResource();
94 bool JsonGenerator( char *jsonBuf, uint16_t buf_length )
96 if ( g_PROXIUnderObservation == 1 )
99 PROXIResource *ref = &PROXI;
100 int ref_cnt = SLAVER_EA;
101 uint16_t base_length = 0;
102 base_length = strlen(JSON_BASE) + strlen(JSON_BASE00) + strlen(JSON_BASE01) + strlen(
103 JSON_BASE02) + strlen(JSON_BASE03) + \
104 strlen(JSON_BASE04) + strlen(JSON_BASE05) + strlen(JSON_BASE06) + strlen(JSON_BASE07) + \
105 strlen(JSON_BASE08) + strlen(JSON_BASE09) + strlen(JSON_BASE10);
107 // base_length = strlen(JSON_BASE00)+ strlen(JSON_BASE01)+ strlen(JSON_BASE02)+ strlen(JSON_BASE03)+\
108 // strlen(JSON_BASE04)+ strlen(JSON_BASE05)+ strlen(JSON_BASE10);
110 OC_LOG_V(INFO, TAG, "base length = %d, buf_length=%d", base_length, buf_length );
112 if ( ((long)buf_length - (long)base_length) < LENGTH_VAR )
114 OC_LOG_V(ERROR, TAG, "Error : length is very long.");
118 sprintf(jsonBuf, JSON_BASE );
119 sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE00"%s"JSON_BASE01"%d", trackeeID, ref_cnt);
120 sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE02"%s"JSON_BASE03"%d.%03d", slaveList[0],
121 (int)ref->m_distance[0], (int)((ref->m_distance[0] - (int)ref->m_distance[0]) * 1000.0) );
122 sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE04"%d"JSON_BASE05"0.0", (int)ref->m_proximity[0] );
123 sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE06"%s"JSON_BASE07"%d.%03d", slaveList[1],
124 (int)ref->m_distance[1], (int)((ref->m_distance[1] - (int)ref->m_distance[1]) * 1000.0) );
125 sprintf(jsonBuf + strlen(jsonBuf), JSON_BASE08"%d"JSON_BASE09"0.0", (int)ref->m_proximity[1] );
126 strcpy(jsonBuf + strlen(jsonBuf), JSON_BASE10 );
128 OC_LOG_V(INFO, TAG, "json length = %u", strlen(jsonBuf) );
132 #else // Slave Json Code.
138 OC_LOG_V(INFO, TAG, "Not Support Observer unfounded mode." );
143 // On Arduino Atmel boards with Harvard memory architecture, the stack grows
144 // downwards from the top and the heap grows upwards. This method will print
145 // the distance(in terms of bytes) between those two.
146 // See here for more details :
147 // http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
148 void PrintArduinoMemoryStats()
150 #ifdef ARDUINO_AVR_MEGA2560
151 //This var is declared in avr-libc/stdlib/malloc.c
152 //It keeps the largest address not allocated for heap
153 extern char *__brkval;
154 //address of tmp gives us the current stack boundry
156 OC_LOG_V(INFO, TAG, "Stack: %u Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
157 OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
158 ((unsigned int)&tmp - (unsigned int)__brkval));
162 // This is the entity handler for the registered resource.
163 // This is invoked by OCStack whenever it recevies a request for this resource.
164 OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
165 OCEntityHandlerRequest *entityHandlerRequest )
167 OCEntityHandlerResult ehRet = OC_EH_OK;
169 if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
171 OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
172 if (OC_REST_GET == entityHandlerRequest->method)
174 if (JsonGenerator((char *)entityHandlerRequest->resJSONPayload, \
175 entityHandlerRequest->resJSONPayloadLen))
183 if (OC_REST_PUT == entityHandlerRequest->method)
185 //Do something with the 'put' payload
186 if (JsonGenerator((char *)entityHandlerRequest->resJSONPayload, \
187 entityHandlerRequest->resJSONPayloadLen))
196 if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
198 if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo->action)
200 OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_REGISTER from client"));
201 g_PROXIUnderObservation = 1;
203 else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo->action)
205 OC_LOG (INFO, TAG, PCF("Received OC_OBSERVE_DEREGISTER from client"));
214 void ChangePROXIRepresentation (void *param)
217 OCStackResult result = OC_STACK_ERROR;
218 float avg[SLAVER_EA] = {0,};
220 for (int i = 0; i < SLAVER_EA; i++)
222 if ( rssicnt[i] > arraysize - 1)
224 rssicnt[i] = rssicnt[i] % arraysize;
227 ble.streamDummy(NULL, NULL);
228 /* if( ble.pollingConnect(&slaveList[slaver_num][0]) == false )
230 OC_LOG_V("Error : Not Connected.\r\n");
232 while (ble.pollingConnect(&slaveList[slaver_num][0]) == false)
234 ble.streamDummy(NULL, NULL);
237 if ( ble.IsConnected() == true )
239 // print the string when a newline arrives:
240 OC_LOG_V(INFO, TAG, "Connected. (%s)\r\n", slaveList[slaver_num]);
243 for (int j = 0; j < RSSI_EA; j++)
245 rssi[i][rssicnt[i]] = ble.pollingGetRSSI();
246 OC_LOG_V(INFO, TAG, "rssi val : %d \r\n", rssi[i][rssicnt[i]]);
249 // oldTime = millis();
250 // float TpR = (float)(((oldTime-time)/1000.0)/20.0);
251 // OC_LOG_V("time per rssi : %d.%03d\r\n", (int)TpR, (int)(TpR*1000.0 -((int)TpR)*1000.0) );
253 while ( ble.IsSelfArduino() == false )
254 ble.pollingDisconnect();
257 slaver_num = slaver_num % SLAVER_EA;
260 avg[i] = CalculateExponentialAverage(RSSI_EA, rssi[i], startindex[i], flag[i]);
261 Serial.println(avg[i]);
262 Serial.print("distance : ");
264 PROXI.m_distance[i] = calculateDistance(avg[i], -58);
266 if (PROXI.m_distance[i] <= 1)
268 PROXI.m_proximity[i] = 1;
270 else if (PROXI.m_distance[i] <= 2)
272 PROXI.m_proximity[i] = 2;
276 PROXI.m_proximity[i] = 3;
279 Serial.println(PROXI.m_distance[i]);
280 Serial.println(PROXI.m_proximity[i]);
281 //Serial.println(calculateDistance(avg[i], -58));
282 startindex[i] += RSSI_EA;
284 // This call displays the amount of free SRAM available on Arduino
285 PrintArduinoMemoryStats();
287 if (startindex[i] >= arraysize)
292 if (flag[i] < (arraysize / RSSI_EA))
298 result = OCNotifyAllObservers (m_handle, OC_NA_QOS);
300 if (OC_STACK_NO_OBSERVERS == result)
302 OC_LOG_V(INFO, TAG, "g_PROXIUnderObservation is 0." );
303 g_PROXIUnderObservation = 0;
312 //The setup function is called once at startup of the sketch
315 Serial.begin(115200);
317 // Add your initialization code here
320 OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
321 // uint16_t port = OC_WELL_KNOWN_PORT;
323 // Connect to Ethernet or WiFi network
324 if (ConnectToNetwork() != 0)
326 OC_LOG(ERROR, TAG, "Unable to connect to network");
330 // Initialize the OC Stack in Server mode
331 if (OCInit(NULL, OC_WELL_KNOWN_PORT, OC_SERVER) != OC_STACK_OK)
333 OC_LOG(ERROR, TAG, PCF("OCStack init error"));
338 // Declare and create the example resource
341 // This call displays the amount of free SRAM available on Arduino
342 PrintArduinoMemoryStats();
344 ble.init( (long)115200, BLE_MASTER, trackeeID);
346 ble.init( (long)115200, BLE_SLAVER, slaveList[0]);
348 ble.init( (long)115200, BLE_SLAVER, slaveList[1]);
353 OC_LOG_V(INFO, TAG, "Program Start-\r\n");
357 // The loop function is called in an endless loop
360 // This artificial delay is kept here to avoid endless spinning
361 // of Arduino microcontroller. Modify it as per specfic application needs.
363 if (OCProcess() != OC_STACK_OK)
365 OC_LOG(ERROR, TAG, PCF("OCStack process error"));
369 ChangePROXIRepresentation(NULL);
371 char *user_cmd = NULL;
373 // ble.pollingDisconnect();
375 user_cmd = ble.Debug2BLE(true);
376 ble.BLE2Debug( true );
393 void createResource()
396 OCStackResult res = OCCreateResource(&m_handle,
398 OC_RSRVD_INTERFACE_DEFAULT,
401 OC_DISCOVERABLE | OC_OBSERVABLE);
402 OC_LOG_V(INFO, TAG, "Created PROXI resource with result: %s", getResult(res));
405 const char *getResult(OCStackResult result)
410 return "OC_STACK_OK";
411 case OC_STACK_INVALID_URI:
412 return "OC_STACK_INVALID_URI";
413 case OC_STACK_INVALID_QUERY:
414 return "OC_STACK_INVALID_QUERY";
415 case OC_STACK_INVALID_IP:
416 return "OC_STACK_INVALID_IP";
417 case OC_STACK_INVALID_PORT:
418 return "OC_STACK_INVALID_PORT";
419 case OC_STACK_INVALID_CALLBACK:
420 return "OC_STACK_INVALID_CALLBACK";
421 case OC_STACK_INVALID_METHOD:
422 return "OC_STACK_INVALID_METHOD";
423 case OC_STACK_NO_MEMORY:
424 return "OC_STACK_NO_MEMORY";
425 case OC_STACK_COMM_ERROR:
426 return "OC_STACK_COMM_ERROR";
427 case OC_STACK_INVALID_PARAM:
428 return "OC_STACK_INVALID_PARAM";
429 case OC_STACK_NOTIMPL:
430 return "OC_STACK_NOTIMPL";
431 case OC_STACK_NO_RESOURCE:
432 return "OC_STACK_NO_RESOURCE";
433 case OC_STACK_RESOURCE_ERROR:
434 return "OC_STACK_RESOURCE_ERROR";
435 case OC_STACK_SLOW_RESOURCE:
436 return "OC_STACK_SLOW_RESOURCE";
437 case OC_STACK_NO_OBSERVERS:
438 return "OC_STACK_NO_OBSERVERS";
440 return "OC_STACK_ERROR";