Strona 1 z 1

Udoskonalony termometr bezprzewodowy. Pytania.

: 20 maja 2023, 21:40
autor: inspector_electro
Witam szanownych forumowiczów.
Jako że nikt już chyba nie zagląda do tematu z termometrem, postanowiłem utworzyć nowy.
Chodzi o termometr :

viewtopic.php?f=10&t=46
Mam nadzieję że założyciel forum BARTek mnie za to nie zlinczuje. ;)
Ale do rzeczy. Mam do Was, do znających Bascom, Assembler pytania odnośnie programów nadajnika i odbiornika.
Złożyłem sobie zestaw z Tiny13 i odbiornikiem z M328p na wyświetlaczach led.
Mam problem z dwoma zagadnieniami.

1. W nadajniku z Tiny13, mam zaremowany kawałek kodu:
  1. 'If Multip = 0 Then
  2.  
  3.       Open "COMB.0:1200,8,N,1" For Output As #1
  4.  
  5.         'Set Tx_pin
  6.  
  7.       'DS18B20
  8.        'Buffer(1) = &HBB
  9.        'Buffer(2) = &HBB
  10.  
  11.       'ADC
  12.        'Buffer(3) = &HF0
  13.        'Buffer(4) = &H00
  14.  
  15.        Adc_read = Getadc(battery_terminal)                  'result in Buffer(1), Buffer(2)
  16.  
  17.       'NODE
  18.         Buffer(5) = Node_nr
  19.         Buffer(17) = Node_nr
  20.  
  21.       'CRC
  22.         Buffer(18) = Crc8(buffer(1) , 5)
  23.  
  24.  
  25.    ''  Wrd1 and Wrd2 (four bytes)can be filled at the end so now can be as helpw
  26.  
  27.        Wrd_3 = Code(buffer(1))                              'ds
  28.        Wrd_4 = Code(buffer(2))                              'ds
  29.        Wrd_5 = Code(buffer(3))                              'adc
  30.        Wrd_6 = Code(buffer(4))                              'adc
  31.        Wrd_7 = Code(buffer(17))                             'id
  32.        Wrd_8 = Code(buffer(18))                             'crc
  33.        Buffer(1) = Tail
  34.        Wrd_9 = Code(buffer(1))
  35.  
  36.        Buffer(1) = Tail
  37.        Buffer(2) = Tail
  38.  
  39.        Buffer(3) = Tail
  40.        Buffer(4) = Tail
  41.  
  42.        Printbin #1 , Buffer(1)
  43.  
  44.        Reset Tx_pin
  45.         Set Divider_gnd
  46.  
  47.    'End If
Bez tego odbiornik nie reaguje na wysyłane dane, ani przez radio, ani Przez USART spięty bezpośrednio kablami. Zaremowany kawałek kodu powoduje że dane odbierane są bezbłędnie.
Poszedłem za poradą BARTka, i spojrzałem sobie co wysyła DALLAS na terminal. Dane wydają się być ok.

