2014年5月20日 星期二

powerbuilder匯入(讀取)檔案時的注意技巧

先看看下面一段程式碼:

ls_path = "C:\inetpub\ftproot\upload\custOrder.txt"
do while FileExists(ls_path)
   yield()
loop
dw_1.importFile(text!,ls_path)
// next , processing dw1 row data
FileDelete(ls_path)

這是一個讓客戶用FTP上傳檔案後,並讀取檔案內容,處理後便把檔案刪除的作業,邏輯上是合理的,絕大多數的情況下也是沒有問題的。

但是偶爾發生了客戶資料沒有處理的問題,客戶也說明明就上傳成功了,FTP傳輸日誌有出現傳輸成功的指令,但,為什麼卻沒有處理到資料?

這段程式碼持續使用迴圈檢查檔案是否生成,只要檔案出現就進行讀取。

這看起來沒有錯,但是卻常常發生檔案讀出空白或是不完整的情況。

為什麼會這樣?
最大問題出在『時間差』,也就是檔案名稱產生的時間和檔案內容產生的時間有時間差異存在。檔案越大這個問題越明顯!

因為檔案系統會先生成檔案名稱並賦予記憶體指標(檔案內容緩衝區),當檔案指標被應用程式Close時,OS才會把檔案內容緩衝區的內容,寫到磁碟機上。



這個動作是作業系統為了加快檔案處理的速度而設計,緩衝區大小預設為磁碟sector大小,也就是說你的磁碟如果 sector 是 512K ,預設緩衝區就是 512K,若是sector 為 4096K,緩衝區就是 4096K。然而這個緩衝區可以依照應用程式去要求作業系統調整的,基本的原則是sector的倍數。
相關參考:微軟檔案緩存資料緩存定義

因此,要如何判斷得知檔案是否已經寫入完成,並且可以讀取呢?

目前我測試有兩種方法可以使用:
一、檔案大小法:如果運作的磁碟機 Sector 是 512K,而你非常肯定你的檔案大小絕對不會超過512K,那很好,除了取得檔案名稱外另外加判斷檔案大小,只要取得的檔案大小超過0,就代表檔案已經從緩衝區 Flush或Close 了,這樣就可以讀取了。

ls_path = "C:\inetpub\ftproot\upload\custOrder.txt"
do while FileExists(ls_path)
   yield()
loop

if FileLength(ls_path) > 0 tehn
   dw_1.importFile(text!,ls_path)
   // next , processing dw1 row data
   FileDelete(ls_path)
else
  //go next perpare reading loop cycle
end if

二、檔案鎖定法:利用獨佔式開啟檔案方式,確認該檔案是否已經被FTP釋放(Close)掉。

ls_path = "C:\inetpub\ftproot\upload\custOrder.txt"
do while FileExists(ls_path)
   yield()
loop

/*利用R/W lock來開啟檔案,開啟成功就代表檔案已經釋放,開啟失敗,代表檔案還被FTP使用中*/
li_file = FileOpen(ls_path,StreamMode,Read!,LockReadWrite!)
if li_file > 0 tehn
   // 這裡使用pb10版本提供的ReadEx比較方便,若是舊版,請記得使用迴圈讀取檔案全部內容
   ll_byte = FileReadEx(li_file,ls_data)
   FileClose(li_file)
   // 改用ImportString
   dw_1.importString(text!,ls_data)
   // next , processing dw1 row data
   FileDelete(ls_path)
else
  //go next perpare reading loop cycle
end if

請注意,範例裡的測試檔案存在的迴圈沒有停止機制,如果您要實作,記得要加上停止機制以免當檔案一直不出現就會出現的無限迴圈


2014年5月19日 星期一

Coldfusion直接讀取/產生Excel檔案 (使用POI元件)

最近在 Ben Nadel 先生的網站發現他有個Component計畫,他利用 apache.org 的 poi project 來製作一個可以讀寫 EXCEL 檔案的 Component,操作 EXCEL 檔真的蠻方便的。而且 poi project 以處理 office文件為目標,算是很棒的專案。

正在想如何直接透過 Coldfusion 網頁處理客戶的 Excel 檔案時,這真是一大幫助啊!

請先參考相關連結:

apache.org 的 poi 計畫 apache poi jar下載

Ben Nadel 的 POIUtility 文章出處Ben Nadel 的 POIUtility 專案

我的環境
本人使用 Railo 3.3.4.003 執行 Coldfusion ,所以核心是 Apache 比較沒有問題,至於Adobe的Coldfusion可能要再研究一下 Ben Nadel 的專案了。

