fw9.bas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. '------------------------------------------------
  2. ' LC Meter Firmware
  3. ' June 2020 - coreWeaver / ioConnected
  4. '------------------------------------------------
  5. $regfile = "m328pdef.dat"
  6. $crystal = 8000000
  7. $baud = 19200
  8. $hwstack = 256
  9. $swstack = 256
  10. $framesize = 256
  11. ' UART Config
  12. Config Com1 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  13. Open "com1:" For Binary As #1
  14. Config Serialin0 = Buffered , Size = 30 , Bytematch = All
  15. ' Use ADC's Channel_5 to measure VBAT
  16. Config Adc = Single , Prescaler = Auto , Reference = Avcc
  17. Start Adc
  18. 'using watchdog for SW RST
  19. Config Watchdog = 128 'ovf after 128ms and resets the uC
  20. ' Frequency Counter from 4 Hz to 5 MHz
  21. ' Timer1 is used to generate a 1sec time interval for frequency measurement
  22. ' Timer0 is used to count the incoming pulses on T0 (PD4)
  23. ' Config Timer1 for 1 Second time interval
  24. ' Timer1 Config
  25. On Timer1 Timer1_routine
  26. Tccr1a = &B00000000
  27. Tccr1b = &B00000101 ' Prescaller 1024
  28. Timsk2 = &B00000001 ' Interrupt for Timer 2 active
  29. Timsk1 = &B00000001 ' Interrupt for Timer 1 active
  30. Timsk0 = &B00000001 ' Interrupt for Timer 0 active
  31. Sreg = &B10000000 ' Global Interrupts on
  32. Timer1 = 57644
  33. ' this value was found by using a resonator (4MHz)
  34. ' and adjusting the value of timer1 to match the 4000000 Hz output
  35. ' Timer0 Config
  36. On Timer0 Timer0_routine
  37. Tccr0 = &B00000111 ' Count external Signals on Rising Edge
  38. ' Timer2 is used to read and display the battery voltage every 4 seconds
  39. ' Timer2 Config
  40. On Timer2 Timer2_routine
  41. Tccr2a = &B00000000
  42. Tccr2b = &B00000101 ' Prescaller 1024
  43. Timer2 = 178 ' OVF each 10 ms
  44. ' count 4 seconds in INT routine then raise Ok_to_read_vbat Flag
  45. Enable Interrupts
  46. $lib "glcd-Nokia3310.lib"
  47. ' LCD Rst & Cs1 are not used
  48. Config Graphlcd = 128x64sed , Rst = Portd.3 , A0 = Portb.4 , Si = Portb.3 , Sclk = Portb.5
  49. 'Const Negative_lcd = 1 ' Invert screen
  50. Const Rotate_lcd = 0
  51. ' LEDs
  52. Config Portd.5 = Output
  53. Blue_led Alias Portd.5
  54. Reset Blue_led
  55. Config Portd.6 = Output
  56. Red_led Alias Portd.6
  57. Reset Red_led
  58. ' Keys
  59. Config Pinb.1 = Input
  60. Key1 Alias Pinb.1
  61. Portb.1 = 1
  62. Config Pind.2 = Input
  63. Key2 Alias Pind.2
  64. Portd.2 = 1
  65. ' Reed Relay (adds Calibration Capacitor)
  66. Config Portb.2 = Output
  67. Calibrate Alias Portb.2
  68. Set Calibrate ' disconnect Ccal
  69. ' Measure Mode
  70. ' double relay
  71. ' SET (Normally Open) >> C Mode
  72. ' RESET (Normally Close) >> L Mode
  73. Config Portb.0 = Output
  74. Measure_mode Alias Portb.0
  75. Reset Measure_mode
  76. Dim Overflowed As Long
  77. Dim Pulses As Long
  78. Dim I As Byte , J As Byte , K As Byte
  79. Dim Tim2var As Integer
  80. Const Pi = 3.141592653589793
  81. Const 2pi = 6.283185307179586
  82. Const Ccal = 0.000000001006 ' Farads or 1006 [pF]
  83. Const Milli = 0.001
  84. Const Micro = 0.000001
  85. Const Nano = 0.000000001
  86. Const Pico = 0.000000000001
  87. Const Cr = &H0D
  88. Const Lf = &H0A
  89. Dim F1 As Single ' Oscillator's base freq. (Ccal, C_det & L_det disconnected)
  90. Dim F2 As Single ' Calibration freq. (Ccal connected, C_det & L_det disconnected)
  91. Dim F3 As Single ' Ccal disconnected, C_det connected, L_det disconnected
  92. Dim F4 As Single ' Ccal disconnected, C_det disconnected, L_det disconnected
  93. Dim Dvar1 As Single
  94. Dim Dvar2 As Single
  95. Dim Svar1 As Single
  96. Dim C_measured As Single
  97. Dim L_measured As Single
  98. Dim Scaled_val As Single
  99. Dim New_str_value As String * 20
  100. Dim Adcval As Word
  101. Dim Vbat As Single
  102. Dim Vbat_str As String * 5
  103. Dim X As Byte
  104. Dim Lbat_pic As Bit
  105. Reset Lbat_pic
  106. Dim Ok_to_read_vbat As Bit
  107. Reset Ok_to_read_vbat
  108. Dim A As Byte
  109. Dim Rx_buffer As String * 30 , Rx_string As String * 30
  110. Dim Full_buffer As Bit , Rx_flag As Bit
  111. Reset Full_buffer : Reset Rx_flag
  112. Declare Sub Read_vbat
  113. Declare Sub Calibration
  114. Declare Sub Measure_c
  115. Declare Sub Measure_l
  116. Declare Sub Convert(value As Single)
  117. ' Initialize LCD
  118. Initlcd
  119. Glcdcmd 33 : Glcdcmd 200 ' Normal Contrast
  120. Cls
  121. ' select Capacity Mode
  122. Set Measure_mode
  123. Print "LC-Meter.ioConnected.OK"
  124. Setfont Newfont6x8
  125. Showpic 1 , 1 , Splash
  126. Waitms 1000
  127. Cls
  128. Lcdat 3 , 10 , "ioConnected"
  129. Lcdat 4 , 52 , "2020"
  130. Waitms 2000
  131. Print "Ready"
  132. Waitms 500
  133. Call Calibration
  134. Print
  135. Print
  136. Do
  137. If Ok_to_read_vbat = 1 Then Call Read_vbat
  138. If Key1 = 0 Then
  139. Print "Measuring Capacitance >>>>"
  140. Waitms 500
  141. If Key2 = 0 Then
  142. Call Calibration
  143. Else
  144. Call Measure_c
  145. End If
  146. End If
  147. If Key2 = 0 Then
  148. Print "Measuring Inductance >>>>"
  149. Waitms 500
  150. If Key1 = 0 Then
  151. Call Calibration
  152. Else
  153. Call Measure_l
  154. End If
  155. End If
  156. If Rx_flag = 1 Then
  157. Select Case Rx_string
  158. Case "rst!":
  159. Start Watchdog
  160. End Select
  161. End If
  162. Loop
  163. End
  164. $include "newfont6x8.font"
  165. $include "font12x16dig.font"
  166. Splash:
  167. $bgf "splash_s.bgf"
  168. Battery100:
  169. $bgf "b100.bgf"
  170. Battery75:
  171. $bgf "b75.bgf"
  172. Battery50:
  173. $bgf "b50.bgf"
  174. Batterylow1:
  175. $bgf "blow1.bgf"
  176. Batterylow2:
  177. $bgf "blow2.bgf"
  178. Inductor:
  179. $bgf "ind_s.bgf"
  180. Capacitor:
  181. $bgf "cap_s.bgf"
  182. Serial0bytereceived:
  183. Pushall
  184. If Ischarwaiting() > 0 Then
  185. A = Inkey()
  186. If A <> 10 And A <> 13 Then
  187. Rx_buffer = Rx_buffer + Chr(a)
  188. End If
  189. If Len(rx_buffer) >= 20 Then Set Full_buffer
  190. End If
  191. If A = 10 Or Full_buffer = 1 Then
  192. Reset Full_buffer
  193. Set Rx_flag
  194. Rx_string = Rx_buffer
  195. Rx_buffer = ""
  196. End If
  197. Popall
  198. Return
  199. Timer1_routine:
  200. 'Timer1 = 57898
  201. 'Timer1 = 57880
  202. 'Timer1 = 57870
  203. Timer1 = 57644
  204. Overflowed = Overflowed * 255
  205. Pulses = Overflowed + Timer0
  206. Overflowed = 0
  207. Timer0 = 0
  208. Return
  209. Timer0_routine:
  210. Incr Overflowed
  211. Return
  212. Timer2_routine:
  213. Timer2 = 178 ' OVF every 10mS
  214. Incr Tim2var
  215. If Tim2var >= 400 Then
  216. Tim2var = 0
  217. Ok_to_read_vbat = 1
  218. End If
  219. Return
  220. Sub Read_vbat
  221. Ok_to_read_vbat = 0
  222. Adcval = Getadc(5)
  223. Vbat = Adcval * 4.92
  224. ' Vbat is measured through a voltage divider (R1=R2)
  225. Vbat = Vbat * 2.01 ' R2's measured resistance is slightly smaller
  226. ' show in Volts
  227. Vbat = Vbat / 1000
  228. Vbat_str = Fusing(vbat , "#.&&")
  229. 'Print : Print "Battery Voltage= " ; Vbat_str ; " [V]"
  230. Select Case Vbat
  231. Case Is > 8.3 : Showpic 72 , 1 , Battery100
  232. Case 7.8 To 8.3 : Showpic 72 , 1 , Battery75
  233. Case 7.2 To 7.8 : Showpic 72 , 1 , Battery50
  234. Case Is < 7.2 :
  235. Toggle Lbat_pic
  236. If Lbat_pic = 0 Then
  237. Showpic 72 , 1 , Batterylow2
  238. Else
  239. Showpic 72 , 1 , Batterylow1
  240. Print "Battery low !"
  241. End If
  242. End Select
  243. End Sub
  244. Sub Calibration
  245. Ok_to_read_vbat = 0
  246. Cls
  247. Print "Calibration"
  248. Print "make sure to remove any L or C from the Measuring Terminals"
  249. Print
  250. Print "please wait ..."
  251. Lcdat 2 , 1 , "Calibration" ;
  252. Lcdat 3 , 1 , "please wait .." ;
  253. Waitms 400
  254. Lcdat 5 , 1 , "Æ"
  255. Print "^"
  256. Reset Red_led
  257. Reset Blue_led
  258. ' prepare to measure the Frequency without Calibration Capacity
  259. Set Calibrate ' disconnect Ccal
  260. Lcdat 5 , 1 , "Æ"
  261. Print "^"
  262. I = 0
  263. J = 0
  264. K = 0
  265. For I = 1 To 6
  266. 'Print I
  267. Incr J
  268. Waitms 500
  269. X = I * 6
  270. X = X + 1
  271. Lcdat 5 , X , "Æ"
  272. Print "^"
  273. If J = 2 Then
  274. Incr K
  275. J = 0
  276. Print "F1= " ; Pulses ; " [Hz] (base frequency)"
  277. If K = 3 Then
  278. F1 = Pulses
  279. Print "F1= " ; F1 ; " [Hz] (base frequency)"
  280. ' now prepare to measure the Frequency with added Calibration Capacitance
  281. Reset Calibrate ' connect Ccal
  282. End If
  283. End If
  284. Next
  285. Lcdat 5 , 43 , "Æ"
  286. Print "^"
  287. Waitms 500
  288. Lcdat 5 , 49 , "Æ"
  289. Print "^"
  290. J = 0
  291. K = 0
  292. For I = 9 To 14
  293. 'Print I
  294. Incr J
  295. Waitms 500
  296. X = I * 6
  297. X = X + 1
  298. Lcdat 5 , X , "Æ"
  299. Print "^"
  300. If J = 2 Then
  301. Incr K
  302. J = 0
  303. Print "F2= " ; Pulses ; " [Hz] (calibration frequency)"
  304. If K = 3 Then
  305. K = 0
  306. F2 = Pulses
  307. Print "F2= " ; F2 ; " [Hz] (calibration frequency)"
  308. End If
  309. End If
  310. Next
  311. Cls
  312. Lcdat 2 , 1 , "Calibration"
  313. Lcdat 3 , 1 , "complete !"
  314. Print "Calibration complete !"
  315. Waitms 2000
  316. Cls
  317. Lcdat 5 , 1 , "L-Mode C-Mode"
  318. Print "C Done !"
  319. Print
  320. Print
  321. End Sub
  322. Sub Measure_c
  323. Ok_to_read_vbat = 1
  324. Cls
  325. Lcdat 1 , 1 , "Capacitance"
  326. Showpic 14 , 10 , Capacitor
  327. Waitms 2000
  328. Set Blue_led
  329. Set Measure_mode ' select Capacitance Mode
  330. Set Calibrate ' disconnect Ccal
  331. For I = 1 To 4
  332. Waitms 250
  333. Next
  334. I = 0
  335. Do
  336. F3 = Pulses
  337. Print "F3= " ; F3 ; " [Hz] (frequency for C_det)"
  338. Dvar1 = F1 / F3
  339. Dvar1 = Dvar1 * Dvar1
  340. Dvar1 = Dvar1 - 1
  341. Dvar2 = F1 / F2
  342. Dvar2 = Dvar2 * Dvar2
  343. Dvar2 = Dvar2 - 1
  344. Dvar1 = Dvar1 / Dvar2
  345. C_measured = Dvar1
  346. C_measured = C_measured * Ccal
  347. Call Convert(c_measured)
  348. If New_str_value <> "Error !" Then
  349. New_str_value = "C= " + New_str_value
  350. New_str_value = New_str_value + "F]"
  351. End If
  352. Print New_str_value
  353. Lcdat 4 , 1 , " "
  354. Lcdat 4 , 1 , New_str_value
  355. Incr I
  356. Waitms 1000
  357. Loop Until I > 4
  358. Reset Blue_led
  359. Lcdat 5 , 1 , "L-Mode C-Mode"
  360. Print "CM Done !"
  361. End Sub
  362. Sub Measure_l
  363. Ok_to_read_vbat = 1
  364. Cls
  365. Lcdat 1 , 1 , "Inductance "
  366. Showpic 14 , 12 , Inductor
  367. Waitms 2000
  368. Set Red_led
  369. Reset Measure_mode ' select Inductance Mode
  370. Set Calibrate ' disconnect Ccal
  371. For I = 1 To 4
  372. Waitms 250
  373. Next
  374. I = 0
  375. Do
  376. F4 = Pulses
  377. Print "F4= " ; F4 ; " [Hz] (frequency for C_det)"
  378. Dvar1 = F1 / F4
  379. Dvar1 = Dvar1 * Dvar1
  380. Dvar1 = Dvar1 - 1
  381. Dvar2 = F1 / F2
  382. Dvar2 = Dvar2 * Dvar2
  383. Dvar2 = Dvar2 - 1
  384. Dvar1 = Dvar1 * Dvar2
  385. Svar1 = F1
  386. Svar1 = 2pi * Svar1
  387. Svar1 = 1 / Svar1
  388. Svar1 = Svar1 ^ 2
  389. L_measured = Dvar1
  390. L_measured = L_measured / Ccal
  391. L_measured = L_measured * Svar1
  392. Call Convert(l_measured)
  393. If New_str_value <> "Error !" Then
  394. New_str_value = "L= " + New_str_value
  395. New_str_value = New_str_value + "H]"
  396. End If
  397. Print New_str_value
  398. Lcdat 4 , 1 , " "
  399. Lcdat 4 , 1 , New_str_value
  400. Incr I
  401. Waitms 1000
  402. Loop Until I > 4
  403. Reset Red_led
  404. Lcdat 5 , 1 , "L-Mode C-Mode"
  405. Print "LM Done !"
  406. End Sub
  407. Sub Convert(value As Single)
  408. New_str_value = ""
  409. If Value > 0 Then
  410. If Value < Nano Then
  411. Scaled_val = Value * 1000000000000
  412. New_str_value = Fusing(scaled_val , "#.&&")
  413. New_str_value = New_str_value + " [p"
  414. Else
  415. If Value < Micro Then
  416. Scaled_val = Value * 1000000000
  417. New_str_value = Fusing(scaled_val , "#.&&")
  418. New_str_value = New_str_value + " [n"
  419. Else
  420. If Value < Milli Then
  421. Scaled_val = Value * 1000000
  422. New_str_value = Fusing(scaled_val , "#.&&")
  423. New_str_value = New_str_value + " [u"
  424. Else
  425. If Value < 1 Then
  426. New_str_value = Fusing(scaled_val , "#.&&&")
  427. New_str_value = New_str_value + " [m"
  428. Else
  429. If Value < 10 Then
  430. New_str_value = Fusing(scaled_val , "#.&")
  431. New_str_value = New_str_value + " ["
  432. Else
  433. New_str_value = "Error !"
  434. End If
  435. End If
  436. End If
  437. End If
  438. End If
  439. Else
  440. New_str_value = "Error !"
  441. End If
  442. End Sub