1
1
import { customElement , html , LitElement , property , css , svg } from 'lit-element' ;
2
2
import { fontA00 } from './lcd1602-font-a00' ;
3
3
import { ElementPin , i2c } from './pin' ;
4
-
5
- const ROWS = 2 ;
6
- const COLS = 16 ;
4
+ import { mmToPix } from './utils/units' ;
7
5
8
6
const charXSpacing = 3.55 ;
9
7
const charYSpacing = 5.95 ;
@@ -26,6 +24,9 @@ export class LCD1602Element extends LitElement {
26
24
@property ( ) backlight = true ;
27
25
@property ( ) pins : 'full' | 'i2c' | 'none' = 'full' ;
28
26
27
+ protected numCols = 16 ;
28
+ protected numRows = 2 ;
29
+
29
30
@property ( )
30
31
get text ( ) {
31
32
return Array . from ( this . characters )
@@ -60,7 +61,13 @@ export class LCD1602Element extends LitElement {
60
61
` ;
61
62
}
62
63
64
+ protected get panelHeight ( ) {
65
+ return this . rows * 5.75 ;
66
+ }
67
+
63
68
get pinInfo ( ) : ElementPin [ ] {
69
+ const { panelHeight } = this ;
70
+ const y = 87.5 + panelHeight * mmToPix ;
64
71
switch ( this . pins ) {
65
72
case 'i2c' :
66
73
return [
@@ -73,33 +80,42 @@ export class LCD1602Element extends LitElement {
73
80
case 'full' :
74
81
default :
75
82
return [
76
- { name : 'VSS' , x : 32 , y : 131 , number : 1 , signals : [ { type : 'power' , signal : 'GND' } ] } ,
77
- { name : 'VDD' , x : 41.5 , y : 131 , number : 2 , signals : [ { type : 'power' , signal : 'VCC' } ] } ,
78
- { name : 'V0' , x : 51.5 , y : 131 , number : 3 , signals : [ ] } ,
79
- { name : 'RS' , x : 60.5 , y : 131 , number : 4 , signals : [ ] } ,
80
- { name : 'RW' , x : 70.5 , y : 131 , number : 5 , signals : [ ] } ,
81
- { name : 'E' , x : 80 , y : 131 , number : 6 , signals : [ ] } ,
82
- { name : 'D0' , x : 89.5 , y : 131 , number : 7 , signals : [ ] } ,
83
- { name : 'D1' , x : 99.5 , y : 131 , number : 8 , signals : [ ] } ,
84
- { name : 'D2' , x : 109 , y : 131 , number : 9 , signals : [ ] } ,
85
- { name : 'D3' , x : 118.5 , y : 131 , number : 10 , signals : [ ] } ,
86
- { name : 'D4' , x : 128 , y : 131 , number : 11 , signals : [ ] } ,
87
- { name : 'D5' , x : 137.5 , y : 131 , number : 12 , signals : [ ] } ,
88
- { name : 'D6' , x : 147 , y : 131 , number : 13 , signals : [ ] } ,
89
- { name : 'D7' , x : 156.5 , y : 131 , number : 14 , signals : [ ] } ,
90
- { name : 'A' , x : 166.5 , y : 131 , number : 15 , signals : [ ] } ,
91
- { name : 'K' , x : 176 , y : 131 , number : 16 , signals : [ ] } ,
83
+ { name : 'VSS' , x : 32 , y, number : 1 , signals : [ { type : 'power' , signal : 'GND' } ] } ,
84
+ { name : 'VDD' , x : 41.5 , y, number : 2 , signals : [ { type : 'power' , signal : 'VCC' } ] } ,
85
+ { name : 'V0' , x : 51.5 , y, number : 3 , signals : [ ] } ,
86
+ { name : 'RS' , x : 60.5 , y, number : 4 , signals : [ ] } ,
87
+ { name : 'RW' , x : 70.5 , y, number : 5 , signals : [ ] } ,
88
+ { name : 'E' , x : 80 , y, number : 6 , signals : [ ] } ,
89
+ { name : 'D0' , x : 89.5 , y, number : 7 , signals : [ ] } ,
90
+ { name : 'D1' , x : 99.5 , y, number : 8 , signals : [ ] } ,
91
+ { name : 'D2' , x : 109 , y, number : 9 , signals : [ ] } ,
92
+ { name : 'D3' , x : 118.5 , y, number : 10 , signals : [ ] } ,
93
+ { name : 'D4' , x : 128 , y, number : 11 , signals : [ ] } ,
94
+ { name : 'D5' , x : 137.5 , y, number : 12 , signals : [ ] } ,
95
+ { name : 'D6' , x : 147 , y, number : 13 , signals : [ ] } ,
96
+ { name : 'D7' , x : 156.5 , y, number : 14 , signals : [ ] } ,
97
+ { name : 'A' , x : 166.5 , y, number : 15 , signals : [ ] } ,
98
+ { name : 'K' , x : 176 , y, number : 16 , signals : [ ] } ,
92
99
] ;
93
100
}
94
101
}
95
102
103
+ get cols ( ) {
104
+ return this . numCols ;
105
+ }
106
+
107
+ get rows ( ) {
108
+ return this . numRows ;
109
+ }
110
+
96
111
path ( characters : Uint8Array | number [ ] ) {
97
112
const xSpacing = 0.6 ;
98
113
const ySpacing = 0.7 ;
99
114
const result = [ ] ;
115
+ const { cols } = this ;
100
116
for ( let i = 0 ; i < characters . length ; i ++ ) {
101
- const charX = ( i % COLS ) * charXSpacing ;
102
- const charY = Math . floor ( i / COLS ) * charYSpacing ;
117
+ const charX = ( i % cols ) * charXSpacing ;
118
+ const charY = Math . floor ( i / cols ) * charYSpacing ;
103
119
104
120
for ( let py = 0 ; py < 8 ; py ++ ) {
105
121
const row = this . font [ characters [ i ] * 8 + py ] ;
@@ -116,17 +132,18 @@ export class LCD1602Element extends LitElement {
116
132
}
117
133
118
134
renderCursor ( ) {
119
- const xOffset = 12.45 + this . cursorX * charXSpacing ;
120
- const yOffset = 12.55 + this . cursorY * charYSpacing ;
121
- if ( this . cursorX < 0 || this . cursorX >= COLS || this . cursorY < 0 || this . cursorY >= ROWS ) {
135
+ const { cols, rows, cursor, cursorX, cursorY, blink, color } = this ;
136
+ const xOffset = 12.45 + cursorX * charXSpacing ;
137
+ const yOffset = 12.55 + cursorY * charYSpacing ;
138
+ if ( cursorX < 0 || cursorX >= cols || cursorY < 0 || cursorY >= rows ) {
122
139
return null ;
123
140
}
124
141
125
142
const result = [ ] ;
126
143
127
- if ( this . blink ) {
144
+ if ( blink ) {
128
145
result . push ( svg `
129
- < rect x ="${ xOffset } " y ="${ yOffset } " width ="2.95 " height ="5.55 " fill ="${ this . color } ">
146
+ < rect x ="${ xOffset } " y ="${ yOffset } " width ="2.95 " height ="5.55 " fill ="${ color } ">
130
147
< animate
131
148
attributeName ="opacity "
132
149
values ="0;0;0;0;1;1;0;0;0;0 "
@@ -138,11 +155,9 @@ export class LCD1602Element extends LitElement {
138
155
` ) ;
139
156
}
140
157
141
- if ( this . cursor ) {
158
+ if ( cursor ) {
142
159
const y = yOffset + 0.7 * 7 ;
143
- result . push (
144
- svg `< rect x ="${ xOffset } " y ="${ y } " width ="2.95 " height ="0.65 " fill ="${ this . color } " /> `
145
- ) ;
160
+ result . push ( svg `< rect x ="${ xOffset } " y ="${ y } " width ="2.95 " height ="0.65 " fill ="${ color } " /> ` ) ;
146
161
}
147
162
148
163
return result ;
@@ -159,45 +174,52 @@ export class LCD1602Element extends LitElement {
159
174
` ;
160
175
}
161
176
162
- renderPins ( ) {
177
+ renderPins ( panelHeight : number ) {
178
+ const y = panelHeight + 21.1 ;
163
179
return svg `
164
- < rect x ="7.55 " y ="33.5 " height ="2.5 " width ="40.64 " fill ="url(#pins) " />
165
- < text x ="6 " y ="35.3 " fill ="white "> 1</ text >
166
- < text x ="7.2 " y ="33.3 " fill ="white "> VSS</ text >
167
- < text x ="9.9 " y ="33.3 " fill ="white "> VDD</ text >
168
- < text x ="12.7 " y ="33.3 " fill ="white "> V0</ text >
169
- < text x ="15.2 " y ="33.3 " fill ="white "> RS</ text >
170
- < text x ="17.8 " y ="33.3 " fill ="white "> RW</ text >
171
- < text x ="20.8 " y ="33.3 " fill ="white "> E</ text >
172
- < text x ="22.7 " y ="33.3 " fill ="white "> D0</ text >
173
- < text x ="25.3 " y ="33.3 " fill ="white "> D1</ text >
174
- < text x ="27.9 " y ="33.3 " fill ="white "> D2</ text >
175
- < text x ="30.4 " y ="33.3 " fill ="white "> D3</ text >
176
- < text x ="33 " y ="33.3 " fill ="white "> D4</ text >
177
- < text x ="35.6 " y ="33.3 " fill ="white "> D5</ text >
178
- < text x ="38.2 " y ="33.3 " fill ="white "> D6</ text >
179
- < text x ="40.8 " y ="33.3 " fill ="white "> D7</ text >
180
- < text x ="43.6 " y ="33.3 " fill ="white "> A</ text >
181
- < text x ="46.2 " y ="33.3 " fill ="white "> K</ text >
182
- < text x ="48 " y ="35.3 " fill ="white "> 16</ text >
180
+ < g transform ="translate(0, ${ y } ) ">
181
+ < rect x ="7.55 " y ="1 " height ="2.5 " width ="40.64 " fill ="url(#pins) " />
182
+ < text x ="6 " y ="2.7 " fill ="white "> 1</ text >
183
+ < text x ="7.2 " y ="0.7 " fill ="white "> VSS</ text >
184
+ < text x ="9.9 " y ="0.7 " fill ="white "> VDD</ text >
185
+ < text x ="12.7 " y ="0.7 " fill ="white "> V0</ text >
186
+ < text x ="15.2 " y ="0.7 " fill ="white "> RS</ text >
187
+ < text x ="17.8 " y ="0.7 " fill ="white "> RW</ text >
188
+ < text x ="20.8 " y ="0.7 " fill ="white "> E</ text >
189
+ < text x ="22.7 " y ="0.7 " fill ="white "> D0</ text >
190
+ < text x ="25.3 " y ="0.7 " fill ="white "> D1</ text >
191
+ < text x ="27.9 " y ="0.7 " fill ="white "> D2</ text >
192
+ < text x ="30.4 " y ="0.7 " fill ="white "> D3</ text >
193
+ < text x ="33 " y ="0.7 " fill ="white "> D4</ text >
194
+ < text x ="35.6 " y ="0.7 " fill ="white "> D5</ text >
195
+ < text x ="38.2 " y ="0.7 " fill ="white "> D6</ text >
196
+ < text x ="40.8 " y ="0.7 " fill ="white "> D7</ text >
197
+ < text x ="43.6 " y ="0.7 " fill ="white "> A</ text >
198
+ < text x ="46.2 " y ="0.7 " fill ="white "> K</ text >
199
+ < text x ="48 " y ="2.7 " fill ="white "> 16</ text >
200
+ </ g >
183
201
` ;
184
202
}
185
203
186
204
render ( ) {
187
- const { color, characters, background } = this ;
205
+ const { color, characters, background, pins , panelHeight , cols } = this ;
188
206
189
207
const darken = this . backlight ? 0 : 0.5 ;
190
208
const actualBgColor =
191
209
background in backgroundColors ? backgroundColors [ background ] : backgroundColors ;
192
210
211
+ const panelWidth = cols * 3.5125 ;
212
+ const width = panelWidth + 23.8 ;
213
+ const height = panelHeight + 24.5 ;
214
+
193
215
// Dimensions according to:
194
216
// https://www.winstar.com.tw/products/character-lcd-display-module/16x2-lcd.html
195
217
return html `
196
218
< svg
197
- width ="80mm "
198
- height ="36mm "
219
+ width ="${ width } mm "
220
+ height ="${ height } mm "
199
221
version ="1.1 "
200
- viewBox ="0 0 80 36 "
222
+ viewBox ="0 0 ${ width } ${ height } "
201
223
style ="font-size: 1.5px; font-family: monospace "
202
224
xmlns ="http://www.w3.org/2000/svg "
203
225
>
@@ -220,13 +242,35 @@ export class LCD1602Element extends LitElement {
220
242
< circle r ="0.45 " cx ="0.827 " cy ="0.9 " color ="black " />
221
243
</ pattern >
222
244
</ defs >
223
- < rect width ="80 " height ="36 " fill ="#087f45 " />
224
- < rect x ="4.95 " y ="5.7 " width ="71.2 " height ="25.2 " />
225
- < rect x ="7.55 " y ="10.3 " width ="66 " height ="16 " rx ="1.5 " ry ="1.5 " fill ="${ actualBgColor } " />
226
- < rect x ="7.55 " y ="10.3 " width ="66 " height ="16 " rx ="1.5 " ry ="1.5 " opacity ="${ darken } " />
227
- ${ this . pins === 'i2c' ? this . renderI2CPins ( ) : null }
228
- ${ this . pins === 'full' ? this . renderPins ( ) : null }
229
- < rect x ="12.45 " y ="12.55 " width ="56.2 " height ="11.5 " fill ="url(#characters) " />
245
+ < rect width ="${ width } " height ="${ height } " fill ="#087f45 " />
246
+ < rect x ="4.95 " y ="5.7 " width ="${ panelWidth + 15 } " height ="${ panelHeight + 13.7 } " />
247
+ < rect
248
+ x ="7.55 "
249
+ y ="10.3 "
250
+ width ="${ panelWidth + 9.8 } "
251
+ height ="${ panelHeight + 4.5 } "
252
+ rx ="1.5 "
253
+ ry ="1.5 "
254
+ fill ="${ actualBgColor } "
255
+ />
256
+ < rect
257
+ x ="7.55 "
258
+ y ="10.3 "
259
+ width ="${ panelWidth + 9.8 } "
260
+ height ="${ panelHeight + 4.5 } "
261
+ rx ="1.5 "
262
+ ry ="1.5 "
263
+ opacity ="${ darken } "
264
+ />
265
+ ${ pins === 'i2c' ? this . renderI2CPins ( ) : null }
266
+ ${ pins === 'full' ? this . renderPins ( panelHeight ) : null }
267
+ < rect
268
+ x ="12.45 "
269
+ y ="12.55 "
270
+ width ="${ panelWidth } "
271
+ height ="${ panelHeight } "
272
+ fill ="url(#characters) "
273
+ />
230
274
< path d ="${ this . path ( characters ) } " transform ="translate(12.45, 12.55) " fill ="${ color } " />
231
275
${ this . renderCursor ( ) }
232
276
</ svg >
0 commit comments