My Projects

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

arduino:metp0000_driver_library [2019/01/16 09:54]
tony
arduino:metp0000_driver_library [2023/03/12 22:01] (current)
tony [METP0000 Library]
Line 33: Line 33:
  
 ===== Hardware description ===== ===== Hardware description =====
-The controller consists of a single NEC D7225GB ({{:​electronic:​datasheet:​nec:​upd7225.pdf|μPD7225}}) chip, with a Schmitt trigger inverter input buffer ({{http://​xgistor-echo.scorchingbay.nz/​files/​Electronics/​datasheets/​74HC14.pdf|74HC14}}),​ another ​ inverter ({{http://​www.ti.com/​lit/​ds/​symlink/​sn74hc05.pdf|74HC05}}) and an 8-bit parallel-in/​serial out shift register ({{http://​xgistor-echo.scorchingbay.nz/​files/​Electronics/​datasheets/​74HC165.pdf|74HC165}}). ​  The inverters mean that all the control signals to the μPD7225 are inverted, but this is easily accommodated in software. ​ The control lines are brought out on an 8 pin RJ45 style connector (as used for twisted pair Ethernet). ​ The signals are are "​Busy",​ "​Reset",​ "​SI"​ (serial input), "​SCLK"​ (serial clock), ​ "​CS"​ (chip select) and "​C/​D"​ (control/​data).+The controller consists of a single NEC D7225GB ({{:​electronic:​datasheet:​nec:​upd7225.pdf|μPD7225}}) chip, with a Schmitt trigger inverter input buffer ({{http://​xgistor-echo.scorchingbay.nz/​files/​Electronics/​datasheets/​74HC14.pdf|74HC14}}),​ another ​ inverter ({{http://​www.ti.com/​lit/​ds/​symlink/​sn74hc05.pdf|74HC05}}) and an 8-bit parallel-in/​serial-out shift register ({{http://​xgistor-echo.scorchingbay.nz/​files/​Electronics/​datasheets/​74HC165.pdf|74HC165}}). ​  The inverters mean that all the control signals to the μPD7225 are inverted, but this is easily accommodated in software. ​ The control lines are brought out on an 8 pin RJ45 style connector (as used for twisted-pair Ethernet). ​ The signals are are "​Busy",​ "​Reset",​ "​SI"​ (serial input), "​SCLK"​ (serial clock), ​ "​CS"​ (chip select) and "​C/​D"​ (control/​data).
 Initially I interfaced all the control lines, but realised that I didn't need to use the Reset or the C/D line.  Reset could be wired to do a reset at power on, and C/D could be tied low which would hold the chip in command receipt state continually. ​ The other two pins are +5V and Ground. Initially I interfaced all the control lines, but realised that I didn't need to use the Reset or the C/D line.  Reset could be wired to do a reset at power on, and C/D could be tied low which would hold the chip in command receipt state continually. ​ The other two pins are +5V and Ground.
  
Line 52: Line 52:
 It took me a while to realise that the inbuilt segment decoder on the μPD7225 chip wasn't really much use.  The 7-segment decoder couldn'​t drive all nine segments and an examination of the board revealed that the COM3 output wasn't connected so the 14-segment decoder wasn't being used either. ​ ((It is conceivable that the 14-segment decoder was used, but COM3 was ignored, I haven'​t checked out this possibility.))\\ It took me a while to realise that the inbuilt segment decoder on the μPD7225 chip wasn't really much use.  The 7-segment decoder couldn'​t drive all nine segments and an examination of the board revealed that the COM3 output wasn't connected so the 14-segment decoder wasn't being used either. ​ ((It is conceivable that the 14-segment decoder was used, but COM3 was ignored, I haven'​t checked out this possibility.))\\
 \\ \\
-So it appeared that the only way to address all the segments of each character was to use the command "​write-immediate-data",​ to write directly into the display memory - three writes of 3 bit words (n to n+2 on the segment layout diagram). ​ Hence my driver does not need to do any "​data"​ writes, everything is a "​command"​ write, the "​C/​D"​ control line is not needed.\\+So it appeared that the only way to address all the segments of each character was to use the command "​write-immediate-data",​ to write directly into the display memory - three writes of 3-bit words (n to n+2 on the segment layout diagram). ​ Hence my driver does not need to do any "​data"​ writes, everything is a "​command"​ write, the "​C/​D"​ control line is not needed.\\
 \\ \\
-Details of the module'​s controller configuration choices : R1 across the cl1/cl2 clock generation pins is 200kΩ - giving nominally an about 120kHz clock. ​ The resistor ladder wired across the Vlc1,2,3 pins is for 1/3 bias.  COM3 appears to be unconnected,​ which implies a divide by 3 time division type of LCD (using COM0,​1,​2). +Details of the module'​s controller configuration choices : R1 across the cl1/cl2 clock generation pins is 200kΩ - giving nominally an about 120kHz clock. ​ The resistor ladder wired across the Vlc1,2,3 pins is for 1/3 bias.  COM3 appears to be unconnected,​ which implies a divide by 3 time-division type of LCD (using COM0,​1,​2). 
-Testing was done with mode byte set to 0x48 (= 1/3 bias method, divide-by-3 time division drive , and a frequency division ratio of 1/2^7 (frame frequency=fCL /(2^7 × 3)).\\+Testing was done with mode byte set to 0x48 (= 1/3 bias method, divide-by-3 time-division drive , and a frequency division ratio of 1/2^7 (frame frequency=fCL /(2^7 × 3)).\\
 \\ \\
 \\ \\
Line 68: Line 68:
 There is no contrast adjustment on this module. There is no contrast adjustment on this module.
  
-===== METP0000 ​Library ​=====+===== METP0000 ​library ​=====
  
-As mentioned earlier the library is based on a standard Arduino ​ LiquidCrystal.cpp LCD library. ​  I wrote a version (v1.30) with a "​write()"​ function suitable for using with the standard <​print.h>​ routines. ​ This worked fine, but didn't allow for controlling the decimal point - it was unable to set the decimal point as part of a digit. ​ Instead it had to display a blank digit with a decimal point set in the corner. ​ Besides looking strange, that wasted a whole digit space just to display a decimal point, and we don't have a lot of digits to play with.+As mentioned earlier the library is based on a standard Arduino ​ LiquidCrystal.cpp LCD library. ​  I wrote a version (v1.30) with a "​write()"​ function suitable for use with the standard <​print.h>​ routines. ​ This worked fine, but didn't allow for controlling the decimal point - it was unable to set the decimal point as part of a digit. ​ Instead it had to display a blank digit with a decimal point set in the corner. ​ Besides looking strange, that wasted a whole digit space just to display a decimal point, and we don't have a lot of digits to play with.
  
 ==== Character Set ==== ==== Character Set ====
-Because driving the 9 segments necessitates bypassing the 7 segment decoder, we are free to create whatever character shapes we wish out of the available segments. ​ To simplify development I used a 16bit word to define each character - 3 nybbles containing 3bits each, plus a fourth nybble that I occasionally used to specify the digit position (as not all digit positions are exactly the same). ​ If I continue to develop this driver, I might truncate this to 8bits per digit, and handle the single bits for the decimal point or comma separately. ​ I initially hand crafted a table of 9 bit alpha-numeric character patterns based on other peoples 7-segment character fonts. ​ I then came across Jose Pino's XLS spreadsheet ((http://​www.josepino.com/​microcontroller/​7-segment-ascii)),​ which I modified for the 9 segments and odd coding required for this display. ​ In my version the results are shown as a 3 digit number suitable to use as the hex character definition in my driver.\\+Because driving the 9 segments necessitates bypassing the 7 segment decoder, we are free to create whatever character shapes we wish out of the available segments. ​ To simplify development I used a 16bit word to define each character - 3 nybbles containing 3bits each, plus a fourth nybble that I occasionally used to specify the digit position (as not all digit positions are exactly the same). ​ If I continue to develop this driver, I might truncate this to 8bits per digit, and handle the single bits for the decimal point or comma separately. ​ I initially hand crafted a table of 9-bit alpha-numeric character patterns based on other peoples 7-segment character fonts. ​ I then came across Jose Pino's XLS spreadsheet ((http://​www.josepino.com/​microcontroller/​7-segment-ascii)),​ which I modified for the 9 segments and odd coding required for this display. ​ In my version the results are shown as a 3 digit number suitable to use as the hex character definition in my driver.\\
 {{ :​arduino:​metp0000:​metp0000 character_set.png?​600 |7 Segment character set v1.1.}} {{ :​arduino:​metp0000:​metp0000 character_set.png?​600 |7 Segment character set v1.1.}}
 {{:​arduino:​metp0000:​metp0000_7seg_design.xls|7 Segment design spreadsheet in Excel format}}, for designing segment layout.\\ {{:​arduino:​metp0000:​metp0000_7seg_design.xls|7 Segment design spreadsheet in Excel format}}, for designing segment layout.\\
Line 132: Line 132:
 In normal operation the μPD7225 would be configured to use the segment decoder, so a display sequence would consist of asserting Chip select (CS),  asserting Command/​Data (CD) for a command, writing the positioning the data pointer (cursor) command, asserting C/D for data, writing digit codes to the LCD, and de-asserting CS.  The digit codes are 8bits, the MSB selecting between the 7 and 14 segment decoders, and then 4 or 7 bits are data for the decoder. ​ For the 7 segment decoder data values from 0 to 9 generate the symbols '​0'​ through '​9'​ on the display. ​ Internally the decoder just stores a sequence of bits into the display memory, corresponding to the segments to be displayed. ​ So after positioning the cursor 6 writes are needed to fill the 6 digit display. In normal operation the μPD7225 would be configured to use the segment decoder, so a display sequence would consist of asserting Chip select (CS),  asserting Command/​Data (CD) for a command, writing the positioning the data pointer (cursor) command, asserting C/D for data, writing digit codes to the LCD, and de-asserting CS.  The digit codes are 8bits, the MSB selecting between the 7 and 14 segment decoders, and then 4 or 7 bits are data for the decoder. ​ For the 7 segment decoder data values from 0 to 9 generate the symbols '​0'​ through '​9'​ on the display. ​ Internally the decoder just stores a sequence of bits into the display memory, corresponding to the segments to be displayed. ​ So after positioning the cursor 6 writes are needed to fill the 6 digit display.
  
-If the decoder is not used, you instead write bits corresponding to the desired segment patterns directly to the display memory. ​ And here the sequence is slightly different as the sets of 3 data bits specifying each segment are part of write-immediate-data-commands (or to look at it another way there are lots of commands, each one specifying a different part of the segment pattern). ​ A sequence of three commands defines the segments displayed at one digit location. ​ So after positioning the cursor 18 writes are need to fill the 6 digit display. ​ But all of these writes are '​commands',​ no '​data'​ writes are needed.+If the decoder is not used, you instead write bits corresponding to the desired segment patterns directly to the display memory. ​ And here the sequence is slightly different as the sets of 3 data bits specifying each segment are part of write-immediate-data-commands (or to look at it another way there are lots of commands, each one specifying a different part of the segment pattern). ​ A sequence of three commands defines the segments displayed at one digit location. ​ So after positioning the cursor 18 writes are needed ​to fill the 6 digit display. ​ But all of these writes are '​commands',​ no '​data'​ writes are needed.
  
 ==== Standard LiquidCrystal library functions implemented ==== ==== Standard LiquidCrystal library functions implemented ====
Line 197: Line 197:
  
 All the print() functions are re-inventions of the wheel necessitated by wanting to handle the decimal point segment as an extra character space. ​ That is, when a decimal point or full-stop (period) is printed by these routines, they turn on the appropriate decimal point segment instead of somehow using the whole digit position just for that character. ​ This allows us to print what would otherwise be 7 character strings like ''"​1.23456"'', ​ rather than ''"​1 .2345"''​. ​  This even extends to printing strings like ''"​8.8.8.8.8.8"''​. ​ But we can't print a leading ''"​."''​ or a trailing ''"​."''​ without having a blank digit at that first or last location - eg ''"​ .12345"''​ or ''"​12345. "''​ .   This is because there physically isn't a leading or trailing decimal point as part of the display segments.\\ All the print() functions are re-inventions of the wheel necessitated by wanting to handle the decimal point segment as an extra character space. ​ That is, when a decimal point or full-stop (period) is printed by these routines, they turn on the appropriate decimal point segment instead of somehow using the whole digit position just for that character. ​ This allows us to print what would otherwise be 7 character strings like ''"​1.23456"'', ​ rather than ''"​1 .2345"''​. ​  This even extends to printing strings like ''"​8.8.8.8.8.8"''​. ​ But we can't print a leading ''"​."''​ or a trailing ''"​."''​ without having a blank digit at that first or last location - eg ''"​ .12345"''​ or ''"​12345. "''​ .   This is because there physically isn't a leading or trailing decimal point as part of the display segments.\\
-We could conceivably extent this to the "​comma"​ segment, or accommodate ​Europeans ​languages that use a comma ''","''​ as a decimal signifier rather than ''"​."''​ .   The comma segment is really just a '​tail'​ below the decimal point, and it looks better to display the decimal point and comma tail segments to get a good looking comma. ​ But handling commas presents two problems. ​ First the comma segments are on the opposite side of each digit (see single digit image in the "​Hardware description"​ section), complicating the logic, especially if you want to display the decimal point simultaneously with the comma to form a more complete looking comma. ​ The second problem is that I use the comma as a small corner "​tick"​ in my alphanumeric characters to hint that this is an alternate use of the same symbol.+We could conceivably extent this to the "​comma"​ segment, or accommodate ​European ​languages that use a comma ''","''​ as a decimal signifier rather than ''"​."''​ .   The comma segment is really just a '​tail'​ below the decimal point, and it looks better to display the decimal point and comma tail segments to get a good looking comma. ​ But handling commas presents two problems. ​ Firstthe comma segments are on the opposite side of each digit (see single-digit image in the "​Hardware description"​ section), complicating the logic, especially if you want to display the decimal point simultaneously with the comma to form a more complete looking comma. ​ The second problem is that I use the comma as a small corner "​tick"​ in my alphanumeric characters to hint that this is an alternate use of the same symbol.
  
 I am still contemplating whether it is sensible to drive such a short display as though it is a normal character output device, it might be more useful to have output routines that update the whole display each time, rather than printing a partial line, and keeping track of the cursor. I am still contemplating whether it is sensible to drive such a short display as though it is a normal character output device, it might be more useful to have output routines that update the whole display each time, rather than printing a partial line, and keeping track of the cursor.
Line 239: Line 239:
      * [[https://​github.com/​adafruit/​Adafruit-RGB-LCD-Shield-Library/​blob/​master/​Adafruit_RGBLCDShield.cpp|Adafruit RGB LCD Shield-Library      * [[https://​github.com/​adafruit/​Adafruit-RGB-LCD-Shield-Library/​blob/​master/​Adafruit_RGBLCDShield.cpp|Adafruit RGB LCD Shield-Library
 ]]. ]].
 +    * [[:​arduino:​ks0073 driver library|KS0073 SPI LCD]], LCD display panel Arduino driver
     * [[:​arduino:​mx300 driver library|Canon MX300]], Canon MX300/310 printer LCD display panel Arduino driver.     * [[:​arduino:​mx300 driver library|Canon MX300]], Canon MX300/310 printer LCD display panel Arduino driver.
     * [[:​arduino:​uPD7228 driver library|NEC µPD7228]] and μPD16434 LCD display panels Arduino driver     * [[:​arduino:​uPD7228 driver library|NEC µPD7228]] and μPD16434 LCD display panels Arduino driver