Skip to content
This repository was archived by the owner on Apr 24, 2019. It is now read-only.

Commit 5e0b3e3

Browse files
Merge pull request #290 from ARMmbed/button-abstraction
IOTCLT-1737: use abstracted button names
2 parents 3afd408 + 955c2ac commit 5e0b3e3

11 files changed

+199
-44
lines changed

build_all.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mbed compile -m K64F -t $TOOL
1111
cp BUILD/K64F/$TOOL/mbed-os-example-client.bin k64f-$TOOL-eth-v4.bin
1212
mbed compile -m NUCLEO_F429ZI -t $TOOL
1313
cp ./BUILD/NUCLEO_F429ZI/$TOOL/mbed-os-example-client.bin f429zi-$TOOL-eth-v4.bin
14+
cp configs/eth_odin_v4.json ./mbed_app.json
1415
mbed compile -m UBLOX_EVK_ODIN_W2 -t $TOOL
1516
cp ./BUILD/UBLOX_EVK_ODIN_W2/$TOOL/mbed-os-example-client.bin ublox-odin-$TOOL-eth-v4.bin
1617

@@ -21,6 +22,7 @@ mbed compile -m K64F -t $TOOL
2122
cp BUILD/K64F/$TOOL/mbed-os-example-client.bin k64f-$TOOL-eth-v6.bin
2223
mbed compile -m NUCLEO_F429ZI -t $TOOL
2324
cp ./BUILD/NUCLEO_F429ZI/$TOOL/mbed-os-example-client.bin f429zi-$TOOL-eth-v4.bin
25+
cp configs/eth_odin_v6.json ./mbed_app.json
2426
mbed compile -m UBLOX_EVK_ODIN_W2 -t $TOOL
2527
cp ./BUILD/UBLOX_EVK_ODIN_W2/$TOOL/mbed-os-example-client.bin ublox-odin-$TOOL-eth-v6.bin
2628

configs/eth_odin_v4.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"config": {
3+
"network-interface":{
4+
"help": "Options are ETHERNET, WIFI_ESP8266, WIFI_ODIN, MESH_LOWPAN_ND, MESH_THREAD",
5+
"value": "ETHERNET"
6+
}
7+
},
8+
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],
9+
"target_overrides": {
10+
"*": {
11+
"target.features_add": ["LWIP", "COMMON_PAL"],
12+
"platform.stdio-baud-rate": 115200,
13+
"platform.stdio-convert-newlines": true,
14+
"lwip.ipv4-enabled": true,
15+
"lwip.ipv6-enabled": false,
16+
"mbed-trace.enable": 0
17+
},
18+
"UBLOX_EVK_ODIN_W2": {
19+
"target.device_has_remove": ["EMAC"]
20+
}
21+
}
22+
}

configs/eth_odin_v6.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"config": {
3+
"network-interface":{
4+
"help": "Options are ETHERNET, WIFI_ESP8266, WIFI_ODIN, MESH_LOWPAN_ND, MESH_THREAD",
5+
"value": "ETHERNET"
6+
}
7+
},
8+
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],
9+
"target_overrides": {
10+
"*": {
11+
"target.features_add": ["LWIP", "COMMON_PAL"],
12+
"platform.stdio-baud-rate": 115200,
13+
"platform.stdio-convert-newlines": true,
14+
"lwip.ipv4-enabled": false,
15+
"lwip.ipv6-enabled": true,
16+
"mbed-trace.enable": 0
17+
},
18+
"UBLOX_EVK_ODIN_W2": {
19+
"target.device_has_remove": ["EMAC"]
20+
}
21+
}
22+
}

configs/eth_v4.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
"network-interface":{
44
"help": "Options are ETHERNET, WIFI_ESP8266, WIFI_ODIN, MESH_LOWPAN_ND, MESH_THREAD",
55
"value": "ETHERNET"
6+
},
7+
"button1": {
8+
"help": "Use BUTTON1 from PinNames.h by default",
9+
"value": "BUTTON1"
610
}
711
},
812
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],

configs/eth_v6.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
"network-interface":{
44
"help": "Options are ETHERNET, WIFI_ESP8266, WIFI_ODIN, MESH_LOWPAN_ND, MESH_THREAD",
55
"value": "ETHERNET"
6+
},
7+
"button1": {
8+
"help": "Use BUTTON1 from PinNames.h by default",
9+
"value": "BUTTON1"
610
}
711
},
812
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],

configs/mesh_6lowpan.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
"mesh_radio_type": {
88
"help": "options are ATMEL, MCR20",
99
"value": "ATMEL"
10+
},
11+
"button1": {
12+
"help": "Use BUTTON1 from PinNames.h by default",
13+
"value": "BUTTON1"
1014
}
1115
},
1216
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],

