fw10.bas 15 KB

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