1741 lines
45 KiB
Plaintext
1741 lines
45 KiB
Plaintext
module main
|
|
author unknown
|
|
version 1 0
|
|
description ''
|
|
|
|
|
|
module 'Gesture (PAJ7620)' Input
|
|
author 'José García'
|
|
version 1 0
|
|
tags sensor gesture
|
|
description 'Support for PAJ7620 gesture sensor.
|
|
The "read" block returns the name of the detected gesture.
|
|
Based on github.com/Seeed-Studio/Gesture_PAJ7620'
|
|
variables '_paj7620 initialized'
|
|
|
|
spec 'r' 'paj7620 read' 'paj7620 read'
|
|
spec ' ' '_paj7620 setup' '_paj7620 setup'
|
|
spec 'r' 'paj7620 connected' 'paj7620 connected'
|
|
spec ' ' '_paj7620 setup bank0' '_paj7620 setup bank0'
|
|
spec ' ' '_paj7620 setup bank1' '_paj7620 setup bank1'
|
|
|
|
to '_paj7620 setup' {
|
|
if ('paj7620 connected') {
|
|
'_paj7620 setup bank0'
|
|
'_paj7620 setup bank1'
|
|
i2cSet (hexToInt '73') (hexToInt '65') (hexToInt '12')
|
|
i2cSet (hexToInt '73') (hexToInt 'EF') 0
|
|
'_paj7620 initialized' = 1
|
|
}
|
|
}
|
|
|
|
to '_paj7620 setup bank0' {
|
|
i2cSet (hexToInt '73') (hexToInt 'EF') 0
|
|
local 'i' 1
|
|
local 'list' '3229
|
|
3301
|
|
3400
|
|
3501
|
|
3600
|
|
3707
|
|
3817
|
|
3906
|
|
3A12
|
|
3F00
|
|
4002
|
|
41FF
|
|
4201
|
|
462D
|
|
470F
|
|
483C
|
|
4900
|
|
4A1E
|
|
4B00
|
|
4C20
|
|
4D00
|
|
4E1A
|
|
4F14
|
|
5000
|
|
5110
|
|
5200
|
|
5C02
|
|
5D00
|
|
5E10
|
|
5F3F
|
|
6027
|
|
6128
|
|
6200
|
|
6303
|
|
64F7
|
|
6503
|
|
66D9
|
|
6703
|
|
6801
|
|
69C8
|
|
6A40
|
|
6D04
|
|
6E00
|
|
6F00
|
|
7080
|
|
7100
|
|
7200
|
|
7300
|
|
74F0
|
|
7500
|
|
8042
|
|
8144
|
|
8204
|
|
8320
|
|
8420
|
|
8500
|
|
8610
|
|
8700
|
|
8805
|
|
8918
|
|
8A10
|
|
8B01
|
|
8C37
|
|
8D00
|
|
8EF0
|
|
8F81
|
|
9006
|
|
9106
|
|
921E
|
|
930D
|
|
940A
|
|
950A
|
|
960C
|
|
9705
|
|
980A
|
|
9941
|
|
9A14
|
|
9B0A
|
|
9C3F
|
|
9D33
|
|
9EAE
|
|
9FF9
|
|
A048
|
|
A113
|
|
A210
|
|
A308
|
|
A430
|
|
A519
|
|
A610
|
|
A708
|
|
A824
|
|
A904
|
|
AA1E
|
|
AB1E
|
|
CC19
|
|
CD0B
|
|
CE13
|
|
CF64
|
|
D021
|
|
D10F
|
|
D288
|
|
E001
|
|
E104
|
|
E241
|
|
E3D6
|
|
E400
|
|
E50C
|
|
E60A
|
|
E700
|
|
E800
|
|
E900
|
|
EE07'
|
|
repeatUntil (i > (size list)) {
|
|
local 'reg' ('[data:copyFromTo]' list i (i + 1))
|
|
local 'val' ('[data:copyFromTo]' list (i + 2) (i + 4))
|
|
i2cSet (hexToInt '73') (hexToInt reg) (hexToInt val)
|
|
i += 5
|
|
waitMicros 10
|
|
}
|
|
}
|
|
|
|
to '_paj7620 setup bank1' {
|
|
i2cSet (hexToInt '73') (hexToInt 'EF') 1
|
|
local 'i' 1
|
|
local 'list' '001E
|
|
011E
|
|
020F
|
|
0310
|
|
0402
|
|
0500
|
|
06B0
|
|
0704
|
|
080D
|
|
090E
|
|
0A9C
|
|
0B04
|
|
0C05
|
|
0D0F
|
|
0E02
|
|
0F12
|
|
1002
|
|
1102
|
|
1200
|
|
1301
|
|
1405
|
|
1507
|
|
1605
|
|
1707
|
|
1801
|
|
1904
|
|
1A05
|
|
1B0C
|
|
1C2A
|
|
1D01
|
|
1E00
|
|
2100
|
|
2200
|
|
2300
|
|
2501
|
|
2600
|
|
2739
|
|
287F
|
|
2908
|
|
3003
|
|
3100
|
|
321A
|
|
331A
|
|
3407
|
|
3507
|
|
3601
|
|
37FF
|
|
3836
|
|
3907
|
|
3A00
|
|
3EFF
|
|
3F00
|
|
4077
|
|
4140
|
|
4200
|
|
4330
|
|
44A0
|
|
455C
|
|
4600
|
|
4700
|
|
4858
|
|
4A1E
|
|
4B1E
|
|
4C00
|
|
4D00
|
|
4EA0
|
|
4F80
|
|
5000
|
|
5100
|
|
5200
|
|
5300
|
|
5400
|
|
5780
|
|
5910
|
|
5A08
|
|
5B94
|
|
5CE8
|
|
5D08
|
|
5E3D
|
|
5F99
|
|
6045
|
|
6140
|
|
632D
|
|
6402
|
|
6596
|
|
6600
|
|
6797
|
|
6801
|
|
69CD
|
|
6A01
|
|
6BB0
|
|
6C04
|
|
6D2C
|
|
6E01
|
|
6F32
|
|
7100
|
|
7201
|
|
7335
|
|
7400
|
|
7533
|
|
7631
|
|
7701
|
|
7C84
|
|
7D03
|
|
7E01'
|
|
repeatUntil (i > (size list)) {
|
|
local 'reg' ('[data:copyFromTo]' list i (i + 1))
|
|
local 'val' ('[data:copyFromTo]' list (i + 2) (i + 4))
|
|
i2cSet (hexToInt '73') (hexToInt reg) (hexToInt val)
|
|
i += 5
|
|
waitMicros 10
|
|
}
|
|
}
|
|
|
|
to 'paj7620 connected' {
|
|
return (and ((i2cGet (hexToInt '73') 0) == 32) ((i2cGet (hexToInt '73') 1) == 118))
|
|
}
|
|
|
|
to 'paj7620 read' {
|
|
if ((v '_paj7620 initialized') == 0) {'_paj7620 setup'}
|
|
local 'msg' '?'
|
|
local 'g' (i2cGet (hexToInt '73') (hexToInt '43'))
|
|
if ((g & 1) != 0) {
|
|
msg = 'right'
|
|
} ((g & 2) != 0) {
|
|
msg = 'left'
|
|
} ((g & 4) != 0) {
|
|
msg = 'up'
|
|
} ((g & 8) != 0) {
|
|
msg = 'down'
|
|
} ((g & 16) != 0) {
|
|
msg = 'fordward'
|
|
} ((g & 32) != 0) {
|
|
msg = 'backward'
|
|
} ((g & 64) != 0) {
|
|
msg = 'clockwise'
|
|
} ((g & 128) != 0) {
|
|
msg = 'anti-clockwise'
|
|
}
|
|
return msg
|
|
}
|
|
|
|
|
|
module Servo Output
|
|
author MicroBlocks
|
|
version 1 4
|
|
tags servo motor angle rotation position
|
|
description 'Control both positional (angle) and rotational servo motors.
|
|
'
|
|
variables _servoPin _servoPulseWidth
|
|
|
|
spec ' ' 'setServoAngle' 'set servo _ to _ degrees (-90 to 90)' 'num num' 1 90
|
|
spec ' ' 'setServoSpeed' 'set servo _ to speed _ (-100 to 100)' 'num num' 1 100
|
|
spec ' ' 'stopServo' 'stop servo _' 'num' 1
|
|
spec 'r' '_servoIndex' '_servoIndex _' 'num' 1
|
|
spec ' ' '_servoPulse' '_servoPulse pin _ usecs _' 'num num' 1 1500
|
|
spec ' ' '_servoUpdateLoop' '_servoUpdateLoop'
|
|
|
|
to '_servoIndex' which {
|
|
if (_servoPin == 0) {
|
|
_servoPin = ('[data:makeList]')
|
|
_servoPulseWidth = ('[data:makeList]')
|
|
sendBroadcast '_servoUpdateLoop'
|
|
}
|
|
local 'i' ('[data:find]' which _servoPin)
|
|
if (i < 0) {
|
|
comment 'Add new pin'
|
|
'[data:addLast]' which _servoPin
|
|
'[data:addLast]' 1500 _servoPulseWidth
|
|
i = (size _servoPin)
|
|
}
|
|
return i
|
|
}
|
|
|
|
to '_servoPulse' pin usecs {
|
|
if (usecs == 0) {
|
|
comment 'Servo stopped; do nothing'
|
|
return 0
|
|
}
|
|
usecs = (maximum 500 (minimum usecs 2900))
|
|
comment 'Split wait into a long wait followed by a wait of <= 30 usecs for greater accuracy'
|
|
local 'endTime' ((microsOp) + usecs)
|
|
digitalWriteOp pin true
|
|
waitMicros (usecs - 30)
|
|
waitMicros (endTime - (microsOp))
|
|
digitalWriteOp pin false
|
|
}
|
|
|
|
to '_servoUpdateLoop' {
|
|
forever {
|
|
if (_servoPin != 0) {
|
|
comment 'If the _servoPin list is not 0, update the servos'
|
|
for i (size _servoPin) {
|
|
local 'pin' (at i _servoPin)
|
|
local 'usecs' (at i _servoPulseWidth)
|
|
if (and (pin >= 0) (usecs != 0)) {
|
|
'_servoPulse' pin usecs
|
|
}
|
|
}
|
|
waitMillis 15
|
|
}
|
|
}
|
|
}
|
|
|
|
to setServoAngle which degrees optionalReverse {
|
|
local 'reversed' false
|
|
if ((pushArgCount) > 2) {
|
|
reversed = optionalReverse
|
|
}
|
|
if reversed {
|
|
degrees = (0 - degrees)
|
|
}
|
|
local 'pulseWidth' (1500 - (10 * degrees))
|
|
if ('[io:hasServo]') {
|
|
'[io:setServo]' which pulseWidth
|
|
} else {
|
|
atPut ('_servoIndex' which) _servoPulseWidth pulseWidth
|
|
}
|
|
}
|
|
|
|
to setServoSpeed which speed optionalReverse {
|
|
local 'reversed' false
|
|
if ((pushArgCount) > 2) {
|
|
reversed = optionalReverse
|
|
}
|
|
if reversed {
|
|
speed = (0 - speed)
|
|
}
|
|
local 'pulseWidth' (1500 - (10 * speed))
|
|
if ((absoluteValue speed) < 2) {
|
|
pulseWidth = 0
|
|
}
|
|
if ('[io:hasServo]') {
|
|
'[io:setServo]' which pulseWidth
|
|
} else {
|
|
atPut ('_servoIndex' which) _servoPulseWidth pulseWidth
|
|
}
|
|
}
|
|
|
|
to stopServo which {
|
|
if ('[io:hasServo]') {
|
|
'[io:setServo]' which 0
|
|
} else {
|
|
atPut ('_servoIndex' which) _servoPulseWidth 0
|
|
}
|
|
}
|
|
|
|
|
|
module Spark Input
|
|
author 'FABLAB BH credits Turgut for the OLED Graphics'
|
|
version 1 1
|
|
depends '/Spark_Digital' '/Spark_Analog' '/Spark_MP' '/Spark_PWM' '/Spark_I2C'
|
|
choices DispTypeMenu 'OLED_0.96in' 'OLED_2.42in'
|
|
choices OnOffMenu On Off
|
|
choices VideoMenu Inverse Normal
|
|
choices ModeMenu Horizontal Vertical
|
|
description 'Supports 0.96in and 2.42in OLED Displays with SD1306 and SD1309 chipsets. Comm mode is I2C or SPI.
|
|
Changes:
|
|
- always display buffer
|
|
- defer display updates block
|
|
- remove reveal
|
|
- switch to x (0-127), y (0-63)
|
|
- Pruned commands and vars
|
|
- textX and textY
|
|
- Text at any x and y
|
|
- handles newLines
|
|
- removed dependencies
|
|
- unified data format for chars, sprites, and images
|
|
- image draw at any x,y
|
|
- filled rectangle
|
|
- image draw bug fix
|
|
- stack overflow fix
|
|
- improve conversion ops, i2c io, rect fill, img processing, and buffer displays
|
|
- reduce i2c buffer to 128 bytes
|
|
- reduce i2c buffer to 64 bytes
|
|
- correct internal draws, clean-up vars, restore _clearDisplay
|
|
'
|
|
variables OLEDReady OLEDi2cAddr _GDBuffer _cDecTBL _comma _cTABLE _comMode _dcPin _delayGDUpd _displayType _eol _resetPin _textX _textY _dataPrefix _byteCount _imgData _imgWidth _imgHeight
|
|
|
|
spec ' ' 'OLEDInit_I2C' 'initialize i2c _ address(hex) _ reset pin# _ flip _' 'str.DispTypeMenu auto str bool' 'OLED_0.96in' '3C' '-' false
|
|
spec ' ' 'OLEDInit_SPI' 'initialize spi _ d/c pin# _ reset pin# _ flip _' 'str.DispTypeMenu auto auto bool' 'OLED_2.42in' 16 8 false
|
|
spec ' ' 'OLEDwrite' 'write _ at x _ y _ inverse _' 'auto auto auto bool' 'Hello!' 0 0 false
|
|
spec ' ' 'OLEDshowGDBuffer' 'show display buffer'
|
|
spec ' ' 'OLEDclear' 'clear'
|
|
spec ' ' 'OLEDcontrast' 'set contrast (1-4) _' 'auto' 2
|
|
spec ' ' 'OLEDdrawCircle' 'draw circle at x _ y _ radius _ erase _' 'auto auto auto bool' 64 32 '10' false
|
|
spec ' ' 'OLEDdrawImage' 'draw image _ at x _ y _' 'auto auto auto' 0 0 0
|
|
spec ' ' 'OLEDdrawLine' 'draw line from x _ y _ to x _ y _ erase _' 'auto auto auto auto bool' 0 0 127 63 false
|
|
spec ' ' 'OLEDdrawRect' 'draw rectangle x _ y _ w _ h _ erase _ rounding(3-15) _' 'auto auto auto auto bool auto' 0 0 127 63 false 0
|
|
spec ' ' 'OLEDfillRect' 'fill rectangle x _ y _ w _ h _ erase _' 'auto auto auto auto bool' 20 20 30 20 false
|
|
spec ' ' '_OLEDflip' '_flip display top _' 'bool' false
|
|
spec 'r' 'OLEDmakeImage' 'make image _' 'microbitDisplay' 33084991
|
|
spec ' ' 'OLEDpixel' 'set pixel x _ y _ erase _' 'auto auto bool' 0 0 false
|
|
spec ' ' 'OLEDsetVideo' 'set video _' 'str.VideoMenu' 'Inverse'
|
|
spec 'r' 'OLEDwru' 'cursor location'
|
|
spec ' ' 'defer display updates' 'defer display updates'
|
|
spec ' ' '_GDDRAMoff' '_GDDRAMoff'
|
|
spec ' ' '_GDDRAMon' '_GDDRAMon'
|
|
spec ' ' '_OLEDcursorReset' '_cursor reset'
|
|
spec ' ' '_OLEDsetDisplay' '_set display _' 'str.OnOffMenu' 'On'
|
|
spec ' ' '_OLEDreset' '_set reset Pin# _' 'auto' '0'
|
|
spec ' ' '_SPIWriteCmd' '_SPIWriteCmd'
|
|
spec ' ' '_SPIWriteData' '_SPIWriteData'
|
|
spec ' ' '_T1' '_T1'
|
|
spec ' ' '_T2' '_T2'
|
|
spec ' ' '_T3' '_T3'
|
|
spec 'r' '_cBMP' '_cBMP _ InvYN _' 'auto bool' '' false
|
|
spec ' ' '_clearDisplay' '_clearDisplay'
|
|
spec ' ' '_corner' '_corner _ _ _ _ _' 'auto auto auto auto bool' 'TL' 32 1 0 true
|
|
spec 'r' '_dec2hex' '_dec2hex _' 'auto' 0
|
|
spec ' ' '_initChars' '_initChars'
|
|
spec ' ' '_initCheck' '_initCheck'
|
|
spec ' ' '_initDisplayHW' '_initDisplayHW'
|
|
spec ' ' '_initLibrary' '_initLibrary'
|
|
spec ' ' '_process image data' '_process image data _' 'auto' ' '
|
|
spec ' ' '_sendCmd' '_sendCmd _' 'auto' ''
|
|
spec ' ' '_verifyXY' '_verifyXY _ _' 'auto auto' 0 0
|
|
|
|
to OLEDInit_I2C dispType i2cAddr resetPin flip {
|
|
comment 'Sets display type and interface and initializes HW settings.
|
|
Do NOT set a ResetPin# unless one exists on the display hardware.
|
|
NOTE:
|
|
Displays supported:
|
|
- OLED 0.96in (SD1306 chip) and
|
|
- OLED 2.42" (SD1309 chip)
|
|
Both displays are 128x64 pixels or 16x8 characters in size.
|
|
Displays come in dual mode version (i2c and spi) and pure i2c.
|
|
Pure i2c models do not have a Reset pin.
|
|
|
|
flip setting controls display hardware write direction:
|
|
- false: top to bottom
|
|
- true: bottom to top'
|
|
_comma = ('[data:unicodeString]' 44)
|
|
_comMode = 'i2c'
|
|
OLEDi2cAddr = (hexToInt ('[data:join]' ('[data:unicodeString]' 32) i2cAddr))
|
|
_resetPin = resetPin
|
|
_displayType = (ifExpression (dispType == 'OLED_0.96in') 9 6)
|
|
'_initDisplayHW'
|
|
if flip {
|
|
'_OLEDflip' true
|
|
}
|
|
'_initLibrary'
|
|
OLEDclear
|
|
}
|
|
|
|
to OLEDInit_SPI dispType dcPin resetPin flip {
|
|
comment 'Sets display type and interface and initializes HW settings.
|
|
SPI four wire in Mode-0 is supported. Max speed=10000000.
|
|
|
|
Do NOT set a ResetPin# unless one exists on the display hardware.
|
|
NOTE:
|
|
Displays supported:
|
|
- OLED 0.96in (SD1306 chip) and
|
|
- OLED 2.42" (SD1309 chip)
|
|
Both displays are 128x64 pixels or 16x8 characters in size.
|
|
Displays come in dual mode version (i2c and spi) and pure i2c.
|
|
Pure i2c models do not have a Reset pin.
|
|
flip setting controls display hardware write direction:
|
|
- false: top to bottom
|
|
- true: bottom to top'
|
|
_comma = ('[data:unicodeString]' 44)
|
|
_comMode = 'spi'
|
|
_dcPin = dcPin
|
|
if (_displayType != 0) {
|
|
return
|
|
}
|
|
if (dispType == 'OLED_0.96in') {
|
|
_displayType = 6
|
|
_resetPin = resetPin
|
|
} else {
|
|
_displayType = 9
|
|
_resetPin = resetPin
|
|
}
|
|
'[sensors:spiSetup]' 10000000
|
|
'_initDisplayHW'
|
|
if flip {
|
|
'_OLEDflip' true
|
|
}
|
|
'_initLibrary'
|
|
OLEDclear
|
|
}
|
|
|
|
to OLEDclear {
|
|
comment 'Set bounds to FullScreen and CLEARs display
|
|
and GDBuffer.'
|
|
_GDBuffer = ('[data:newByteArray]' 1024)
|
|
'_initCheck'
|
|
'_OLEDcursorReset'
|
|
OLEDshowGDBuffer
|
|
}
|
|
|
|
to OLEDcontrast contrast {
|
|
comment 'Sets the brightness control of the display to one of four values.
|
|
1 is the least bright, 4 is the brightest setting.'
|
|
'_initCheck'
|
|
local 'cLevels' ('[data:makeList]' 0 '1F' '2F' 'F0')
|
|
if (and (contrast >= 1) (contrast <= 4)) {
|
|
local 'i2cCmd' ('[data:join]' '81' _comma (at contrast cLevels))
|
|
'_sendCmd' i2cCmd
|
|
} else {
|
|
sayIt 'Error in CONTRAST Level'
|
|
}
|
|
}
|
|
|
|
to OLEDdrawCircle cx cy r erase {
|
|
comment 'Bresenham Circle:
|
|
Draws circles, even partially bigger than the display.
|
|
x: 0-127
|
|
y: 0-63
|
|
void plotCircle(int xm, int ym, int r)
|
|
{
|
|
int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */
|
|
do {
|
|
setPixel(xm-x, ym+y); /* I. Quadrant */
|
|
setPixel(xm-y, ym-x); /* II. Quadrant */
|
|
setPixel(xm+x, ym-y); /* III. Quadrant */
|
|
setPixel(xm+y, ym+x); /* IV. Quadrant */
|
|
r = err;
|
|
if (r <= y) err += ++y*2+1; /* e_xy+e_y < 0 */
|
|
if (r > x || err > y) err += ++x*2+1; /* e_xy+e_x > 0 or no 2nd y-step */
|
|
} while (x < 0);
|
|
}'
|
|
'_initCheck'
|
|
local 'oldDelayGDUpd' _delayGDUpd
|
|
_delayGDUpd = (booleanConstant true)
|
|
local 'x' (-1 * r)
|
|
local 'y' 0
|
|
local 'err' (2 - (2 * r))
|
|
repeatUntil (x >= 0) {
|
|
OLEDpixel (cx - x) (cy + y) erase
|
|
OLEDpixel (cx - y) (cy - x) erase
|
|
OLEDpixel (cx + x) (cy - y) erase
|
|
OLEDpixel (cx + y) (cy + x) erase
|
|
r = err
|
|
if (r <= y) {
|
|
y += 1
|
|
err = (err + ((y * 2) + 1))
|
|
}
|
|
if (or (r > x) (err > y)) {
|
|
x += 1
|
|
err = (err + ((x * 2) + 1))
|
|
}
|
|
}
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
}
|
|
|
|
to OLEDdrawImage image x y {
|
|
comment '_imgHeight has to be mod8 or 1-8'
|
|
if (0 == image) {
|
|
return 0
|
|
}
|
|
local 'oldDelayGDUpd' _delayGDUpd
|
|
_delayGDUpd = (booleanConstant true)
|
|
for row# (maximum 1 ((minimum _imgHeight (64 - y)) / 8)) {
|
|
local 'GDidx' ((((y / 8) * 128) + x) + 1)
|
|
local 'imgDispl' ((row# - 1) * _imgWidth)
|
|
for byte# (minimum _imgWidth (128 - x)) {
|
|
comment 'If y is on page boundary, just copy'
|
|
if (0 == (y % 8)) {
|
|
atPut GDidx _GDBuffer (at (imgDispl + byte#) image)
|
|
GDidx += 1
|
|
if (GDidx > 1024) {
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
return 0
|
|
}
|
|
} else {
|
|
comment 'Else, copy GDLowBits + shiftedByte + GDHiBits to GDBuffer and GDBuffer +128'
|
|
local 'shiftedByte' ('_dec2hex' ((at (imgDispl + byte#) image) << (y % 8)))
|
|
local 'temp' 0
|
|
local 'tempHI' ('[data:copyFromTo]' shiftedByte 1 2)
|
|
local 'tempLO' ('[data:copyFromTo]' shiftedByte 3 4)
|
|
local 'GDLowBits' ((1 << (y % 8)) - 1)
|
|
local 'GDHiBits' (255 - GDLowBits)
|
|
tempLO = ((hexToInt tempLO) | ((at GDidx _GDBuffer) & GDLowBits))
|
|
atPut GDidx _GDBuffer tempLO
|
|
if ((GDidx + 128) <= 1024) {
|
|
tempHI = ((hexToInt tempHI) | ((at (GDidx + 128) _GDBuffer) & GDHiBits))
|
|
atPut (GDidx + 128) _GDBuffer tempHI
|
|
}
|
|
GDidx += 1
|
|
if (GDidx > 1024) {
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
return 0
|
|
}
|
|
}
|
|
waitMillis 0
|
|
}
|
|
y += 8
|
|
}
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
}
|
|
|
|
to OLEDdrawLine x0 y0 x1 y1 erase {
|
|
comment 'Draws a line from x0,y0 to x1,y1 using the Bresenham Algorithm
|
|
x: 0-127
|
|
y: 0-63
|
|
plotLine(int x0, int y0, int x1, int y1)
|
|
dx = abs(x1-x0);
|
|
sx = x0<x1 ? 1 : -1;
|
|
dy = -abs(y1-y0);
|
|
sy = y0<y1 ? 1 : -1;
|
|
err = dx+dy; /* error value e_xy */
|
|
while (true) /* loop */
|
|
plot(x0, y0);
|
|
if (x0 == x1 && y0 == y1) break;
|
|
e2 = 2*err;
|
|
if (e2 >= dy) /* e_xy+e_x > 0 */
|
|
err += dy;
|
|
x0 += sx;
|
|
end if
|
|
if (e2 <= dx) /* e_xy+e_y < 0 */
|
|
err += dx;
|
|
y0 += sy;
|
|
end if
|
|
end while'
|
|
'_initCheck'
|
|
local 'oldDelayGDUpd' _delayGDUpd
|
|
_delayGDUpd = (booleanConstant true)
|
|
results = ('[data:makeList]')
|
|
local 'dx' (absoluteValue (x1 - x0))
|
|
local 'dy' (-1 * (absoluteValue (y1 - y0)))
|
|
local 'err' (dx + dy)
|
|
local 'e2' 0
|
|
local 'done' (booleanConstant false)
|
|
if (x0 < x1) {
|
|
local 'sx' 1
|
|
} else {
|
|
local 'sx' -1
|
|
}
|
|
if (y0 < y1) {
|
|
local 'sy' 1
|
|
} else {
|
|
local 'sy' -1
|
|
}
|
|
repeatUntil done {
|
|
OLEDpixel x0 y0 erase
|
|
if (and (x0 == x1) (y0 == y1)) {
|
|
done = (booleanConstant true)
|
|
}
|
|
e2 = (2 * err)
|
|
if (e2 >= dy) {
|
|
err += dy
|
|
x0 += sx
|
|
}
|
|
if (e2 <= dx) {
|
|
err += dx
|
|
y0 += sy
|
|
}
|
|
}
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
}
|
|
|
|
to OLEDdrawRect TLx TLy width height erase cornerRad {
|
|
comment 'Draw Rectangle with optional rounded corners with radius R.
|
|
Does not check for reversed rectangle coordinates for round corners.'
|
|
'_initCheck'
|
|
local 'oldDelayGDUpd' _delayGDUpd
|
|
_delayGDUpd = (booleanConstant true)
|
|
local 'BRx' (TLx + width)
|
|
local 'BRy' (TLy + height)
|
|
if (cornerRad >= 3) {
|
|
'_corner' 'TL' TLx TLy cornerRad erase
|
|
'_corner' 'TR' BRx TLy cornerRad erase
|
|
'_corner' 'BR' BRx BRy cornerRad erase
|
|
'_corner' 'BL' TLx BRy cornerRad erase
|
|
comment 'TOP - Adjust x'
|
|
OLEDdrawLine (TLx + cornerRad) TLy ((BRx - 1) - cornerRad) TLy erase
|
|
comment 'RIGHT- Adjust y'
|
|
OLEDdrawLine BRx ((TLy + 1) + cornerRad) BRx ((BRy - 1) - cornerRad) erase
|
|
comment 'BOTTOM - Adjust x'
|
|
OLEDdrawLine ((BRx - 1) - cornerRad) BRy ((TLx + 1) + cornerRad) BRy erase
|
|
comment 'LEFT - Adjust y'
|
|
OLEDdrawLine TLx ((BRy - 1) - cornerRad) TLx ((TLy + 1) + cornerRad) erase
|
|
} else {
|
|
OLEDdrawLine TLx TLy BRx TLy erase
|
|
OLEDdrawLine BRx (TLy + 1) BRx BRy erase
|
|
OLEDdrawLine (BRx - 1) BRy TLx BRy erase
|
|
OLEDdrawLine TLx (BRy - 1) TLx (TLy + 1) erase
|
|
}
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
}
|
|
|
|
to OLEDfillRect x y w h erase {
|
|
local 'oldDelayGDUpd' _delayGDUpd
|
|
_delayGDUpd = (booleanConstant true)
|
|
for row ('[data:range]' 0 (h - 1)) {
|
|
for col ('[data:range]' 0 (w - 1)) {
|
|
OLEDpixel (x + col) (y + row) erase
|
|
}
|
|
}
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
}
|
|
|
|
to OLEDmakeImage spr# {
|
|
comment 'Receives a spr# representing 5x5 image matrix.
|
|
Converts it to a HOR array of 5 VERT bitmap numbers.
|
|
This can be displayed with the draw image block.
|
|
sprNum max is 33554431'
|
|
'_initCheck'
|
|
local 'spriteList' ('[data:newByteArray]' 5)
|
|
local 'val' 0
|
|
for col 5 {
|
|
for row ('[data:asByteArray]' ('[data:makeList]' 0 5 10 15 20)) {
|
|
local 'bit' (col + row)
|
|
local 'vertBit#' (bit / 5)
|
|
if ((spr# & (1 << (bit - 1))) != 0) {
|
|
if (col != 5) {
|
|
val += (1 << vertBit#)
|
|
} else {
|
|
val += (1 << (vertBit# - 1))
|
|
}
|
|
}
|
|
}
|
|
atPut col spriteList val
|
|
val = 0
|
|
}
|
|
_imgWidth = 5
|
|
_imgHeight = 5
|
|
return spriteList
|
|
}
|
|
|
|
to OLEDpixel x y erase {
|
|
comment 'Places a pixel at x,y in the virtual GDBuffer
|
|
Use OLEDshowGDBuffer to display it
|
|
8192 Pixels over 1024 Bytes
|
|
x: 0-127
|
|
y: 0-63
|
|
page#: 0-7
|
|
pagePixel#: 0-7
|
|
GDIndex: 1-1024
|
|
|
|
RangeCheck:
|
|
verify x and y are in range of display limits
|
|
if X <= num <= Y'
|
|
'_initCheck'
|
|
local 'pagePixel#' (y % 8)
|
|
local 'GDIndex' ((x + ((y / 8) * 128)) + 1)
|
|
local 'byteBMP' (at GDIndex _GDBuffer)
|
|
byteBMP = (ifExpression (not erase) (byteBMP | (1 << pagePixel#)) (byteBMP & ('~' (1 << pagePixel#))))
|
|
atPut GDIndex _GDBuffer byteBMP
|
|
}
|
|
|
|
to OLEDsetVideo videoMode {
|
|
comment 'Switches the entire display:
|
|
Inverse: inverse video mode (bit 0 = on)
|
|
Normal: normal video mode (bit 1 = on).
|
|
Any image on the display will be preserved when mode changes.'
|
|
'_initCheck'
|
|
if (videoMode == 'Inverse') {
|
|
local 'i2cCmd' 'A7'
|
|
} else {
|
|
local 'i2cCmd' 'A6'
|
|
}
|
|
'_sendCmd' i2cCmd
|
|
}
|
|
|
|
to OLEDshowGDBuffer {
|
|
comment 'Copies contents of virtual _GDBuffer to display
|
|
i2c:
|
|
in 60 byte chunks for speed.
|
|
1 byte is used for the command 40
|
|
spi:
|
|
fastest is dump buffer
|
|
_GDBuffer is in decimal'
|
|
'_initCheck'
|
|
if (_comMode == 'i2c') {
|
|
local 'idx' 0
|
|
repeat 17 {
|
|
'[sensors:i2cWrite]' OLEDi2cAddr ('[data:join]' _dataPrefix ('[data:copyFromTo]' _GDBuffer idx (idx + 60)))
|
|
idx += 61
|
|
}
|
|
} else {
|
|
'_SPIWriteData'
|
|
'[sensors:spiExchange]' ('[data:copyFromTo]' _GDBuffer 1)
|
|
}
|
|
_delayGDUpd = (booleanConstant false)
|
|
}
|
|
|
|
to OLEDwrite string x y invFlag {
|
|
comment 'Writes strings to display at any x,y; processing CR LF and wrapping at col x.
|
|
_textX and _textY are next write locations.'
|
|
'_initCheck'
|
|
local 'oldDelayGDUpd' _delayGDUpd
|
|
_delayGDUpd = (booleanConstant true)
|
|
'_verifyXY' x y
|
|
local 'origX' x
|
|
if (not (isType string 'string')) {
|
|
string = ('[data:join]' '' string)
|
|
}
|
|
for char string {
|
|
comment 'If in table process it - LINE SET is not supported.'
|
|
if (('[data:find]' char _cTABLE) != -1) {
|
|
OLEDdrawImage ('_cBMP' char invFlag) x y
|
|
x += 8
|
|
if (x > 127) {
|
|
x = origX
|
|
y += 8
|
|
if (y > 63) {
|
|
y = 0
|
|
}
|
|
}
|
|
} (13 == ('[data:unicodeAt]' 1 char)) {
|
|
noop
|
|
} (10 == ('[data:unicodeAt]' 1 char)) {
|
|
x = origX
|
|
y += 8
|
|
if (y > 63) {
|
|
y = 0
|
|
}
|
|
} else {
|
|
comment 'bad char - STOP'
|
|
sayIt 'Invalid CHAR value:' char 'uniCode:' ('[data:unicodeAt]' 1 char)
|
|
stopTask
|
|
}
|
|
}
|
|
_textX = x
|
|
_textY = y
|
|
_delayGDUpd = oldDelayGDUpd
|
|
if (not _delayGDUpd) {
|
|
OLEDshowGDBuffer
|
|
}
|
|
}
|
|
|
|
to OLEDwru {
|
|
comment 'Next Row and Column to print
|
|
_textY, _textX'
|
|
return ('[data:asByteArray]' ('[data:makeList]' _textY _textX))
|
|
}
|
|
|
|
to '_GDDRAMoff' {
|
|
comment 'Displays a full empty screen of reverse video.
|
|
It disengages the hardware GDBuffer. '
|
|
local 'i2cCmd' 'A5'
|
|
'_sendCmd' i2cCmd
|
|
}
|
|
|
|
to '_GDDRAMon' {
|
|
comment 'It disables the GDDRAMoff mode and engages the hardware GDBuffer for display content.'
|
|
local 'i2cCmd' 'A4'
|
|
'_sendCmd' i2cCmd
|
|
}
|
|
|
|
to '_OLEDcursorReset' {
|
|
comment 'Sets display bounds to full range and resets cursor
|
|
to the origin top-left (0,0)
|
|
Rows: 0-7
|
|
Cols: 0-127
|
|
Cursor position is affected by any display operation
|
|
and also by OLEDColMode block.'
|
|
'_initCheck'
|
|
local 'cmdString' '22,00,07,21,00,7F'
|
|
'_sendCmd' cmdString
|
|
_textX = 0
|
|
_textY = 0
|
|
}
|
|
|
|
to '_OLEDflip' flip {
|
|
comment 'Flips the display initialization horizontally or vertically.
|
|
Horizontal or vertical is based on the pin connector location.'
|
|
if flip {
|
|
'_sendCmd' 'A0,C0'
|
|
} else {
|
|
'_sendCmd' 'A1,C8'
|
|
}
|
|
}
|
|
|
|
to '_OLEDreset' pin {
|
|
comment 'Does a power off and on on the display,
|
|
thus forcing a hardware initialization.'
|
|
digitalWriteOp pin false
|
|
waitMillis 1
|
|
digitalWriteOp pin true
|
|
waitMillis 1
|
|
}
|
|
|
|
to '_OLEDsetDisplay' onoff {
|
|
comment 'Puts the display into
|
|
Off:SLEEP On:WAKE mode.
|
|
Images on display are preserved.'
|
|
'_initCheck'
|
|
if (onoff == 'On') {
|
|
local 'i2cCmd' 'AF'
|
|
} else {
|
|
local 'i2cCmd' 'AE'
|
|
}
|
|
'_sendCmd' i2cCmd
|
|
}
|
|
|
|
to '_SPIWriteCmd' {
|
|
comment 'In SPI mode, we send either a write command
|
|
or write data control code. Then follow it with
|
|
the appropriate command/data bundle.'
|
|
digitalWriteOp _dcPin false
|
|
}
|
|
|
|
to '_SPIWriteData' {
|
|
comment 'In SPI mode, we send either a write command
|
|
or write data control code. Then follow it with
|
|
the appropriate command/data bundle.'
|
|
digitalWriteOp _dcPin true
|
|
}
|
|
|
|
to '_T1' {
|
|
comment 'THIN-SS Character Set
|
|
Range: space - ?'
|
|
local '_cHEX1' '00000000000000000000005F00000000000007000007000000147F14147F140000242A6B6B2A12000046261008646200304A454D324848000000040300000000001C224100000000000041221C000000082A1C1C1C2A08000008083E080800000000806000000000000808080808080000000060000000000040201008040200003E615149453E000044427F4040000000625151494966000022414949493600101814527F5010000027454545453900003C4A4949493000000301710905030000364949494936000006494949291E00000000660000000000008066000000000008142241000000002424242424240000000041221408000002010151090600'
|
|
local 'idx' 1
|
|
for i 256 {
|
|
atPut i _cDecTBL (hexToInt ('[data:copyFromTo]' _cHEX1 idx (idx + 1)))
|
|
idx += 2
|
|
}
|
|
_cHEX1 = ''
|
|
}
|
|
|
|
to '_T2' {
|
|
comment 'THIN-SS Character Set
|
|
Range: @ - _ (underscore)'
|
|
local '_cHEX2' '003E415D55551E00007C121111127C0000417F4949493600001C22414141220000417F4141221C0000417F495D41630000417F491D010300001C224151517200007F080808087F000000417F4100000000304040413F010000417F081422414000417F4140406000007F01020402017F007F010204087F00003E414141413E0000417F4909090600001E212131215E4000417F49192946000026494949493200000301417F410103003F404040403F00000F10204020100F003F40403840403F004122140814224100010244784402010043615149454361007F4141410000000102040810204000004141417F00000008040201020408008080808080808080'
|
|
local 'idx' 1
|
|
for i 256 {
|
|
atPut (256 + i) _cDecTBL (hexToInt ('[data:copyFromTo]' _cHEX2 idx (idx + 1)))
|
|
idx += 2
|
|
}
|
|
_cHEX2 = ''
|
|
}
|
|
|
|
to '_T3' {
|
|
comment 'THIN-SS Character Set
|
|
Range: '' - . (last char)'
|
|
local '_cHEX3' '0000000304000000002054545454784000017F304848483000384444444428000030484848317F4000385454545418000000487E490102000098A4A4A4A4780400417F08040478000000447D400000000060808080847D0000017F10284440000000417F40000000007C040478040478007C08040404780000384444444438000084FC98242418000018242498FC840000447C480404180000485454545424000004043F44442000003C404040207C00000C10204020100C003C40403840403C0044281028440000009CA0A0A0A07C00004464544C44000000080836414100000000007700000000000041413608080000020101020201000000000000000000'
|
|
local 'idx' 1
|
|
for i 256 {
|
|
atPut (512 + i) _cDecTBL (hexToInt ('[data:copyFromTo]' _cHEX3 idx (idx + 1)))
|
|
idx += 2
|
|
}
|
|
_cHEX3 = ''
|
|
}
|
|
|
|
to '_cBMP' char invFlag {
|
|
comment 'Returns DEC char bitmap from _cHexTbl and
|
|
optionally converts it to inverse (XOR).
|
|
Line segments are NOT supported.
|
|
A: 00,7c,12,11,12,7c,00
|
|
dec: 0,124,18,17,17,124,0
|
|
inv: 255,131,237,238,238,131,255'
|
|
local 'key' (((('[data:unicodeAt]' 1 char) - 32) * 8) + 1)
|
|
local 'charList' ('[data:copyFromTo]' _cDecTBL key (key + 7))
|
|
comment 'inverse'
|
|
if invFlag {
|
|
for item# (size charList) {
|
|
atPut item# charList ((at item# charList) ^ 255)
|
|
}
|
|
}
|
|
_imgWidth = 8
|
|
_imgHeight = 8
|
|
return charList
|
|
}
|
|
|
|
to '_clearDisplay' {
|
|
comment 'Clear Screen without initializing _GDBuffer'
|
|
'_initCheck'
|
|
'_OLEDcursorReset'
|
|
if ('i2c' == _comMode) {
|
|
repeat 17 {
|
|
'[sensors:i2cWrite]' OLEDi2cAddr ('[data:join]' _dataPrefix ('[data:newByteArray]' 60))
|
|
}
|
|
'[sensors:i2cWrite]' OLEDi2cAddr ('[data:join]' _dataPrefix ('[data:newByteArray]' 4))
|
|
} else {
|
|
'_SPIWriteData'
|
|
'[sensors:spiExchange]' ('[data:newByteArray]' 1024)
|
|
}
|
|
}
|
|
|
|
to '_corner' loc cx cy r erase {
|
|
comment 'Calculates and displays the rounded corners for the rectangles.
|
|
loc is one of TL, TR, BL, BR ... topLeft, topright, bottomleft, bottomright
|
|
cx,cy are the corner coordinates for the rounded corner.
|
|
r is the radius in pixels of the arc to be calculated.'
|
|
local 'x' (-1 * r)
|
|
local 'y' 0
|
|
local 'err' (2 - (2 * r))
|
|
if (loc == 'TL') {
|
|
cx += r
|
|
cy += r
|
|
} (loc == 'TR') {
|
|
cx += (-1 * r)
|
|
cy += r
|
|
} (loc == 'BL') {
|
|
cx += r
|
|
cy += (-1 * r)
|
|
} (loc == 'BR') {
|
|
cx += (-1 * r)
|
|
cy += (-1 * r)
|
|
}
|
|
repeatUntil (x >= 0) {
|
|
if (loc == 'TL') {
|
|
OLEDpixel (cx + x) (cy - y) erase
|
|
} (loc == 'TR') {
|
|
OLEDpixel (cx + y) (cy + x) erase
|
|
} (loc == 'BL') {
|
|
OLEDpixel (cx - y) (cy - x) erase
|
|
} (loc == 'BR') {
|
|
OLEDpixel (cx - x) (cy + y) erase
|
|
}
|
|
r = err
|
|
if (r <= y) {
|
|
y += 1
|
|
err = (err + ((y * 2) + 1))
|
|
}
|
|
if (or (r > x) (err > y)) {
|
|
x += 1
|
|
err = (err + ((x * 2) + 1))
|
|
}
|
|
}
|
|
}
|
|
|
|
to '_dec2hex' num {
|
|
comment 'Fast version w/o inversion. (~115uSecs)'
|
|
local '_hexTbl' '0123456789ABCDEF'
|
|
local 'hexNum' ''
|
|
repeatUntil (num < 0) {
|
|
local 'temp' ('[data:join]' (at ((num % 16) + 1) _hexTbl) hexNum)
|
|
hexNum = temp
|
|
num = (ifExpression ((num / 16) != 0) (num / 16) -1)
|
|
}
|
|
comment 'If not half-byte length, pad it.'
|
|
hexNum = ('[data:join]' ('[data:copyFromTo]' '000' 1 (4 - (size hexNum))) hexNum)
|
|
return hexNum
|
|
}
|
|
|
|
to '_initChars' {
|
|
comment 'Creates the character set used in the Library (96 characters)
|
|
used JOIN for SPACE (uni-32) character so it won''t be deleted by mistake.
|
|
For each character, _cDecTbl is updated with 8 byte array values.'
|
|
_cTABLE = ('[data:join]' ('[data:unicodeString]' 32) '!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~.')
|
|
'_T1'
|
|
'_T2'
|
|
'_T3'
|
|
}
|
|
|
|
to '_initCheck' {
|
|
comment 'Verifies Library initialization status.'
|
|
if (not OLEDReady) {
|
|
sayIt 'Display needs to be initialized before using the library blocks.'
|
|
stopTask
|
|
}
|
|
}
|
|
|
|
to '_initDisplayHW' {
|
|
comment '*** DO NOT CHANGE THESE WITHOUT UNDERSTANDING THEIR MEANINGS ***
|
|
*** IT CAN MAKE THE DISPLAY NOT OPERATE CORRECTLY ***
|
|
|
|
Initializes display HW timings
|
|
OLED INITIALIZATION STRINGS:
|
|
1306: pins are on top
|
|
1309: pins are on the right
|
|
|
|
A8 3F - Multiplex Ratio 0F-3F (16mux to 64mux)
|
|
D3 00 - Display Offset (vertical) 00-63
|
|
40 - Display Start Line 40-7F (40:0)
|
|
A0 - Set Segment Remap A0: Remap 0:0, A1: 127:0 [A1]
|
|
C0 - Scan Direction C0:0-127, C8:127-0 [C8]
|
|
DA 12 - COM pin hw config 02:double-high 12:normal bits
|
|
81 F0 - Set contrast 00-FF (00:dimmest, FF:brightest) [F0]
|
|
A4 - A4:display shows GDRAM, A5:display all ON pixels
|
|
A6 - A6:Normal video, A7:Inverse video
|
|
D5 F0 - Set display clock HB:OSC freq / LB:divide ratio (00-FF)
|
|
D9 22 - Set pre-charge period HB:Phase2 / LB:Phase1 (1-15 DCLK)
|
|
DB 20 - Set Vcomh deselect level 20:1306(~0.77xVcc), 34:1309(~0.78xVcc)
|
|
8D 14 - Charge Pump Setting 10:disable CP, 14:enable CP
|
|
20 00 - Set HORIZONTAL mode
|
|
AF - Display ON/OFF AE:off (sleep mode), AF:on'
|
|
if (_resetPin != '-') {
|
|
'_OLEDreset' _resetPin
|
|
}
|
|
if (9 == _displayType) {
|
|
local 'initCmd' 'A8,3F,D3,00,40,A1,C8,DA,12,81,F0,A4,A6,D5,70,D9,22,DB,34,8D,14,20,00,AF'
|
|
} else {
|
|
local 'initCmd' 'A8,3F,D3,00,40,A1,C8,DA,12,81,F0,A4,A6,D5,70,D9,22,DB,20,8D,14,20,00,AF'
|
|
}
|
|
'_sendCmd' initCmd
|
|
}
|
|
|
|
to '_initLibrary' {
|
|
comment 'Sets all Library variables and initializes the display hardware.
|
|
It also initializes the virtual GDBuffer, and clears the display.
|
|
NOTE:
|
|
Displays supported: OLED1306 (0.96in) and OLED1309 (2.42"), selected via boolean position.
|
|
OLED1309 requires the connection of RESET pin to a digital pin.
|
|
Both displays are 128x64 pixels or 16x8 characters in size.
|
|
Make sure the character hex tables are \n (LF) terminated.
|
|
Otherwise, extra lines are added in between and it gets messed up.
|
|
eg: A: 00,7C,12,11,11,12,7C,00\n
|
|
Max i2c IO is 64 bytes: buffered writes need to be max that size - 16 x 64'
|
|
_comma = ('[data:unicodeString]' 44)
|
|
_eol = ('[data:unicodeString]' 10)
|
|
comment 'Col starts are in HEX'
|
|
_dataPrefix = ('[data:newByteArray]' 1 (hexToInt '40'))
|
|
comment 'There is no FF/255 in th cHexTBL.
|
|
this value is used to build the byteArray.'
|
|
_cDecTBL = ('[data:newByteArray]' 768 255)
|
|
_GDBuffer = ('[data:newByteArray]' 1024)
|
|
_textX = 0
|
|
_textY = 0
|
|
_delayGDUpd = (booleanConstant false)
|
|
'_initChars'
|
|
OLEDReady = (booleanConstant true)
|
|
'_OLEDsetDisplay' 'On'
|
|
repeat 2 {
|
|
setUserLED true
|
|
waitMillis 50
|
|
setUserLED false
|
|
waitMillis 50
|
|
}
|
|
}
|
|
|
|
to '_process image data' image {
|
|
comment 'Processes the new hex image data format.
|
|
Each _imgHex gets added to _imgData in DEC byteArray format.
|
|
_byteCount keeps track of total bytes processed.
|
|
_imgWidth and _imgHeight (mod8) are dimensions.'
|
|
local '_ptr' 1
|
|
comment '_imgData is not initialized yet.'
|
|
if (or (0 == _imgData) (not (isType _imgData 'byte array'))) {
|
|
_imgWidth = (hexToInt ('[data:copyFromTo]' image 1 2))
|
|
_imgHeight = (hexToInt ('[data:copyFromTo]' image 3 4))
|
|
image = ('[data:copyFromTo]' image 5)
|
|
comment 'If _imgHeight is partial byte, adjust to full byte'
|
|
if (not (0 == (_imgHeight % 8))) {
|
|
_imgHeight += (8 - (_imgHeight % 8))
|
|
}
|
|
_imgData = ('[data:newByteArray]' ((_imgWidth * _imgHeight) / 8))
|
|
}
|
|
for byte ('[data:range]' 1 (size image) 2) {
|
|
atPut (_byteCount + _ptr) _imgData (hexToInt ('[data:copyFromTo]' image byte (byte + 1)))
|
|
_ptr += 1
|
|
}
|
|
_byteCount += (_ptr - 1)
|
|
}
|
|
|
|
to '_sendCmd' cmdString {
|
|
comment 'Input is a comma sep. STRING.
|
|
MAKE SURE ALL INPUT PARAMETERS ARE HEX'
|
|
local '_cList' ('[data:split]' cmdString _comma)
|
|
local 'cmdPrefix' (hexToInt '80')
|
|
if ('i2c' == _comMode) {
|
|
for cmd _cList {
|
|
'[sensors:i2cWrite]' OLEDi2cAddr ('[data:asByteArray]' ('[data:makeList]' cmdPrefix (hexToInt cmd)))
|
|
}
|
|
} else {
|
|
'_SPIWriteCmd'
|
|
for cmd _cList {
|
|
spiSend (hexToInt cmd)
|
|
}
|
|
}
|
|
}
|
|
|
|
to '_verifyXY' x y {
|
|
if (and (and (x >= 0) (x <= 127)) (and (y >= 0) (y <= 63))) {
|
|
return 0
|
|
} else {
|
|
sayIt 'x or y value error:' ('[data:unicodeString]' 10) 'x:' x ' y:' y
|
|
stopTask
|
|
}
|
|
}
|
|
|
|
to 'defer display updates' {
|
|
_delayGDUpd = (booleanConstant true)
|
|
}
|
|
|
|
|
|
module Spark_Analog Operators
|
|
author 'FABLAB BH'
|
|
version 1 1
|
|
choices analog_pins '3' '4' '6' '7' '8'
|
|
description ''
|
|
|
|
spec 'r' '_Analog Pins' '_Analog Pins _' 'num' 3
|
|
spec 'r' 'Film Pressure Pin' 'Film Pressure Pin _' 'menu.analog_pins' 3
|
|
spec 'r' 'PhotoResistance Pin' 'Photoresistance Pin _' 'menu.analog_pins' 3
|
|
spec 'r' 'Potentiometer' 'Potentiometer Pin _' 'menu.analog_pins' 3
|
|
spec 'r' 'Steam Sensor' 'Steam Sensor _' 'menu.analog_pins' 3
|
|
|
|
to 'Analog Pins' Pin {
|
|
return (at Pin ('[data:makeList]' 0 0 4 39 0 36 35 34 0))
|
|
}
|
|
|
|
to 'Film Pressure Pin' Pin {
|
|
return (analogReadOp ('Analog Pins' Pin))
|
|
}
|
|
|
|
to 'PhotoResistance Pin' Pin {
|
|
return (analogReadOp ('Analog Pins' Pin))
|
|
}
|
|
|
|
to Potentiometer Pin {
|
|
return (analogReadOp ('Analog Pins' Pin))
|
|
}
|
|
|
|
to 'Steam Sensor' Pin {
|
|
return (analogReadOp ('Analog Pins' Pin))
|
|
}
|
|
|
|
|
|
module Spark_Digital Data
|
|
author 'FABLAB BH'
|
|
version 1 1
|
|
depends '_Temperature Humidity (DHT11, DHT22)'
|
|
choices digital_pins '1' '2' '3' '4' '6' '7' '8' '9'
|
|
description ''
|
|
|
|
spec 'r' 'Button Pin' 'Button Pin _' 'menu.digital_pins' 1
|
|
spec 'r' '_DigitalPins' '_DigitalPins _' 'menu.digital_pins' 1
|
|
spec 'r' 'Inverted Button Pin' 'Inverted Button Pin _' 'menu.digital_pins' 1
|
|
spec 'r' 'Photo Interrupter Pin' 'Photo Interrupter Pin _' 'menu.digital_pins' 1
|
|
spec 'r' 'Tilt Switch Pin' 'Tilt Switch Pin _' 'menu.digital_pins' 1
|
|
spec 'r' 'Touch Pin' 'Touch Pin _' 'menu.digital_pins' 1
|
|
spec 'r' 'Humidity Pin' 'Humidity Pin _' 'menu.digital_pins' 1
|
|
spec 'r' 'Temperature Pin' 'Temperature Pin _' 'menu.digital_pins' 1
|
|
space
|
|
space
|
|
spec ' ' 'Buzzer2' 'Buzzer Pin _ State _' 'menu.digital_pins bool' 1 false
|
|
spec ' ' 'LED' 'LED Pin _ State _' 'menu.digital_pins bool' 1 false
|
|
spec ' ' 'Horn' 'Horn Pin _ State _' 'menu.digital_pins bool' 1 false
|
|
spec ' ' 'Relay Pin' 'Relay Pin _ State _' 'menu.digital_pins bool' 1 false
|
|
space
|
|
spec ' ' 'Buzzer' 'Buzzer Pin _ Tone _' 'menu.digital_pins num' 1 1000
|
|
spec ' ' 'LED2 Pin' 'LED Pin _ Brightness _' 'menu.digital_pins num' 1 1000
|
|
spec ' ' 'Horn Pin' 'Horn Pin _ Tone _' 'menu.digital_pins num' 1 1000
|
|
|
|
to 'Button Pin' Pin {
|
|
local 'Read1' (digitalReadOp (DigitalPins Pin) 'up')
|
|
if (Read1 == (booleanConstant true)) {
|
|
return (not Read1)
|
|
} else {
|
|
return (booleanConstant true)
|
|
}
|
|
}
|
|
|
|
to Buzzer Pin Tone {
|
|
analogWriteOp (DigitalPins Pin) Tone
|
|
}
|
|
|
|
to Buzzer2 Pin State {
|
|
digitalWriteOp (DigitalPins Pin) State
|
|
}
|
|
|
|
to DigitalPins Pin {
|
|
return (at Pin ('[data:makeList]' 13 2 26 27 0 23 16 5 18))
|
|
}
|
|
|
|
to Horn Pin State {
|
|
digitalWriteOp (DigitalPins Pin) State
|
|
}
|
|
|
|
to 'Horn Pin' Pin Tone {
|
|
analogWriteOp (DigitalPins Pin) Tone
|
|
}
|
|
|
|
to 'Humidity Pin' Pin {
|
|
return (humidity_DHT11 (DigitalPins Pin))
|
|
}
|
|
|
|
to 'Inverted Button Pin' Pins {
|
|
local 'Read2' (digitalReadOp (DigitalPins Pin) 'up')
|
|
if (Read2 == (booleanConstant false)) {
|
|
return Read2
|
|
} else {
|
|
return (booleanConstant true)
|
|
}
|
|
}
|
|
|
|
to LED Pin State {
|
|
digitalWriteOp (DigitalPins Pin) State
|
|
}
|
|
|
|
to 'LED2 Pin' Pin Brightness {
|
|
analogWriteOp (DigitalPins Pin) Brightness
|
|
}
|
|
|
|
to 'Photo Interrupter Pin' Pin {
|
|
return (digitalReadOp (DigitalPins Pin))
|
|
}
|
|
|
|
to 'Relay Pin' Pin State {
|
|
digitalWriteOp (DigitalPins Pin) State
|
|
}
|
|
|
|
to 'Temperature Pin' Pin {
|
|
return (temperature_DHT11 (DigitalPins Pin))
|
|
}
|
|
|
|
to 'Tilt Switch Pin' Pin {
|
|
return (digitalReadOp (DigitalPins Pin))
|
|
}
|
|
|
|
to 'Touch Pin' Pin {
|
|
return (digitalReadOp (DigitalPins Pin))
|
|
}
|
|
|
|
|
|
module Spark_I2C Output
|
|
author FABLAB
|
|
version 1 1
|
|
depends '_Gesture (PAJ7620)'
|
|
choices direction clockwise 'counter-clockwise'
|
|
description ''
|
|
variables Gesture
|
|
|
|
spec 'r' 'Gesture Read' 'Gesture Read'
|
|
space
|
|
spec ' ' 'Motor Driver A' 'Motor Driver A Direction _ Speed _' 'menu.direction num' 'clockwise' 10
|
|
spec ' ' 'Motor Driver B' 'Motor Driver B Direction _ Speed _' 'menu.direction num' 'clockwise' 10
|
|
spec 'r' '_Direction' '_Direction _' 'menu.direction' 'clockwise'
|
|
|
|
to 'Gesture Read' {
|
|
return ('paj7620 read')
|
|
}
|
|
|
|
to 'Motor Driver A' Direction Speed {
|
|
if ((Direction Direction) == (booleanConstant true)) {
|
|
i2cSet 0 1 Speed
|
|
i2cSet 0 2 0
|
|
} ((Direction Direction) == (booleanConstant false)) {
|
|
i2cSet 0 1 0
|
|
i2cSet 0 2 Speed
|
|
} else {
|
|
i2cSet 0 1 0
|
|
i2cSet 0 2 0
|
|
}
|
|
}
|
|
|
|
to 'Motor Driver B' Direction Speed {
|
|
if ((Direction Direction) == (booleanConstant true)) {
|
|
i2cSet 0 3 Speed
|
|
i2cSet 0 4 0
|
|
} ((Direction Direction) == (booleanConstant false)) {
|
|
i2cSet 0 3 0
|
|
i2cSet 0 4 Speed
|
|
} else {
|
|
i2cSet 0 3 0
|
|
i2cSet 0 4 0
|
|
}
|
|
}
|
|
|
|
|
|
module Spark_MP Variables
|
|
author FABLAB
|
|
version 1 1
|
|
choices MP_pins '1' '9'
|
|
description ''
|
|
|
|
spec 'r' 'Ultrasonic Pin' 'Ultrasonic Pin _' 'menu.MP_pins' 1
|
|
spec 'r' '_Multipins' 'Multipins _' 'menu.MP_pins' '1'
|
|
space
|
|
spec ' ' 'RGBLED3' 'RGBLED Pin _ R _ G _ B _' 'menu.MP_pins num num num' 1 50 50 50
|
|
spec ' ' 'RGBLED3 Pin' 'RGBLED Pin _ R _ G _ B _' 'menu.MP_pins bool bool bool' 1 true true true
|
|
spec ' ' 'Traffic Light' 'Traffic Light Pin _ R _ Y _ G _' 'menu.MP_pins bool bool bool' 1 true true true
|
|
spec ' ' 'Traffic Light Pin' 'Traffic Light Pin _ R _ Y _ G _' 'menu.MP_pins num num num' 1 255 255 255
|
|
|
|
to Multipins Pin {
|
|
return (at Pin ('[data:makeList]' 12 0 0 0 0 0 0 0 17))
|
|
}
|
|
|
|
to RGBLED3 Pin Red Green Blue {
|
|
analogWriteOp (Multipins Pin) Red
|
|
analogWriteOp ((Multipins Pin) + 1) Green
|
|
analogWriteOp ((Multipins Pin) + 2) Blue
|
|
}
|
|
|
|
to 'RGBLED3 Pin' Pin Red Green Blue {
|
|
digitalWriteOp (Multipins Pin) Red
|
|
digitalWriteOp ((Multipins Pin) + 1) Green
|
|
digitalWriteOp ((Multipins Pin) + 2) Blue
|
|
}
|
|
|
|
to 'Traffic Light' Pin Red Yellow Green {
|
|
digitalWriteOp (Multipins Pin) Red
|
|
digitalWriteOp ((Multipins Pin) + 1) Yellow
|
|
digitalWriteOp ((Multipins Pin) + 2) Green
|
|
}
|
|
|
|
to 'Traffic Light Pin' Pin Red Yellow Green {
|
|
analogWriteOp (Multipins Pin) Red
|
|
analogWriteOp ((Multipins Pin) + 1) Yellow
|
|
analogWriteOp ((Multipins Pin) + 2) Green
|
|
}
|
|
|
|
to 'Ultrasonic Pin' Pin {
|
|
comment 'Contributed by Joan Guillén and Josep Ferràndiz'
|
|
digitalWriteOp ((Multipins Pin) + 1) false
|
|
waitMicros 2
|
|
digitalWriteOp ((Multipins Pin) + 1) true
|
|
waitMicros 50
|
|
digitalWriteOp ((Multipins Pin) + 1) false
|
|
local 'start' (microsOp)
|
|
waitUntil (or (not (digitalReadOp ((Multipins Pin) + 2))) (((microsOp) - start) > 23320))
|
|
waitUntil (or (digitalReadOp ((Multipins Pin) + 2)) (((microsOp) - start) > 23320))
|
|
if (((microsOp) - start) > 23320) {
|
|
comment 'Distance sensor not ready; return the last distance reading'
|
|
return _sr04_last
|
|
}
|
|
comment 'Pulse sent. Measure time until echo is detected.'
|
|
start = (microsOp)
|
|
waitUntil (or (not (digitalReadOp ((Multipins Pin) + 2))) (((microsOp) - start) > 23320))
|
|
_sr04_last = ((10 * ((microsOp) - start)) / 583)
|
|
comment 'Leave some time for reverberations to die away.'
|
|
waitMillis 10
|
|
return _sr04_last
|
|
}
|
|
|
|
|
|
module Spark_PWM Control
|
|
author 'FABLAB BH'
|
|
version 1 1
|
|
depends _Servo
|
|
choices PWM_pins2 '3' '4' '6' '7' '8'
|
|
choices PWM_pins '1' '9'
|
|
choices direction clockwise 'counter-clockwise'
|
|
choices servo_pins '32' '33'
|
|
description ''
|
|
|
|
spec 'r' '_PWM Pin' '_PWM Pin _' 'menu.PWM_pins' 1
|
|
spec 'r' '_Direction' '_Direction _' 'menu.direction' 'clockwise'
|
|
spec ' ' 'Fan Motor3' 'Fan Motor Pin _ Speed _ (0-100)' 'menu.PWM_pins2 num' 3 50
|
|
spec ' ' 'Fan Motor4' 'Fan Motor Pin _ Speed _ (0-1023)' 'menu.PWM_pins2 num' 3 50
|
|
space
|
|
spec ' ' 'Fan Motor' 'Fan Motor Pin _ Direction _ Speed _ (0-100)' 'menu.PWM_pins menu.direction num' 1 'clockwise' 50
|
|
spec ' ' 'Fan Motor2' 'Fan Motor Pin _ Direction _ Speed _ (0-1023)' 'menu.PWM_pins menu.direction num' 1 'clockwise' 50
|
|
space
|
|
spec ' ' 'Servo' 'Servo Motor Pin _ Speed _ (-100 to 100)' 'menu.servo_pins num' 33 50
|
|
spec ' ' 'Servo Motor Pin' 'Servo Motor Pin _ Degrees _ (-90 to 90)' 'menu.servo_pins num' 33 90
|
|
|
|
to Direction Direction {
|
|
if (Direction == ('[data:toString]' 'counter-clockwise')) {
|
|
return (booleanConstant false)
|
|
} else {
|
|
return (booleanConstant true)
|
|
}
|
|
}
|
|
|
|
to 'Fan Motor' Pin Direction Speed {
|
|
if (and (Speed > 0) (Speed <= 100)) {
|
|
local 'PWM' (absoluteValue (((Speed - 1) * ((1023 - 1) / 99)) + 1))
|
|
if ((Direction Direction) == (not true)) {
|
|
if (and (PWM > 0) (PWM < 1024)) {
|
|
digitalWriteOp ('PWM Pin' Pin) true
|
|
analogWriteOp (('PWM Pin' Pin) + 1) (1023 - PWM)
|
|
}
|
|
} else {
|
|
if (and (PWM > 0) (PWM < 1024)) {
|
|
digitalWriteOp ('PWM Pin' Pin) false
|
|
analogWriteOp (('PWM Pin' Pin) + 1) PWM
|
|
}
|
|
}
|
|
} (Speed == 0) {
|
|
digitalWriteOp ('PWM Pin' Pin) false
|
|
digitalWriteOp (('PWM Pin' Pin) + 1) false
|
|
} else {
|
|
sayIt 'The range is between 0 and 100'
|
|
}
|
|
}
|
|
|
|
to 'Fan Motor2' Pin Direction Speed {
|
|
if (and (Speed > 0) (Speed <= 1023)) {
|
|
if ((Direction Direction) == (not true)) {
|
|
digitalWriteOp ('PWM Pin' Pin) true
|
|
analogWriteOp (('PWM Pin' Pin) + 1) (1023 - Speed)
|
|
} else {
|
|
digitalWriteOp ('PWM Pin' Pin) false
|
|
analogWriteOp (('PWM Pin' Pin) + 1) Speed
|
|
}
|
|
} (Speed == 0) {
|
|
digitalWriteOp ('PWM Pin' Pin) false
|
|
digitalWriteOp (('PWM Pin' Pin) + 1) false
|
|
} else {
|
|
sayIt 'The range is between 0 and 1023'
|
|
}
|
|
}
|
|
|
|
to 'Fan Motor3' Pin Speed {
|
|
if (and (Speed > 0) (Speed <= 100)) {
|
|
local 'PWM' (absoluteValue (((Speed - 1) * ((1023 - 1) / 99)) + 1))
|
|
analogWriteOp ('PWM Pin' Pin) PWM
|
|
} (Speed == 0) {
|
|
digitalWriteOp ('PWM Pin' Pin) false
|
|
} else {
|
|
sayIt 'The range is between 0 and 100'
|
|
}
|
|
}
|
|
|
|
to 'Fan Motor4' Pin Speed {
|
|
if (and (Speed > 0) (Speed <= 1023)) {
|
|
analogWriteOp ('PWM Pin' Pin) Speed
|
|
} (Speed == 0) {
|
|
digitalWriteOp ('PWM Pin' Pin) false
|
|
} else {
|
|
sayIt 'The range is between 0 and 1023'
|
|
}
|
|
}
|
|
|
|
to 'PWM Pin' Pin {
|
|
return (at Pin ('[data:makeList]' 13 0 26 27 0 23 16 5 18))
|
|
}
|
|
|
|
to Servo Pin Speed {
|
|
setServoSpeed Pin Speed
|
|
}
|
|
|
|
to 'Servo Motor Pin' Pin Degrees {
|
|
setServoAngle Pin Degrees
|
|
}
|
|
|
|
|
|
module 'Temperature Humidity (DHT11, DHT22)' Input
|
|
author MicroBlocks
|
|
version 1 3
|
|
tags sensor dht11 dht22 temperature humidity
|
|
description 'Support for the DHT11 and DHT22 environmental sensors. These sensors provide temperature and humidity readings.
|
|
'
|
|
variables _dht_temperature _dht_humidity _dhtData _dhtLastReadTime data
|
|
|
|
spec 'r' 'temperature_DHT11' 'temperature (Celsius) DHT11 pin _' 'auto' 4
|
|
spec 'r' 'humidity_DHT11' 'humidity DHT11 pin _' 'auto' 4
|
|
spec 'r' 'temperature_DHT22' 'temperature (Celsius) DHT22 pin _' 'auto' 4
|
|
spec 'r' 'humidity_DHT22' 'humidity DHT22 pin _' 'auto' 4
|
|
spec ' ' '_dhtReadData' '_dhtReadData pin _' 'auto any' 4
|
|
spec 'r' '_dhtChecksumOkay' '_dhtChecksumOkay' 'any'
|
|
spec ' ' '_dhtUpdate' '_dhtUpdate _ isDHT11 _' 'auto bool any' 4 true
|
|
spec 'r' '_dhtReady' '_dhtReady' 'any'
|
|
spec ' ' '_dhtCaptureData' '_dhtCaptureData _' 'num' 4
|
|
|
|
to '_dhtCaptureData' pin {
|
|
'[sensors:captureStart]' pin
|
|
waitMillis 10
|
|
local 'pulses' ('[sensors:captureEnd]')
|
|
local 'pulseCount' (size pulses)
|
|
if (pulseCount < 80) {
|
|
return 0
|
|
} (pulseCount > 80) {
|
|
pulses = ('[data:copyFromTo]' pulses (pulseCount - 79))
|
|
}
|
|
data = pulses
|
|
local 'byte' 0
|
|
for i 40 {
|
|
if ((at ((2 * i) - 1) pulses) > 40) {
|
|
comment 'Long pulse - appends a "1" bit'
|
|
byte += 1
|
|
}
|
|
if ((i % 8) == 0) {
|
|
atPut (i / 8) _dhtData byte
|
|
byte = 0
|
|
} else {
|
|
byte = (byte << 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
to '_dhtChecksumOkay' {
|
|
if (not (isType _dhtData 'list')) {return (booleanConstant false)}
|
|
local 'checksum' 0
|
|
for i 4 {
|
|
checksum += (at i _dhtData)
|
|
}
|
|
checksum = (checksum & 255)
|
|
return (checksum == (at 5 _dhtData))
|
|
}
|
|
|
|
to '_dhtReadData' pin {
|
|
comment 'Create DHT data array the first time'
|
|
if (_dhtData == 0) {
|
|
_dhtData = (newList 5)
|
|
}
|
|
comment 'fill with 1''s set checksum will be bad if read fails'
|
|
atPut 'all' _dhtData 1
|
|
comment 'Pull pin low for >18msec to request data'
|
|
digitalWriteOp pin false
|
|
waitMillis 20
|
|
local 'useDHTPrimitive' (booleanConstant true)
|
|
if useDHTPrimitive {
|
|
'_dhtCaptureData' pin
|
|
return 0
|
|
}
|
|
comment 'Read DHT start pulses (H L H L)'
|
|
waitUntil (digitalReadOp pin)
|
|
waitUntil (not (digitalReadOp pin))
|
|
waitUntil (digitalReadOp pin)
|
|
waitUntil (not (digitalReadOp pin))
|
|
local 'i' 1
|
|
local 'byte' 0
|
|
local 'bit' 1
|
|
comment 'Read 40 bits (5 bytes)'
|
|
repeat 40 {
|
|
waitUntil (digitalReadOp pin)
|
|
local 'start' (microsOp)
|
|
waitUntil (not (digitalReadOp pin))
|
|
if (((microsOp) - start) > 40) {
|
|
comment 'Long pulse - append a "1" bit'
|
|
byte += 1
|
|
}
|
|
if (bit == 8) {
|
|
atPut i _dhtData byte
|
|
i += 1
|
|
byte = 0
|
|
bit = 1
|
|
} else {
|
|
byte = (byte << 1)
|
|
bit += 1
|
|
}
|
|
waitUntil (not (digitalReadOp pin))
|
|
}
|
|
}
|
|
|
|
to '_dhtReady' {
|
|
local 'elapsed' ((millisOp) - _dhtLastReadTime)
|
|
return (or (elapsed < 0) (elapsed > 2000))
|
|
}
|
|
|
|
to '_dhtUpdate' pin isDHT11 {
|
|
if ('_dhtReady') {
|
|
_dht_temperature = 0
|
|
_dht_humidity = 0
|
|
'_dhtReadData' pin
|
|
_dhtLastReadTime = (millisOp)
|
|
}
|
|
if ('_dhtChecksumOkay') {
|
|
if isDHT11 {
|
|
_dht_temperature = (at 3 _dhtData)
|
|
_dht_humidity = (at 1 _dhtData)
|
|
} else {
|
|
local 'n' (((at 1 _dhtData) * 256) + (at 2 _dhtData))
|
|
_dht_humidity = ((n + 5) / 10)
|
|
n = ((((at 3 _dhtData) & 127) * 256) + (at 4 _dhtData))
|
|
if (((at 3 _dhtData) & 128) != 0) {
|
|
n = (0 - n)
|
|
}
|
|
_dht_temperature = ((n + 5) / 10)
|
|
}
|
|
}
|
|
}
|
|
|
|
to humidity_DHT11 pin {
|
|
'_dhtUpdate' pin true
|
|
return _dht_humidity
|
|
}
|
|
|
|
to humidity_DHT22 pin {
|
|
'_dhtUpdate' pin false
|
|
return _dht_humidity
|
|
}
|
|
|
|
to temperature_DHT11 pin {
|
|
'_dhtUpdate' pin true
|
|
return _dht_temperature
|
|
}
|
|
|
|
to temperature_DHT22 pin {
|
|
'_dhtUpdate' pin false
|
|
return _dht_temperature
|
|
}
|
|
|