Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

oshonsoft , 3 ds18B20 problem & 18f4550

Status
Not open for further replies.

dim78

New Member
hello there,

i am newbie in the forum and i have register because i have a strange problem with my programm......

i have 3 ds18B20 & and a 18f4550 and when i read tempurature from the ds's i get the same tempurature and for the 3's... the tempurature i effective from the last ds18B20...the third....

here is my code....

please help....




Code:
'------------------------------------------------------------------------------------------

Define CLOCK_FREQUENCY = 20
AllDigital

Define LCD_LINES = 4
Define LCD_CHARS = 20
Define LCD_BITS = 4
Define LCD_DREG = PORTD
Define LCD_DBIT = 4
Define LCD_RSREG = PORTD
Define LCD_RSBIT = 2
Define LCD_EREG = PORTD
Define LCD_EBIT = 3
Define LCD_RWREG = 0
Define LCD_RWBIT = 0

'Lcdcmdout LcdClear
'Lcdcmdout LcdLine1Home


Dim temp1 As Word
Dim temp11 As Byte

Dim temp2 As Word
Dim temp21 As Byte

Dim temp3 As Word
Dim temp31 As Byte

Lcdinit




start:


s1:
temp1 = 0
temp11 = 0
Define 1WIRE_REG = PORTB
Define 1WIRE_BIT = 0

1wireInit
1wireSendByte 0xcc, 0x44
WaitMs 1
1wireInit
1wireSendByte 0xcc, 0xbe
1wireGetByte temp1.LB, temp1.HB

'---resolution 12bit => 0.0625 *C   1*C/0.0625=16

If temp1 < 2000 Then  '2000*0.0625=125*C
temp11 = temp1 / 16
temp1 = (temp1 - ((temp1 / 16) * 16)) / 10
PORTB.3 = 0
Else
temp1 = 65535 - temp1
temp11 = temp1 / 16
temp1 = temp1 - ((temp1 / 16) * 16)
PORTB.3 = 1
Endif

Lcdcmdout LcdClear
Lcdcmdout LcdLine1Home
Lcdout "test ds1820"
Lcdcmdout LcdLine2Home
Lcdout "t1: ", #temp11, ".", #temp1
WaitMs 2000


s2:
temp2 = 0
temp21 = 0
Define 1WIRE_REG = PORTB
Define 1WIRE_BIT = 1

1wireInit
1wireSendByte 0xcc, 0x44
WaitMs 1
1wireInit
1wireSendByte 0xcc, 0xbe
1wireGetByte temp2.LB, temp2.HB

'---resolution 12bit => 0.0625 *C   1*C/0.0625=16

If temp2 < 2000 Then  '2000*0.0625=125*C
temp21 = temp2 / 16
temp2 = (temp2 - ((temp2 / 16) * 16)) / 10
PORTB.3 = 0
Else
temp2 = 65535 - temp2
temp21 = temp2 / 16
temp2 = temp2 - ((temp2 / 16) * 16)
PORTB.3 = 1
Endif

Lcdcmdout LcdClear
Lcdcmdout LcdLine1Home
Lcdout "test ds1820"
Lcdcmdout LcdLine2Home
Lcdout "t2: ", #temp21, ".", #temp2
WaitMs 2000


s3:
temp3 = 0
temp31 = 0
Define 1WIRE_REG = PORTB
Define 1WIRE_BIT = 2

1wireInit
1wireSendByte 0xcc, 0x44
WaitMs 1
1wireInit
1wireSendByte 0xcc, 0xbe
1wireGetByte temp3.LB, temp3.HB

'---resolution 12bit => 0.0625 *C   1*C/0.0625=16

If temp3 < 2000 Then  '2000*0.0625=125*C
temp31 = temp3 / 16
temp3 = (temp3 - ((temp3 / 16) * 16)) / 10
PORTB.3 = 0
Else
temp3 = 65535 - temp3
temp31 = temp3 / 16
temp3 = temp3 - ((temp3 / 16) * 16)
PORTB.3 = 1
Endif

