11import { customElement , html , LitElement , property , css , svg } from 'lit-element' ;
22import { fontA00 } from './lcd1602-font-a00' ;
33import { ElementPin , i2c } from './pin' ;
4-
5- const ROWS = 2 ;
6- const COLS = 16 ;
4+ import { mmToPix } from './utils/units' ;
75
86const charXSpacing = 3.55 ;
97const charYSpacing = 5.95 ;
@@ -26,6 +24,9 @@ export class LCD1602Element extends LitElement {
2624 @property ( ) backlight = true ;
2725 @property ( ) pins : 'full' | 'i2c' | 'none' = 'full' ;
2826
27+ protected numCols = 16 ;
28+ protected numRows = 2 ;
29+
2930 @property ( )
3031 get text ( ) {
3132 return Array . from ( this . characters )
@@ -60,7 +61,13 @@ export class LCD1602Element extends LitElement {
6061 ` ;
6162 }
6263
64+ protected get panelHeight ( ) {
65+ return this . rows * 5.75 ;
66+ }
67+
6368 get pinInfo ( ) : ElementPin [ ] {
69+ const { panelHeight } = this ;
70+ const y = 87.5 + panelHeight * mmToPix ;
6471 switch ( this . pins ) {
6572 case 'i2c' :
6673 return [
@@ -73,33 +80,42 @@ export class LCD1602Element extends LitElement {
7380 case 'full' :
7481 default :
7582 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 : [ ] } ,
9299 ] ;
93100 }
94101 }
95102
103+ get cols ( ) {
104+ return this . numCols ;
105+ }
106+
107+ get rows ( ) {
108+ return this . numRows ;
109+ }
110+
96111 path ( characters : Uint8Array | number [ ] ) {
97112 const xSpacing = 0.6 ;
98113 const ySpacing = 0.7 ;
99114 const result = [ ] ;
115+ const { cols } = this ;
100116 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 ;
103119
104120 for ( let py = 0 ; py < 8 ; py ++ ) {
105121 const row = this . font [ characters [ i ] * 8 + py ] ;
@@ -116,17 +132,18 @@ export class LCD1602Element extends LitElement {
116132 }
117133
118134 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 ) {
122139 return null ;
123140 }
124141
125142 const result = [ ] ;
126143
127- if ( this . blink ) {
144+ if ( blink ) {
128145 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 } ">
130147 < animate
131148 attributeName ="opacity "
132149 values ="0;0;0;0;1;1;0;0;0;0 "
@@ -138,11 +155,9 @@ export class LCD1602Element extends LitElement {
138155 ` ) ;
139156 }
140157
141- if ( this . cursor ) {
158+ if ( cursor ) {
142159 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 } " /> ` ) ;
146161 }
147162
148163 return result ;
@@ -159,45 +174,52 @@ export class LCD1602Element extends LitElement {
159174 ` ;
160175 }
161176
162- renderPins ( ) {
177+ renderPins ( panelHeight : number ) {
178+ const y = panelHeight + 21.1 ;
163179 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 >
183201 ` ;
184202 }
185203
186204 render ( ) {
187- const { color, characters, background } = this ;
205+ const { color, characters, background, pins , panelHeight , cols } = this ;
188206
189207 const darken = this . backlight ? 0 : 0.5 ;
190208 const actualBgColor =
191209 background in backgroundColors ? backgroundColors [ background ] : backgroundColors ;
192210
211+ const panelWidth = cols * 3.5125 ;
212+ const width = panelWidth + 23.8 ;
213+ const height = panelHeight + 24.5 ;
214+
193215 // Dimensions according to:
194216 // https://www.winstar.com.tw/products/character-lcd-display-module/16x2-lcd.html
195217 return html `
196218 < svg
197- width ="80mm "
198- height ="36mm "
219+ width ="${ width } mm "
220+ height ="${ height } mm "
199221 version ="1.1 "
200- viewBox ="0 0 80 36 "
222+ viewBox ="0 0 ${ width } ${ height } "
201223 style ="font-size: 1.5px; font-family: monospace "
202224 xmlns ="http://www.w3.org/2000/svg "
203225 >
@@ -220,13 +242,35 @@ export class LCD1602Element extends LitElement {
220242 < circle r ="0.45 " cx ="0.827 " cy ="0.9 " color ="black " />
221243 </ pattern >
222244 </ 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+ />
230274 < path d ="${ this . path ( characters ) } " transform ="translate(12.45, 12.55) " fill ="${ color } " />
231275 ${ this . renderCursor ( ) }
232276 </ svg >
0 commit comments