1、下載  JAR 檔案
注意下載的 poi jar 版本,由於我使用的 Railo 3.3.4.003版本無法搭配最新的 poi,所以測試到使用 poi-3.0-FINAL.jar 是沒有問題的,太新的反而不能用。

把下載的 jar 放在 Railo Server 路徑下的 \lib\ext 裡面,重新啟動服務即完成掛載。

2、下載 Ben Nedal 的 POIUtility.cfc

假設網頁運行路徑在 \webroot\
你可接放在 \webroot\
而我的測試是放在 \webroot\COM 裡面 (我個人習慣Component都是放在COM路徑下)

3-1、測試一:讀取全部
首先,建立一個 Excel 檔案 "測試活頁簿.xls",裡面有3個Sheet




3-1.1、寫一段讀取用的 script:
<!--- 建立並初始化POI物件 --->
<cfset POIobj = CreateObject("component","COM.POIUtility").Init() >

<!--- 取得我要測試的Excel檔案路徑. --->
<cfset myFile = ExpandPath( "./測試活頁簿.xls" ) >

<!--- 測試一:透過POI物件讀取Excel檔案,並指定此excel檔案有標題列(第一行) --->
<cfset myExcel = POIobj.ReadExcel(FilePath = myFile,HasHeaderRow = true) >

<!--- 傾印出內容 --->
<cfdump var="#myExcel#">

3-1.2、顯示結果:




3-2、測試二:單獨讀取檔案中第二個Sheet資料
利用3-1的EXCEL檔案

3-2.1、寫一段讀取用的 script:
<!--- 建立並初始化POI物件 --->
<cfset POIobj = CreateObject("component","COM.POIUtility").Init() >

<!--- 取得我要測試的Excel檔案路徑. --->
<cfset myFile = ExpandPath( "./測試活頁簿.xls" ) >

<!---測試二:透過POI物件讀取Excel檔案,指定此excel檔案有標題列,並指定讀取第二Sheet表
(SheetIndex索引從0開始) --->
<cfset mySheet = POIobj.ReadExcel(FilePath = myFile,HasHeaderRow = true,SheetIndex = 1) >

<!--- 傾印出內容 --->
<cfdump var="#mySheet#">

3-2.2、顯示結果:



4、寫入測試:把3-1讀取出的檔案寫到另一個檔案去
<!--- 建立並初始化POI物件 --->
<cfset POIobj = CreateObject("component","COM.POIUtility").Init() >

<!--- 取得我要測試的Excel檔案路徑. --->
<cfset myFile = ExpandPath( "./測試活頁簿.xls" ) >

<!--- 測試一:透過POI物件讀取Excel檔案,並指定此excel檔案有標題列(第一行) --->
<cfset myExcel = POIobj.ReadExcel(FilePath = myFile,HasHeaderRow = true) >

<!--- 建立一個儲存用的陣列 --->
<cfset mySheets = ArrayNew( 1 ) >

<!--- 利用POI元件建立Sheet結構,再將讀取的Excel檔案,逐個Sheet填入,
並且重新變更Sheet名稱,與欄位名稱,
這裡要注意的是,Query陣列起始是1不是0(呼叫底層Java元件才要用0)--->
<cfset mySheets[ 1 ] = POIobj.GetNewSheetStruct() >
<cfset mySheets[ 1 ].Query = myExcel[ 1 ].Query >
<cfset mySheets[ 1 ].SheetName = "材料" >
<cfset mySheets[ 1 ].ColumnList = "column1,column2,column3" >
<cfset mySheets[ 1 ].ColumnNames = "料別,菜式,費用" >

<!--- 設定第二Sheet --->
<cfset mySheets[ 2 ] = POIobj.GetNewSheetStruct() >
<cfset mySheets[ 2 ].Query = myExcel[ 2 ].Query >
<cfset mySheets[ 2 ].SheetName = "廚師團" >
<cfset mySheets[ 2 ].ColumnList = "column1,column2,column3,column4" >
<cfset mySheets[ 2 ].ColumnNames = "name,gender,job,payments" >

<!--- 設定第三Sheet --->
<cfset mySheets[ 3 ] = POIobj.GetNewSheetStruct() >
<cfset mySheets[ 3 ].Query = myExcel[ 3 ].Query >
<cfset mySheets[ 3 ].SheetName = "月收入" >
<cfset mySheets[ 3 ].ColumnList = "column1,column2,column3,column4" >
<cfset mySheets[ 3 ].ColumnNames = "month,desk,套餐,營收" >