Lcdcmdout LcdClear
Lcdcmdout LcdLine1Home
Lcdout "test ds1820"
Lcdcmdout LcdLine2Home
Lcdout "t3: ", #temp31, ".", #temp3
WaitMs 2000

Goto start
 
'---------------------------------------------------------------------------------------------------
 
Last edited by a moderator:
I haven't checked, but I think you can only use the define command once, so the following ;

Define 1WIRE_REG = PORTB
Define 1WIRE_BIT = 2

is the one which the program will compile with. (which is the last define it will see and overides the previous 2 defines)

I will check when I have time but I suspect this is what's happening.

Regards,
Leftfield95.
 
Thank you leftfield95 for the reply....
and now????? what i can do???

the only way is to put the 3 ds's to 1 pin?? and read the factory code from each of them??

has any one an example code for that??
 
The following link provides some information: **broken link removed**

The simple answer; use a mux (multiplexer) to multiplex the onewire connection between devices (it does require a couple more pins though).

The not so simple (but perhaps more correct way) is to search for each available device address. The link above gives you information on that.
 
You can read each one but how you code it for this basic I have not done but In swordfish basic I have done this using the onewire library

Basely you scan the bus you'll find one after you find the first one you get the ID and then tell it to not take the line if you don't send it's ID
Then find the next one

This will help you better
SEARCH ROM [F0h]
When a system is initially powered up, the master must identify the ROM codes of all slave devices on the bus, which allows the master to determine the number of slaves and their device types. The master learns the ROM codes through a process of elimination that requires the master to perform a Search ROM cycle (i.e., Search ROM command followed by data exchange) as many times as necessary to identify all of the slave devices. If there is only one slave on the bus, the simpler Read ROM command (see below) can be used in place of the Search ROM process. For a detailed explanation of the Search ROM procedure, refer to the iButton® Book of Standards at www.maxim-ic.com/ibuttonbook. After every Search ROM cycle, the bus master must return to Step 1 (Initialization) in the transaction sequence.
 
thanks again folks, but i cant solve this problem.....

i have paste this code to compiler to find the 64bit code of each ds....(first code)..it give one code (hope is the correct!!!)

