Go Down

Topic: New fork of max7219 7-segment tube library for good reason (Read 2563 times) previous topic - next topic

HermannSW

I want to use an 8 digit 7-segment tube max7219 for displaying information and capturing with camera.
So it is important to know how fast the display update is done, and whether display is valid or in transition.

I found many max7219 libraries, and decided to start with Ozhan's DigitLedDisplay library:
https://github.com/ozhantr/DigitLedDisplay
It had a good set of functionality, and was really small despite that.

My fork of that repo made it usable under Linux Arduino IDE in addition to Windows, added support for negative number printing, added setDecimalPos() while keeping datatype to be printed as long, ...:
https://github.com/Hermann-SW/DigitLedDisplay


Most importantly I did some optimizations in loop orders that allow to "see" what is really going on.
New example Digit7SegmentMillis.ino just displays "millis() / divi", default divi=10 meaning displaying 1/100th of seconds. In order to know when display is valid, only necessary display updates are done by remembering last value printed. A "8." is displayed on the leftmost of the 8 positions. It gets cleared away as very first step in printing, and is redrawn [ld.write(7, B11111111)] after printing is complete. This allows to tell whether any frame of a video taken shows a valid value or a just flipping value.

I used Raspberry v1 camera (clone, 3$ incl. shipping from aliexpress.com) with raspiraw. While maximal framerate for that camera is 90fps for 640x480, I made it capture at much higher framerates last year. Today I did capture 640x64 frames at 665fps(!), which allowed to see what is needed of the tube 7-segment display.

This is 1st animation created from such a video, played at 1fps. It shows that the update of 8 positions in display does take less than 3/665=4.5ms:



Next I took 665fps video of new example showing 1/100th seconds with decimal point. At that framerate (video had 0 frameskips), an update happens every 6th or 7th frame:



With either 1 or 2 frames in transition, there remain definitely 4(5) frames with valid display for update after 6(7) frames.

What I find remarkable is the following:
Normally I have to provide very bright light to a scene in order to get any meaningful video, because the shutter time of 1.5ms per frame is really short. Here the tube 7-segment display seems to provide enough brightness with rest of the scene dark.
αβ, xy & L₁/L₂ positioning systems with two 28BYJ48 stepper motors:
https://forum.arduino.cc/index.php?topic=649769.0
stepper PT camera system:
https://forum.arduino.cc/index.php?topic=647703.0
https://stamm-wilbrandt.de/en/Raspberry_camera.html

HermannSW

Okay, this is the planned setup, the 7-segment tube max7219 display near 7-segment display of electronic micrometer. The electronic micrometer has a data out port, but with no documentation. So plan is to capture video, take the frames in post processing and do a simple OCR on them to determine pairs of tube and micrometer 7-segment values (tube values will be the stepper motor half-step position in 0..92,000 range for measured distances 0..11,291µm):



I remembered my biggest project in 1st half of this year, teaching the 3$ Raspberry v1 camera clone to do global (external) shutter capturing, see the repo for many cool global shutter videos and frames (typically captured with 5000lm flashes of 9µs length in dark scene):
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter#introduction


Today I tried to capture global shutter video, without the "external".
That did not really work, at least with "flash" auto-white-balance I used all the time in that repo.

This was the command I executed:
Code: [Select]
pi@raspberrypi4B:~/Raspberry_v1_camera_global_external_shutter/tools $ ./raspivid_ges -md 7 -w 640 -h 480 -p 22,50,640,480 -fps 90 --shutter 22 -awb flash -o tst.h264 -t 0

Yes, really only 22µs  shutter time -- you can verify that by the first frames in the animation where raspivid determines the right settings to use. Those frames are dark, and only a small vertical part of tube display digits gets captured in the 22µs. When raspivid changes parameters, the whole scene can be seen. For those frames the camera does capture light even after the 22µs shutter time.

So this kind of capturing is not helpful for the task planned, but I thought this animation is worth to be shown (from 90fps framerate video, played at 1fps):



I already know what to do next -- I have 0.3/1.0/2.0MP Arducam monochrome global shutter cameras that fit into the Raspberry Pi CSI-2 interface. Will see whether (real) global shutter frames will be more helpful for the OCR preparation video capture.
αβ, xy & L₁/L₂ positioning systems with two 28BYJ48 stepper motors:
https://forum.arduino.cc/index.php?topic=649769.0
stepper PT camera system:
https://forum.arduino.cc/index.php?topic=647703.0
https://stamm-wilbrandt.de/en/Raspberry_camera.html

HermannSW

It turned out not to be an easy task.
The problem was that what Arduino displayed and when Pi camera captured were decoupled.

There is a solution for this, Raspberry allows to signal hardware camera sync pulses:
https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter#hardware-camera-sync-pulses

So I made the Raspberry Pi signal the camera sync pulses to the Arduino.
The Arduino looks in loop and acts on frame end.
Then it waits for next frame start, prints millis(), does 1ms delay and finally clears all.
Clearing had to be done in reverse direction, so I commited change that allows to specify reverse order clearing:
https://github.com/Hermann-SW/DigitLedDisplay/commit/449da258e353439fa8c33577f62776fabd9025d6
Code: [Select]
#include "DigitLedDisplay.h"

DigitLedDisplay ld = DigitLedDisplay(5, 6, 7);

// Raspberry Pi camera hardware sync pulse
int sync=11;
bool reverse = true;

void setup() {
  pinMode(sync, INPUT);  
  ld.setBright(10);
  ld.setDigitLimit(8);
  ld.setDecimalPos(4);
}

void loop() {
  // wait for frame end
  if (digitalRead(sync)==0) {
    // wait for start of frame
    while (digitalRead(sync)==0) { }

    ld.printDigit(millis());
    delay(1);
    // short display
    ld.clear(1, reverse);
    // for global (external) shutter capturing
  }
}


I did global external shutter capturing with 90fps as yesterday.
Because the digits are visible for few milliseconds only, this time the captured video is much butter.
I had to make the room dark for this to work (that is normal, it is the "external" in "global external shutter").
This is the result, not perfect, will have to see whether it allows for simple handcrafted OCR of the digits.
The deltas in milliseconds are caused by 90.15fps video capturing (measured with logic analyzer):



P.S:
I added the sketch as new example to the repo, and the animation with short description to README.md:
https://github.com/Hermann-SW/DigitLedDisplay/blob/master/examples/Digit7SegmentMillisSync/Digit7SegmentMillisSync.ino
αβ, xy & L₁/L₂ positioning systems with two 28BYJ48 stepper motors:
https://forum.arduino.cc/index.php?topic=649769.0
stepper PT camera system:
https://forum.arduino.cc/index.php?topic=647703.0
https://stamm-wilbrandt.de/en/Raspberry_camera.html

Go Up