<!--- 把新作陣列(POI結構化)存到新的Excel檔案去 --->
<cfset POIobj.WriteExcel(FilePath = ExpandPath("./新活頁簿.xls"),Sheets = mySheets) >

4.1、輸出檔案結果:





整個測試結果都很正常,表示這些元件都可用,這下終於可以好好處理客戶的 EXCEL 了。


2014年5月13日 星期二

Coldfusion 對 query 語句生成

一般的 query 查詢方式

<cfquery name="QryName" DataSource="ConnecttionName">
SELECT field-A,field-B
FROM TableName
WHERE strfield = '#sdata#'
AND numfield = #ndata#
AND dtmfield = #parseDatetime(dtdata)#
</cfquery>

上面是純粹帶『查詢資料』進去 Query 語句時所使用的方式,SQL語句屬於固定類的,
但若你把它改成動態語句:

<cfset qs = "strfield = '#sdata#' AND numfield = #ndata# AND dtmfield = #parseDatetime(dtdata)#">
<cfquery name="QryName" DataSource="ConnecttionName">
SELECT field-A,field-B
FROM TableName
WHERE #qs#
</cfquery>

這個語句絕對會失敗的,
因為 Coldfusion 為了防止 SQL injection 所以會對 生成 SQL語句的變數裡 ' single-quotation 產生escape 字元,導致生成了不是你想像中的語句。

正確的作法,如果你希望使用動態語句生成,那就是加個指令要求ColdFusion不要去處理 single-quotation 問題即可解決:

<cfset qs = "strfield = '#sdata#' AND numfield = #ndata# AND dtmfield = #parseDatetime(dtdata)#">
<cfquery name="QryName" DataSource="ConnecttionName">
SELECT field-A,field-B
FROM TableName
WHERE #PreserveSingleQuotes(qs)#
</cfquery>

2014年5月12日 星期一

Coldfusion 來自不同資料庫的join作法

Coldfusion server 提供了許多資料庫的Native Connection方式,或是Jconnect的方式,在我認為效率總是比ODBC好多了,所以我寫的網頁常常遊走在不同資料庫上,我最常用的資料庫不外乎Sybase ASE 與 MS SQL (或是更早的MSDE)這兩種資料庫,所以需要用到兩種BD來源的Table需要Join的問題:

這技術需要用到 inMemory Query 的作法就可以達成

首先從各資料庫先取出需要 join 的資料(可以盡量使用篩選過的,減少記憶體用量)

<cfquery name="emp" datasource="SYB_CONN">
SELECT empl_no,empl_name,title_no
FROM rmployee WHERE depart_no = 'sales'
</cfquery>
<cftransaction action="commit" />

<cfquery name="ttl" datasource="MSSQL_CONN">
SELECT title_no,title_name
FROM outsider_title WHERE title_kind = 'S'
</cfquery>
<cftransaction action="commit" />

Join 兩邊的資料源

<cfquery name="emptlo" dbtype="query">
SELECT a.empl_name,b.title_name
FROM emp a, ttl b
WHERE a.title_no = b.title_no
</cfquery>

輸出測試

<cfloop query="emptlo">
<cfoutput>#empl_name# , #title_name# <br /></cfoutput>
</cfloop>

簡單吧!

2014年5月9日 星期五

jQuery設定/變更select物件預設值的方法

寫網頁服務最討厭的一件事就是:各種瀏覽器的DOM生成方式不同,導致認為可以的反應卻沒預期發生...

就說 HTML 裡面的 select 這個物件吧

<select id="SelectID">
  <option value="A" selected="selected">單位A</option>
  <option value="B">單位B</option>
  <option value="C">單位C</option>
</select>

當我想要設定 select 預設值時,可以用下面幾種方式:

$('#SelectID')[0].selectedIndex = 1; //選取第二個欄位 單位B (索引從0開始)
$('#SelectID').get(0).selectedIndex = 1; //效果同上
$('#SelectID').val(selectedValue); //selectedValue是變數,裡面是select option其中一個的value值
$('#SelectID').val('B') //選擇第二欄位,效果同上
$('#SelectID option').filter('[value="'+selectedValue+'"]').attr("selected",true); //filter選項後設定屬性
想要取得其選擇值時可以用:

var dataValue = $('#SelectID').val();  //取得被選項目的value
var dataValue = $('#SelectID').find('option:selected').val(); //效果同上,問題比較少
var dataText = $('#SelectID').find('option:selected').html(); //取得被選項目的文字描述部分