the second is to find the tempurature from the ds...(for 1 ds now to test the 0x55 command of recogize the correct ds...(2 code) but i read 0*C...

have any one try read with oshonsoft 2-3 ds in one wire successfully????


any ideas again??


1code:


Define CLOCK_FREQUENCY = 20
Define LCD_LINES = 4
Define LCD_CHARS = 16
Define LCD_BITS = 4
Define LCD_DREG = PORTD
Define LCD_DBIT = 4
Define LCD_RSREG = PORTD
Define LCD_RSBIT = 2
Define LCD_EREG = PORTD
Define LCD_EBIT = 3
Define LCD_RWREG = 0
Define LCD_RWBIT = 0


Define 1WIRE_REG = PORTB
Define 1WIRE_BIT = 0

'Declare variables to be used
Dim numb As Byte
Dim hexh As Byte
Dim hexl As Byte

AllDigital

Dim loop1 As Byte
Dim romcode(8) As Byte


Lcdinit

start:

1wireInit
'Command to read ROM contents
1wireSendByte 0x33
For loop1 = 0 To 7
1wireGetByte romcode(loop1)
Next loop1

'Now display device family code
Lcdout "FC= "
numb = romcode(0)
Call convert_to_hex(numb)
Lcdout "h CRC= "
numb = romcode(7)
Call convert_to_hex(numb)
Lcdout "h"
'Now display serial number on LCD line 2
Lcdcmdout LcdLine2Home
Lcdout "#="
For loop1 = 6 To 1 Step -1
numb = romcode(loop1)
Call convert_to_hex(numb)
Next loop1
Lcdout "h"
WaitMs 500
Lcdcmdout LcdClear
Goto start
End
'Convert HEX byte to 2 nibbles

Proc convert_to_hex(num1 As Byte)
hexh = num1 And 0xf0
hexh = ShiftRight(hexh, 4)
Call display_hex(hexh)
hexl = num1 And 0x0f
Call display_hex(hexl)
End Proc
'Convert HEX nibble to ASCII and display

Proc display_hex(numb As Byte)
If numb <= 9 Then
numb = numb + 30h
Else
numb = numb + 37h
Endif
Lcdout numb
End Proc


2 code:

Define CLOCK_FREQUENCY = 20
AllDigital

Define LCD_LINES = 4
Define LCD_CHARS = 20
Define LCD_BITS = 4
Define LCD_DREG = PORTD
Define LCD_DBIT = 4
Define LCD_RSREG = PORTD
Define LCD_RSBIT = 2
Define LCD_EREG = PORTD
Define LCD_EBIT = 3
Define LCD_RWREG = 0
Define LCD_RWBIT = 0

'Lcdcmdout LcdClear
'Lcdcmdout LcdLine1Home


Dim temp1 As Word
Dim temp11 As Byte

Dim temp2 As Word
Dim temp21 As Byte

Dim temp3 As Word
Dim temp31 As Byte

Lcdinit


start:


s1:
temp1 = 0
temp11 = 0
Define 1WIRE_REG = PORTB
Define 1WIRE_BIT = 0

1wireInit
'1wireSendByte 0xcc, 0x44
1wireSendByte 0x55, 0x28, 0x0e, 0x00, 0x00, 0x01, 0x68, 0xcd, 0x8e, 0x44
WaitMs 1
1wireInit
1wireSendByte 0x55, 0x28, 0x0e, 0x00, 0x00, 0x01, 0x68, 0xcd, 0x8e, 0xbe
'1wireSendByte 0xcc, 0xbe
1wireGetByte temp1.LB, temp1.HB

'---resolution 12bit => 0.0625 *C 1*C/0.0625=16

If temp1 < 2000 Then '2000*0.0625=125*C
temp11 = temp1 / 16
temp1 = (temp1 - ((temp1 / 16) * 16)) / 10
PORTB.3 = 0
Else
temp1 = 65535 - temp1
temp11 = temp1 / 16
temp1 = temp1 - ((temp1 / 16) * 16)
PORTB.3 = 1
Endif

Lcdcmdout LcdClear
Lcdcmdout LcdLine1Home
Lcdout "test ds1820"
Lcdcmdout LcdLine2Home
Lcdout "t1: ", #temp11, ".", #temp1
WaitMs 2000

Goto start
 
Here the code that finds more then one device
Code:
Public Function Access Search(pCommand As Byte, pOnSearch As TOnSearch = 0) As Byte
   Dim BitA, BitB As Bit           
   Dim BitIndex, LastDiscrepancy, Marker As Byte
   
   FAbort = false
   LastDiscrepancy = 0
   Result = 0
   Repeat
      BitIndex = 1
      Marker = 0
      
      // issue command...
      Reset
      WriteByte(pCommand)

      Repeat
         // read a bit and its complement...
         BitA = ReadBit 
         BitB = ReadBit
      
         // no device present...
         If (BitA = 1 And BitB = 1) Then
            Exit

         // conflict...
         ElseIf (BitA = 0) And (BitB = 0) Then
            If BitIndex = LastDiscrepancy Then
               SetIDBit(BitIndex,1)
               WriteBit(1)
             ElseIf BitIndex > LastDiscrepancy Then
                SetIDBit(BitIndex,0)
                Marker = BitIndex
                WriteBit(0)
             Else
                BitA = GetIDBit(BitIndex)
                If BitA = 0 Then
                   Marker = BitIndex
                EndIf   
               WriteBit(BitA)
             EndIf
         
         // no conflict...
         Else
            SetIDBit(BitIndex,BitA)
            WriteBit(BitA)
         EndIf

         Inc(BitIndex)
      Until BitIndex > 64
      
      // execute handler...
      FIgnore = false
      pOnSearch() 
      If Not FIgnore Then
         Inc(Result)
      EndIf   

      LastDiscrepancy = Marker  
   Until (LastDiscrepancy = 0) Or FAbort
End Function
{
 
thanks Burt i will try it but maybe tomorrow... to tired for today!!

good night from me.. (or good afternoon to far friends :) )
 
Hi dim78,

Your code2 looks OK for reading the individual device, but you are not waiting long enough for the temperature conversion to take place, you also missed this stage in your original code in post#1.

Either use Vladimir's method posted in his examples to wait or use a longer wait statement.

Vladimir's method.

Code:
Define CLOCK_FREQUENCY = 20
AllDigital

Define LCD_LINES = 4
Define LCD_CHARS = 20
Define LCD_BITS = 4
Define LCD_DREG = PORTD
Define LCD_DBIT = 4
Define LCD_RSREG = PORTD
Define LCD_RSBIT = 2
Define LCD_EREG = PORTD
Define LCD_EBIT = 3
Define LCD_RWREG = 0
Define LCD_RWBIT = 0

'Lcdcmdout LcdClear
'Lcdcmdout LcdLine1Home


Dim temp1 As Word
Dim temp11 As Byte

Dim temp2 As Word
Dim temp21 As Byte

Dim temp3 As Word
Dim temp31 As Byte

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim finish As Bit
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Lcdinit


start:


s1:
temp1 = 0
temp11 = 0
Define 1WIRE_REG = PORTB
Define 1WIRE_BIT = 0

1wireInit
'1wireSendByte 0xcc, 0x44
1wireSendByte 0x55, 0x28, 0x0e, 0x00, 0x00, 0x01, 0x68, 0xcd, 0x8e, 0x44
WaitMs 1
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
loop: 
      1wireGetBit finish 
      If finish = 0 Then Goto loop
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
1wireInit
1wireSendByte 0x55, 0x28, 0x0e, 0x00, 0x00, 0x01, 0x68, 0xcd, 0x8e, 0xbe
'1wireSendByte 0xcc, 0xbe
1wireGetByte temp1.LB, temp1.HB

'---resolution 12bit => 0.0625 *C 1*C/0.0625=16

If temp1 < 2000 Then '2000*0.0625=125*C
temp11 = temp1 / 16
temp1 = (temp1 - ((temp1 / 16) * 16)) / 10
PORTB.3 = 0
Else
temp1 = 65535 - temp1
temp11 = temp1 / 16
temp1 = temp1 - ((temp1 / 16) * 16)
PORTB.3 = 1
Endif

Lcdcmdout LcdClear
Lcdcmdout LcdLine1Home
Lcdout "test ds1820"
Lcdcmdout LcdLine2Home
Lcdout "t1: ", #temp11, ".", #temp1
WaitMs 2000

Goto start

Or replace 'WaitMs 1' with something like 'WaitMs 1000'.

Unfortunately I can't try the above code as all my gear is currently burried under a pile of junk.

Regards,
Leftfield95

P.S. How do you highlight parts of code in a different colour ?
 
hi again.... :(

-Burt i didnt make to compile your example...
-leftfield95 it does not work either with longer waitms statement , either with the loop...

- may the code 1 be wrong?? what is going on??? have the Oshonsoft basic bugs?????

(?????? - i didnt highlights nothing leftfield95 ?????)

if some try to read from 3 ds with oshonsoft successfully!!!! (or read from 3 different ports or by the 64 code method...)
i have made my first temp recorder with lm50 (analog exit sensor) and when i use 3 together the first one make some tricks so i went to ds18B20... other tricks now!!!
 
-leftfield95 it does not work either with longer waitms statement , either with the loop...

Does not work in what way ?
-Is the temperature wrong
-Does the DS chip not respond

Are you using parasitic power, how are you connecting things up ?
My advice would be to go back to basics, start with the simplest setup possible, then build on that step by step.

1. Use a single DS chip and don't address it by its ROM code, use SKIP ROM. Send a convert command, read it, display the raw data and then calculate the temperature and display on LCD.

2. When this works correctly, add some code below it so that it reads the temperature and then displays the ROM address code on the next line of the LCD.

3. When this works correctly, add some code below that so it reads the temperature of the DS using the ROM address code and displays the raw data and temperature on the 3rd line of the LCD.

When that all works and the lcd data all match up start removing the unwanted code.

I have an interest in this project as I will be doing something similar using 10 x DS18B20 on the same bus in the near future. But I can't find my PICKIT2 at the moment.

Regards,
Leftfield95
 
friend leftfield95..

i had read successfully with my first post code the tempurature from ds18B20 but from only one sensor....

the reason is that the compiler it recognize only the last define for the 1wire statement...

the tempurature was right and the ds18B20 responce but only for the last of the 3 ds that i want to use...it work the last ds of the code because the compiler support only one define????? (us you post me in your first reply)... the other 2 ds show the same temp of the last defined ds...

so the solution is 3 ds18B20 in the same pin of 18f4550 and use the method of the 64bit code of them to recognize what temp is from which ds18b20....

i find a code of reading the 64bit serial number of ds (6 reply ( the 3 from me )) hope that is a right code !

i have read the serial code each of 3 ds18B20....

this what i read:
-----------------------------------
ds18B20 codes


FC: / CRC: / serial:

1) 28 / 0E / 00000168CD8E

2) 28 / 91 / 0000017584A7

