Skip to content

Commit 7818167

Browse files
committed
Add movement sensor
1 parent 216650c commit 7818167

File tree

8 files changed

+154
-16
lines changed

8 files changed

+154
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ Web Components library for micro:bit
2222
- [x] Connection State
2323
- [x] Button A State
2424
- [x] Button B State
25+
- [x] Movement State
2526
- [ ] IO Pin State
2627

2728
## Data
2829
- [x] Temperature
2930
- [x] Compass
30-
- [ ] Movement
3131
- [ ] Write IO
3232

3333
## LEDs

src/components.d.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,45 @@ export namespace Components {
325325
*/
326326
'disconnectedClass'?: string;
327327
}
328+
329+
interface MicrobitStateMovement {
330+
/**
331+
* The frequency to read the sensor
332+
*/
333+
'frequency': number;
334+
/**
335+
* The css class to use when moved
336+
*/
337+
'movedClass': string;
338+
/**
339+
* The sensitivity of the sensor
340+
*/
341+
'sensitivity': number;
342+
'services': Services;
343+
/**
344+
* The css class to use when still
345+
*/
346+
'stillClass': string;
347+
}
348+
interface MicrobitStateMovementAttributes extends StencilHTMLAttributes {
349+
/**
350+
* The frequency to read the sensor
351+
*/
352+
'frequency'?: number;
353+
/**
354+
* The css class to use when moved
355+
*/
356+
'movedClass'?: string;
357+
/**
358+
* The sensitivity of the sensor
359+
*/
360+
'sensitivity'?: number;
361+
'services'?: Services;
362+
/**
363+
* The css class to use when still
364+
*/
365+
'stillClass'?: string;
366+
}
328367
}
329368

