View previous topic :: View next topic |
Author |
Message |
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
need help with TC74 digital thermal sensor |
Posted: Fri Sep 01, 2006 12:33 pm |
|
|
I am using PIC 18F6722, TC74A0-5 and a CUI CEM1206 magnetic buzzer along with CCS C compiler and MPLAB IDE. I am trying to beep a buzzer whenever temperature goes above 40 F.
Here is my code:
-----------------------------------------------------------------------------------------------------------
#include <18F6722.h>
#device adc=10
#fuses INTRC, NOWDT
#include <stdio.h>
#include <stdlib.h>
#include <pic_micro.h>
//Pins already defined in pic_micro.h
//#define FP_SCL PIN_D6
//#define FP_SDA PIN_D5
//#define BUZZER PIN_C2
#use delay(clock=16000000) // Set clock to 16MHz
#use standard_io(D) //Port D has I2C master
#use i2c(master, scl=FP_SCL, sda=FP_SDA)
void buzzerbeep(void);
void main()
{
set_tris_c(0x00);
set_tris_d(0x00);
while(1)
{
int16 data;
int16 fahr;
i2c_start();
i2c_write(0x9A); //Need your suggestion for what address to use here
i2c_write(0x00); //Need your suggestion for what address to use here
//Send start again
i2c_start();
i2c_write(0x9B); //Need your suggestion for what address to use here
data = i2c_read(0);
i2c_stop();
//Convert data into Farenheit
fahr = (9 *data);
fahr = fahr/5;
fahr = fahr + 32;
if(fahr>40)
{
buzzerbeep();
}
}
}
void buzzerbeep(void)
{
output_high(BUZZER);
delay_us(209);
output_low(BUZZER);
delay_us(209);
}
I am using following sample code as a reference
http://www.ccsinfo.com/forum/viewtopic.php?t=24083&highlight=picdem2
The buzzer works fine when beepbuzzer() is called outside while loop. I toggled FP_SCL and FP_SDA signals and I can see the signals as expected in my oscilloscope.
I am inside a room where thermometer indicates 70F. What modifications do I need to make in my codes so that buzzer beeps when fahr>40F?
Thank you for your time. |
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
update |
Posted: Fri Sep 01, 2006 2:16 pm |
|
|
I changed
#use i2c(master, scl=FP_SCL, sda=FP_SDA)
to
#use i2c(master, scl=FP_SCL, sda=FP_SDA, FORCE_HW) //FORCE_HW=Use Hardware I2C functions
Yet, no results. No signals seen at FP_SCL and FP_SDA pins. |
|
|
Ttelmah Guest
|
|
Posted: Fri Sep 01, 2006 2:27 pm |
|
|
You have got the pull up resistors on the lines?.
I2C, is an 'open collector' bus drive, and requires the lines to be pulled up with resistors to work. Toggling the lines, will drive them both ways.
Best Wishes |
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
update |
Posted: Fri Sep 01, 2006 2:40 pm |
|
|
Unlike PICDEM 2 PLUS DEMO BOARD, I do not have pull-up resistors connected to PIN_D5 and PIN_D6 (FP_SDA and FP_SCL signal respectively)
Is this the source of my problem? |
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
|
Posted: Fri Sep 01, 2006 2:46 pm |
|
|
Ttelmah,
Thank you very much.
Now, I see where the problem is. |
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
data conversion/comparision problem |
Posted: Fri Sep 08, 2006 8:23 am |
|
|
I added pull-up resistors to SCL and SDA signals and I am using hardware I2C module to read temperature from TC74. I believe my code is working as I can see SCL and SDA signals in my oscilloscope (I may be wrong)
TC74 datasheet says that Temperature is read in 8 bits binary format.
http://ww1.microchip.com/downloads/en/devicedoc/21462c.pdf#search=%22microchip%20tc74%22
Here is my code:
#include <18F6722.h>
#device adc=10
#fuses INTRC, NOWDT, NOPROTECT, NOLVP
#include <stdio.h>
#include <stdlib.h>
#include <pic_micro.h>
#use delay(clock=16000000) // Set clock to 16MHz
#use standard_io(D) //Port D has I2C master
//Already defined in "pic_micro.h"
//#define BUZZER PIN_C2
//#define FP_SCL PIN_D6
//#define FP_SDA PIN_D5
#use I2C(master, SCL=FP_SCL, SDA=FP_SDA)
void buzzerbeep(void);
void main()
{
set_tris_c(0x00); //Buzzer output port
while(1)
{
int ack=0;
int8 data=0;
i2c_start();
ack=i2c_write(0x9A);
ack=i2c_write(0x00);
i2c_start();
ack=i2c_write(0x9B);
data = i2c_read(0); //data is
i2c_stop();
if(data>60) // I want buzzer to beep when temperature > 60 degree Celsius
{
buzzerbeep();
}
}
}
void buzzerbeep(void)
{
output_high(BUZZER);
delay_us(209);
output_low(BUZZER);
delay_us(209);
}
My buzzer beeps for almost all values (i.e. from data>0 to data>100)
How can I make buzzer beep only when data>60 degree celsius?
What is wrong with my data conversion/comparision? |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Sep 08, 2006 9:09 am |
|
|
Try declaring the variable outside the while loop. It looks like you are resetting the values each pass of the while loop in which case you are sounding the buzzer but it is so short you cannot hear it. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
|
Posted: Sun Sep 10, 2006 2:56 pm |
|
|
Asmallri, thank you for your help.
The problem I have now is that my Temp. Sensor reads -1 Celsius when room temperature is 75 F (23.8 Celsius). i.e. the buzzer beeps when (temp==-1) when I use the following code.
#include <18F6722.h>
#device adc=10
#fuses INTRC, NOWDT, NOPROTECT, NOLVP /
#include <stdio.h>
#include <stdlib.h>
#include <pic_micro.h>
#use delay(clock=4000000) // Set clock to 4MHz
#use standard_io(D) //Port D has I2C master
//Already defined in "pic_micro.h"
//#define BUZZER PIN_C2
//#define FP_SCL PIN_D6
//#define FP_SDA PIN_D5
#use I2C(master, SCL=FP_SCL, SDA=FP_SDA)
void buzzerbeep(void);
void main()
{
int1 ack=0;
int8 data=0;
signed int temp=0;
set_tris_c(0x00); //Buzzer output Port C
while(1)
{
i2c_start();
ack=i2c_write(0x9A); // Device address
ack=i2c_write(0x00); // Data address
i2c_stop();
//Send start again
i2c_start();
ack=i2c_write(0x9B); //Device address + 1 = [read]
data = i2c_read(0); //data is read in Celsius
i2c_stop();
if(data==0b01111111) //Is this a good way to convert 8 bits data into temperature integer
temp=127;
else if(data==0b01111110)
temp=126;
else if(data==0b00011001)
temp=25;
else if(data==0b00000000)
temp=0;
else if(data==0b11111111)
temp=-1;
else if(data==0b11100111)
temp=-25;
else if(data==0b11100110)
temp=-26;
else if(data==0b11001001)
temp=-55;
else if(data==0b10111111)
temp=-65;
if(temp==-1) // Buzzer,of course, also beeps for (temp<126) and (temp>-65)
{
buzzerbeep();
buzzerbeep();
}
}
}
void buzzerbeep(void)
{
output_high(BUZZER);
delay_us(209);
output_low(BUZZER);
delay_us(209);
}
What is that I am doing wrong? If the room temperature inside my office is 75F (23.8 Celsius), why does my buzzer beep at -1 Celsius.
I tried using two different Temp. Sensor ICs in my board. But it gave me same results both times. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 10, 2006 4:09 pm |
|
|
Quote: | while(1)
{
i2c_start();
ack=i2c_write(0x9A); // Device address
ack=i2c_write(0x00); // Data address
i2c_stop();
//Send start again
i2c_start();
ack=i2c_write(0x9B); //Device address + 1 = [read]
data = i2c_read(0); //data is read in Celsius
i2c_stop(); |
You've modified the sample program that was posted in the Code Library.
You have added an i2c_stop() statement in a location where there
shouldn't be one. You can't just arbitrarily modify a low-level driver.
It won't work.
I've take the sample posted in the Code Library and turned into a
function instead of inline code. Then I've written a demo program
that calls the function. I tested this program on a PicDem2-Plus board
which has a TC74 chip on it. It works.
It displays this output on a terminal window:
Quote: |
Temperature (C) = 22
Temperature (C) = 22
Temperature (C) = 22
Temperature (C) = 23
Temperature (C) = 22
Temperature (C) = 22
|
That's the correct temperature for my office today.
Note:
I've deleted the code in this post because it only worked with positive
temperature values. See the corrected code, posted a little bit further
below in this thread. It works with both positive and negative
temperature values.
Last edited by PCM programmer on Fri Oct 20, 2006 1:04 pm; edited 1 time in total |
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
|
Posted: Mon Sep 11, 2006 8:55 am |
|
|
PCM Programmer, thank you for your help.
No, I do not have RS232 support to send/display Temperature data to any Display unit or LCD like in PIC DEM2 PLUS board.
I am using TC74 SOT-23 which is different than TC74 TO-220 (in shape and pin labels). I am using a custom design PCB board which has a PIC 18F6722, TC74, and a CUI 1206S Magnetic Buzzer. I want my buzzer to read the room temperature and beep the buzzer when temperature exceeds 30 Centigrade.
I tried your code with slight modifications in main() program. The buzzer beeps for (temp==-1) and for all values (temp>-1).
#include <18F6722.h>
#device adc=10
#fuses INTRC, NOWDT, NOPROTECT, NOLVP
#include <stdio.h>
#include <stdlib.h>
#include <pic_micro.h>
#use delay(clock=4000000) // Set clock to 4MHz
//Already defined in "pic_micro.h"
//#define BUZZER PIN_C2
//#define FP_SCL PIN_D6
//#define FP_SDA PIN_D5
#use I2C(master, SCL=FP_SCL, SDA=FP_SDA)
#define TC74_I2C_WRITE_ADDRESS 0x9A
#define TC74_I2C_READ_ADDRESS 0x9B
#define TC74_READ_TEMP_COMMAND 0x00
#define TC74_READ_CONFIG_COMMAND 0x01
void buzzerbeep(void);
int8 TC74_read_temperature(void);
//====================================
void main()
{
int8 temp;
set_tris_c(0x00); //Buzzer output Port C
while(1)
{
temp = TC74_read_temperature();
if(temp==-1)
{
buzzerbeep(); //Buzzer beeps for (temp==-1) and (temp>-1)
buzzerbeep();
buzzerbeep();
}
}
}
//====================================
// Read the temperature (in degrees Centigrade)
// from the TC74.
int8 TC74_read_temperature(void)
{
int8 retval;
i2c_start();
i2c_write(TC74_I2C_WRITE_ADDRESS);
i2c_write(TC74_READ_TEMP_COMMAND);
i2c_start(); // Re-start
i2c_write(TC74_I2C_READ_ADDRESS);
retval = i2c_read(0);
i2c_stop();
return(retval);
}
void buzzerbeep(void)
{
output_high(BUZZER);
delay_us(209);
output_low(BUZZER);
delay_us(209);
}
Isn't my Temp Sensor still reading the room temperature as -1 Centigrade? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 11, 2006 10:24 am |
|
|
In all your previous programs you were testing against a positive
number such as 60, so I had that in mind when I made that program.
However, it's for the best, because you've shown up a bug in the
driver that I posted. All of the variables should have been 'signed int8'
instead of 'int8'. Also, in the printf() statement, "%d" should have been
used instead of "%u". So here's the revised test program with all
those corrections added.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(master, sda=PIN_C4, scl=PIN_C3)
#define TC74_I2C_WRITE_ADDRESS 0x9A
#define TC74_I2C_READ_ADDRESS 0x9B
#define TC74_READ_TEMP_COMMAND 0x00
#define TC74_READ_CONFIG_COMMAND 0x01
signed int8 TC74_read_temperature(void);
//====================================
void main()
{
signed int8 temp;
while(1)
{
temp = TC74_read_temperature();
printf("Temperature (C) = %d\n\r", temp);
delay_ms(1000);
}
}
//====================================
// Read the temperature (in degrees Centigrade)
// from the TC74.
signed int8 TC74_read_temperature(void)
{
signed int8 retval;
i2c_start();
i2c_write(TC74_I2C_WRITE_ADDRESS);
i2c_write(TC74_READ_TEMP_COMMAND);
i2c_start(); // Re-start
i2c_write(TC74_I2C_READ_ADDRESS);
retval = i2c_read(0);
i2c_stop();
return(retval);
} |
Note that all the int8 variables have been changed to signed int8.
I got out a can of freeze spray and tested the program.
Here is the output:
Quote: |
Temperature (C) = 14
Temperature (C) = 15
Temperature (C) = 16
Temperature (C) = 15
Temperature (C) = 15
Temperature (C) = 8
Temperature (C) = -2
Temperature (C) = -5
Temperature (C) = -7
Temperature (C) = -21
Temperature (C) = -26
Temperature (C) = -28
Temperature (C) = -28 |
|
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
|
Posted: Mon Sep 11, 2006 11:50 am |
|
|
I changed the data type from 'int8' to 'signed int8'
My buzzer still beeps at (temp==-1) but it doesnot beep at (temp>0) as it did with temp datatype as 'int8'.
void main()
{
signed int8 temp;
set_tris_c(0x00); //Buzzer output Port C
while(1)
{
temp = TC74_read_temperature();
if(temp==-1) //Buzzer beeps
{
buzzerbeep();
buzzerbeep();
buzzerbeep();
}
}
}
Am I doing something wrong with 'temp' data conversion/comparision?
I understand that PCM programmer is sending data through RS232 to display in LCD or computer monitor. All I am trying to to do is read the temperature, compare it to some standard value and trigger buzzer when it exceeds that standard value.
I compared my schematics with PIC DEMO2 PLUS schematics and I found no differences except my pull-up resistors in I2C bus are 10k instead of 4.7k and PIC microcontroller that I am using is 18F6722 instead of 18F458
And I am using TC74 SOT-23-5 instead of TO-220. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 11, 2006 12:08 pm |
|
|
The fahrenheit conversion code needs to be fixed. The 'fahr' variable
needs to be signed 16-bit because it holds an intermediate result that's
larger than 8 bits. I tested this code and it works. The buzzer doesn't
really beep. It just clicks. That's on a PicDem2-Plus board.
Code: | void main()
{
signed int8 temp;
signed int16 fahr;
while(1)
{
temp = TC74_read_temperature();
printf("Temperature (C) = %d\n\r", temp);
//Convert data into Fahrenheit.
fahr = 9 * (signed int16)temp;
fahr = fahr / 5;
fahr = fahr + 32;
printf("Temperature (F) = %ld\n\r", fahr);
printf("\n\r");
if(fahr > 40)
{
buzzerbeep();
}
delay_ms(1000);
}
} |
|
|
|
jspencer
Joined: 22 Dec 2003 Posts: 57 Location: Boise, ID USA
|
|
Posted: Mon Sep 11, 2006 1:11 pm |
|
|
pdswar wrote: | My buzzer still beeps at (temp==-1) but it doesnot beep at (temp>0) as it did with temp datatype as 'int8'.
Code: |
void main()
{
signed int8 temp;
set_tris_c(0x00); //Buzzer output Port C
while(1)
{
temp = TC74_read_temperature();
if(temp==-1) //Buzzer beeps WHERE ARE YOU CHECKING FOR temp > 0???
{
buzzerbeep();
buzzerbeep();
buzzerbeep();
}
}
}
|
|
I don't see where you are checking for temp > 0??? Only if temp == -1. |
|
|
pdswar
Joined: 18 Jul 2006 Posts: 33 Location: Maryland, USA
|
|
Posted: Mon Sep 11, 2006 2:00 pm |
|
|
jspencer,
Sorry about the confusion. What I meant was that if I replace
if(temp==-1) statement with if(temp>0) the buzzer still beeps.
That problem has been fixed with PCM Programmer's code. i.e. by using "signed int8" instead of "int8"
I am sure PCM Programmer's code is right. I am checking my schematics again. Now, I think it could be a hardware problem. In my PCB, I was missing SDA signal. I also didnot have pull-up resistors placed for my I2C bus in my original PCB. I am connecting SDA signal with external wire and pull-up resistors externally which could be a source of problem. I had SCL signal routed inside the board. Now I am connecting pull-up resistors to SCL signal and again connecting to TC74. Now there are two paths for SCL signal to reach TC 74.
Thank you all for your help. |
|
|
|