content/hp34970a_4.rst

changeset 66
70aad9a1272b
child 69
56bcb94f6ff5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/content/hp34970a_4.rst	Sat Sep 17 02:08:03 2016 +0200
@@ -0,0 +1,161 @@
+==========================================
+ HP 34970A Data Acquisition Unit - part 4
+==========================================
+
+:Author: David Douard
+:Category: Electronics
+:Tags: HP, 34970A, DMM, repair, test equipment
+:series: HP 34970A repair
+:series_index: 4
+
+
+After a summer pause, I'm back on my HP34970A replair project.  In
+`the previous post in this series <{filename}/hp34970a_3.rst>`_, I've
+started to reverse ingineer the serial protocol between the CPU board
+and the fonrt panel, and implement a prototype of replacement display.
+
+
+OLED display
+============
+
+I bought the bigest OLED display I could find (at a reasonable price)
+that would fit in the front panel assembly. It's a `blue 256x64 OLED
+display`_ drived by a SSD1322 controler.
+
+.. _`blue 256x64 OLED display`: http://www.buydisplay.com/default/oled-3-2-inch-displays-module-companies-with-driver-circuit-blue-on-black
+
+.. image:: {filename}/images/hp34970a/oled_module.jpg
+   :alt: 3"2 blue OLED module used as a replacement display for the HP34970A.
+
+My first problem was to drive the display from my Nucleo board. I
+couldn't find graphic library that worked directly. I was already
+using the UniGraphic_ library with the small TFT display, so I decided
+to implement support for this OLED module in the library.
+
+.. _UniGraphic: https://developer.mbed.org/teams/GraphicsDisplay/code/UniGraphic
+
+I spent quite some time to make this work for several reasons, among
+others:
+
+- I was first using my Nucleo F031K6 board; it's nice, it's small, but
+  it only have 4k of RAM, so the malloc I as doing in my test code to
+  allocate the "framebuffer" in which drawings are done before being
+  tranferred to the display module... well let's say if I took time to
+  check the return value of the malloc call (which one should always
+  do, even on small embedded devices), I would have not lost a couple
+  of hours, so to speak (tip: allocating 8k in a 4k RAM will not fit),
+
+- The SSD1322 controller is *reasonnably* well documented, but what's
+  not documented is how it is used on the OLED display... In fact,
+  once I could at least see some pixels on my display, I spent quite
+  some time trying to control where my pixels are located on the
+  module. There is not that much demo material available for this
+  module besides a `poorly written sample C code`_ (in a .txt file!)
+  for the 80C51 processor. What's hidden in this file (which I could
+  not fing any where else) is the magic 0x1C value which must be given
+  as first argument to the SET_COLUMN_ADDR "function" of the SSD1322.
+
+- I also lost some time trying to implement the support for this module
+  as a class derived from UniGraphic's `LCD class`_ (like several
+  other supported modules like the SSD1306_), but that was a mistake,
+  since this kind of OLED module is too different from both a TFT
+  display or a monochrome LCD display. So I've reimplemented the class
+  as a derived class of the GraphicDisplay_. This work is far for being
+  finished yet (and ready for a *Pull Request* to submit to the
+  UniGrahic project), but at least, I can continue my work on the
+  HP34970's display.
+
+
+.. _`LCD class`: https://developer.mbed.org/teams/GraphicsDisplay/code/UniGraphic/file/tip/Display/LCD.h
+.. _SSD1306: https://developer.mbed.org/teams/GraphicsDisplay/code/UniGraphic/file/tip/Inits/SSD1306.h
+.. _GraphicDisplay: https://developer.mbed.org/teams/GraphicsDisplay/code/UniGraphic/file/tip/Graphics/GraphicsDisplay.h 
+.. _`poorly written sample C code`: http://www.buydisplay.com/download/democode/ER-OLEDM032-1_DemoCode.txt
+
+
+Improving the serial sniffer
+============================
+
+Once I could draw pixels on my OLED module, I put this code in my
+existing prototype replacing the simple display code I used with the
+TFT module.
+
+And one problem I already had with the previous "working" prototype
+became bigger: I was missing many characters on the serial bus between
+the CPU and the front panel.
+
+My first implementation of the protocol sniffing was very tedious and
+poorly written. It was not reading at all the traffic on the Tx line
+(ie the key strokes), so I was never sure if a 0x66 was the beginning
+of a transmission or some payload for which I missed the beginning.
+
+Using the interrupt-based (asynchronous) BufferedSerial_
+implementation did not help that much.
+
+So I rewrote this part of the using 2 serial ports, using only the Rx
+line on both of them, one plugged on the Rx line of the serial
+communication, and the other on the Tx line of this comm. Doing so I
+can sniff the whole communication between the CPU and the display
+panel and make a way better protocol interpreter.
+
+The result was way better than before, and now I was able to detect
+the protocol interpretation errors, but still, I was missing many
+parts of the transmission.
+
+I ended up to figure that the culprit was my
+``SSD1322::copy_to_lcd()`` method: it takes almost 20ms to transmit
+the whole display content the module. And with the way my code was
+written, even with interrupt driven serial handlers, these interrupt
+were not captured during the execution of this copy routine.
+
+At this point, I've started to read a bit more the asynchronous and
+event driven APIs of the mbed platform, but could not clearly see a
+pattern to prevent this long "frozen" periods during which I was
+unable to capture serial communications.
+
+.. _BufferedSerial: https://developer.mbed.org/users/sam_grove/code/BufferedSerial/
+
+I was almost ready to use 2 microcontrollers for the job: one to sniff
+and interpret the serial communication and one to drive the display.
+
+.. image:: {filename}/images/hp34970a/poc_oled.jpg
+   :alt: Improvment of the POC based on the Nucleo F446RE and using a blue OLED module.
+
+Improving the tasks
+===================
+
+But I've discovered a few days ago that the RTOS project is now part
+of the mbed platform, allowing to use threads instead of pure event
+driven code. So I tried to put the copy_to_lcd routine executions in a
+dedicated thread, and bingo, I've got now something that begins to
+work enough to make it usable:
+
+.. dailymotion:: x4tib5s
+   :width: 270
+   :height: 480
+
+
+What's next
+===========
+
+There is still a lot of work to do:
+
+- improve the display reactivity: I'll probably try to implement
+  partial copy of the display instead of sending the whole
+  "framebuffer" each time something is changed on the display (the
+  SSD1322 allows to specify a "window" in which to send data),
+
+- improve overall display organisation and find the missing flags (I
+  still have not found the flag values for OC, MIN, MAX, AVG, ONCE,
+  AUTO and MEM),
+
+- try to install the display module and the Nucleo board in the front
+  panel assembly (I don't want to go for a specifically designed PCB,
+  at least for now),
+
+- publish the code.
+
+
+
+
+
+

mercurial