1
+
2
+ <!doctype html>
3
+ < html lang ="en ">
4
+ < head >
5
+
6
+ < meta charset ="utf-8 ">
7
+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
8
+ < script src ="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.js "> </ script >
9
+ < script type ="text/javascript " src ="js/jquery.mobile-events.js "> </ script >
10
+ < script src ="js/gatt.js "> </ script >
11
+ < script src ="js/setBit.js "> </ script >
12
+ < script src ="js/joystick.js "> </ script >
13
+ < script src ="js/pep.js "> </ script >
14
+ < script src ="js/virtualJoystick.js "> </ script >
15
+
16
+
17
+ < style >
18
+ @import url (https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400, 500 , 700 , 300 );
19
+ body {
20
+ font-family : "Roboto" ;
21
+ margin : 0 ;
22
+ padding : 0px ;
23
+ }
24
+
25
+ .column {
26
+ width : 500px ;
27
+ display : inline-block;
28
+ padding-left : 20px ;
29
+
30
+ }
31
+ .notification {
32
+ display : inline-block;
33
+ margin : 15px ;
34
+ width : 35px ;
35
+ height : 35px ;
36
+ background-color : blue;
37
+ color : white;
38
+ font-size : 34px ;
39
+ text-align : center;
40
+ font-weight : 700 ;
41
+ }
42
+
43
+ h2 {
44
+ display : inline-block;
45
+ clear : both;
46
+ cursor : pointer;
47
+ padding : 3px ;
48
+ background-color : # eee ;
49
+ margin : 6px ;
50
+ }
51
+
52
+ .demo {
53
+ background : # f3eee6 ;
54
+ width : 200px ;
55
+ height : 200px ;
56
+ display : inline-block;
57
+ border-radius : 100px ;
58
+ margin : 0 ;
59
+ }
60
+
61
+
62
+ .ball {
63
+ width : 70px ;
64
+ height : 70px ;
65
+ background : red;
66
+ position : absolute;
67
+ top : 65px ;
68
+ left : 65px ;
69
+ border-radius : 70px ;
70
+ }
71
+ .ball .outline {
72
+ background : # eee ;
73
+ }
74
+ .ball .ease {
75
+ -moz-transition : all 0.2s ease;
76
+ -o-transition : all 0.2s ease;
77
+ -webkit-transition : all 0.2s ease;
78
+ transition : all 0.2s ease;
79
+ }
80
+
81
+ # pos-x , # pos-y {
82
+ margin-left : 20px ;
83
+
84
+ }
85
+
86
+
87
+ .slider-container {
88
+ display : inline-block;
89
+ float : left;
90
+ margin : 0 auto;
91
+ width : 100px ;
92
+ text-align : center;
93
+ }
94
+ input [type = range ] {
95
+ display : inline-block;
96
+ width : 50px ;
97
+ height : 100px ;
98
+ writing-mode : bt-lr; /* IE */
99
+ -webkit-appearance : slider-vertical; /* WebKit */
100
+ }
101
+ .side-by-side {
102
+ display : inline-block;
103
+ float : left;
104
+ width : 50px ;
105
+
106
+ }
107
+ # connectionStatus {
108
+ position : fixed;
109
+ top : 0 ;
110
+ right : 0 ;
111
+
112
+ padding : 5px ;
113
+ background-color : red;
114
+ color : white;
115
+ visibility : hidden;
116
+ }
117
+ # container {
118
+ width : 200px ;
119
+ height : 200px ;
120
+ background-color : # EEE ;
121
+ border-radius : 100% ;
122
+
123
+ }
124
+
125
+ </ style >
126
+
127
+ < title > Physical Web Toy</ title >
128
+
129
+
130
+
131
+ </ head >
132
+
133
+ < body >
134
+ < div id ="connectionStatus "> Connection</ div >
135
+ < div id ="container ">
136
+
137
+ </ div >
138
+ < div class ="column ">
139
+
140
+
141
+
142
+ < h2 onclick ="connect(); " id ='connect '> Koble til</ h2 >
143
+ < h2 onclick ="disconnect(); " id ='disconnect '> Koble fra</ h2 >
144
+ < h2 onclick ="readFromCharacteristic(1); "> Les</ h2 >
145
+ < h2 onclick ="writeToCharacteristic(1, 240); "> Skriv</ h2 >
146
+ < h2 onclick ="printDiscardedPackets(); "> Tapte pakker</ h2 >
147
+
148
+
149
+
150
+
151
+ < div >
152
+ < div class ="notification " id ="notification_1 "> 1</ div >
153
+ < div class ="notification " id ="notification_2 "> 2</ div >
154
+ < div class ="notification " id ="notification_3 "> 3</ div >
155
+ < div class ="notification " id ="notification_4 "> 4</ div >
156
+ </ div >
157
+
158
+
159
+ < p id ="pos-x "> </ p >
160
+ < p id ="pos-y "> </ p >
161
+ < p id ="speed "> </ p >
162
+ < p id ="angle "> </ p >
163
+ < p id ="output-left "> </ p >
164
+ < p id ="output-right "> </ p >
165
+
166
+
167
+
168
+
169
+
170
+
171
+ < script >
172
+
173
+
174
+
175
+ var charVal = new Uint8Array ( 20 ) ;
176
+
177
+
178
+
179
+ var writePermission = 1 ;
180
+ var discardedPackets = [ ] ;
181
+
182
+
183
+
184
+
185
+ $ ( '#element' ) . on ( "touchmove mousemove" , function ( ) {
186
+ $ ( this ) . css ( 'background-color' , 'red' ) ;
187
+
188
+ } )
189
+
190
+
191
+
192
+
193
+
194
+ function printDiscardedPackets ( ) {
195
+ console . log ( discardedPackets ) ;
196
+ }
197
+
198
+ //*** Joystick
199
+ var joystickContainer = document . getElementById ( 'container' ) ;
200
+ var joystick = new VirtualJoystick ( {
201
+ container : joystickContainer ,
202
+ mouseSupport : true ,
203
+ stationaryBase : true ,
204
+ baseX : 100 ,
205
+ baseY : 100 ,
206
+ limitStickTravel : true ,
207
+ stickRadius : 100
208
+ } ) ;
209
+
210
+
211
+
212
+
213
+
214
+
215
+ $ ( '#element' ) . on ( "touchmove mousemove" , function ( ) {
216
+ $ ( this ) . css ( 'background-color' , 'red' ) ;
217
+
218
+ } )
219
+
220
+ ////////////////////////////////////
221
+
222
+ // Funksjon for at joysticken skal gå tilbake til nullpunktet når den slippes
223
+
224
+ var outputRight ;
225
+ var outputLeft ;
226
+ var tapEnd ;
227
+
228
+ $ ( '#container' ) . on ( 'change touchmove mousemove' , function ( ) {
229
+ var y = joystick . deltaX ( ) ;
230
+ var x = joystick . deltaY ( ) ;
231
+ var hypotenus = Math . sqrt ( ( Math . pow ( x , 2 ) ) + ( Math . pow ( y , 2 ) ) ) ;
232
+ var speed = Math . round ( ( 255 / 100 ) * hypotenus ) ;
233
+ var angle = ( 180 / Math . PI ) * Math . acos ( x / hypotenus ) ;
234
+ var direction ;
235
+
236
+ if ( y < 0 ) {
237
+ angle = 360 - angle ;
238
+ direction = 0 ;
239
+ } else {
240
+ direction = 1 ;
241
+ }
242
+
243
+ angle = Math . round ( angle ) ;
244
+
245
+ if ( speed > 255 )
246
+ speed = 255 ;
247
+
248
+ if ( tapEnd == 1 ) {
249
+ outputRight = outputLeft = 0 ;
250
+ tapEnd = 0 ;
251
+ } else {
252
+ if ( angle >= 10 && angle <= 80 ) {
253
+ outputRight = ( angle / 80 ) * speed ;
254
+ outputLeft = speed ;
255
+ } else if ( angle > 80 && angle < 100 ) {
256
+ outputLeft = outputRight = speed ;
257
+ } else if ( angle >= 100 && angle <= 170 ) {
258
+ outputRight = speed ;
259
+ outputLeft = ( ( 180 - angle ) / 80 ) * speed ; ;
260
+ } else if ( angle > 170 && angle < 190 ) {
261
+ outputRight = speed ;
262
+ outputLeft = 0 ;
263
+ } else if ( angle >= 190 && angle <= 260 ) {
264
+ outputRight = speed ;
265
+ outputLeft = ( ( angle - 180 ) / 80 ) * speed ;
266
+ } else if ( angle > 260 && angle < 280 ) {
267
+ outputRight = outputLeft = speed ;
268
+ } else if ( angle >= 280 && angle <= 350 ) {
269
+ outputRight = ( ( 360 - angle ) / 80 ) * speed ;
270
+ outputLeft = speed ;
271
+ } else if ( angle > 350 || angle < 10 ) {
272
+ outputRight = 0 ;
273
+ outputLeft = speed ;
274
+ }
275
+ }
276
+
277
+ $ ( '#pos-x' ) . html ( 'x: ' + x + 'px' ) ;
278
+ $ ( '#pos-y' ) . html ( 'y: ' + y + 'px' ) ;
279
+ $ ( '#speed' ) . html ( 'Hastighet: ' + speed ) ;
280
+ $ ( '#angle' ) . html ( 'Vinkel: ' + angle ) ;
281
+ $ ( '#output-left' ) . html ( 'Pådrag V: ' + Math . round ( outputLeft ) ) ;
282
+ $ ( '#output-right' ) . html ( 'Pådrag H: ' + Math . round ( outputRight ) ) ;
283
+
284
+ $ ( "#sliderLeft" ) . val ( outputLeft ) ;
285
+ $ ( "#sliderRight" ) . val ( outputRight ) ;
286
+
287
+ var charVal = new Uint8Array ( 20 ) ;
288
+
289
+ var interrupt = 0 ;
290
+
291
+ // Sjekker i hvilket intervall slider-verdien er, og sender korresponderende verdi
292
+ // via BLE til firmware.
293
+ // Setter 1. bit lik 1 for å tenne 1. LED osv.
294
+ writePermission = 0 ;
295
+
296
+ charVal [ 10 ] = outputRight ; // Motor 1
297
+ charVal [ 14 ] = direction ;
298
+
299
+ charVal [ 11 ] = outputLeft ; // Motor 2
300
+ charVal [ 15 ] = direction ;
301
+
302
+ charVal [ 12 ] = outputLeft ; // Motor 3
303
+ charVal [ 16 ] = direction ;
304
+
305
+ charVal [ 13 ] = outputRight ; // Motor 4
306
+ charVal [ 17 ] = direction ;
307
+
308
+
309
+
310
+ if ( readWriteCharacteristic && ( writePermission == 1 ) && ( interrupt != 1 ) ) {
311
+
312
+ return readWriteCharacteristic . writeValue ( charVal )
313
+ . then ( writeReturn => {
314
+ writePermission = 1 ;
315
+ console . log ( 'Sendt: ' + charVal ) ;
316
+ } ) ;
317
+ } else if ( interrupt == 1 ) {
318
+ if ( writePermission == 1 )
319
+ interruptWrite ( charVal ) ;
320
+ else
321
+ setTimeout ( function ( ) {
322
+ //interruptWrite(charVal);
323
+ } , 100 ) ;
324
+ } else if ( writePermission == 0 ) {
325
+ discardedPackets . push ( charVal ) ;
326
+ }
327
+
328
+
329
+
330
+
331
+ } ) ;
332
+
333
+
334
+
335
+
336
+ $ ( '#container' ) . on ( "tapend" , function ( ) {
337
+
338
+ $ ( '#pos-x' ) . html ( 'x: 0px reset' ) ;
339
+ $ ( '#pos-y' ) . html ( 'y: 0px reset ' ) ;
340
+
341
+ $ ( '#speed' ) . html ( 'Hastighet: 0' ) ;
342
+ $ ( '#angle' ) . html ( 'Vinkel: 0' ) ;
343
+
344
+ $ ( '#output-left' ) . html ( 'Pådrag V: 0' ) ;
345
+ $ ( '#output-right' ) . html ( 'Pådrag H: 0' ) ;
346
+
347
+ $ ( "#sliderLeft" ) . val ( 0 ) ;
348
+ $ ( "#sliderRight" ) . val ( 0 ) ;
349
+
350
+ tapEnd = 1 ;
351
+
352
+ var charVal = new Uint8Array ( 20 ) ;
353
+
354
+ setTimeout ( function ( ) {
355
+ if ( writePermission )
356
+ readWriteCharacteristic . writeValue ( charVal ) ;
357
+ else {
358
+ setTimeout ( function ( ) {
359
+ readWriteCharacteristic . writeValue ( charVal ) ;
360
+ } , 300 ) ;
361
+ }
362
+
363
+ } , 100 ) ;
364
+
365
+
366
+ } ) ;
367
+
368
+ </ script >
369
+
370
+
371
+ </ body >
372
+ </ html >
0 commit comments