configs/mesh_6lowpan_subg.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
"mesh_radio_type": {
88
"help": "options are ATMEL, MCR20, SPIRIT1",
99
"value": "SPIRIT1"
10+
},
11+
"button1": {
12+
"help": "Use BUTTON1 from PinNames.h by default",
13+
"value": "BUTTON1"
1014
}
1115
},
1216
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],

configs/mesh_thread.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
"mesh_radio_type": {
88
"help": "options are ATMEL, MCR20, EFR32",
99
"value": "ATMEL"
10+
},
11+
"button1": {
12+
"help": "Use BUTTON1 from PinNames.h by default",
13+
"value": "BUTTON1"
1014
}
1115
},
1216
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],

configs/wifi_esp8266_v4.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
"wifi-rx": {
2020
"help": "RX pin for serial connection to external device",
2121
"value": "D0"
22+
},
23+
"button1": {
24+
"help": "Use BUTTON1 from PinNames.h by default",
25+
"value": "BUTTON1"
2226
}
2327
},
2428
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],

configs/wifi_odin_v4.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
"wifi-rx": {
2020
"help": "RX pin for serial connection to external device",
2121
"value": "D0"
22+
},
23+
"button1": {
24+
"help": "Use BUTTON1 from PinNames.h by default",
25+
"value": "BUTTON1"
2226
}
2327
},
2428
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_mbed_client_config.h\""],

main.cpp

