ds1820 temperature to 7 segment display

General discussion on mikroBasic.
Post Reply
Author
Message
mark7930
Posts: 16
Joined: 16 Nov 2007 12:39

ds1820 temperature to 7 segment display

#1 Post by mark7930 » 27 Dec 2007 12:43

Hi, I've a problem with one wire comunication and 7 seg display..
i have EasyPic4 + mkroicd
I must show temperature read from ds1820 into a four display 7 segment..
I have both one wire comunication routine both 7 seg multplexing routing..

i don't know how trasform data from ds1820 to 7 segment format data...

can't Nobody help me?

Zoka
Posts: 19
Joined: 21 Apr 2007 11:39
Location: Bosnia & Herzegovina

#2 Post by Zoka » 28 Dec 2007 10:42

Zoka

mark7930
Posts: 16
Joined: 16 Nov 2007 12:39

Why don't it Work?

#3 Post by mark7930 » 31 Dec 2007 19:29

I use this code but display show always 0000...
I'need to finish this very simple project...
help me please...
And why icd debugger say me :Debug Error: pc out of scope?

program display3

dim zz, c3,j, v as byte
dim por as byte[8]
dim i,temp,ww as word


const TEMP_RESOLUTION as byte = 9

sub function Mask(dim num as byte) as byte ' this function returns masks

select case num ' for common cathode 7-seg. display
case 0 result = $3F
case 1 result = $06
case 2 result = $5B
case 3 result = $4F
case 4 result = $66
case 5 result = $6D
case 6 result = $7D
case 7 result = $07
case 8 result = $7F
case 9 result = $6F
end select 'case end
end sub

sub procedure interrupt
PORTA = 0
PORTD = por[v]
PORTA = zz ' turn on appropriate 7seg. display
Inc(v)
zz = zz >> 1
if zz = 0 then
zz = 8 ' prepare mask for digit
end if
if v > 3 then
v = 0 ' turn on 1st, turn off 2nd 7seg.
end if
TMR0 = 0
INTCON = $20
end sub

main:

OPTION_REG = 0 ' Timer0 settings
j = 0
v = 0
zz = 8
TMR0 = 0
INTCON = $A0 ' Disable PEIE,INTE,RBIE,T0IE
TRISA = 0
TRISD = 0
PORTD = 0
TRISE = 0
PORTE = 0
PORTA = 0
i = 1234


while true

Ow_Reset(PORTE,2) ' Onewire reset signal
Ow_Write(PORTE,2,0xCC) ' Issue command SKIP_ROM
Ow_Write(PORTE,2,0x44) ' Issue command CONVERT_T
Delay_us(120)

Ow_Reset(PORTE,2)
Ow_Write(PORTE,2,0xCC) ' Issue command SKIP_ROM
Ow_Write(PORTE,2,0xBE) ' Issue command READ_SCRATCHPAD
Delay_ms(400)

c3 = OW_Read(PORTE,2) ' Get temperature LSB
temp = OW_Read(PORTE,2) ' Get temperature MSB
temp = temp << 8
temp = temp + c3

i=temp

j = i div 1000 ' prepare digits for diplays
por[0] = Mask(j)
j = i div 100 mod 10
por[1] = Mask(j)
j = i div 10 mod 10
por[2] = Mask(j)
j = i mod 10
por[3] = Mask(j)
'Delay_ms(1000)
'Inc(i) ' increment counter
'if i > 9999 then
'i = 0
'end if

wend
end.

xor
Posts: 5465
Joined: 18 May 2005 00:59
Location: NYC
Contact:

#4 Post by xor » 31 Dec 2007 20:24

Turn off the analogs.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

mark7930
Posts: 16
Joined: 16 Nov 2007 12:39

i don't know

#5 Post by mark7930 » 01 Jan 2008 21:43

I disabled anlogs inputs and something work .
But pic show a lot of number that are not temperature bytes...
I don't know what data pic displaying...
Here is source that a i use..

program display

dim zz, j,j1,j2, v as byte
dim i,n,temp as word
dim por as byte[4]
dim cc as boolean

sub function Mask(dim num as byte) as byte ' this function returns masks

select case num ' for common cathode 7-seg. display
case 0 result = $3F
case 1 result = $06
case 2 result = $5B
case 3 result = $4F
case 4 result = $66
case 5 result = $6D
case 6 result = $7D
case 7 result = $07
case 8 result = $7F
case 9 result = $6F
end select 'case end
end sub