常常遇到某些版本瀏覽器沒有反應,所以就選擇其中有效的試試看吧

2014年5月8日 星期四

用VBscript定時刪除暫存檔案

有很多時候系統因為查詢的關係會產生很多暫存檔案,然而若是系統本身沒有暫存檔管理功能的話,漸漸的暫存檔就會消耗硬碟空間,嚴重的話會導致作業系統空間不足而將服務給停止,因此定期刪除這些暫存檔案的技巧是管理的基本常識
所以寫一隻可以幫忙有條件清除的程序是很重要的。

檔案:Time2Delete.vbs
內容:
' 指定所有變數必須事先宣告才能使用
Option Explicit

'WScript.Echo("作業開始執行:" & Date & " " & Time)

' 宣告變數
Dim FSO, agoMins, modifiedDate, delFolder

' 請將下面的變數值換成你要的
' == 開始 ==
' 指定 n 分鐘前的檔案,現在是 15 分前
agoMins = 15
' 欲刪除檔案所在之目錄
delFolder = "C:\inetpub\wwwroot\tempfile"
' == 結束 ==

' 建立檔案系統物件(File System Object)
Set FSO = CreateObject("Scripting.FileSystemObject")

' 取得檔案的修改時間
modifiedDate = DateAdd("n", -agoMins, Date)

' 呼叫刪除檔案的子程序
DelFilesInFolder FSO.GetFolder(delFolder)

' 刪除檔案的子程序
Sub DelFilesInFolder(folder)
 ' 宣告變數
 Dim file, subFolder

 ' 找出目前所在目錄內所有的檔案
 For Each file In folder.Files
  ' 檢查檔案日期是否符合條件,若符合,就刪除
  If ((file.DateLastModified <= modifiedDate)) Then
   'normal=0,readonly=1,hideen=2,system=4,Volume=8,Directory=16,Archive=32,Alias=64,Compressed=2048 
   If (file.attributes <> 1) then
    file.delete
   End If
  End If
 Next

 ' 如果遇到子目錄,也要進去檢查並刪除
 For Each subFolder in folder.SubFolders
  DelFilesInFolder subFolder
 Next
End Sub

'WScript.Echo("作業執行完畢:" & Date & " " & Time)


最後只要放在系統排程內,每15到30分鐘執行一次就OK啦!!

2014年5月7日 星期三

用VBscript取得每一層資料夾底下的儲存容量

檔案:CheckSpaceUsed.vbs
內容:
' 指定所有變數必須事先宣告才能使用
Option Explicit

'WScript.Echo("作業開始執行:" & Date & " " & Time)

' 宣告變數
Dim FSO, chkFolder, vbcrlf, logf

' == 開始 ==
vbcrlf = chrB(13) & chrB(10)

' 檔案所在之目錄
chkFolder = "C:\FTPROOT\UPLOAD"

' 建立檔案系統物件(File System Object)
Set FSO = CreateObject("Scripting.FileSystemObject")
' 建立紀錄檔案
Set logf = FSO.CreateTextFile("Csize.csv", True)

' 取得目錄層所有的資料夾,目錄層下的檔案不處理
FatchFolder FSO.GetFolder(chkFolder)

'關閉記錄檔
logf.Close

'取得清單子程序
Sub FatchFolder(path1)
 Dim fid, xsize, bs, axx
 '找出主資料夾下的資料夾清單
 For Each fid In path1.SubFolders
  bs = "B"
  ' 呼叫統計檔案大小的子程序
  xsize = CalFilesInFolder(fid)

  axx = fid.name & "," & Cstr(xsize)
  
  '計算 BYTE單位(最多到MB即可)
  If(xsize > 1024)then
   xsize = CLng(xsize / 1024)
   bs = "KB"
  End If
  If(xsize > 1024)then
   xsize = CLng(xsize / 1024)
   bs = "MB"
  End If
   
  '寫入紀錄檔
  logf.WriteLine(axx & "," & xsize & bs)
  
  '顯示在console畫面 
  WScript.Echo fid.name & " = " & xsize & bs
 
 Next
End Sub

' 統計檔案的子程序
Function CalFilesInFolder(folder)
 ' 宣告變數
 Dim file, subFolder,fsize,tfsize,dsize
 
 tfsize = 0
 dsize = 0
 ' 找出目前所在目錄內所有的檔案,並加總其大小
 For Each file In folder.Files
  fsize = file.Size
  tfsize = tfsize + fsize
 Next

 ' 如果遇到子目錄,也要進去檢查並計算
 For Each subFolder in folder.SubFolders
  dsize = dsize + CalFilesInFolder(subFolder)
 Next
 '合計本路徑下檔案大小與子資料夾內的大小並回傳
 CalFilesInFolder = tfsize + dsize
