Dali D8X3N Thermal Camera: Difference between revisions
Gamerpaddy (talk | contribs) added secret menu tree |
Gamerpaddy (talk | contribs) m edit command typos |
||
| (20 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
=Dali D8X3N Thermal Camera Reverse Engineering= | |||
<br /> | <br /> | ||
| Line 48: | Line 48: | ||
<br /> | <br /> | ||
==D8X3N Module closer look== | |||
From now on, i will refer to the Thermal Imaging Module as TIM | From now on, i will refer to the Thermal Imaging Module as TIM | ||
| Line 84: | Line 84: | ||
==Viewing the Video Stream== | |||
[[File:Onvif Device Manager ODM.png|thumb|ODM streaming the Thermal view]] | [[File:Onvif Device Manager ODM.png|thumb|ODM streaming the Thermal view]] | ||
when first connecting it to power and Ethernet, the camera will have 192.168.1.102 as a Static ip. | when first connecting it to power and Ethernet, the camera will have 192.168.1.102 as a Static ip. | ||
| Line 140: | Line 140: | ||
==Viewing Raw Thermal Data from the Web API== | |||
there is a hidden endpoint in the stream.so file that could be found while decompiling | there is a hidden endpoint in the stream.so file that could be found while decompiling | ||
| Line 150: | Line 150: | ||
we are mainly interessted in Raw thermal data. | we are mainly interessted in Raw thermal data. | ||
==== | ====Source (Stream Type)==== | ||
*<code>Major</code> - Main video stream (channel 0) | *<code>Major</code> - Main video stream (channel 0) | ||
| Line 160: | Line 160: | ||
*<code>YUV</code> - YUV raw video stream | *<code>YUV</code> - YUV raw video stream | ||
==== | ====Type (Data Format)==== | ||
*<code>H264</code> - H.264 video encoding | *<code>H264</code> - H.264 video encoding | ||
| Line 168: | Line 168: | ||
*<code>FRAME</code> - Frame-based format | *<code>FRAME</code> - Frame-based format | ||
==== | ====Mode (Transport Protocol)==== | ||
*<code>TCP</code> - TCP streaming (default) | *<code>TCP</code> - TCP streaming (default) | ||
| Line 174: | Line 174: | ||
*<code>MUL</code> - Multicast streaming | *<code>MUL</code> - Multicast streaming | ||
==== | ====Quality Parameters==== | ||
*<code>Quality=[1-100]</code> - Video quality level | *<code>Quality=[1-100]</code> - Video quality level | ||
| Line 180: | Line 180: | ||
*<code>Interval=[ms]</code> - Frame interval in milliseconds | *<code>Interval=[ms]</code> - Frame interval in milliseconds | ||
==== | ====Network Parameters==== | ||
*<code>IPAddr=[ip]</code> - Client IP address for UDP/multicast | *<code>IPAddr=[ip]</code> - Client IP address for UDP/multicast | ||
| Line 186: | Line 186: | ||
*<code>Heart-beat=[Yes/No]</code> - Enable/disable heartbeat | *<code>Heart-beat=[Yes/No]</code> - Enable/disable heartbeat | ||
==== | ====Snapshot Parameters==== | ||
*[[File:Dali D8X3N Raw Thermal viewer.png|thumb|Raw Data Viewer in python]] | *<code>Snap=[Yes/No]</code> - Enable snapshot mode | ||
<br /> | |||
====Raw Viewer for PC (Python)==== | |||
[[File:Dali D8X3N Raw Thermal viewer.png|thumb|Raw Data Viewer in python]] | |||
| Line 195: | Line 201: | ||
it is low fps tho, due to bad optimizations. | it is low fps tho, due to bad optimizations. | ||
https://pastebin.com/dyNWDPT3 | rev1 first working version https://pastebin.com/dyNWDPT3 | ||
rev2 with temperature readout https://pastebin.com/u107Q85w | |||
rev3 first web only edition running in javascript on the device. | |||
rev4..5: added CLAHE contrast enhancement, noise reduction, peformance improvement, see blow. | |||
====Raw Viewer for the internal Webserver (recommended)==== | |||
It is also possible to use the Raw viewer directly in the browser. | |||
To achieve this, the stream had to be proxied from port 5000 to 80 due to CORS. | |||
luckily the internal lighttpd had the CGI module enabled, so piping it troug (using wget ... i know) worked with very low overhead. | |||
To install, you need '''Terminal access''' to the Camera. see below. | |||
optional for simplicity: '''ftp''' access | |||
[[File:Dali D8X3N Webviewer.png|thumb|Web Raw Viewer with histogram (rev3)]] | |||
Create the files and the code inside. | |||
'''/app/web/webpages/raw.html''' https://pastebin.com/LM3Gmeez | |||
'''/app/web/webpages/raw.js''' https://pastebin.com/n9wAVW63 | |||
and | |||
'''/app/web/webpages/cgi-bin/proxy.cgi''' https://pastebin.com/vii1HXcU | |||
then run | |||
chmod +x /app/web/webpages/cgi-bin/proxy.cgi | |||
'''restart''' your camera. | |||
It should be accessible now trough '''http://<camera ip>/raw.html''' in the browser and click Start Stream | |||
'''NOTE''': ''<u>If it does not work</u>'', check the contents of both files. FTP sometimes messes them up. | |||
also run | |||
dos2unix /app/web/webpages/cgi-bin/proxy.cgi | |||
because linux <> windows difficulties that couldnt be resolved in over 30 years. | |||
<blockquote> | |||
performance may need improvement.</blockquote> | |||
==Getting Root Terminal Access== | |||
To access the Terminal you need to solder or plug in a UART connection to Connector J7 on the "Glue" board. | To access the Terminal you need to solder or plug in a UART connection to Connector J7 on the "Glue" board. | ||
| Line 212: | Line 266: | ||
<br /> | <br /> | ||
=== | ====Enabling Telnet access to make patching easier==== | ||
[[File:Upgrade ici dali firmware updater.png|thumb|ICI Firmware updater software with modified firmware loaded]] | [[File:Upgrade ici dali firmware updater.png|thumb|ICI Firmware updater software with modified firmware loaded]] | ||
| Line 223: | Line 277: | ||
The Login credentials are '''User: roo'''t '''Password: DLroot''' | The Login credentials are '''User: roo'''t '''Password: DLroot''' | ||
<br /> | |||
===Patching Device=== | |||
===Patching the Web Server=== | ===Patching the Web Server=== | ||
<br /> | |||
====Enabling Telnet and ftpd permanently==== | |||
This only works if you also patch the Thermal Camera module flash! | This only works if you also patch the Thermal Camera module flash! | ||
to permanently enable Telnet, go to '''/etc/init.d''' and edit '''S90app''' | |||
vi S90app | vi S90app | ||
in vi, move your cursor to the '''#''' at '''#telnetd''' and press x<blockquote>optional: enable ftp by removing the '''#''' at '''ftpd''' and adjust the path to / </blockquote>now press ''':''' and type '''wq''' and hit '''enter'''. this should be it. | in vi, move your cursor to the '''#''' at '''#telnetd''' and press x<blockquote>optional: enable ftp by removing the '''#''' at '''ftpd''' and adjust the path to / </blockquote>now press ''':''' and type '''wq''' and hit '''enter'''. this should be it. | ||
==== | ====Patching the decoder and streamer to 640x480:==== | ||
go to /app and edit the mach.cfg | go to /app and edit the mach.cfg | ||
| Line 245: | Line 309: | ||
repeat that procedure for the dali.cfg | repeat that procedure for the dali.cfg | ||
===== (optional) patching app.sh to prevent it from rebooting ===== | =====(optional) patching app.sh to prevent it from rebooting===== | ||
edit the app.sh in /app and remove all "reboot" occasions to prevent the camera from rebooting if onvifserver, httpd or daliServer arent running for debugging purposes. | edit the app.sh in /app and remove all "reboot" occasions to prevent the camera from rebooting if onvifserver, httpd or daliServer arent running for debugging purposes. | ||
===Patching the Thermal Camera module=== | |||
<br /> | |||
====Patching the Thermal Camera module==== | |||
To patch it, you need to disassemble everything down to the FPGA Board, | To patch it, you need to disassemble everything down to the FPGA Board, | ||
| Line 269: | Line 337: | ||
==Hardware Hacking== | |||
===Flash Contents=== | ===Flash Contents=== | ||
| Line 354: | Line 422: | ||
<br /> | <br /> | ||
====Bad Pixel and Flatframe Maps 0x280000 and 0x4C0000==== | |||
Thermal cameras require a bad pixel and flat frame map to compensate for manufacturing inconsistencies. | Thermal cameras require a bad pixel and flat frame map to compensate for manufacturing inconsistencies. | ||
| Line 364: | Line 432: | ||
The [https://2477569.playcode.io/ Viewer Page] is written in JS and does not require any special dependencies, it can run as a plain html file offline. | The [https://2477569.playcode.io/ Viewer Page] is written in JS and does not require any special dependencies, it can run as a plain html file offline. | ||
''See "Automatic Dead Pixels and Flatmap Correction" below how to create new dead pixel and flatmaps using the system menu.'' | |||
| Line 382: | Line 446: | ||
==Dali Commands== | |||
To control the TIM you can either use Pelco or Dali command set. By default the Dali commandset is used at 38400 BAUD. | To control the TIM you can either use Pelco or Dali command set. By default the Dali commandset is used at 38400 BAUD. | ||
| Line 408: | Line 472: | ||
By bruteforcing the UART with AAA to ZZZ a list of Commands could be obtained, but some with unknown Parameters or functionality yet. including some from a decompiled DM60comm.so module found in /app/modules folder.<syntaxhighlight lang="vb"> | By bruteforcing the UART with AAA to ZZZ a list of Commands could be obtained, but some with unknown Parameters or functionality yet. including some from a decompiled DM60comm.so module found in /app/modules folder.<syntaxhighlight lang="vb"> | ||
KBD KEY Keyboard (F S M C + -) | |||
KBD KEY Keyboard button (F, S, M, C, +, -) | |||
SSM 0-1 Image Filtering Off/On | SSM 0-1 Image Filtering Off/On | ||
GSM | GSM Image filter enabled? | ||
SEH 0-1 Image | |||
GEH | SEH 0-1 Image enhancement Off/On | ||
SCO 0-255 Set Gain | GEH Image enhancement enabled? | ||
GCO | |||
INT | SCO 0-255 Set Gain | ||
GCO Get Gain | |||
INT 10-320 Set Integration time | |||
GIT Get current integration time | |||
IBR 0-255 Set brightness | IBR 0-255 Set brightness | ||
GBR 0- | GBR Get Brightness | ||
SMR 0-3 Mirror | |||
GMR | SAG 0-2 Set auto gain mode | ||
GAG Get auto gain mode | |||
SMR 0-3 Mirror image (bit 0 horizontal, bit 1 vertical) | |||
GMR Get Rotation/flip | |||
SNU 0-1 Shutter close or open | |||
GNU Get shutter closed or open | |||
STD 0-1 Set Range 0: -20-180°C 1: 100-600°C | STD 0-1 Set Range 0: -20-180°C 1: 100-600°C | ||
GTD 0-1 Get Range | GTD 0-1 Get Range | ||
SET °C Set Ambient temperature | SET °C Set Ambient temperature | ||
GET °C Get Ambient temperature | GET °C Get Ambient temperature | ||
SEM 0-100 0-1 set emissivity x100 | SEM 0-100 0-1 set emissivity x100 | ||
GEM 0-100 Get Emissivity | GEM 0-100 Get Emissivity | ||
SRT °C Set revise temperature -100-100 -10-10° | SRT °C Set revise temperature -100-100 -10-10° | ||
GRT °C Get revise temperature | GRT °C Get revise temperature | ||
SRD 100 Set Distance 4.4m x100 | SRD 100 Set Distance 4.4m x100 | ||
GRD | GRD Get Distance | ||
SHD 0-100 Set Humidity | SHD 0-100 Set Humidity | ||
GHD | GHD Get Humidity | ||
SWP 0-1 invert | |||
GWP | SWP 0-1 invert polarity of image | ||
GWP Get polarity inverted | |||
SPA 0-10? Set color palette | SPA 0-10? Set color palette | ||
GPA | GPA 3 is white hot | ||
SMV 0-1 Show temperature 3x3 grid?? in combination with GTV maybe | SMV 0-1 Show temperature 3x3 grid?? in combination with GTV maybe | ||
GMV 0 | GMV 0 | ||
SMS 0-1 displays "collected 0/<number set by SCT>" by SCP delay "saves the daily number of highest temperatures?" | SMS 0-1 displays "collected 0/<number set by SCT>" by SCP delay "saves the daily number of highest temperatures?" | ||
GMS 0 | GMS 0 | ||
SCT 1-500 sets the amount of "collected" points for SMS | SCT 1-500 sets the amount of "collected" points for SMS | ||
GCT 80 | GCT 80 gets the amount of collected points ??? | ||
SCP 5-60 "collected" delay in seconds for SMS | SCP 5-60 "collected" delay in seconds for SMS | ||
GCP 60 | GCP 60 | ||
SLR 0-9 ??? | SLR 0-9 ??? | ||
GLR 0 | GLR 0 | ||
SRP 0 | |||
GRP 320,240 get crosshair position | SRP 0 to 639,479 set crosshair position | ||
GRP 320,240 get crosshair position | |||
SCX +-1 Set x axis range | |||
SCY +-1 Set y axis range | |||
DRC 0-1 Show crosshair | DRC 0-1 Show crosshair | ||
SLG -500-500 ?? | SLG -500-500 ?? | ||
GLG | GLG | ||
SCE text ?? | SCE text ?? | ||
GCE 0 | GCE 0 | ||
SCB text ?? | SCB text ?? | ||
GCB 0 | GCB 0 | ||
SVB 0-16383 | |||
GVB 6733 value is 16383 minus SVB | SVB 0-16383 Adjust brightness value can be +1 or -1 too instead of absolute | ||
SVC 1-1023 | GVB 6733 Get brightness value (is 16383 minus what SVB is set to) | ||
GVC | |||
SVF 100-? | |||
SVS 100-? | SVC 1-1023 Adjust contrast value, can be +1 or -1 too instead of absolute | ||
SOT 0-1 | GVC Get contrast value | ||
SZM 1-4 | |||
GZM | SVF 100-? Set VF voltage, 3400 was good for me. | ||
SVS 100-? Set VS voltage, 3300 was good for me. | |||
SOT 0-1 Set output image, 0 original, 1 calibrated. | |||
ALD 0,2? | |||
MSV Menu Save value | |||
SZM 1-4 Set zoom value | |||
GZM Get zoom value | |||
ASN <val> Set partition number | |||
ASV <val> Save area data of area <val>? | |||
ALD 0,2? Load area data of area <val>? blanks lots of eeprom activity. reload pixel map?? | |||
CBP B,X,Y Dead pixel calibration. example B,100,100. S,<val> to save to area | |||
C2P L,H,B,S Two point calibration. L low, H High, B two point, S, <val> save to area. | |||
GCS Get Core status & faults: | |||
0:Normal | |||
1:SDRAM storage failure | |||
2:Flash storage failure | |||
3:Video chip setup failure | |||
4:Software run failure; | |||
5:FPGA run failure; | |||
6:software run abnormal; | |||
7:detector fault; | |||
8:Power module fault | |||
9:unit cooler fault | |||
SAV 0-9999 set Fire threshold | SAV 0-9999 set Fire threshold | ||
GAV 2100 get Fire Threshold | GAV 2100 get Fire Threshold | ||
BAC | |||
BAC ? change uart protocol? careful | |||
CCM Communication Test | |||
GFV Get Clarity value | |||
QYA Get average grey level | |||
QYI Get min grey level | |||
QYM Get max grey level | |||
MED Turn on indication info | |||
MEH Turn off indication info | |||
GME Get active menu 0-7 | |||
PWI 0-1 changing palette from wh to fire | |||
CBD Displays Recovery successful? | CBD Displays Recovery successful? | ||
CBS Displays Saved successfully | CBS Displays Saved successfully | ||
| Line 484: | Line 621: | ||
LRE Displays Temperature Repair successful? | LRE Displays Temperature Repair successful? | ||
CBT Displays Calibration successful? | CBT Displays Calibration successful? | ||
DBP ??? shutter clicks | DBP ??? shutter clicks | ||
DPI Show weird pixels | DPI Show weird pixels | ||
API Hide weird pixels | API Hide weird pixels | ||
GAB 4 vals ?? 3,-10,50,150 | GAB 4 vals ?? 3,-10,50,150 | ||
GAN 1 ?? | GAN 1 ?? | ||
GAR 11 vals ?? 10,10,5,20,35,50,70,90,120,150,180,, | GAR 11 vals ?? 10,10,5,20,35,50,70,90,120,150,180,, | ||
GCM 6 values ?? | GCM 6 values ?? | ||
GTV Get the collected temp values? | GTV Get the collected temp values? | ||
PTS echoes but with extra stuff?? | PTS echoes but with extra stuff?? | ||
VTP 400-4000 Set iVtemp? | |||
VTP 400-4000 | |||
MTD U/S,0,0 ?? S answers with bytes, U upload bytes? | MTD U/S,0,0 ?? S answers with bytes, U upload bytes? | ||
MTC U/S? ?? | MTC U/S? ?? U answers MTC,U,0,0,I, S answers MTC,U,0,11,A000000.... | ||
SDT 0-1 displays temp=44.65°C in osd | |||
GPT Display temp of SDT | |||
GDT 0-1 Get temp display active? | |||
return 0 | |||
return 0 command failed / missing params: | |||
STS ?? | STS ?? | ||
STT ?? | STT ?? | ||
| Line 512: | Line 653: | ||
SAS ?? | SAS ?? | ||
SAT ?? | SAT ?? | ||
GAC ?? | GAC ?? | ||
GAH ?? | GAH ?? | ||
| Line 533: | Line 672: | ||
BPM 0-1 stream ready? answers with 0 stop, 1 go, 2 when prompted | BPM 0-1 stream ready? answers with 0 stop, 1 go, 2 when prompted | ||
AVS 0,1 | AVS 0,1 | ||
unconfirmed (from dm60comm.so): | unconfirmed and non working or wrong (from dm60comm.so): | ||
SDT 2024,03,15,14,30,25 Set Date Time with year,month,day,hour,minute,second | SDT 2024,03,15,14,30,25 Set Date Time with year,month,day,hour,minute,second | ||
STS 1 Set Temperature Show display (0=off, 1=on) | STS 1 Set Temperature Show display (0=off, 1=on) | ||
| Line 602: | Line 739: | ||
QYA | QYA | ||
QYM | QYM | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 610: | Line 745: | ||
==Secret Menu Overview== | |||
The secret menus Main and System can be openend with the password '''+-MC+-''' | The secret menus Main and System can be openend with the password '''+-MC+-''' | ||
| Line 756: | Line 891: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Automatic Dead Pixels and Flatmap Correction === | ===Automatic Dead Pixels and Flatmap Correction=== | ||
| Line 762: | Line 897: | ||
<br /> | <br /> | ||
===== Dead pixels: ===== | =====Dead pixels:===== | ||
In the secret menu "System", navigate to | In the secret menu "System", navigate to Area - DeadPixelModel and set the AutoBP (sensitivity for auto bad pixel finding) to 50 or so. Then press C Button | ||
This can take a while. | This can take a while. | ||
| Line 772: | Line 907: | ||
<br /> | <br /> | ||
===== Flatfield: ===== | =====Flatfield:===== | ||
In the Debug menu navigate to R2 and press + | In the Debug menu navigate to R2 and press + | ||
| Line 790: | Line 925: | ||
<br /> | <br /> | ||
==Using the Thermal module without Webserver== | |||
[[File: | [[File:Breakoutboard d8x3c dali v1.1.png|alt=|thumb|Breakout board for D8X3C]] | ||
to use it, you need to interface it directly. | to use it, you need to interface it directly. | ||
| Line 801: | Line 936: | ||
To interface, you need to | To interface, you need to have a adapter board with a DF12-50DS-0.5V(86) Docking socket. | ||
A open source project can be found here, it includes pin access to: | |||
*FPGA JTAG | |||
*UART 3.3V with pin compatible FT232 socket | |||
*Power 5V over USB-C | |||
*5 Button inputs | |||
*Buffered video output and socket for USB Videograbber | |||
*Digital 14 bit video out header with hsync vsync and clk. | |||
* | |||
the pcb layout has been tested and seems to work. | |||
<blockquote>Very basic fanout of pins to 2.54mm headers with a socket for a Video grabber and FT232 adapter and buttons. by gamerpaddy | |||
https://oshwlab.com/gamerpaddy/d8x3c-backpack-usb</blockquote><blockquote>Professional adapter with integrated Video grabber and USB/UART bridge built in including a FFC connector for pin fanout and buttons. by TOA-HI / Killy.THI | |||
https://github.com/TOA-HI/Dali-Tech-D8X3C-Thermal-Camera-Backpack</blockquote> | |||
==Sending Serial Commands directly over UART== | |||
Sending Serial commands directly over UART to the core requires some additional bytes. | |||
The packet structure is as follows (Strip spaces, commands are allways uppercase and 3 chars) | |||
<STX> <LENGTH1> <LENGTH2> Command, Value, Checksum <ETX> | |||
Pseudocode to craft a command packet may look like this<syntaxhighlight lang="c"> | |||
//cmd is allways 3 byte uppercase chars | |||
//values can be multiple comma seperated like 320,240 | |||
function make_packet(cmd, values): | |||
payload = cmd + "," + join(values, ",") + "," | |||
bytes = ascii(payload) | |||
length = len(bytes) | |||
checksum = sum(bytes) mod 256 | |||
return [0x02, length&0xFF, length>>8] + bytes + [checksum, 0x03] | |||
</syntaxhighlight> | |||
<br /> | <br /> | ||
==Sensor Pinout== | |||
[[File:Dali DLD384 Sensor pinout basic.png|thumb|basic pinout of a DLD384]] | [[File:Dali DLD384 Sensor pinout basic.png|thumb|basic pinout of a DLD384]] | ||
the pinout of the thermal sensor havent been | the pinout of the thermal sensor havent been analyzed much. | ||