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:
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- 'If Multip = 0 Then
- Open "COMB.0:1200,8,N,1" For Output As #1
- 'Set Tx_pin
- 'DS18B20
- 'Buffer(1) = &HBB
- 'Buffer(2) = &HBB
- 'ADC
- 'Buffer(3) = &HF0
- 'Buffer(4) = &H00
- Adc_read = Getadc(battery_terminal) 'result in Buffer(1), Buffer(2)
- 'NODE
- Buffer(5) = Node_nr
- Buffer(17) = Node_nr
- 'CRC
- Buffer(18) = Crc8(buffer(1) , 5)
- '' Wrd1 and Wrd2 (four bytes)can be filled at the end so now can be as helpw
- Wrd_3 = Code(buffer(1)) 'ds
- Wrd_4 = Code(buffer(2)) 'ds
- Wrd_5 = Code(buffer(3)) 'adc
- Wrd_6 = Code(buffer(4)) 'adc
- Wrd_7 = Code(buffer(17)) 'id
- Wrd_8 = Code(buffer(18)) 'crc
- Buffer(1) = Tail
- Wrd_9 = Code(buffer(1))
- Buffer(1) = Tail
- Buffer(2) = Tail
- Buffer(3) = Tail
- Buffer(4) = Tail
- Printbin #1 , Buffer(1)
- Reset Tx_pin
- Set Divider_gnd
- 'End If
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:
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- $regfile = "m328pdef.dat"
- $crystal = 8000000
- $hwstack = 64
- $swstack = 32
- $framesize = 128
- $baud = 1200
- $timeout = 10000
- '****************************************************
- '*---- 3x 7SEGMENT MULTIPLEXED VERSION :D ------- *
- '****************************************************
- '* WIRELESS THERMOMETER *
- '* WITH CIRCULAR BUFFER *
- '* RECEIVER PART *
- '* niveasoft@tlen.pl *
- '* 2017-02-06 *
- '****************************************************
- '-DESCRIPTION-
- '
- ' Code receive incomming data in interrupt background mode.
- ' If special Tail byte is detected then this byte is the last in whole frame.
- ' Circular buffer size is calculated to hold only 14 bytes.
- ' So if Tail is detected then rest of buffer must be previous data.
- ' In this way preamble is rejected and you have only data bytes.
- ' These are coded im Manchester six bytes. First two contains data from DS18B20
- ' Second two bytes contains ADC value readed from node battery terminals.
- ' Fifth byte is a Node number so you can have more of them and recognize.
- ' Sixth byte is a CRC from provious five bytes.
- '7SEGMENT ERRATA
- '* DISPLAYING
- '
- ' For temperatures below -9,9 decimal figures are not shown so it will be displayed "-10"
- '
- '* SWITCH
- ' Switch added for change displayed data
- ' ->Temp Outside->Temp Inside->Transmitter Battery Voltage->
- ' After change info is displayed for about 1s "In","Out" and "Bat"
- ' If no valid data from >Inactivity time then three "---" signs popup in "Out" mode
- ' Schematic is attached with this code or can be found at bart-projects.cba.pl.
- '
- '* AUTOMATIC BRIGHTNESS CONTROL
- ' Displays are dimmed with COMPARE1B
- Const Maximum_inactivity = 240 '4min
- Config Submode = New
- Config 1wire = Portd.3
- Config Portb = Output
- Config Portd.7 = Input : Set Portd.7 : Switch Alias Pind.7
- 'Config Portc.0 = Input : Foto Alias 0 'for ADC
- Config Portc.3 = Output
- Config Portc.4 = Output
- Config Portc.5 = Output
- Config Portc.1 = Output
- Config Portc.2 = Output
- Dot Alias 6 : Disp_port Alias Portb
- Config Timer1 = Timer , Prescale = 256 , Compare_a = Disconnect , Compare_b = Disconnect , Clear_timer = 1
- Enable Compare1a : On Compare1a Mux_isr Nosave : Compare1a = 155 '5ms @8MHz/256 =200Mz
- Enable Compare1b : On Compare1b Dimm_isr Nosave : Compare1b = 150 'DIMMING
- '********************[ TIMEBASE ]********************
- Dim 5ms As Byte , 1000ms As Byte , Refresh As Byte
- Dim In_out As Byte , Show_timeout As Byte
- Dim Last_msg_time As Byte , Error As Byte , Errors As Byte
- '******************[ MULTIPURPOSE ]******************
- Dim N As Byte
- '**************[ DISPLAYS MULTIPLEXING ]*************
- Dim 7segment_displ(5) As Byte , In_temp(3) As Byte , Out_temp(3) As Byte <<<<<<<___________________ tu dodałem 5 na 5 wyświetlaczy
- '****************[ DIMMING DISPLAY ]*****************
- 'Config Adc = Single , Prescaler = Auto , Reference = Avcc
- 'Dim Adc_read As Word , Dimm As Word
- '***************[ SERIAL DATA RECEIVER ]*************
- Config Serialin0 = Buffered , Size = 20
- Const Buff_len = 14 : Dim Ring(buff_len) As Byte
- Dim Ring_cnt , Copy_cnt , Prev , Test As Byte
- Dim Rx_word As Word
- Dim Tail As Byte : Tail = &HAA
- '****************[ TEMPERATURE DATA ]****************
- Dim Bytes(9) As Byte : Dim Temperature As Integer At Bytes(1) Overlay
- '****************[ BATTERY MONITOR ]*****************
- Dim Voltage As Word , Volt(3) As Byte
- Function Decode_manchester(byval Tempw As Word ) As Byte
- Local Bit_number As Byte : Bit_number = 8
- Local Manchester As Word
- Local Temp_1 As Word
- Local Data_error As Byte : Data_error = 0
- Do
- Shift Manchester , Left , 1
- Decr Bit_number
- Temp_1 = Tempw And &B1100_0000_0000_0000
- If Temp_1 = &B0100_0000_0000_0000 Then Incr Manchester '01
- If Temp_1 = &B1100_0000_0000_0000 Or Temp_1 = 0 Then Data_error = 1 '11 or 00
- Shift Tempw , Left , 2
- Loop Until Bit_number = 0
- If Data_error = 0 Then
- Decode_manchester = Manchester
- Else
- Decode_manchester = 0
- End If
- End Function
- Sub Fill_volt()
- Local Helpw As Word
- Voltage = Makeint(bytes(3) , Bytes(4)) 'Word ADC value
- Shift Voltage , Right , 1
- Helpw = Voltage Mod 10
- Volt(3) = Lookup(helpw , Values)
- Voltage = Voltage / 10
- Helpw = Voltage Mod 10
- Volt(2) = Lookup(helpw , Values)
- Helpw = Voltage / 10
- Volt(1) = Lookup(helpw , Values)
- Volt(1).dot = 0
- End Sub
- Sub Fill_array(byval T As Integer , Byref Dest() As Byte)
- Local Helpi1 As Integer , Helpi2 As Integer
- T = T * 10 : T = T / 16
- If T >= 0 Then
- Helpi1 = T Mod 10
- Dest(3) = Lookup(helpi1 , Values)
- Helpi2 = T / 10
- Helpi1 = Helpi2 Mod 10
- Dest(2) = Lookup(helpi1 , Values)
- Dest(2).dot = 0
- Helpi1 = Helpi2 / 10
- If Helpi1 = 0 Then Helpi1 = 14
- Dest(1) = Lookup(helpi1 , Values)
- Else
- Dest(1) = Lookup(13 , Values) 'minus
- Helpi2 = Abs(t)
- If T >= -99 Then
- Helpi1 = Helpi2 Mod 10
- Dest(3) = Lookup(helpi1 , Values)
- Helpi1 = Helpi2 / 10
- Dest(2) = Lookup(helpi1 , Values)
- Dest(2).dot = 0
- Else 'if -10 and needed two digits then no result after comma
- Helpi1 = Helpi2 / 10
- Helpi2 = Helpi1 / 10
- Dest(2) = Lookup(helpi2 , Values)
- Helpi2 = Helpi1 Mod 10
- Dest(3) = Lookup(helpi2 , Values)
- End If
- End If
- End Sub
- Sub Clear_array(byref Dest() As Byte)
- For N = 1 To 3
- Dest(n) = Lookup(13 , Values)
- Next
- End Sub
- Call Clear_array(in_temp(1)) 'make three minus to indicate theres no data yet
- Call Clear_array(out_temp(1))
- Call Clear_array(volt(1))
- Enable Interrupts
- Refresh = 1
- Do
- If Ischarwaiting() > 0 Then
- 'move forward in circular buffer
- Incr Ring_cnt : If Ring_cnt > Buff_len Then Ring_cnt = 1
- If Ring_cnt = 1 Then Prev = Buff_len Else Prev = Ring_cnt - 1
- Inputbin Test
- Ring(ring_cnt) = Test 'write to buffer
- Rx_word = Makeint(ring(prev) , Ring(ring_cnt)) 'make word from two last bytes
- Test = Decode_manchester(rx_word) 'decode it from manchester into byte
- If Test = Tail Then 'test if this is our tail ;)
- Copy_cnt = Ring_cnt
- 'beacause Tail is the last frame byte so read back six bytes from buffer
- For N = 1 To 6
- Incr Copy_cnt : If Copy_cnt > Buff_len Then Copy_cnt = 1
- Incr Copy_cnt : If Copy_cnt > Buff_len Then Copy_cnt = 1
- If Copy_cnt = 1 Then Prev = Buff_len Else Prev = Copy_cnt - 1
- Rx_word = Makeint(ring(prev) , Ring(copy_cnt))
- Test = Decode_manchester(rx_word)
- Bytes(n) = Test
- Next
- 'data was displayed
- 'now validate it
- 'CRC from empty array is also 0 so check if atleast one byte is differ
- If Bytes(1) <> 0 Then
- If Crc8(bytes(1) , 5) = Bytes(6) Then
- Call Fill_array(temperature , Out_temp(1))
- Call Fill_volt()
- Last_msg_time = 0
- End If
- End If
- End If
- End If
- If 5ms = 1 Then
- 5ms = 0 : Incr 1000ms
- If 1000ms = 200 Then
- Refresh = 1
- Error = 0
- 1wreset
- If Err = 0 Then
- 1wwrite &HCC
- 1wwrite &HBE
- Bytes(1) = 1wread(9)
- If Bytes(8) = &H10 Then
- If Crc8(bytes(1) , 8) <> Bytes(9) Then Error = 1
- Else
- Error = 1
- End If
- Else
- Error = 1
- End If
- If Error = 0 Then
- Call Fill_array(temperature , In_temp(1))
- Errors = 0
- Else
- If Errors < 3 Then
- Incr Errors
- Else
- Call Clear_array(in_temp(1))
- End If
- End If
- 1wreset
- 1wwrite &HCC
- 1wwrite &H44
- '--[DIMMING]--
- 'Adc_read = Adc_read + Getadc(foto)
- 'Shift Adc_read , Right , 3
- ' Dimm = 200 - Adc_read
- 'If Dimm > 150 Then Dimm = 150
- 'Compare1b = Dimm
- '--[INACTIVITY OF SENSOR]--
- Incr Last_msg_time
- If Last_msg_time > Maximum_inactivity Then
- Last_msg_time = 0 : Call Clear_array(out_temp(1))
- End If
- End If
- End If
- If Refresh = 1 Then
- Refresh = 0 : 1000ms = 0
- If Show_timeout > 0 Then
- Decr Show_timeout
- Else
- Select Case In_out
- Case 0
- 7segment_displ(1) = Out_temp(1)
- 7segment_displ(2) = Out_temp(2)
- 7segment_displ(3) = Out_temp(3)
- 7segment_displ(4) = Out_temp(1) <<<<<<<<<<<<<<<<<<<<<<<<<<<-------------------------------- Tu na próbę, czy zapalą się kolejne dwa wyświetlacze
- 7segment_displ(5) = Out_temp(2) <<<<<<<<<<<<<<<<<<<<<<<<<<<---------------------------------||-||-
- Case 1
- 7segment_displ(1) = In_temp(1)
- 7segment_displ(2) = In_temp(2)
- 7segment_displ(3) = In_temp(3)
- Case 2
- 7segment_displ(1) = Volt(1)
- 7segment_displ(2) = Volt(2)
- 7segment_displ(3) = Volt(3)
- End Select
- ' **************[ DISPLAYS MULTIPLEXING ]*************
- End If
- End If
- Debounce Switch , 0 , Switch_sub , Sub
- Loop
- End
- Switch_sub:
- Incr In_out : If In_out > 2 Then In_out = 0
- Select Case In_out
- Case 0
- 7segment_displ(1) = Lookup(0 , Values)
- 7segment_displ(2) = Lookup(10 , Values) 'out
- 7segment_displ(3) = Lookup(11 , Values)
- Case 1
- 7segment_displ(1) = Lookup(1 , Values)
- 7segment_displ(2) = Lookup(12 , Values) 'in
- 7segment_displ(3) = Lookup(14 , Values)
- Case 2
- 7segment_displ(1) = Lookup(15 , Values)
- 7segment_displ(2) = Lookup(16 , Values) 'bat
- 7segment_displ(3) = Lookup(11 , Values)
- End Select
- Refresh = 1 : Show_timeout = 1
- Return
- 'G,DP,A,B,C,D,E,F
- Values:
- ' 0 1 2 3 4
- Data &B11000000 , &B11100111 , &B01001001 , &B01000011 , &B01100110
- ' 5 6 7 8 9
- Data &B01010010 , &B01010000 , &B11000111 , &B01000000 , &B01000010
- ' u 10 t 11 n 12 - 13 blank 14
- Data &B11110001 , &B01111000 , &B01110101 , &B01111111 , &B11111111
- ' b 15 A 16
- Data &B01110000 , &B01000100
- Mux_isr:
- $asm
- !PUSH R10
- !PUSH R16
- !PUSH R20
- !PUSH R22
- !PUSH R24
- !PUSH R25
- !PUSH R26
- !PUSH R27
- !PUSH R28
- !PUSH R31
- !in R24, sreg
- !PUSH R24
- $end Asm
- Incr Displ : If Displ > 5 Then Displ = 3
- Disp_port = 7segment_displ(displ - 2)
- Reset Portc.displ
- 5ms = 1
- ' Tuned with NoSave Tool
- $asm
- !POP R24
- !out sreg, R24
- !POP R31
- !POP R28
- !POP R27
- !POP R26
- !POP R25
- !POP R24
- !POP R22
- !POP R20
- !POP R16
- !POP R10
- $end Asm
- Return
- Dimm_isr:
- $asm
- !PUSH R24
- !in R24, sreg
- !PUSH R24
- $end Asm
- Portc = Portc Or &B00111110 <<<<<<<<<<<<<<<<<<<<<<<<<--------------------- Tu dodałem 2 bity dla dwu wyświetlaczy.
- ' Tuned with NoSave Tool
- $asm
- !POP R24
- !out sreg, r24
- !POP R24
- $end Asm
- Return