End Function

' == 結束 ==
'WScript.Echo("作業執行完畢:" & Date & " " & Time)

這是用來統計FTP使用者代號下每個人使用的空間,雖然都有劃分空間使用限制,但是可以用一個簡單程序稍微計算一下還是比較方便的,這個程序就使用VBS寫好,放在系統排程下每周執行一次,可以產生Csize.csv,然後用EXCEL來檢視,方便多了。

2014年3月18日 星期二

coldfusion send email (1): only text or html

Coldfusion 發送簡易電子郵件的方法:

使用 cfmail 標籤指令

純文字模式

<cfmail
  to="recipient1@mail.domain.com,recipient2@mail.domain.com"
  from="sender@mail.mydomain.com"
  subject="顧客意見反映"
  server="mail.mydomain.com"
  username="MySmtpAccount"
  password="MyPassword"
  type="text">
本訊息由網頁『顧客意見』發出,請勿回覆此信件。#chr(13)##chr(10)#
發訊時間 :#DateFormat(NOW() , 'yyyy/mm/dd')# #TimeFormat(NOW() , 'HH:mm:ss')#
發訊人姓名:#SenderName##chr(13)##chr(10)#
發訊人電話:#SenderTEL##chr(13)##chr(10)#
發訊人郵件:#SenderMail##chr(13)##chr(10)#
= = = = = = = = = = = = = = = = = = = =
#MailBodyText#
</cfmail>

HTML模式

<cfmail
  to="recipient1@mail.domain.com,recipient2@mail.domain.com"
  from="sender@mail.mydomain.com"
  subject="顧客意見反映"
  server="mail.mydomain.com"
  username="MySmtpAccount"
  password="MyPassword"
  type="html">
<div style="width:700px;margin:auto 10px;font-size:16px;background-color:##FFC;">
<span style="color:##060;">本訊息由網頁『顧客意見』發出,請勿回覆此信件。</span><br />
發訊時間 :<span style="color:##00F;font-weight:700;">#DateFormat(NOW() , 'yyyy/mm/dd')# #TimeFormat(NOW() , 'HH:mm:ss')#</span><br />
發訊人姓名:<span style="color:##00F;font-weight:700;">#SenderName#</span><br />
發訊人電話:<span style="color:##00F;font-weight:700;">#SenderTEL#</span><br />
發訊人郵件:<span style="color:##00F;font-weight:700;text-decoration:underline;">#SenderMail#</span><br />
= = = = = = = = = = = = = = = = = = = = = = = = = =<br />
<b><pre>#MailBodyText#</pre></b>
</div>
</cfmail>

cfmail可以直接使用SMTP伺服器發送郵件,所以只要你有架設標準SMTP伺服器就可以發信了。
from 沒有一定要與自己的smtp有關聯,所以可以寄偽信(汗),當然,這樣很容易被對方郵件主機反查失敗而SPAM掉。

2014年2月26日 星期三

微軟windows特殊指令收集

Windows 7 以後的作業系統,為了安全考量都會把administrator隱藏,但對於IT人員頗不方便,可以用以下指令開啟/關閉:

net user administrator /active:yes
net user administrator /active:no
--------------------------------------------------------------------------------------------------
DNS快取混亂,可能因為連到錯誤的DNS,導致IP解析錯誤,除了重新開機以外可以用:

ipconfig /flushdns

--------------------------------------------------------------------------------------------------
本機網路路由設定,一般windows自己會調整,不需要設定,顯示路由紀錄:

route print

--------------------------------------------------------------------------------------------------
但是公司內如果有特殊路由需要從走特定網卡,就要設定:

route add 10.8.0.0 mask 255.255.255.0 192.168.2.250
10.8.0.0是目的IP或網段
255.255.255.0 是遮罩(這裡是指定一個C)
192.168.2.250 是路由器IP

--------------------------------------------------------------------------------------------------
重新開機指令,這個在遠端桌面很好用:

shutdown -r -t 3 -c "因為維修關係重新啟動"
-r 重新開機
-t 3 指定3秒後執行
-c "因為維修關係重新啟動" 顯示的註解

--------------------------------------------------------------------------------------------------
以後持續加入...
PS:windows的指令有非常多種組合,詳細方式可以利用指令 /?來得知,此處只記錄我需要用到又容易忘記的指令。

