rabbit-slide-hasumikin-RubyConfTaiwan2023 2023.12.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rabbit +1 -0
- data/PicoRuby_ep4.rab +508 -0
- data/README.rd +24 -0
- data/Rakefile +17 -0
- data/config.yaml +24 -0
- data/images/QR_R2P2.png +0 -0
- data/images/QR_picoruby.png +0 -0
- data/images/QR_prk_firmware.png +0 -0
- data/images/R2D2_mosaic.png +0 -0
- data/images/boot_button_1.png +0 -0
- data/images/broadcaster_bb.png +0 -0
- data/images/c3p0_icon-icons.com_76936.png +0 -0
- data/images/disable-bluetooth.jpg +0 -0
- data/images/download-r2p2.png +0 -0
- data/images/ewok_icon-icons.com_76943.png +0 -0
- data/images/hasumi.jpg +0 -0
- data/images/hello_taiwan.jpg +0 -0
- data/images/install-uf2.png +0 -0
- data/images/kamos-2023.jpg +0 -0
- data/images/lcd-and-thermo.jpg +0 -0
- data/images/mark_g.png +0 -0
- data/images/mark_y.png +0 -0
- data/images/observer_bb.png +0 -0
- data/images/pico-and-pico_w.jpg +0 -0
- data/images/r2d2_icon-icons.com_76952.png +0 -0
- data/images/setup.jpg +0 -0
- data/images/star-background.jpg +0 -0
- data/images/teraterm.png +0 -0
- data/images/title-background.png +0 -0
- data/pdf/RubyConfTaiwan2023-PicoRuby_ep4.pdf +0 -0
- data/theme.rb +182 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ed5c251ae68675cfad989272e87c634d1f9d2922d2037bda80b02905aecbf9e6
|
4
|
+
data.tar.gz: a152b4b8cf5d17656ce7b0650e9646e6bbf73d1923155bab027f1075181bf703
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c801ae7cbdf4a9c25b1c986e33b03ec9be314f642dff50c092c72339f4ec568ffcd1f95e5f1dd9683ba946f1d5f7ee4ccdfb14315a02133f064f889f78b7f58c
|
7
|
+
data.tar.gz: d9229b3b921d4cefd68a38871698a85c4e1c3e0b1b11fb024c91e3a198fd5aef236365913565aa346ebe5844707c1abedc94836da76bc2a7bae223845543d0d8
|
data/.rabbit
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
PicoRuby_ep4.rab
|
data/PicoRuby_ep4.rab
ADDED
@@ -0,0 +1,508 @@
|
|
1
|
+
= pico
|
2
|
+
|
3
|
+
: subtitle
|
4
|
+
THE RISE OF MICROCONTROLLER
|
5
|
+
: author
|
6
|
+
ruby
|
7
|
+
: content-source
|
8
|
+
EPISODE Ⅳ
|
9
|
+
: institution
|
10
|
+
@hasumikin
|
11
|
+
: place
|
12
|
+
RubyConf Taiwan 2023
|
13
|
+
: date
|
14
|
+
Dec. 15, 2023
|
15
|
+
: allotted-time
|
16
|
+
38m
|
17
|
+
: theme
|
18
|
+
theme
|
19
|
+
|
20
|
+
= sub_chapter
|
21
|
+
Find PicoRuby's history on the internet
|
22
|
+
\n
|
23
|
+
\n
|
24
|
+
EPISODE Ⅱ
|
25
|
+
\n
|
26
|
+
(('tag:large:ATTACK OF THE RAKE'))
|
27
|
+
\n
|
28
|
+
\n
|
29
|
+
EPISODE Ⅲ
|
30
|
+
\n
|
31
|
+
(('tag:large:REVENGE OF THE STDIN'))
|
32
|
+
\n
|
33
|
+
\n
|
34
|
+
Extra edition in Euruko 2023
|
35
|
+
\n
|
36
|
+
(('tag:large:"A Beginner's Complete Guide"'))
|
37
|
+
|
38
|
+
== prop
|
39
|
+
: hide-title
|
40
|
+
true
|
41
|
+
|
42
|
+
= self.inspect
|
43
|
+
|
44
|
+
* Hitoshi HASUMI
|
45
|
+
* hasumikin (('tag:small:(GitHub ,ex-Twitter, Bluesky and Mastodon)'))
|
46
|
+
* Creator of PicoRuby and PRK Firmware
|
47
|
+
* Committer of CRuby's IRB and Reline
|
48
|
+
* First prize of Fukuoka Ruby Award\n(2020 and 2022✌️)
|
49
|
+
* A final nominee of Ruby Prize 2021
|
50
|
+
|
51
|
+
# image
|
52
|
+
# src = images/hasumi.jpg
|
53
|
+
# align = right
|
54
|
+
# relative-height = 95
|
55
|
+
# relative_margin_top = 50
|
56
|
+
# relative_margin_left = 25
|
57
|
+
|
58
|
+
= I have a favor to ask
|
59
|
+
|
60
|
+
(('tag:center'))
|
61
|
+
If possible, please turn off your Bluetooth
|
62
|
+
|
63
|
+
# image
|
64
|
+
# src = images/disable-bluetooth.jpg
|
65
|
+
# relative_height = 80
|
66
|
+
|
67
|
+
(('tag:center'))
|
68
|
+
To avoid channel congestion during my talk
|
69
|
+
|
70
|
+
= Let's begin 1/5
|
71
|
+
* Connect Pi Pico and PC while\npressing the BOOTSEL button
|
72
|
+
* You'll find "RPI-RP2" drive\nin file manager
|
73
|
+
|
74
|
+
# image
|
75
|
+
# align = right
|
76
|
+
# src = images/boot_button_1.png
|
77
|
+
# relative-height = 80
|
78
|
+
# relative_margin_left = 0
|
79
|
+
# relative_margin_top = 0
|
80
|
+
|
81
|
+
(('tag:right'))
|
82
|
+
(('tag:xx-small'))\n\n\n\n\n\n\n
|
83
|
+
https://www.raspberrypi.org/documentation/rp2040/getting-started
|
84
|
+
|
85
|
+
= Let's begin 2/5
|
86
|
+
* Download the latest\n`((*R2P2*))-*.uf2`\nfrom GitHub
|
87
|
+
|
88
|
+
# image
|
89
|
+
# align = right
|
90
|
+
# src = images/download-r2p2.png
|
91
|
+
# relative-height = 90
|
92
|
+
# relative_margin_left = 20
|
93
|
+
# relative_margin_top = 0
|
94
|
+
|
95
|
+
(('tag:x-small'))\n\n\n\n
|
96
|
+
https://github.com/picoruby/((*R2P2*))/releases
|
97
|
+
|
98
|
+
= Let's begin 3/5
|
99
|
+
|
100
|
+
* Drag & drop `((*R2P2*))-*.uf2` into RPI-RP2 drive
|
101
|
+
|
102
|
+
# image
|
103
|
+
# align = bottom
|
104
|
+
# src = images/install-uf2.png
|
105
|
+
# relative-height = 90
|
106
|
+
# relative_margin_left = 0
|
107
|
+
# relative_margin_top = 1
|
108
|
+
|
109
|
+
= Let's begin 4/5
|
110
|
+
* Open a proper\nserial port on\nterminal emulator
|
111
|
+
|
112
|
+
# image
|
113
|
+
# align = right
|
114
|
+
# src = images/teraterm.png
|
115
|
+
# relative-height = 90
|
116
|
+
# relative_margin_left = 12
|
117
|
+
# relative_margin_top = 0
|
118
|
+
|
119
|
+
= Let's begin 5/5
|
120
|
+
* ((*R2P2*)) is a Unix-like shell\nrunning on Pi Pico
|
121
|
+
* You can use some\ncommands like `cd`,\n`ls`, `mkdir`, and `((*irb*))`
|
122
|
+
* Every computing process\nis happening on Pi Pico
|
123
|
+
|
124
|
+
# image
|
125
|
+
# align = right
|
126
|
+
# src = images/teraterm.png
|
127
|
+
# relative-height = 90
|
128
|
+
# relative_margin_left = 20
|
129
|
+
# relative_margin_top = 5
|
130
|
+
|
131
|
+
= By the way, ((*R2P2*)) stands for
|
132
|
+
|
133
|
+
\n\n
|
134
|
+
(('tag:large:((*R*))uby on'))
|
135
|
+
\n
|
136
|
+
(('tag:large:((*R*))aspberry'))
|
137
|
+
\n
|
138
|
+
(('tag:large:((*P*))i'))
|
139
|
+
\n
|
140
|
+
(('tag:large:((*P*))ico'))
|
141
|
+
|
142
|
+
# image
|
143
|
+
# align = right
|
144
|
+
# src = images/R2D2_mosaic.png
|
145
|
+
# relative-height = 90
|
146
|
+
# relative_margin_left = -10
|
147
|
+
# relative_margin_top = 0
|
148
|
+
|
149
|
+
= Today's setup
|
150
|
+
|
151
|
+
* Raspberry Pi Pico W * 2
|
152
|
+
* AQM0802 charactor\ndisplay module
|
153
|
+
* ADT7310 thermo\nsensor module
|
154
|
+
* FTDI USB-TTL serial\ncoverter cable
|
155
|
+
|
156
|
+
# image
|
157
|
+
# align = right
|
158
|
+
# src = images/setup.jpg
|
159
|
+
# relative-height = 85
|
160
|
+
# relative_margin_left = 10
|
161
|
+
# relative_margin_top = 0
|
162
|
+
|
163
|
+
= Raspberry Pi "Pico" and "Pico W"
|
164
|
+
|
165
|
+
# image
|
166
|
+
# src = images/pico-and-pico_w.jpg
|
167
|
+
# relative_height = 100
|
168
|
+
# draw1 = [text, Pico, 0.18, 0.75, {color: white, size: 80, font_family: 'Courier Prime', weight: bold}]
|
169
|
+
# draw2 = [text, Pico W, 0.5, 0.75, {color: white, size: 80, font_family: 'Courier Prime', weight: bold}]
|
170
|
+
|
171
|
+
= GPIO
|
172
|
+
|
173
|
+
irb> gpio = CYW43::GPIO.new(CYW43::GPIO::LED_PIN)
|
174
|
+
# gpio = GPIO.new(25, GPIO::OUT) # If Pico w/o W
|
175
|
+
irb> gpio.write 1 #=> LED turns on
|
176
|
+
irb> gpio.write 0 #=> LED turns off
|
177
|
+
irb> 3.times do
|
178
|
+
irb* gpio.write 1
|
179
|
+
irb* sleep 1
|
180
|
+
irb* gpio.write 0
|
181
|
+
irb* sleep 1
|
182
|
+
irb* end #=> LED blinks three times
|
183
|
+
|
184
|
+
= LED wraps GPIO
|
185
|
+
|
186
|
+
# enscript ruby
|
187
|
+
# /lib/led.rb in R2P2 drive
|
188
|
+
require 'gpio'
|
189
|
+
require 'cyw43'
|
190
|
+
CYW43.init
|
191
|
+
class LED
|
192
|
+
def initialize
|
193
|
+
@gpio = CYW43::GPIO.new(CYW43::GPIO::LED_PIN)
|
194
|
+
# = GPIO.new(25, GPIO::OUT) # If Pico w/o W
|
195
|
+
end
|
196
|
+
def on
|
197
|
+
@gpio.write 1
|
198
|
+
end
|
199
|
+
def off
|
200
|
+
@gpio.write 0
|
201
|
+
end
|
202
|
+
def invert
|
203
|
+
@gpio.read == 1 ? off : on
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
= LED wraps GPIO
|
208
|
+
|
209
|
+
irb> require 'led'
|
210
|
+
irb> led = LED.new
|
211
|
+
irb> 3.times do
|
212
|
+
irb* led.invert
|
213
|
+
irb* sleep 1
|
214
|
+
irb* end
|
215
|
+
|
216
|
+
= Peripherals for serial communication
|
217
|
+
* I2C: To communicate between integrated circuits with support for multiple devices connected to the same bus
|
218
|
+
* SPI: To facilitate high-speed communication between microcontrollers and peripheral devices
|
219
|
+
* UART: To establish asynchronous serial communication between devices
|
220
|
+
|
221
|
+
= I2C
|
222
|
+
|
223
|
+
irb> require 'i2c'
|
224
|
+
irb> i2c = I2C.new(unit: :RP2040_I2C1, sda_pin: 26, scl_pin: 27)
|
225
|
+
irb> [0x38, 0x39, 0x14, 0x70, 0x56, 0x6c].each { |i| i2c.write(0x3e, 0, i); sleep_ms 1 }
|
226
|
+
irb> [0x38, 0x0c, 0x01].each { |i| i2c.write(0x3e, 0, i); sleep_ms 1 }
|
227
|
+
irb> "Hello,".bytes.each { |c| i2c.write(0x3e, 0x40, c); sleep_ms 1 }
|
228
|
+
irb> i2c.write(0x3e, 0, 0x80|0x40)
|
229
|
+
irb> "Taiwan!".bytes.each { |c| i2c.write(0x3e, 0x40, c); sleep_ms 1 }
|
230
|
+
|
231
|
+
\n
|
232
|
+
|
233
|
+
# image
|
234
|
+
# src = images/hello_taiwan.jpg
|
235
|
+
# relative_height = 110
|
236
|
+
# relative_margin_top = -15
|
237
|
+
|
238
|
+
= LCD wraps I2C
|
239
|
+
|
240
|
+
# enscript ruby
|
241
|
+
# /lib/lcd.rb in R2P2 drive
|
242
|
+
require 'i2c'
|
243
|
+
class LCD
|
244
|
+
ADDRESS = 0x3e # 0x7c == (0x3e << 1) + 0 (R/W)
|
245
|
+
def initialize(i2c:)
|
246
|
+
@i2c = i2c
|
247
|
+
reset
|
248
|
+
end
|
249
|
+
def reset
|
250
|
+
[0x38, 0x39, 0x14, 0x70, 0x56, 0x6c].each { |i| @i2c.write(ADDRESS, 0, i) }
|
251
|
+
sleep_ms 200
|
252
|
+
[0x38, 0x0c, 0x01].each { |i| @i2c.write(ADDRESS, 0, i) }
|
253
|
+
end
|
254
|
+
def putc(c)
|
255
|
+
@i2c.write(ADDRESS, 0x40, c)
|
256
|
+
sleep_ms 1
|
257
|
+
end
|
258
|
+
def print(line)
|
259
|
+
line.bytes.each { |c| putc c }
|
260
|
+
end
|
261
|
+
# ...
|
262
|
+
# See https://github.com/picoruby/picoruby/tree/master/mrbgems/picoruby-ble/example/broadcaster-observer
|
263
|
+
|
264
|
+
= LCD wraps I2C
|
265
|
+
|
266
|
+
irb> require 'lcd'
|
267
|
+
irb> lcd = LCD.new(i2c: I2C.new(unit: :RP2040_I2C1, sda_pin: 26, scl_pin: 27))
|
268
|
+
irb> lcd.print "Hello,"
|
269
|
+
irb> lcd.break_line
|
270
|
+
irb> lcd.print "Taiwan!"
|
271
|
+
|
272
|
+
\n
|
273
|
+
|
274
|
+
# image
|
275
|
+
# src = images/hello_taiwan.jpg
|
276
|
+
# relative_height = 110
|
277
|
+
# relative_margin_top = -5
|
278
|
+
|
279
|
+
= SPI
|
280
|
+
|
281
|
+
irb> require 'spi'
|
282
|
+
irb> spi = SPI.new(unit: :RP2040_SPI0, cipo_pin: 16,
|
283
|
+
cs_pin: 17, sck_pin: 18, copi_pin: 19)
|
284
|
+
irb> spi.select
|
285
|
+
irb> spi.write(255,255,255,255) # Reset
|
286
|
+
irb> spi.write(0x54) # Start continuous mode
|
287
|
+
irb> data = spi.read(2).bytes
|
288
|
+
irb> temp = data[0] << 8 | data[1]
|
289
|
+
irb> temp / 128.0 # Convert to Celsius
|
290
|
+
=> 19.5621
|
291
|
+
|
292
|
+
= THERMO wraps SPI
|
293
|
+
|
294
|
+
# enscript ruby
|
295
|
+
# /lib/thermo.rb in R2P2 drive
|
296
|
+
require 'spi'
|
297
|
+
class THERMO
|
298
|
+
def initialize(unit:, sck_pin:, cipo_pin:, copi_pin:, cs_pin:)
|
299
|
+
@spi = SPI.new(unit: unit, frequency: 500_000, mode: 0, cs_pin: cs_pin,
|
300
|
+
sck_pin: sck_pin, cipo_pin: cipo_pin, copi_pin: copi_pin
|
301
|
+
)
|
302
|
+
@spi.select
|
303
|
+
@spi.write 0xFF, 0xFF, 0xFF, 0xFF # Reset
|
304
|
+
@spi.write 0x54 # Start continuous mode
|
305
|
+
sleep_ms 240
|
306
|
+
end
|
307
|
+
|
308
|
+
def read
|
309
|
+
data = @spi.read(2).bytes
|
310
|
+
temp = (data[0] << 8 | data[1]) >> 3
|
311
|
+
# If it minus?
|
312
|
+
temp -= 0x2000 if 0 < temp & 0b1_0000_0000_0000
|
313
|
+
temp / 16.0 # Convert to Celsius
|
314
|
+
end
|
315
|
+
end
|
316
|
+
# See https://github.com/picoruby/picoruby/tree/master/mrbgems/picoruby-ble/example/broadcaster-observer
|
317
|
+
|
318
|
+
= THERMO wraps SPI
|
319
|
+
|
320
|
+
irb> require 'thermo'
|
321
|
+
irb> thermo = THERMO.new(unit: :RP2040_SPI0,
|
322
|
+
cipo_pin: 16, cs_pin: 17, sck_pin: 18, copi_pin: 19)
|
323
|
+
irb> thermo.read
|
324
|
+
=> 19.5621
|
325
|
+
|
326
|
+
= LCD and THERMO
|
327
|
+
|
328
|
+
irb> require 'lcd'
|
329
|
+
irb> lcd = LCD.new(i2c: I2C.new(unit: :RP2040_I2C1, sda_pin: 26, scl_pin: 27))
|
330
|
+
irb> require 'thermo'
|
331
|
+
irb> thermo = THERMO.new(unit: :RP2040_SPI0,
|
332
|
+
cipo_pin: 16, cs_pin: 17, sck_pin: 18, copi_pin: 19)
|
333
|
+
irb> lcd.print sprintf("%5.2f \xdfC", thermo.read)
|
334
|
+
|
335
|
+
\n
|
336
|
+
|
337
|
+
# image
|
338
|
+
# src = images/lcd-and-thermo.jpg
|
339
|
+
# relative_height = 115
|
340
|
+
# relative_margin_top = -8
|
341
|
+
|
342
|
+
= UART
|
343
|
+
|
344
|
+
irb> require 'uart'
|
345
|
+
irb> uart = UART.new(unit: :RP2040_UART0, txd_pin: 16, rxd_pin: 17, baudrate: 115200)
|
346
|
+
irb> uart.puts "Hello from Pico!"
|
347
|
+
=> nil
|
348
|
+
irb> while true
|
349
|
+
irb* if c = uart.read
|
350
|
+
irb* uart.write c # Echo back
|
351
|
+
irb* print c
|
352
|
+
irb* end
|
353
|
+
irb* end
|
354
|
+
Hello to Pico! # <= "Hello to Pico!" in UART device
|
355
|
+
|
356
|
+
(('tag:center'))
|
357
|
+
\n
|
358
|
+
You don't need to wrap UART. Use as it is
|
359
|
+
|
360
|
+
= BLE Broadcaster
|
361
|
+
# image
|
362
|
+
# src = images/broadcaster_bb.png
|
363
|
+
# align = right
|
364
|
+
# relative_height = 90
|
365
|
+
# relative_margin_left = 7
|
366
|
+
# draw1 = [text, THERMO, 0.63, 0.09, {color: blue, size: 70, font_family: 'Courier Prime', weight: bold}]
|
367
|
+
|
368
|
+
* Pin assign
|
369
|
+
* 3V3 to {LCD,THERMO}:VCC
|
370
|
+
* GND to {LCD,THERMO}:GND
|
371
|
+
* GPIO16 to THERMO:SDO
|
372
|
+
* GPIO17 to THERMO:CS
|
373
|
+
* GPIO18 to THERMO:SCL
|
374
|
+
* GPIO19 to THERMO:SDI
|
375
|
+
* GPIO26 to LCD:SDA
|
376
|
+
* GPIO27 to LCD:SCL
|
377
|
+
|
378
|
+
= BLE Observer
|
379
|
+
# image
|
380
|
+
# src = images/observer_bb.png
|
381
|
+
# align = right
|
382
|
+
# relative_height = 90
|
383
|
+
# relative_margin_left = 5
|
384
|
+
# draw1 = [text, USB-TTL, 0.33, 0.1, {color: red, size: 70, font_family: 'Courier Prime', weight: bold}]
|
385
|
+
|
386
|
+
* Pin assign
|
387
|
+
* 3V3 to USB-TTL:VCC
|
388
|
+
* GND to USB-TTL:GND
|
389
|
+
* GPIO16 to USB-TTL:RX
|
390
|
+
* GPIO17 to USB-TTL:TX
|
391
|
+
|
392
|
+
= Gems in Broadcaster and Observer
|
393
|
+
|
394
|
+
# in Broadcaster
|
395
|
+
$> ls /lib
|
396
|
+
lcd.rb
|
397
|
+
thermo.rb
|
398
|
+
|
399
|
+
# in Observer
|
400
|
+
$> ls /lib
|
401
|
+
led.rb
|
402
|
+
|
403
|
+
= BLE Broadcaster
|
404
|
+
|
405
|
+
# enscript ruby
|
406
|
+
# /home/app.rb in R2P2 drive
|
407
|
+
class DemoBroadcaster < BLE::Broadcaster
|
408
|
+
def initialize
|
409
|
+
super(nil)
|
410
|
+
led = CYW43::GPIO.new(CYW43::GPIO::LED_PIN)
|
411
|
+
@lcd = LCD.new(i2c: I2C.new(unit: :RP2040_I2C1, sda_pin: 26, scl_pin: 27))
|
412
|
+
@thermo = THERMO.new(unit: :RP2040_SPI0, cipo_pin: 16, cs_pin: 17, sck_pin: 18, copi_pin: 19)
|
413
|
+
@counter = 0
|
414
|
+
end
|
415
|
+
def adv_data(send_data)
|
416
|
+
BLE::AdvertisingData.build do |adv|
|
417
|
+
adv.add(0x01, 0xFF)
|
418
|
+
adv.add(0x09, "PicoRuby")
|
419
|
+
adv.add(0xFF, send_data)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
def heartbeat_callback
|
423
|
+
Machine.using_delay do
|
424
|
+
temperature = @thermo.read
|
425
|
+
@lcd.clear
|
426
|
+
@lcd.print sprintf("%5.2f \xdfC", temperature)
|
427
|
+
@lcd.break_line
|
428
|
+
@lcd.print "+" * (@counter % 9)
|
429
|
+
advertise(adv_data (temperature * 100).to_i.to_s)
|
430
|
+
end
|
431
|
+
@counter += 1
|
432
|
+
Watchdog.update
|
433
|
+
end
|
434
|
+
def packet_callback(event_packet)
|
435
|
+
case event_packet[0]&.ord # event type
|
436
|
+
when 0x60 # BTSTACK_EVENT_STATE
|
437
|
+
return unless event_packet[2]&.ord == BLE::HCI_STATE_WORKING
|
438
|
+
@state = :HCI_STATE_WORKING
|
439
|
+
Watchdog.enable(2000)
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
DemoBroadcaster.new.start
|
444
|
+
# See https://github.com/picoruby/picoruby/tree/master/mrbgems/picoruby-ble/example/broadcaster-observer
|
445
|
+
|
446
|
+
= BLE Observer
|
447
|
+
|
448
|
+
# enscript ruby
|
449
|
+
# /home/app.rb in R2P2 drive
|
450
|
+
class DemoObserver < BLE::Observer
|
451
|
+
def initialize
|
452
|
+
super
|
453
|
+
@led = LED.new
|
454
|
+
@uart = UART.new(unit: :RP2040_UART0, txd_pin: 16, rxd_pin: 17, baudrate: 115200)
|
455
|
+
@uart.puts 'Start BLE Observer Demo'
|
456
|
+
@last_time_found = Time.now.to_i
|
457
|
+
Watchdog.enable(4000)
|
458
|
+
end
|
459
|
+
def advertising_report_callback(adv_report)
|
460
|
+
if adv_report&.reports[:complete_local_name] == 'PicoRuby'
|
461
|
+
now = Time.now.to_i
|
462
|
+
if 2 < now - @last_time_found
|
463
|
+
@uart.puts sprintf("%5.2f degC", adv_report.reports[:manufacturer_specific_data].to_f / 100)
|
464
|
+
@last_time_found = now
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
def heartbeat_callback
|
469
|
+
Watchdog.update
|
470
|
+
@led.invert
|
471
|
+
end
|
472
|
+
end
|
473
|
+
DemoObserver.new.scan(stop_state: :no_stop)
|
474
|
+
# See https://github.com/picoruby/picoruby/tree/master/mrbgems/picoruby-ble/example/broadcaster-observer
|
475
|
+
|
476
|
+
= Real world application
|
477
|
+
|
478
|
+
# image
|
479
|
+
# src = images/kamos-2023.jpg
|
480
|
+
# relative_height = 100
|
481
|
+
|
482
|
+
= Wrap up
|
483
|
+
|
484
|
+
* PicoRuby is a Ruby implementaiton targeting on one-chip microcontroller
|
485
|
+
* Built-in peripheral gems for general IOs:\nGPIO, I2C, SPI, UART, ADC, and PWM are ready
|
486
|
+
* You can incrementally write your device drivers and applications with PicoIRB
|
487
|
+
* BLE gem is also almost ready for real applications
|
488
|
+
|
489
|
+
= chapter
|
490
|
+
(('tag:x-large:stargaze at'))
|
491
|
+
# image
|
492
|
+
# src = images/QR_picoruby.png
|
493
|
+
# relative_height = 80
|
494
|
+
(('tag:center'))github.com/picoruby/picoruby
|
495
|
+
== prop
|
496
|
+
: hide-title
|
497
|
+
true
|
498
|
+
|
499
|
+
= chapter
|
500
|
+
(('tag:x-large:may the'))
|
501
|
+
\n
|
502
|
+
(('tag:xx-large:source'))
|
503
|
+
\n
|
504
|
+
(('tag:x-large:be with you'))
|
505
|
+
== prop
|
506
|
+
: hide-title
|
507
|
+
true
|
508
|
+
|
data/README.rd
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
= PicoRuby epsode 4
|
2
|
+
|
3
|
+
Presentation slide for RubyConf Taiwan 2023
|
4
|
+
|
5
|
+
== For author
|
6
|
+
|
7
|
+
=== Show
|
8
|
+
|
9
|
+
rake
|
10
|
+
|
11
|
+
=== Publish
|
12
|
+
|
13
|
+
rake publish
|
14
|
+
|
15
|
+
== For viewers
|
16
|
+
|
17
|
+
=== Install
|
18
|
+
|
19
|
+
gem install rabbit-slide-hasumikin-RubyConfTaiwan2023
|
20
|
+
|
21
|
+
=== Show
|
22
|
+
|
23
|
+
rabbit rabbit-slide-hasumikin-RubyConfTaiwan2023.gem
|
24
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rabbit/task/slide"
|
2
|
+
|
3
|
+
# Edit ./config.yaml to customize meta data
|
4
|
+
|
5
|
+
spec = nil
|
6
|
+
Rabbit::Task::Slide.new do |task|
|
7
|
+
spec = task.spec
|
8
|
+
# spec.files += Dir.glob("doc/**/*.*")
|
9
|
+
# spec.files -= Dir.glob("private/**/*.*")
|
10
|
+
# spec.add_runtime_dependency("rabbit-theme-YOUR-THEME")
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Tag #{spec.version}"
|
14
|
+
task :tag do
|
15
|
+
sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
|
16
|
+
sh("git", "push", "--tags")
|
17
|
+
end
|
data/config.yaml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
id: RubyConfTaiwan2023
|
3
|
+
base_name: PicoRuby_ep4
|
4
|
+
tags:
|
5
|
+
- PicoRuby
|
6
|
+
- Peripheral
|
7
|
+
- Microcontroller
|
8
|
+
presentation_date: '2023-12-15'
|
9
|
+
presentation_start_time:
|
10
|
+
presentation_end_time:
|
11
|
+
version: 2023.12.15.0
|
12
|
+
licenses: ["MIT"]
|
13
|
+
slideshare_id:
|
14
|
+
speaker_deck_id:
|
15
|
+
ustream_id:
|
16
|
+
vimeo_id:
|
17
|
+
youtube_id:
|
18
|
+
author:
|
19
|
+
markup_language: :rd
|
20
|
+
name: HASUMI Hitoshi
|
21
|
+
email: hasumikin@gmail.com
|
22
|
+
rubygems_user: hasumikin
|
23
|
+
slideshare_user:
|
24
|
+
speaker_deck_user:
|
data/images/QR_R2P2.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/images/hasumi.jpg
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/images/mark_g.png
ADDED
Binary file
|
data/images/mark_y.png
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/images/setup.jpg
ADDED
Binary file
|
Binary file
|
data/images/teraterm.png
ADDED
Binary file
|
Binary file
|
Binary file
|
data/theme.rb
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
# puts font_families.sort
|
2
|
+
@xxx_large_font_size = screen_size(22 * Pango::SCALE)
|
3
|
+
@xx_large_font_size = screen_size(18 * Pango::SCALE)
|
4
|
+
@x_large_font_size = screen_size(11 * Pango::SCALE)
|
5
|
+
@large_font_size = screen_size(7.5 * Pango::SCALE)
|
6
|
+
@normal_font_size = screen_size(5 * Pango::SCALE)
|
7
|
+
@small_font_size = screen_size(4.5 * Pango::SCALE)
|
8
|
+
@x_small_font_size = screen_size(3.5 * Pango::SCALE)
|
9
|
+
@xx_small_font_size = screen_size(3 * Pango::SCALE)
|
10
|
+
|
11
|
+
@font_family = find_font_family('Franklin Gothic Medium')
|
12
|
+
@monospace_font_family = 'Ricty Discord'
|
13
|
+
@title_font_family = find_font_family('Star Jedi Hollow')
|
14
|
+
|
15
|
+
@default_headline_line_color = '#ffff00'
|
16
|
+
@default_headline_line_width = 2
|
17
|
+
@default_headline_line_expand = false
|
18
|
+
|
19
|
+
@default_emphasis_color = "#ff0000"
|
20
|
+
@default_emphasis_level2_color = "#ffffff"
|
21
|
+
|
22
|
+
set_graffiti_color "#FF2B22"
|
23
|
+
set_graffiti_line_width 5
|
24
|
+
|
25
|
+
#@table_frame_color = "#ffffff"
|
26
|
+
#@table_fill_color = "#0f0428"
|
27
|
+
#@table_body_frame_color = "#ffffff"
|
28
|
+
#@table_body_fill_color = "#3f3468"
|
29
|
+
#@table_head_frame_color = "#ffffff"
|
30
|
+
#@table_head_fill_color = "#rf0428"
|
31
|
+
|
32
|
+
@preformatted_fill_color = '#000000'
|
33
|
+
# @preformatted_centering = true
|
34
|
+
@space = screen_y(1)
|
35
|
+
|
36
|
+
# @margin_left = 300
|
37
|
+
|
38
|
+
@image_slide_number_start_flag_color = "#53575a"
|
39
|
+
@image_slide_number_goal_flag_color = "#a81313"
|
40
|
+
|
41
|
+
#@slide_headline_hide = true
|
42
|
+
|
43
|
+
@slide_background_image = 'images/star-background.jpg'
|
44
|
+
include_theme("slide-background-image")
|
45
|
+
|
46
|
+
@title_slide_background_image = 'images/star-background.jpg'
|
47
|
+
include_theme("title-slide-background-image")
|
48
|
+
|
49
|
+
include_theme('default')
|
50
|
+
|
51
|
+
match(Slide, HeadLine) do |heads|
|
52
|
+
#heads.prop_set("size", 0)
|
53
|
+
heads.prop_set("weight", "normal")
|
54
|
+
set_font_family(heads)
|
55
|
+
end
|
56
|
+
match(Slide) do |slides|
|
57
|
+
slides.prop_set("foreground", "#ffff00")
|
58
|
+
end
|
59
|
+
|
60
|
+
match TitleSlide do |slides|
|
61
|
+
slides.margin_left = @margin_right
|
62
|
+
slides.prop_set("foreground", "#ffff00")
|
63
|
+
end
|
64
|
+
match TitleSlide, Title do |elem|
|
65
|
+
elem.margin_top = -120
|
66
|
+
elem.prop_set "size", @xxx_large_font_size
|
67
|
+
elem.prop_set "font-family", @title_font_family
|
68
|
+
elem.prop_set "weight", "normal"
|
69
|
+
end
|
70
|
+
match TitleSlide, Subtitle do |elem|
|
71
|
+
elem.prop_set "size", @normal_font_size
|
72
|
+
elem.margin_top = -110
|
73
|
+
end
|
74
|
+
match TitleSlide, Author do |elem|
|
75
|
+
elem.margin_top = -180
|
76
|
+
elem.prop_set "size", @xxx_large_font_size
|
77
|
+
elem.prop_set "font-family", @title_font_family
|
78
|
+
end
|
79
|
+
match TitleSlide, ContentSource do |elem|
|
80
|
+
elem.margin_top = -80
|
81
|
+
elem.prop_set "size", @small_font_size
|
82
|
+
elem.prop_set "style", "normal"
|
83
|
+
end
|
84
|
+
match TitleSlide, Place do |elem|
|
85
|
+
elem.prop_set "size", @xx_small_font_size
|
86
|
+
elem.prop_set "style", "normal"
|
87
|
+
end
|
88
|
+
match TitleSlide, Date do |elem|
|
89
|
+
elem.prop_set "size", @xx_small_font_size
|
90
|
+
elem.prop_set "style", "normal"
|
91
|
+
end
|
92
|
+
match TitleSlide, Institution do |elem|
|
93
|
+
elem.margin_top = 50
|
94
|
+
elem.prop_set "size", @x_small_font_size
|
95
|
+
elem.prop_set "style", "normal"
|
96
|
+
end
|
97
|
+
|
98
|
+
#@slide_logo_image = 'images/mark_g.png'
|
99
|
+
#include_theme('slide-logo')
|
100
|
+
|
101
|
+
@item_image_1 = 'images/r2d2_icon-icons.com_76952.png'
|
102
|
+
@item_image_2 = 'images/c3p0_icon-icons.com_76936.png'
|
103
|
+
@item_image_3 = 'images/ewok_icon-icons.com_76943.png'
|
104
|
+
|
105
|
+
include_theme("default-item-mark")
|
106
|
+
|
107
|
+
add_image_path("rabbit-images")
|
108
|
+
|
109
|
+
slide_body = [Slide, Body]
|
110
|
+
item_list_item = [ItemList, ItemListItem]
|
111
|
+
|
112
|
+
indent = 50
|
113
|
+
|
114
|
+
match(*(slide_body + (item_list_item * 1))) do |items|
|
115
|
+
name = "item1"
|
116
|
+
items.delete_pre_draw_proc_by_name(name)
|
117
|
+
items.delete_post_draw_proc_by_name(name)
|
118
|
+
draw_image_mark(items, @item_image_1, name, indent: indent)
|
119
|
+
end
|
120
|
+
|
121
|
+
match(*(slide_body + (item_list_item * 2))) do |items|
|
122
|
+
name = "item2"
|
123
|
+
items.delete_pre_draw_proc_by_name(name)
|
124
|
+
items.delete_post_draw_proc_by_name(name)
|
125
|
+
draw_image_mark(items, @item_image_2, name, indent: indent)
|
126
|
+
end
|
127
|
+
|
128
|
+
match(*(slide_body + (item_list_item * 3))) do |items|
|
129
|
+
name = "item3"
|
130
|
+
items.delete_pre_draw_proc_by_name(name)
|
131
|
+
items.delete_post_draw_proc_by_name(name)
|
132
|
+
draw_image_mark(items, @item_image_3, name, indent: indent)
|
133
|
+
end
|
134
|
+
|
135
|
+
enum_list_item = [EnumList, EnumListItem]
|
136
|
+
|
137
|
+
match(*(slide_body + enum_list_item + item_list_item)) do |items|
|
138
|
+
name = "enum-item1"
|
139
|
+
items.delete_pre_draw_proc_by_name(name)
|
140
|
+
items.delete_post_draw_proc_by_name(name)
|
141
|
+
draw_image_mark(items, @item_image_1, name, indent: indent)
|
142
|
+
end
|
143
|
+
|
144
|
+
match(*(slide_body + enum_list_item + (item_list_item * 2))) do |items|
|
145
|
+
name = "enum-item2"
|
146
|
+
items.delete_pre_draw_proc_by_name(name)
|
147
|
+
items.delete_post_draw_proc_by_name(name)
|
148
|
+
draw_image_mark(items, @item_image_2, name, indent: indent)
|
149
|
+
end
|
150
|
+
|
151
|
+
# table
|
152
|
+
all_table = ["**", Table]
|
153
|
+
match(*(all_table + [TableBody, TableRow, TableCell])) do |cells|
|
154
|
+
set_font_family(cells, @monospace_font_family)
|
155
|
+
end
|
156
|
+
match(*(all_table + [TableHead, TableRow, TableHeader])) do |headers|
|
157
|
+
set_font_family(headers, @monospace_font_family)
|
158
|
+
end
|
159
|
+
|
160
|
+
match("**", Emphasis, Emphasis) do |texts|
|
161
|
+
texts.prop_set("foreground", @default_emphasis_level2_color)
|
162
|
+
texts.prop_set("weight", "normal")
|
163
|
+
end
|
164
|
+
|
165
|
+
# Chapter
|
166
|
+
match Slide do |slides|
|
167
|
+
slides.each do |slide|
|
168
|
+
if slide.match?(/sub_chapter/)
|
169
|
+
slide.horizontal_centering = true
|
170
|
+
elsif slide.match?(/chapter/)
|
171
|
+
set_font_family slide, @title_font_family
|
172
|
+
slide.horizontal_centering = true
|
173
|
+
elsif slide.match?(/cite/)
|
174
|
+
slide.prop_set "foreground", "#222222"
|
175
|
+
slide.horizontal_centering = true
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
match("**", PreformattedBlock) do |blocks|
|
181
|
+
blocks.prop_set("foreground", "#00FFAF")
|
182
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbit-slide-hasumikin-RubyConfTaiwan2023
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2023.12.15.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- HASUMI Hitoshi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-12-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rabbit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.2
|
27
|
+
description: Presentation slide for RubyConf Taiwan 2023
|
28
|
+
email:
|
29
|
+
- hasumikin@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".rabbit"
|
35
|
+
- PicoRuby_ep4.rab
|
36
|
+
- README.rd
|
37
|
+
- Rakefile
|
38
|
+
- config.yaml
|
39
|
+
- images/QR_R2P2.png
|
40
|
+
- images/QR_picoruby.png
|
41
|
+
- images/QR_prk_firmware.png
|
42
|
+
- images/R2D2_mosaic.png
|
43
|
+
- images/boot_button_1.png
|
44
|
+
- images/broadcaster_bb.png
|
45
|
+
- images/c3p0_icon-icons.com_76936.png
|
46
|
+
- images/disable-bluetooth.jpg
|
47
|
+
- images/download-r2p2.png
|
48
|
+
- images/ewok_icon-icons.com_76943.png
|
49
|
+
- images/hasumi.jpg
|
50
|
+
- images/hello_taiwan.jpg
|
51
|
+
- images/install-uf2.png
|
52
|
+
- images/kamos-2023.jpg
|
53
|
+
- images/lcd-and-thermo.jpg
|
54
|
+
- images/mark_g.png
|
55
|
+
- images/mark_y.png
|
56
|
+
- images/observer_bb.png
|
57
|
+
- images/pico-and-pico_w.jpg
|
58
|
+
- images/r2d2_icon-icons.com_76952.png
|
59
|
+
- images/setup.jpg
|
60
|
+
- images/star-background.jpg
|
61
|
+
- images/teraterm.png
|
62
|
+
- images/title-background.png
|
63
|
+
- pdf/RubyConfTaiwan2023-PicoRuby_ep4.pdf
|
64
|
+
- theme.rb
|
65
|
+
homepage: https://slide.rabbit-shocker.org/authors/hasumikin/RubyConfTaiwan2023/
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubygems_version: 3.4.13
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: PicoRuby epsode 4
|
88
|
+
test_files: []
|