Dali D8X3N Thermal Camera: Difference between revisions

added secret menu tree
m edit command typos
 
(20 intermediate revisions by the same user not shown)
Line 1: Line 1:
==Dali D8X3N Thermal Camera Reverse Engineering==
=Dali D8X3N Thermal Camera Reverse Engineering=
<br />
<br />


Line 48: Line 48:
<br />
<br />


===D8X3N Module closer look===
==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===
==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===
==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)======
====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)======
====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)======
====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'''======
====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'''======
====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'''======
====Snapshot Parameters====


*[[File:Dali D8X3N Raw Thermal viewer.png|thumb|Raw Data Viewer in python]]<code>Snap=[Yes/No]</code> - Enable snapshot mode
*<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




===Getting Root Terminal 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 />


===(optional) Enabling Telnet access to make patching easier===
====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'''====
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.




<br />




====patching the decoder and streamer to 640x480:====
====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==


<br />


===Flash Contents===
===Flash Contents===
Line 354: Line 422:
<br />
<br />


======Bad Pixel and Flatframe Maps 0x280000 and 0x4C0000======
====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.''
 
There still needs to be work done to create own maps and flatfields but the cameras are still very capable and useable with fully cleared maps.
 
To clear the maps, just go to these offsets and fill with values around 0x3F or 0x0 for total length of  X Resolution x Y Resolution x 2 bytes (0x96000 for 640x480)




Line 382: Line 446:




===Dali Commands===
==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 0 Image filter status
GSM Image filter enabled?
SEH 0-1 Image Enhancement Off/On
 
GEH 0-1 Image enhancer status
SEH 0-1 Image enhancement Off/On
SCO 0-255 Set Gain (locked when SAG auto gain is on)
GEH Image enhancement enabled?
GCO 0-255 Get gain
 
INT 15-320 set actual gain? not just contrast sometimes disabled?
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-255 Get brightness
GBR Get Brightness
SMR 0-3 Mirror mode bit0=horizontal, bit1=vertical
 
GMR 0 Get rotation/flip
SAG 0-2 Set auto gain mode
SDT 0-1 displays temp=44.65°C osd, but webserver sends date/time to the cam there....
GAG Get auto gain mode
GDT 0-1 Get temp display active?
 
GPT Display temp oft SDT
SMR 0-3 Mirror image (bit 0 horizontal, bit 1 vertical)
GNU 0-1 Get Shutter closed/open
GMR Get Rotation/flip
SNU 0-1 Shutter close / open
 
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 100 Get Distance
GRD Get Distance
 
SHD 0-100 Set Humidity
SHD 0-100 Set Humidity
GHD 55 Get Humidity
GHD Get Humidity
SWP 0-1 invert s/w polarity image
 
GWP 1 is inverted?
SWP 0-1 invert polarity of image
GWP Get polarity inverted
 
SPA 0-10? Set color palette
SPA 0-10? Set color palette
GPA 3 white hot
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
SAG 0-2 Auto brightness / gain
 
GAG 0
SLR 0-9 ???
SLR 0-9 ???
GLR 0
GLR 0
SRP 0,0 - 639,479 set crosshair position
 
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 adc offset, exposure? good at 9650
 
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 set contrast but better
GVB 6733 Get brightness value (is 16383 minus what SVB is set to)
GVC 260
 
SVF 100-? ?? video freaks out 3400 seems good
 
SVS 100-? ?? video freaks out 3300 seems good
SVC 1-1023 Adjust contrast value, can be +1 or -1 too instead of absolute
SOT 0-1 ?? sensor supply, looks weird when off.
GVC Get contrast value
SZM 1-4 ?
 
GZM 1
SVF 100-? Set VF voltage, 3400 was good for me.
MSV save settings too eeprom
SVS 100-? Set VS voltage, 3300 was good for me.
ASV Saves something aswell?
 
GCS 0 Get Core status & faults
SOT 0-1 Set output image, 0 original, 1 calibrated.
ALD 0,2? video blanks lots of eeprom activity. reload pixel map??
 
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 change uart protocol? careful
 
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
CCM ??
 
ASN 0-4 ??
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 ??
GFV prints screen gray value?
 
GIT 200 ??
 
GTV Get the collected temp values?
GTV Get the collected temp values?
PTS echoes but with extra stuff??
PTS echoes but with extra stuff??
QYA 7170 Query Gray Info (information mode)
 
QYI 7124 Query Gray Average mode
VTP 400-4000 Set iVtemp?  
QYM 7512 Query Gray Minimum mode
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? ?? S answers with U,0,0, S doesnt.
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 invalid params:
 
return 0 command failed / missing params:
STS ??
STS ??
STT ??
STT ??
Line 512: Line 653:
SAS ??
SAS ??
SAT ??
SAT ??
SCX ?? displays crosshair but invalid params
SCY ?? displays crosshair but invalid params
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
MEH
PWI 0-1 changing palette from wh to fire




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 ===
==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 Debug - DeadPixelModel and set the AutoBP (sensitivity for auto bad pixel finding) to 50 or so. Then press C Button  
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===
==Using the Thermal module without Webserver==
[[File:Dali D8X3C Breakout board.png|thumb|Breakout board for D8X3C ]]
[[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 make a adapter board with a DF12-50DS-0.5V(86) Docking socket.
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.


The breakout board files can be found [https://oshwlab.com/gamerpaddy/d8x3c-backpack-usb here] but may be still work in progress.
<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===
==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 analyzes much.
the pinout of the thermal sensor havent been analyzed much.