2014年2月14日 星期五

第三剎車燈改LED(閃爍後恆亮)-有夜燈&無夜燈

最近在路上看到部分車系的車尾燈剎車時會有閃爍後便恆亮的狀態,看起來對後方車輛的警示效果不錯,尤其常上高速公路而言,有比較好的效果。

當然,網路上有不少筆戰關於剎車燈閃爍的議題,主要包括了法律、車型、原理、地區特性以及最常見的主觀。朔其來源應該是歐洲最先採用這種剎車規範,我記得叫做EBL或是EBD。汽車精品店有賣現成的(三角形),但是我發現它只會閃爍,且亮度不太夠,白天不是很清楚。

當然做這種東西不是為了讓車子像電子花車,主要的目的有兩個:純粹電子興趣、增加安全性而已,當然我不去改原始剎車燈,只改第三剎車燈,也是為避免後方混淆。原廠設計的話都會加上剎車力道感應,但是我的車是老車,沒有這類的感應設計,因此在設計時就只能考慮我的線路(只有一組啦),當然加上單軸加速計(Accelerometer)電路也可以做到,但電路可能會太複雜,且這類的零件不好買又貴。

網路上我找到不錯的論壇(喬治查爾斯)
http://gcbbs.digitw.com/phpbb2/viewtopic.php?f=1&t=704&st=0&sk=t&sd=a
我個人是採用版主的設計來改,原因只有一個,我手上有現成的555,但是沒有4096。
一開始電路採用 夜燈+剎車燈 的設計:

這個電路在麵包板上是成功的,且不需要額外電源接入

電路原理:
1、僅夜燈時,電源進入經過2SA684,此時2SCA684基極對接地無分壓(剎車無電力進入),此時晶體導通,電源經過330Ω限流到LED組(亮度稍弱)。
2、當剎車時,剎車線路供電,分壓給2SA684,此時2SA684基極高壓,使得CE斷開,停止夜燈電源供給。
3、剎車供電時,電容100u需3~4秒充電達才能飽和,此時U1輸出高電位Hi,使得2SC1815導通,電容10u可正常充放電,此時U2輸出震盪並推動220Ω與LED組,使LED閃爍(最亮)。
4、電容100u在4秒後達到飽和,U1輸出成為低電位Lo,2SC1815不導通,CE斷開,電容10u無法充放電,致使U2輸出維持高電位Hi,LED組變成恆亮。
5、剎車不供電時,U1、U2所有電路復歸原態,待下次剎車時從2再次循環。

U1是設計成延遲電路,所以腳位7(放電)不接。
汽車的電力大約在13V ~ 15V間,1N4003可以稍微降壓,並確保電路不會被逆接燒毀。
LED的限流電阻,必須依照您購買的LED的Vf去計算,LED電流設計在20mA即可,購買LED請先查詢它的規格,或詢問店家,否則若買到特殊規格LED(例如帶內阻)就可能無法驅動或是燒毀。
這個電路可以由555直接推動4~5組20mA的LED組都沒問題,2SCA684也可以推動4~5組20mA的LED組,但LED組總電流超過200mA就可能需要變更輸出設計,否則電晶體可能無法耐熱。
VR 20KΩ可以調整U1的延遲時間。
VR 10KΩ可以調整U2的閃爍頻率。

接下來要實作,考慮到我的車子第三剎車燈只有剎車線路,且我不想在車子裡面另外拉線,所以就拆下第三剎車燈來改就好,因此電路也稍作修改,後端改用Relay,優點是燈組供電直接,所以可以是自製LED組也可以是燈泡,亦或者是第三方燈組,缺點嘛....就是安靜的時候會聽到Relay的聲音。

純剎車用電路圖

然後實作

Relay我選用R1-1A1200 DIP磁簧繼電器,體積小,方便塞到電路上

燈組的部分就按照車燈內部拆除後,依照大小切割適當的洞洞板來做。


 這個LED燈模組切割得不是很漂亮,但是剛好可以塞到原本燈具位置上,LED的部分,我先焊上排針腳座,以方便我將來更換LED,並在洞洞板噴上白漆增加反光。

與電路板合體

裝上LED


裝回燈具,GJ!!!

============以下分隔============
依照網友需要,改成單純延遲型第三煞車燈,只使用U1(左側555)即可,延遲時間由50K的可變電阻微調。若需要2~3秒的延遲,調整阻值約在18K~30K之間吧。