3) 28 / 3F / 0000016911FD

------------------------------------------

i try the second code in the same post (6 reply ( the 3 from me ))that was working (for skip serial number) with 1 ds now for testing the read of temp with the 64bit serial method(if i was able to read-recogize from the specificate ds18b20 i would add code for another 2 ds) but i cant read...lcd show 0.0 *C

i didnt put a wrong ds because i try and the 3 of them each one alone !!!

sorry for my english guys!! i hope u understand me...

if you could be more lucky of me... (i am a hobbist in programming as u guess!!!!)
 
Looking though this forum and the Yahoo Group, it seems this topic (mutiple ds18x20 on a bus) comes up quite a bit.
It would seem that most attempts fail and they use another solution.

Pommie's post on the subject provides lots of info and a working solution unfortunately its in ASM not Oshon Basic.

https://www.electro-tech-online.com/threads/one-wire-temperature-sensor-ds1820-to-pc-interface.87533/

Since timing can be a problem on the bus, you could try inserting a 10ms wait statement inbetween each onewirebus action.
 
I have some interest on this thread because I have a similar need in the short-term. I have some parts coming; but I would look at the information by Dwight on this link: How to read a one wire DS18B20 temperature sensor (or nine of them)

He explains how to read from each and get the ROMCODE / ID; which you already have. And then how to use that to read directly from each sensor. It looks like you already have the first one done correctly. And you may be very close to getting the second part done as well.