Lines changed: 125 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,63 @@ struct MbedClientDevice device = {
6767
// Instantiate the class which implements LWM2M Client API (from simpleclient.h)
6868
MbedClient mbed_client(device);
6969

70+
// Set up a button interrupt for user interaction
71+
#ifdef MBED_CONF_APP_BUTTON1
72+
InterruptIn counter_btn(MBED_CONF_APP_BUTTON1);
73+
#endif
7074

71-
// In case of K64F board , there is button resource available
72-
// to change resource value and unregister
73-
#ifdef TARGET_K64F
74-
// Set up Hardware interrupt button.
75-
InterruptIn obs_button(SW2);
76-
InterruptIn unreg_button(SW3);
77-
#else
78-
//In non K64F boards , set up a timer to simulate updating resource,
79-
// there is no functionality to unregister.
80-
Ticker timer;
75+
76+
/**
77+
* User interaction handler / simulator. Sets up physical button handler and a ticker
78+
* for regular updates for the resources.
79+
*
80+
* MBED_CONF_APP_BUTTON1 is mapped to actual button pin the mbed_app.json file, where you need to
81+
* specify board-specific value or leave it undefined if the board does not have buttons.
82+
*/
83+
class InteractionProvider {
84+
85+
public:
86+
InteractionProvider(Semaphore& updates_sem) : updates(updates_sem) {
87+
88+
timer_ticked = false;
89+
clicked = false;
90+
91+
// Set up handler function for the interaction button, if available
92+
93+
#ifdef MBED_CONF_APP_BUTTON1
94+
counter_btn.fall(this, &InteractionProvider::counter_button_handler);
8195
#endif
8296

97+
// Use the counter button handler to send an update of endpoint resource values
98+
// to connector every 15 seconds periodically.
99+
timer.attach(this, &InteractionProvider::timer_handler, 15.0);
100+
}
101+
102+
// flags for interaction, these are read from outside interrupt context
103+
volatile bool timer_ticked;
104+
volatile bool clicked;
105+
106+
107+
private:
108+
109+
void timer_handler() {
110+
timer_ticked = true;
111+
updates.release();
112+
}
113+
114+
void counter_button_handler() {
115+
clicked = true;
116+
updates.release();
117+
}
118+
119+
// time-based event source for regular resource updates
120+
Ticker timer;
121+
122+
// Network interaction must be performed outside of interrupt context
123+
Semaphore& updates;
124+
125+
};
126+
83127
/*
84128
* Arguments for running "blink" in it's own thread.
85129
*/
@@ -248,11 +292,7 @@ class ButtonResource {
248292

249293
// up counter
250294
counter++;
251-
#ifdef TARGET_K64F
252295
printf("handle_button_click, new value of counter is %d\n", counter);
253-
#else
254-
printf("simulate button_click, new value of counter is %d\n", counter);
255-
#endif
256296
// serialize the value of counter as a string, and tell connector
257297
char buffer[20];
258298
int size = sprintf(buffer,"%d",counter);
@@ -267,6 +307,61 @@ class ButtonResource {
267307
uint16_t counter;
268308
};
269309

310+
/*
311+
* The timer contains one property: counter.
312+
* When `handle_timer_tick` is executed, the counter updates.
313+
*/
314+
class TimerResource {
315+
public:
316+
TimerResource(): counter(0) {
317+
// create ObjectID with metadata tag of '3200', which is 'digital input'
318+
btn_object = M2MInterfaceFactory::create_object("3200");
319+
M2MObjectInstance* btn_inst = btn_object->create_object_instance();
320+
// create resource with ID '5502', which is digital input counter
321+
M2MResource* btn_res = btn_inst->create_dynamic_resource("5502", "Timer",
322+
M2MResourceInstance::INTEGER, true /* observable */);
323+
// we can read this value
324+
btn_res->set_operation(M2MBase::GET_ALLOWED);
325+
// set initial value (all values in mbed Client are buffers)
326+
// to be able to read this data easily in the Connector console, we'll use a string
327+
btn_res->set_value((uint8_t*)"0", 1);
328+
}
329+
330+
~TimerResource() {
331+
}
332+
333+
M2MObject* get_object() {
334+
return btn_object;
335+
}
336+
337+
/*
338+
* When the timer ticks, we read the current value of the click counter
339+
* from mbed Device Connector, then up the value with one.l
340+
*/
341+
void handle_timer_tick() {
342+
if (mbed_client.register_successful()) {
343+
M2MObjectInstance* inst = btn_object->object_instance();
344+
M2MResource* res = inst->resource("5502");
345+
346+
// up counter
347+
counter++;
348+
printf("handle_timer_click, new value of counter is %d\n", counter);
349+
// serialize the value of counter as a string, and tell connector
350+
char buffer[20];
351+
int size = sprintf(buffer,"%d",counter);
352+
res->set_value((uint8_t*)buffer, size);
353+
} else {
354+
printf("handle_timer_tick, device not registered\n");
355+
}
356+
}
357+
358+
private:
359+
M2MObject* btn_object;
360+
uint16_t counter;
361+
};
362+
363+
364+
270365
class BigPayloadResource {
271366
public:
272367
BigPayloadResource() {
@@ -316,21 +411,8 @@ class BigPayloadResource {
316411
M2MObject* big_payload;
317412
};
318413

319-
// Network interaction must be performed outside of interrupt context
320-
Semaphore updates(0);
321-
volatile bool registered = false;
322-
volatile bool clicked = false;
323-
osThreadId mainThread;
324414

325-
void unregister() {
326-
registered = false;
327-
updates.release();
328-
}
329415

330-
void button_clicked() {
331-
clicked = true;
332-
updates.release();
333-
}
334416

335417
// debug printf function
336418
void trace_printer(const char* str) {
@@ -367,7 +449,7 @@ Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app
367449
368450
status_ticker.attach_us(blinky, 250000);
369451
// Keep track of the main thread
370-
mainThread = osThreadGetId();
452+
osThreadId mainThread = osThreadGetId();
371453
372454
printf("\nStarting mbed Client example\n");
373455
@@ -381,23 +463,17 @@ Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app
381463
return -1;
382464
}
383465
384-
// we create our button and LED resources
466+
// we create our button, timer and LED resources
385467
ButtonResource button_resource;
386468
LedResource led_resource;
387469
BigPayloadResource big_payload_resource;
470+
TimerResource timer_resource;
388471
389-
#ifdef TARGET_K64F
390-
// On press of SW3 button on K64F board, example application
391-
// will call unregister API towards mbed Device Connector
392-
//unreg_button.fall(&mbed_client,&MbedClient::test_unregister);
393-
unreg_button.fall(&unregister);
472+
// Network interaction must be performed outside of interrupt context
473+
Semaphore updates(0);
474+
475+
InteractionProvider interaction_provider(updates);
394476
395-
// Observation Button (SW2) press will send update of endpoint resource values to connector
396-
obs_button.fall(&button_clicked);
397-
#else
398-
// Send update of endpoint resource values to connector every 15 seconds periodically
399-
timer.attach(&button_clicked, 15.0);
400-
#endif
401477
402478
// Create endpoint interface to manage register and unregister
403479
mbed_client.create_interface(MBED_SERVER_ADDRESS, network);
@@ -414,27 +490,32 @@ Add MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES and MBEDTLS_TEST_NULL_ENTROPY in mbed_app
414490
object_list.push_back(button_resource.get_object());
415491
object_list.push_back(led_resource.get_object());
416492
object_list.push_back(big_payload_resource.get_object());
493+
object_list.push_back(timer_resource.get_object());
417494
418495
// Set endpoint registration object
419496
mbed_client.set_register_object(register_object);
420497
421498
// Register with mbed Device Connector
422499
mbed_client.test_register(register_object, object_list);
423-
registered = true;
500+
volatile bool registered = true;
424501
425502
while (true) {
426503
updates.wait(25000);
427504
if(registered) {
428-
if(!clicked) {
505+
if(!interaction_provider.clicked) {
429506
mbed_client.test_update_register();
430507
}
431508
}else {
432509
break;
433510
}
434-
if(clicked) {
435-
clicked = false;
511+
if(interaction_provider.clicked) {
512+
interaction_provider.clicked = false;
436513
button_resource.handle_button_click();
437514
}
515+
if(interaction_provider.timer_ticked) {
516+
interaction_provider.timer_ticked = false;
517+
timer_resource.handle_timer_tick();
518+
}
438519
}
439520
440521
mbed_client.test_unregister();

0 commit comments

Comments
 (0)