330369
declare global {
@@ -343,6 +382,7 @@ declare global {
343382
'MicrobitStateButtonA': Components.MicrobitStateButtonA;
344383
'MicrobitStateButtonB': Components.MicrobitStateButtonB;
345384
'MicrobitStateConnection': Components.MicrobitStateConnection;
385+
'MicrobitStateMovement': Components.MicrobitStateMovement;
346386
}
347387

348388
interface StencilIntrinsicElements {
@@ -360,6 +400,7 @@ declare global {
360400
'microbit-state-button-a': Components.MicrobitStateButtonAAttributes;
361401
'microbit-state-button-b': Components.MicrobitStateButtonBAttributes;
362402
'microbit-state-connection': Components.MicrobitStateConnectionAttributes;
403+
'microbit-state-movement': Components.MicrobitStateMovementAttributes;
363404
}
364405

365406

@@ -447,6 +488,12 @@ declare global {
447488
new (): HTMLMicrobitStateConnectionElement;
448489
};
449490

491+
interface HTMLMicrobitStateMovementElement extends Components.MicrobitStateMovement, HTMLStencilElement {}
492+
var HTMLMicrobitStateMovementElement: {
493+
prototype: HTMLMicrobitStateMovementElement;
494+
new (): HTMLMicrobitStateMovementElement;
495+
};
496+
450497
interface HTMLElementTagNameMap {
451498
'microbit-compass': HTMLMicrobitCompassElement
452499
'microbit-temperature': HTMLMicrobitTemperatureElement
@@ -462,6 +509,7 @@ declare global {
462509
'microbit-state-button-a': HTMLMicrobitStateButtonAElement
463510
'microbit-state-button-b': HTMLMicrobitStateButtonBElement
464511
'microbit-state-connection': HTMLMicrobitStateConnectionElement
512+
'microbit-state-movement': HTMLMicrobitStateMovementElement
465513
}
466514

467515
interface ElementTagNameMap {
@@ -479,6 +527,7 @@ declare global {
479527
'microbit-state-button-a': HTMLMicrobitStateButtonAElement;
480528
'microbit-state-button-b': HTMLMicrobitStateButtonBElement;
481529
'microbit-state-connection': HTMLMicrobitStateConnectionElement;
530+
'microbit-state-movement': HTMLMicrobitStateMovementElement;
482531
}
483532

484533

src/components/data/microbit-compass.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export class MicrobitCompass {
1818
}
1919

2020
const service = this.services.magnetometerService;
21+
this.bearing = await service.getMagnetometerBearing();
2122
service.addEventListener("magnetometerbearingchanged", event => this.bearing = event.detail);
2223
}
2324

src/components/data/microbit-temperature.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export class MicrobitTemperature {
3939
return;
4040
}
4141

42+
const temperature = await service.readTemperature();
43+
this.temperature = `${temperature}°c`;
4244
await service.setTemperaturePeriod(this.temperaturePeriod);
4345
service.addEventListener("temperaturechanged", temp => this.temperature = `${temp.detail}°c`);
4446
}

src/components/state/microbit-state-button-a.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,16 @@ export class MicrobitStateButtonA {
2727
@State() className = this.releaseClass;
2828

2929
@Watch('services')
30-
watchHandler() {
30+
async watchHandler() {
3131
if (!this.services || !this.services.buttonService) {
3232
this.className = this.releaseClass;
3333
return;
3434
}
3535

3636
const service = this.services.buttonService;
37-
service.addEventListener("buttonastatechanged", event => {
38-
this.className = event.detail === 1 ? this.shortPressClass
39-
: event.detail === 2 ? this.longPressClass
40-
: this.releaseClass;
41-
});
37+
const state = await service.readButtonAState();
38+
this.setClassName(state);
39+
service.addEventListener("buttonastatechanged", event => this.setClassName(event.detail));
4240
}
4341

4442
render() {
@@ -48,6 +46,12 @@ export class MicrobitStateButtonA {
4846
</span>
4947
);
5048
}
49+
50+
private setClassName(state: number) {
51+
this.className = state === 1 ? this.shortPressClass
52+
: state === 2 ? this.longPressClass
53+
: this.releaseClass;
54+
}
5155
}
5256

5357
DeviceTunnel.injectProps(MicrobitStateButtonA, ['services']);

src/components/state/microbit-state-button-b.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,16 @@ export class MicrobitStateButtonB {
2727
@State() className = this.releaseClass;
2828

2929
@Watch('services')
30-
watchHandler() {
30+
async watchHandler() {
3131
if (!this.services || !this.services.buttonService) {
3232
this.className = this.releaseClass;
3333
return;
3434
}
3535

3636
const service = this.services.buttonService;
37-
service.addEventListener("buttonbstatechanged", event => {
38-
this.className = event.detail === 1 ? this.shortPressClass
39-
: event.detail === 2 ? this.longPressClass
40-
: this.releaseClass;
41-
});
37+
const state = await service.readButtonBState();
38+
this.setClassName(state);
39+
service.addEventListener("buttonbstatechanged", event => this.setClassName(event.detail));
4240
}
4341

4442
render() {
@@ -48,6 +46,12 @@ export class MicrobitStateButtonB {
4846
</span>
4947
);
5048
}
49+
50+
private setClassName(state: number) {
51+
this.className = state === 1 ? this.shortPressClass
52+
: state === 2 ? this.longPressClass
53+
: this.releaseClass;
54+
}
5155
}
5256

5357
DeviceTunnel.injectProps(MicrobitStateButtonB, ['services']);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Component, Prop, Element, Watch, State } from "@stencil/core";
2+
import { Services } from "microbit-web-bluetooth";
3+
import DeviceTunnel from '../../device-tunnel';
4+
import { AccelerometerPeriod, AccelerometerData } from "microbit-web-bluetooth/types/services/accelerometer";
5+
6+
@Component({
7+
tag: 'microbit-state-movement'
8+
})
9+
export class MicrobitStateMovement {
10+
@Element() el;
11+
@Prop() services: Services = undefined;
12+
13+
/**
14+
* The sensitivity of the sensor
15+
*/
16+
@Prop() sensitivity: number = 1;
17+
18+
/**
19+
* The frequency to read the sensor
20+
*/
21+
@Prop() frequency: number = 20;
22+
23+
/**
24+
* The css class to use when still
25+
*/
26+
@Prop() stillClass: string = "microbit-still";
27+
28+
/**
29+
* The css class to use when moved
30+
*/
31+
@Prop() movedClass: string = "microbit-moved";
32+
33+
@State() className = this.stillClass;
34+
35+
@Watch('services')
36+
async watchHandler() {
37+
if (!this.services || !this.services.accelerometerService) {
38+
this.className = this.stillClass;
39+
return;
40+
}
41+
42+
const service = this.services.accelerometerService;
43+
await service.setAccelerometerPeriod(this.frequency as AccelerometerPeriod);
44+
const data = await service.readAccelerometerData();
45+
this.setClassName(data);
46+
service.addEventListener("accelerometerdatachanged", event => this.setClassName(event.detail));
47+
}
48+
49+
render() {
50+
return (
51+
<span class={this.className}>
52+
<slot />
53+
</span>
54+
);
55+
}
56+
57+
private setClassName(data: AccelerometerData) {
58+
console.log(this.sensitivity);
59+
this.className =
60+
(Math.abs(data.x) > this.sensitivity
61+
|| Math.abs(data.y) > this.sensitivity
62+
|| Math.abs(data.z) > this.sensitivity) ? this.movedClass
63+
: this.stillClass;
64+
}
65+
}
66+
67+
DeviceTunnel.injectProps(MicrobitStateMovement, ['services']);

src/index.html

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
<head>
44
<title>Microbit Web Components</title>
55
<style>
6-
.microbit-connected > .state {
7-
background: yellowgreen;
8-
}
96
.microbit-disconnected > .state {
107
background: lightcoral;
118
}
9+
.microbit-connected > .state {
10+
background: yellowgreen;
11+
}
1212
.microbit-release > .state {
1313
background: lightcoral;
1414
}
@@ -18,6 +18,12 @@
1818
.microbit-long-press > .state {
1919
background: yellowgreen;
2020
}
21+
.microbit-still > .state {
22+
background: lightcoral;
23+
}
24+
.microbit-moved > .state {
25+
background: yellowgreen;
26+
}
2127
#compass {
2228
width: 50px;
2329
height: 50px;
@@ -56,6 +62,11 @@
5662
<span class="state">Button B</span>
5763
</microbit-state-button-b>
5864
</div>
65+
<div>
66+
<microbit-state-movement sensitivity="1.2">
67+
<span class="state">Movement</span>
68+
</microbit-state-movement>
69+
</div>
5970
<div>
6071
<microbit-compass>
6172
<div id="compass"></div>

0 commit comments

Comments
 (0)