2. W odbiorniku chciałbym dołożyć 2 wyświetlacze, aby móc wyświetlać znak stopnia i C. W kodzie autor (BARTek) umieścił wstawki Assemblerowe, które ustawiają pewnie ilość wyświetlaczy. Kompletnie nic nie kumam. Studiowałem trochę w internecie nt. Assemblera. Nie mogę ogarnąć dodania wyświetlaczy do kodu.
Albo jestem za stary, albo za.... tępy? nie wiem. Tak czy owak prosiłbym tęższe głowy o pomoc w tych kwestiach. Co mogłem, ogarnąłem sam.
Wklejam kod odbiornika:
  1. $regfile = "m328pdef.dat"
  2. $crystal = 8000000
  3. $hwstack = 64
  4. $swstack = 32
  5. $framesize = 128
  6. $baud = 1200
  7. $timeout = 10000
  8.  
  9. '****************************************************
  10. '*----  3x  7SEGMENT MULTIPLEXED VERSION :D ------- *
  11. '****************************************************
  12. '*             WIRELESS THERMOMETER                 *
  13. '*             WITH CIRCULAR BUFFER                 *
  14. '*                RECEIVER PART                     *
  15. '*              niveasoft@tlen.pl                   *
  16. '*                 2017-02-06                       *
  17. '****************************************************
  18.  
  19. '-DESCRIPTION-
  20. '
  21. ' Code receive incomming data in interrupt background mode.
  22. ' If special Tail byte is detected then this byte is the last in whole frame.
  23. ' Circular buffer size is calculated to hold only 14 bytes.
  24. ' So if Tail is detected then rest of buffer must be previous data.
  25. ' In this way preamble is rejected and you have only data bytes.
  26. ' These are coded im Manchester six bytes. First two contains data from DS18B20
  27. ' Second two bytes contains ADC value readed from node battery terminals.
  28. ' Fifth byte is a Node number so you can have more of them and recognize.
  29. ' Sixth byte is a CRC from provious five bytes.
  30.  
  31. '7SEGMENT ERRATA
  32.  
  33. '* DISPLAYING
  34. '
  35. ' For temperatures below -9,9 decimal figures are not shown so it will be displayed "-10"
  36. '
  37. '* SWITCH
  38. ' Switch added for change displayed data
  39. ' ->Temp Outside->Temp Inside->Transmitter Battery Voltage->
  40. ' After change info is displayed for about 1s "In","Out" and "Bat"
  41. ' If no valid data from >Inactivity time then three "---" signs popup in "Out" mode
  42. ' Schematic is attached with this code or can be found at bart-projects.cba.pl.
  43. '
  44. '* AUTOMATIC BRIGHTNESS CONTROL
  45. ' Displays are dimmed with COMPARE1B
  46.  
  47.  
  48.  
  49. Const Maximum_inactivity = 240                              '4min
  50.  
  51. Config Submode = New
  52.  
  53. Config 1wire = Portd.3
  54.  
  55. Config Portb = Output
  56. Config Portd.7 = Input : Set Portd.7 : Switch Alias Pind.7
  57. 'Config Portc.0 = Input : Foto Alias 0                       'for ADC
  58.  
  59. Config Portc.3 = Output
  60. Config Portc.4 = Output
  61. Config Portc.5 = Output
  62. Config Portc.1 = Output
  63. Config Portc.2 = Output
  64.  
  65. Dot Alias 6 : Disp_port Alias Portb
  66.  
  67. Config Timer1 = Timer , Prescale = 256 , Compare_a = Disconnect , Compare_b = Disconnect , Clear_timer = 1
  68. Enable Compare1a : On Compare1a Mux_isr Nosave : Compare1a = 155       '5ms @8MHz/256 =200Mz
  69. Enable Compare1b : On Compare1b Dimm_isr Nosave : Compare1b = 150       'DIMMING
  70.  
  71. '********************[ TIMEBASE ]********************
  72. Dim 5ms As Byte , 1000ms As Byte , Refresh As Byte
  73. Dim In_out As Byte , Show_timeout As Byte
  74. Dim Last_msg_time As Byte , Error As Byte , Errors As Byte
  75.  
  76. '******************[ MULTIPURPOSE ]******************
  77.  Dim N As Byte
  78.  
  79. '**************[ DISPLAYS MULTIPLEXING ]*************
  80. Dim 7segment_displ(5) As Byte , In_temp(3) As Byte , Out_temp(3) As Byte  <<<<<<<___________________  tu dodałem 5 na 5 wyświetlaczy  
  81.  
  82. '****************[ DIMMING DISPLAY ]*****************
  83. 'Config Adc = Single , Prescaler = Auto , Reference = Avcc
  84.  'Dim Adc_read As Word , Dimm As Word
  85.  
  86. '***************[ SERIAL DATA RECEIVER ]*************
  87. Config Serialin0 = Buffered , Size = 20
  88.  
  89. Const Buff_len = 14 : Dim Ring(buff_len) As Byte
  90. Dim Ring_cnt , Copy_cnt , Prev , Test As Byte
  91. Dim Rx_word As Word
  92. Dim Tail As Byte : Tail = &HAA                        
  93.  
  94. '****************[ TEMPERATURE DATA ]****************
  95. Dim Bytes(9) As Byte : Dim Temperature As Integer At Bytes(1) Overlay
  96.  
  97. '****************[ BATTERY MONITOR ]*****************
  98. Dim Voltage As Word , Volt(3) As Byte
  99.  
  100.  
  101. Function Decode_manchester(byval Tempw As Word ) As Byte
  102.    Local Bit_number As Byte : Bit_number = 8
  103.    Local Manchester As Word
  104.    Local Temp_1 As Word
  105.    Local Data_error As Byte : Data_error = 0
  106.    Do
  107.       Shift Manchester , Left , 1
  108.       Decr Bit_number
  109.       Temp_1 = Tempw And &B1100_0000_0000_0000
  110.       If Temp_1 = &B0100_0000_0000_0000 Then Incr Manchester       '01
  111.       If Temp_1 = &B1100_0000_0000_0000 Or Temp_1 = 0 Then Data_error = 1       '11 or 00
  112.       Shift Tempw , Left , 2
  113.    Loop Until Bit_number = 0
  114.    If Data_error = 0 Then
  115.       Decode_manchester = Manchester
  116.    Else
  117.       Decode_manchester = 0
  118.    End If
  119. End Function
  120.  
  121. Sub Fill_volt()
  122.  
  123.  Local Helpw As Word
  124.   Voltage = Makeint(bytes(3) , Bytes(4))                    'Word ADC value
  125.    Shift Voltage , Right , 1
  126.     Helpw = Voltage Mod 10
  127.      Volt(3) = Lookup(helpw , Values)
  128.     Voltage = Voltage / 10
  129.      Helpw = Voltage Mod 10
  130.     Volt(2) = Lookup(helpw , Values)
  131.      Helpw = Voltage / 10
  132.     Volt(1) = Lookup(helpw , Values)
  133.     Volt(1).dot = 0
  134.  
  135. End Sub
  136.  
  137. Sub Fill_array(byval T As Integer , Byref Dest() As Byte)
  138.   Local Helpi1 As Integer , Helpi2 As Integer
  139.  
  140.  T = T * 10 : T = T / 16
  141.  
  142.  If T >= 0 Then
  143.    Helpi1 = T Mod 10
  144.     Dest(3) = Lookup(helpi1 , Values)
  145.    Helpi2 = T / 10
  146.     Helpi1 = Helpi2 Mod 10
  147.    Dest(2) = Lookup(helpi1 , Values)
  148.    Dest(2).dot = 0
  149.     Helpi1 = Helpi2 / 10
  150.     If Helpi1 = 0 Then Helpi1 = 14
  151.    Dest(1) = Lookup(helpi1 , Values)
  152.  
  153.  Else
  154.  
  155.   Dest(1) = Lookup(13 , Values)                             'minus
  156.     Helpi2 = Abs(t)
  157.  
  158.    If T >= -99 Then
  159.  
  160.      Helpi1 = Helpi2 Mod 10
  161.     Dest(3) = Lookup(helpi1 , Values)
  162.      Helpi1 = Helpi2 / 10
  163.     Dest(2) = Lookup(helpi1 , Values)
  164.      Dest(2).dot = 0
  165.  
  166.    Else                                                     'if -10 and needed two digits then no result after comma
  167.  
  168.      Helpi1 = Helpi2 / 10
  169.       Helpi2 = Helpi1 / 10
  170.      Dest(2) = Lookup(helpi2 , Values)
  171.       Helpi2 = Helpi1 Mod 10
  172.      Dest(3) = Lookup(helpi2 , Values)
  173.  
  174.    End If
  175.  End If
  176.  
  177. End Sub
  178.  
  179. Sub Clear_array(byref Dest() As Byte)
  180.  For N = 1 To 3
  181.   Dest(n) = Lookup(13 , Values)
  182.  Next
  183. End Sub
  184.  
  185.  
  186. Call Clear_array(in_temp(1))                                'make three minus to indicate theres no data yet
  187.  Call Clear_array(out_temp(1))
  188.   Call Clear_array(volt(1))
  189.  
  190. Enable Interrupts
  191.  Refresh = 1
  192.  
  193. Do
  194.  
  195.  If Ischarwaiting() > 0 Then
  196.  
  197.   'move forward in circular buffer
  198.   Incr Ring_cnt : If Ring_cnt > Buff_len Then Ring_cnt = 1
  199.   If Ring_cnt = 1 Then Prev = Buff_len Else Prev = Ring_cnt - 1
  200.  
  201.   Inputbin Test
  202.    Ring(ring_cnt) = Test                                    'write to buffer
  203.  
  204.   Rx_word = Makeint(ring(prev) , Ring(ring_cnt))            'make word from two last bytes
  205.  
  206.    Test = Decode_manchester(rx_word)                        'decode it from manchester into byte
  207.  
  208.    If Test = Tail Then                                      'test if this is our tail ;)
  209.  
  210.     Copy_cnt = Ring_cnt
  211.  
  212.     'beacause Tail is the last frame byte so read back six bytes from buffer
  213.      For N = 1 To 6
  214.        Incr Copy_cnt : If Copy_cnt > Buff_len Then Copy_cnt = 1
  215.        Incr Copy_cnt : If Copy_cnt > Buff_len Then Copy_cnt = 1
  216.        If Copy_cnt = 1 Then Prev = Buff_len Else Prev = Copy_cnt - 1
  217.  
  218.        Rx_word = Makeint(ring(prev) , Ring(copy_cnt))
  219.         Test = Decode_manchester(rx_word)
  220.  
  221.        Bytes(n) = Test
  222.  
  223.      Next
  224.       'data was displayed
  225.       'now validate it
  226.  
  227.  
  228.      'CRC from empty array is also 0 so check if atleast one byte is differ
  229.       If Bytes(1) <> 0 Then
  230.  
  231.         If Crc8(bytes(1) , 5) = Bytes(6) Then
  232.  
  233.            Call Fill_array(temperature , Out_temp(1))
  234.  
  235.            Call Fill_volt()
  236.  
  237.           Last_msg_time = 0
  238.  
  239.         End If
  240.  
  241.       End If
  242.  
  243.    End If
  244.  
  245.  End If
  246.  
  247.  If 5ms = 1 Then
  248.   5ms = 0 : Incr 1000ms
  249.  
  250.   If 1000ms = 200 Then
  251.    Refresh = 1
  252.  
  253.    Error = 0
  254.    1wreset
  255.    If Err = 0 Then
  256.  
  257.     1wwrite &HCC
  258.     1wwrite &HBE
  259.      Bytes(1) = 1wread(9)
  260.  
  261.      If Bytes(8) = &H10 Then
  262.       If Crc8(bytes(1) , 8) <> Bytes(9) Then Error = 1
  263.      Else
  264.       Error = 1
  265.      End If
  266.  
  267.    Else
  268.     Error = 1
  269.    End If
  270.  
  271.  
  272.    If Error = 0 Then
  273.     Call Fill_array(temperature , In_temp(1))
  274.      Errors = 0
  275.    Else
  276.     If Errors < 3 Then
  277.      Incr Errors
  278.     Else
  279.      Call Clear_array(in_temp(1))
  280.     End If
  281.    End If
  282.  
  283.    1wreset
  284.     1wwrite &HCC
  285.     1wwrite &H44
  286.  
  287.    '--[DIMMING]--
  288.  
  289.     'Adc_read = Adc_read + Getadc(foto)
  290.      'Shift Adc_read , Right , 3
  291.      ' Dimm = 200 - Adc_read
  292.       'If Dimm > 150 Then Dimm = 150
  293.        'Compare1b = Dimm
  294.  
  295.    '--[INACTIVITY OF SENSOR]--
  296.     Incr Last_msg_time
  297.      If Last_msg_time > Maximum_inactivity Then
  298.       Last_msg_time = 0 : Call Clear_array(out_temp(1))
  299.      End If
  300.  
  301.   End If
  302.  
  303.  End If
  304.  
  305.  If Refresh = 1 Then
  306.   Refresh = 0 : 1000ms = 0
  307.  
  308.    If Show_timeout > 0 Then
  309.     Decr Show_timeout
  310.    Else
  311.  
  312.     Select Case In_out
  313.      Case 0
  314.       7segment_displ(1) = Out_temp(1)
  315.       7segment_displ(2) = Out_temp(2)
  316.       7segment_displ(3) = Out_temp(3)
  317.       7segment_displ(4) = Out_temp(1)   <<<<<<<<<<<<<<<<<<<<<<<<<<<-------------------------------- Tu na próbę, czy zapalą się kolejne dwa wyświetlacze
  318.       7segment_displ(5) = Out_temp(2)   <<<<<<<<<<<<<<<<<<<<<<<<<<<---------------------------------||-||-
  319.      Case 1
  320.       7segment_displ(1) = In_temp(1)
  321.       7segment_displ(2) = In_temp(2)
  322.       7segment_displ(3) = In_temp(3)
  323.      Case 2
  324.       7segment_displ(1) = Volt(1)
  325.       7segment_displ(2) = Volt(2)
  326.       7segment_displ(3) = Volt(3)
  327.     End Select
  328.    ' **************[ DISPLAYS MULTIPLEXING ]*************
  329.  
  330.    End If
  331.  End If
  332.  
  333.  Debounce Switch , 0 , Switch_sub , Sub
  334. Loop
  335. End
  336.  
  337.  
  338. Switch_sub:
  339.  Incr In_out : If In_out > 2 Then In_out = 0
  340.   Select Case In_out
  341.    Case 0
  342.     7segment_displ(1) = Lookup(0 , Values)
  343.     7segment_displ(2) = Lookup(10 , Values)    'out
  344.     7segment_displ(3) = Lookup(11 , Values)
  345.    Case 1
  346.     7segment_displ(1) = Lookup(1 , Values)
  347.     7segment_displ(2) = Lookup(12 , Values)  'in
  348.     7segment_displ(3) = Lookup(14 , Values)
  349.    Case 2
  350.     7segment_displ(1) = Lookup(15 , Values)
  351.     7segment_displ(2) = Lookup(16 , Values)   'bat
  352.     7segment_displ(3) = Lookup(11 , Values)
  353.  
  354.   End Select
  355.    Refresh = 1 : Show_timeout = 1
  356. Return
  357.  
  358. 'G,DP,A,B,C,D,E,F
  359. Values:
  360. '       0              1           2            3            4
  361. Data &B11000000 , &B11100111 , &B01001001 , &B01000011 , &B01100110
  362. '       5              6           7            8            9
  363. Data &B01010010 , &B01010000 , &B11000111 , &B01000000 , &B01000010
  364. '      u 10         t 11         n 12         - 13        blank 14
  365. Data &B11110001 , &B01111000 , &B01110101 , &B01111111 , &B11111111
  366. '      b 15         A 16
  367. Data &B01110000 , &B01000100
  368.  
  369. Mux_isr:
  370.  
  371.   $asm
  372.   !PUSH R10
  373.   !PUSH R16
  374.   !PUSH R20
  375.   !PUSH R22
  376.   !PUSH R24
  377.   !PUSH R25
  378.   !PUSH R26
  379.   !PUSH R27
  380.   !PUSH R28
  381.   !PUSH R31
  382.   !in R24, sreg
  383.   !PUSH  R24
  384.   $end Asm
  385.   Incr Displ : If Displ > 5 Then Displ = 3
  386.    Disp_port = 7segment_displ(displ - 2)
  387.     Reset Portc.displ
  388.    5ms = 1
  389.   '          Tuned with NoSave Tool
  390.   $asm
  391.   !POP  R24
  392.   !out sreg, R24
  393.   !POP R31
  394.   !POP R28
  395.   !POP R27
  396.   !POP R26
  397.   !POP R25
  398.   !POP R24
  399.   !POP R22
  400.   !POP R20
  401.   !POP R16
  402.   !POP R10
  403.   $end Asm
  404.  
  405. Return
  406.  
  407. Dimm_isr:
  408.  
  409.   $asm
  410.   !PUSH R24
  411.   !in R24, sreg
  412.   !PUSH  R24
  413.   $end Asm
  414.  
  415.   Portc = Portc Or &B00111110     <<<<<<<<<<<<<<<<<<<<<<<<<--------------------- Tu dodałem 2 bity dla dwu wyświetlaczy.
  416.   '          Tuned with NoSave Tool
  417.  
  418.   $asm
  419.   !POP  R24
  420.   !out sreg, r24
  421.   !POP R24
  422.  
  423.   $end Asm
  424.  
  425. Return