sub procedure interrupt
PORTD = por[v] ' Send the appropriate mask to PORTB
PORTA = zz ' Turn on appropriate 7seg. display
Inc(v)
zz = zz << 1 ' Prepare for next digit
if zz > 8 then
zz = 1
end if
if v > 3 then
v = 0
end if
TMR0 = 0
' Reset timer
INTCON = $20
' Clear TMR0IF and set TMR0IE
end sub

main:
OPTION_REG = 0 '$80
adcon1 = 255
j = 0
v = 0
zz = 1
TMR0 = 0
INTCON = $A0 ' Disable PEIE,INTE,RBIE,T0IE
TRISA = 0
TRISD = 0
PORTD = 0
PORTA = 0

while true

ow_reset(PORTA, 5) ' onewire reset signal
ow_write(PORTA, 5, $CC) ' issue command to DS1820
ow_write(PORTA, 5, $44) ' issue command to DS1820
delay_us(120)
cc = ow_reset(PORTA, 5)
ow_write(PORTA, 5, $CC) ' issue command to DS1820
ow_write(PORTA, 5, $BE) ' issue command to DS1820

j1 = ow_read(PORTA, 5) ' get result
j2 = ow_read(PORTA, 5) ' get result (assuming the temperature is positive)

if j2 = $FF then
'tmp_sign = "-" ' temperature sign
j1= j1 or $FF ' complement of two
j1= j1 + $01
'else
'tmp_sign = "+"
end if
j2 = (j1 and $01) * 5 ' Get decimal value
j1 = j1 >> 1 ' Form the 2byte variable
i= (j1*10) + j2

delay_ms(500)
j = i div 1000 ' prepare digits for diplays
por[3] = Mask(j)
j = i div 100 mod 10
por[2] = Mask(j)
j = i div 10 mod 10
por[1] = Mask(j)
j = i mod 10
por[0] = Mask(j)

wend

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#6 Post by yo2lio » 01 Jan 2008 22:36

Hi,

You must disable interrupt when use 1-Wire function !!!
You must wait minimum 200 - 500 ms after send convert command $44.

Try this code :

Code: Select all

program display

dim zz, j,j1,j2, v as byte
dim i,n,temp as word
dim por as byte[4]
dim cc as boolean

sub function Mask(dim num as byte) as byte ' this function returns masks

select case num ' for common cathode 7-seg. display
  case 0 result = $3F
  case 1 result = $06
  case 2 result = $5B
  case 3 result = $4F
  case 4 result = $66
  case 5 result = $6D
  case 6 result = $7D
  case 7 result = $07
  case 8 result = $7F
  case 9 result = $6F
  end select 'case end
end sub

sub procedure interrupt
  INTCON.TMR0IF = 0 ' Clear TMR0IF
  PORTD = por[v] ' Send the appropriate mask to PORTB
  PORTA = zz ' Turn on appropriate 7seg. display
  Inc(v)
  zz = zz << 1 ' Prepare for next digit
  if zz > 8 then
    zz = 1
  end if
  if v > 3 then
    v = 0
  end if
  TMR0 = 0' Reset timer
end sub

main:
  OPTION_REG = 0 '$80
  adcon1 = 255
  j = 0
  v = 0
  zz = 1
  TMR0 = 0
  INTCON = $A0 ' Disable PEIE,INTE,RBIE,T0IE
  TRISA = 0
  TRISD = 0
  PORTD = 0
  PORTA = 0

while true
  INTCON.GIE = 0
  ow_reset(PORTA, 5) ' onewire reset signal
  ow_write(PORTA, 5, $CC) ' issue command to DS1820
  ow_write(PORTA, 5, $44) ' issue command to DS1820
  INTCON.GIE = 1
  delay_ms(500) 'wait for conversion complete
  INTCON.GIE = 0
  cc = ow_reset(PORTA, 5)
  ow_write(PORTA, 5, $CC) ' issue command to DS1820
  ow_write(PORTA, 5, $BE) ' issue command to DS1820
  j1 = ow_read(PORTA, 5) ' get result
  j2 = ow_read(PORTA, 5) ' get result (assuming the temperature is positive)
  INTCON.GIE = 1

  if j2 = $FF then
    'tmp_sign = "-" ' temperature sign
    j1= j1 or $FF ' complement of two
    j1= j1 + $01
  'else
    'tmp_sign = "+"
  end if
  j2 = (j1 and $01) * 5 ' Get decimal value
  j1 = j1 >> 1 ' Form the 2byte variable
  i= (j1*10) + j2

  delay_ms(500)
  j = i div 1000 ' prepare digits for diplays
  por[3] = Mask(j)
  j = i div 100 mod 10
  por[2] = Mask(j)
  j = i div 10 mod 10
  por[1] = Mask(j)
  j = i mod 10
  por[0] = Mask(j)