For one, I believe on 28 / 0E / 00000168CD8E ; the family code is correct (28), the CRC maybe ok (0E), but the ID (0000168CD8E) is probably tranposed. On all the examples the last bytes (not the first ones) are zeros. This I think can be corrected by changing:
Code:
For loop1 = 6 To 1 Step -1
  numb = romcode(loop1)
  Call convert_to_hex(numb)
Next loop1
to
Code:
For loop1 = 1 To 6 Step 1
  numb = romcode(loop1)
  Call convert_to_hex(numb)
Next loop1
on your code to read the ROM (or simply; 28 00000168CD8E 0E should be 28 8ECD68010000 0E)
 
MYSTERY SOLVED!!!!!!! HAHAHHAAAA!!!!!!!!!!!!!!!!!!!!!!

ops!!! Friend languer you are right!!!


the code that i have copy-paste is wrong in a row!!!!!

in my 3 post (6 reply) this row is that confuse me...

For loop1 = 6 To 1 Step -1

i use now this : For loop1 = 1 To 6 Step 1

code of my first ds that i send and get no reply.... 0x28, 0x0e, 0x00, 0x00, 0x01, 0x68, 0xcd, 0x8e

right code!! : 0x28, 0x8e, 0xcd, 0x68, 0x01, 0x00, 0x00, 0x0e

thanks every one how try to help !!!

we can make more together

Dimitris

Hellas (Greece)
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top