Dziękuję i pozdrawiam.

Re: Udoskonalony termometr bezprzewodowy. Pytania.

: 21 maja 2023, 21:33
autor: niveasoft
Oczywiście widziałm tamten temat bo mam powiadomienia. Czasem jest tak, że nad odpowiedzią musze się zastanowić a to prowadzi do drugiego skutku. Jak czegoś nie zrobię od razu to czasem zapomnę.

Co do dołożenia kolejnych dwóch wyswietlaczy. Mam rozumieć, że to na PC.1 i PC2 tak?

Nie ma to nic wspólnego z Assemblerem który pewnie Tobie tu przesłania pewną prosta rzecz.
Kod miał obsługiwać trzy wyświetlacze : PC.3, PC4 i PC.5, ale bajty były trzy 7segment_displ(3).
Dane o temperaturze są zawarte w bajtach od 1 do 3. Dlatego w subie Mux jest przesunięcię o 2 czyli -2 bo jak jesteśmy na pinie 2 to chcemy wyswietlić zawartość bajtu 1.

Najpierw uruchomienie dwóch kolejnych wyświetlaczy:
  1. Incr Displ : If Displ > 5 Then Displ = 1   'zamiast 3
  2.        Disp_port = 7segment_displ(displ)
I dlatego że nie ma -2 w tym wyrażeniu "7segment_displ(displ-2) to trzeba zapisać dane dla wyświetlaczy 3,4 i 5 a znaki stopnia zapisuj do 1 i 2