wend
end.
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

mark7930
Posts: 16
Joined: 16 Nov 2007 12:39

hey....

#7 Post by mark7930 » 01 Jan 2008 22:41

nobody say me that one wire comunication must be to used WITHOUT interrupt.

mark7930
Posts: 16
Joined: 16 Nov 2007 12:39

last trick

#8 Post by mark7930 » 02 Jan 2008 20:48

Your help it was fantastic: thank you so much...
But now i wan't to know the last thing:
Can I remove display blinking? If yes, what parameter i must adjust?
And, Why there is a shadow on every 7 segment display?
Torn off the light and look with attection all 4 displays (7 segment)...
IE : if display show 125, you can see , on 3th display the decimal number "5" ... back of number "1" you can note number"2",back of ...

Here there my code...

program display

dim zz, j,j1,j2,j3,js, v as byte
dim i as word
dim por as byte[4]
dim cc as boolean

sub function Mask(dim num as byte) as byte ' this function returns masks

select case num ' for common cathode 7-seg. display
case 0 result = $3F
case 1 result = $06
case 2 result = $5B
case 3 result = $4F
case 4 result = $66
case 5 result = $6D
case 6 result = $7D
case 7 result = $07
case 8 result = $7F
case 9 result = $6F
case $A result = $40
case $B result = 0
end select 'case end
end sub

sub procedure interrupt
INTCON.TMR0IF = 0 ' Clear TMR0IF
PORTD = por[v] ' Send the appropriate mask to PORTB
PORTA = zz ' Turn on appropriate 7seg. display
Inc(v)
zz = zz << 1 ' Prepare for next digit
if zz > 8 then
zz = 1
end if
if v > 3 then
v = 0
end if
TMR0 = 0' Reset timer
end sub

main:
OPTION_REG = 0 '$80
adcon1 = 255
j = 9999
v = 0
zz = 1
TMR0 = 0
INTCON = $A0 ' Disable PEIE,INTE,RBIE,T0IE
TRISA = 0
TRISD = 0
PORTD = 0
PORTA = 0

while true

INTCON.GIE = 0
ow_reset(PORTA, 5) ' onewire reset signal
ow_write(PORTA, 5, $CC) ' issue command to DS1820
ow_write(PORTA, 5, $44) ' issue command to DS1820
INTCON.GIE = 1
delay_ms(1000) 'wait for conversion complete
INTCON.GIE = 0
cc = ow_reset(PORTA, 5)
ow_write(PORTA, 5, $CC) ' issue command to DS1820
ow_write(PORTA, 5, $BE) ' issue command to DS1820
j1 = ow_read(PORTA, 5) ' get result
j2 = ow_read(PORTA, 5) ' get result (assuming the temperature is positive)


if j2 = $FF then
js = $a ' temperature sign
j3= 0 - j1 ' convert byte from negative to positive
i= (j3*10) div 2 'format temperature on right value
else
js = $b ' temperature sign
j2 = (j1 and $01) * 5 ' Get decimal value
j1 = j1 >> 1 ' Form the 2byte variable
i= (j1*10) + j2
end if

INTCON.GIE = 1

'delay_ms(500)

por[3] = Mask(js)
j = i div 100 mod 10
por[2] = Mask(j)
j = i div 10 mod 10
por[1] = Mask(j)
j = i mod 10
por[0] = Mask(j)

wend
end.

pomea
Posts: 11
Joined: 02 Dec 2013 18:54

Re: ds1820 temperature to 7 segment display

#9 Post by pomea » 15 Feb 2014 21:29

Hello Everybody,
I am almost new in program and I tried to use the given code on EasyPic4 with 16F877A 8MHz Xstal and a DS1820, however the given code doesn't work.
I have find a working code with LCD but no one with 7 seg. display. By merging 2 working codes I have created the below code with MicroC which is the translated version of Microbasic and its doesn't work .
This project should be an easy task but actually it make me crazy! perhaps the interrupt routine cause the mising reads of sensor value.
Is there someone able to help me?

/*
* Project name: Digital termometer on 4x 7seg. display
Onewire_Test (Interfacing the DS18x20 temperature sensor - all versions)

* Description:
After reset, PIC reads temperature from the sensor and shows on display
The display format of the temperature is 'xxx.xC'.
To obtain correct results, the 18x20's temperature resolution has to be adjusted
(constant TEMP_RESOLUTION)
* Test configuration:
MCU: PIC16F877A
Dev.Board: EasyPIC4 -
Oscillator: HS, 08.0000 MHz
Ext. Modules: DS18x20 connected to RE2 pin, 4x 7seg DSP
SW: mikroC v6.0.0
* NOTES:
- JP24 su N.C., SW2 PORTA/E OFF, Pull up and turning off diode on pin used for one wire bus may be required
(in this example PORTE)

Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
18S20: 9 (default setting; can be 9,10,11,or 12)
18B20: 12
*/
// prova modifica da LCD a 7seg . segna 00.0

const unsigned short TEMP_RESOLUTION = 9; // 9 x DS1820, DS18S20; 12 per DS18B20
unsigned temp;
unsigned short Tdigit0, Tdigit1, Tdigit2, Tdigit3; // 0 a DX
unsigned int digit, temp_whole, temp_fraction, temp_value;
unsigned short TempH, TempL ;
signed int tempinC;
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;

unsigned short shifter, portd_index;
unsigned short portd_array[4];

void interrupt() {
PORTA = 0; // Turn off all 7seg displays
PORTD = portd_array[portd_index]; // bring appropriate value to PORTD
PORTA = shifter; // turn on appropriate 7seg. display

// move shifter to next digit
shifter <<= 1;
if (shifter > 8u)
shifter = 1;

// increment portd_index
portd_index++ ;
if (portd_index > 3u)
portd_index = 0; // turn on 1st, turn off 2nd 7seg.
TMR0IF_bit = 0;
TMR0 = 236;
}
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0x3F; // 0
case 1 : return 0x06; // 1
case 2 : return 0x5B; // 2
case 3 : return 0x4F; // 3
case 4 : return 0x66; // 4
case 5 : return 0x6D; // 5
case 6 : return 0x7D; // 6
case 7 : return 0x07; // 7
case 8 : return 0x7F; // 8
case 9 : return 0x6F; // 9
case 10: return 0x40; // -
case 11: return 0x00; // blank
case 12: return 0x61; // c high position
case 13: return 0x80; // dp .
} //case end
}

void Display_Temperature()
{

//--- perform temperature reading
INTCON.GIE = 0; // need to stop interrupt
Ow_Reset(&PORTE,2); // Onewire reset signal
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0x44); // Issue command CONVERT_T
INTCON.GIE = 1; // need to start interrupt
Delay_ms(100);

INTCON.GIE = 0; // need to stop interrupt
Ow_Reset(&PORTE,2);
Ow_Write(&PORTE,2,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTE,2,0xBE); // Issue command READ_SCRATCHPAD

tempL = Ow_Read(&PORTE,2);
tempH = Ow_Read(&PORTE,2);
temp_value= (TempH << 8) + tempL; //

// check if temperature is negative
if (temp_value & 0x8000) //temp2write
{
Tdigit3 = 10; // menus sign
temp_value = ~temp_value + 1;
}
else
Tdigit3 = 11; // blank digit

// extract temp_whole
temp_whole = temp_value >> RES_SHIFT ;

if (temp_value & 0x0001) {
temp_fraction = 5;
}
else temp_fraction = 0;

tempinC =temp_whole *10+ temp_fraction;
// convert temp_whole to characters
//if (temp_whole/100)
Tdigit2 = (tempinC/100)%10;
Tdigit1 = (tempinC/10)%10;
Tdigit0 = tempinC%10;
//Tdigit2 = 3; //this work
//Tdigit1 = 2; //this work
//Tdigit0 = 5; //this work
// show temperature: 32.5
INTCON.GIE = 1;

portd_array[0] = mask(Tdigit0); // fraction
portd_array[1] = mask(Tdigit1)+ mask(13); //unit
portd_array[2] = mask(Tdigit2) ; // tens
portd_array[3] = mask(Tdigit3); // blank or -

}

void main()
{
ADCON1 = 0; // Set AN pins to Digital I/O;

TRISA = 0; // Configure PORTA as output
PORTA = 0; // Clear PORTA
TRISD = 0; // Configure PORTD as output
PORTD = 0; // Clear PORTD

OPTION_REG = 0x88; // 1usec
TMR0 = 236; // 1usec
INTCON = 0xA0;
digit = 0;
portd_index = 0;
shifter = 1;

GIE_bit = 1;
TMR0IE_bit = 1;


//--- main loop
while (1)
{
Display_Temperature();
}
}

Post Reply

Return to “mikroBasic General”