Autor Tema: ds18b20  (Leído 2320 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado danifiguerola

  • PIC10
  • *
  • Mensajes: 24
ds18b20
« en: 15 de Abril de 2015, 11:19:19 »
Hola a todos.

Tengo una duda. Estoy utilizando un pic24fj64gb002 con el sensor de temperatura ds18b20.

He realizado un código para leer la temperatura pero no me funciona. Al revisarlo he visto que no consigo realizar el reset de inicialización del dispositivo.

He configurado el pin RB7 como open drain (con la resistencia pull-up interna desactivada), conectando una resistencia de 4,7k, pero no hay manera de poner a "0" la salida. Cuando la línea está "libre" al 5V pero cuando la pongo a "0" sólo logro bajarla a 4,23V.

He quitado el sensor y si que se pone a "0" pero con el sensor no. He pensado que el sensor está dañado (aún que es recién comprado), por lo que he probado con otro (también nuevo) y me sucede lo mismo.

Que creen que puede ser? Los dos estarán dañados (aún siendo recién comprados)?

main.c
Código: [Seleccionar]
#include <p24FJ64GB002.h>

#define FCY 4000000UL
#include <libpic30.h>
#include "1wire_protocol.c"

_CONFIG1 (JTAGEN_OFF);                                  //Modulo JTAG deshabilitado (RB5-RB9 i/o digitales)
_CONFIG2 (POSCMOD_NONE & OSCIOFNC_ON & FNOSC_FRC);      //Oscil·lador primari desactivat, RA3 i/o digital, Oscil·lador FRC seleccionat,
_CONFIG3 (SOSCSEL_IO);                                  //RA4 i RB4 i/0 digitales

void main() {

    unsigned char temp_H, temp_L;
    int temp;
    float temperatura;

    AD1PCFG = 0xffff;   //Tots els ports digitals
    ODCB = 0x0000;      //Tots pins port B
    OW_OPEN_DRAIN = 1;   //Pin RB10 (dades ds18b20) en open drain
    _CN23PUE = 0;       //Pull-up inten desactivat

    _TRISB2 = 0;
    _TRISB3 = 0;
    _TRISB4 = 0;

    OW_PIN_DIRECTION = 0; // Output

   
    /*while(1){
    OW_WRITE_PIN = 1;
    __delay_ms(1000);
    OW_WRITE_PIN = 0;
    __delay_ms(1000);
    }*/

    while (1)
    {
        while (OW_reset_pulse()==1);    //Realitzar reset i esperar pols presència ds18b20
               
        OW_write_byte (0xCC);       //Saltar orde ROM
   
        OW_write_byte (0x44);       //Indicar a ds18b20 que realitzi conversió temperatura
   
        while (read_OW()==0);   //Esperar que ds18b20 acabi conversió temperatura
   
        while (OW_reset_pulse()==1);    //Realitzar reset i esperar pols presència ds18b20
       
        OW_write_byte (0xCC);       //Saltar orde ROM
       
        OW_write_byte (0xBE);       //Llegir dades de ds18b20
       
        temp_L = OW_read_byte();    //Registre baix de temperatura
        temp_H = OW_read_byte();    //Registre alt de temperatura
       
        while (OW_reset_pulse()==1); //Reset per aturar la lectura
       
        temp = temp_H << 8;
        temp = temp | temp_L;

        if (temp & 0x80)        // Temperatura negativa
        {
            temp = ~temp + 1;
            temperatura = (((float) temp)/16)* (-1);
        }
        else
            temperatura = ((float) temp)/16;

       
        if (temperatura > 20)
        {
            _LATB2 = 0;
            _LATB3 = 1;
        }
        else
        {
            _LATB2 = 1;
            _LATB3 = 0;
        }

    }
}

1wire_protocol.c

Código: [Seleccionar]
////////////////////////////////////////////////////////////////////////////////
//                 1-WIRE COMMUNICATION PROTOCOL                              //
// 1wire.c                                                                    //
////////////////////////////////////////////////////////////////////////////////


//============================== Includes ====================================//
#include "config.h"
#include "1wire.h"
#include <p24FJ64GB002.h>
#define FCY 4000000UL
#include <libpic30.h>

//============================= Variables ====================================//

//unsigned char macro_delay;


//----------------------------------------------------------------------------//
// Function:        void drive_OW_low (void)
// PreCondition:    None
// Input:           None
// Output:          None
// Overview:        Configure the OW_PIN as Output and drive the OW_PIN LOW.
//----------------------------------------------------------------------------//
void drive_OW_low (void)
{
        OW_PIN_DIRECTION = OUTPUT;
        OW_WRITE_PIN=LOW;
}

//----------------------------------------------------------------------------//
// Function:        void drive_OW_high (void)
// PreCondition:    None
// Input:            None
// Output:           None
// Overview:         Configure the OW_PIN as Output and drive the OW_PIN HIGH.
//----------------------------------------------------------------------------//

void drive_OW_high (void)
{
        OW_PIN_DIRECTION = OUTPUT;
        OW_WRITE_PIN = HIGH;       
}

//----------------------------------------------------------------------------//
// Function:        unsigned char read_OW (void)
// PreCondition:    None
// Input:           None
// Output:          Return the status of OW pin.
// Overview:        Configure as Input pin and Read the status of OW_PIN
//----------------------------------------------------------------------------//
unsigned char read_OW (void)
{
        unsigned char read_data=0;
       
        OW_WRITE_PIN = INPUT;

         if (HIGH == OW_READ_PIN)
                 read_data = SET;
         else         
                read_data = CLEAR;
               
        return read_data;
}

//----------------------------------------------------------------------------//
// Function:        unsigned char OW_reset_pulse(void)
// PreCondition:    None
// Input:           None
// Output:          Return the Presense Pulse from the slave.
// Overview:        Initialization sequence start with reset pulse.
//                 This code generates reset sequence as per the protocol
//----------------------------------------------------------------------------//
unsigned char OW_reset_pulse(void)

{
        unsigned char presence_detect;
       
        drive_OW_low();                          // Drive the bus low
        __delay_ms(10000);                           // delay 480 microsecond (us)



        drive_OW_high ();                        // Release the bus
        __delay_us(70);                            // delay 70 microsecond (us)

       
        presence_detect = read_OW();            //Sample for presence pulse from slave
        __delay_us(410);                            // delay 410 microsecond (us)


       
        drive_OW_high ();                       // Release the bus
       
        return presence_detect;
}       

//----------------------------------------------------------------------------//
// Function:       void OW_write_bit (unsigned char write_data)
// PreCondition:    None
// Input:          Write a bit to 1-wire slave device.
// Output:          None
// Overview:        This function used to transmit a single bit to slave device.
//
//----------------------------------------------------------------------------//

void OW_write_bit (unsigned char write_bit)
{
        if (write_bit)
        {
                //writing a bit '1'
                drive_OW_low();
                __delay_us(6);                               // Drive the bus low
                                                       // delay 6 microsecond (us)
               
                drive_OW_high ();
                __delay_us(64);                              // Release the bus
                                                      // delay 64 microsecond (us)
        }
        else
        {
                //writing a bit '0'
                drive_OW_low();                            // Drive the bus low
                __delay_us(60);
                                                       // delay 60 microsecond (us)
                drive_OW_high ();                       // Release the bus
                __delay_us(10);
                                                       // delay 10 microsecond for recovery (us)
        }
}       

//----------------------------------------------------------------------------//
// Function:        unsigned char OW_read_bit (void)
// PreCondition:    None
// Input:           None
// Output:          Return the status of the OW PIN
// Overview:        This function used to read a single bit from the slave device.
//
//----------------------------------------------------------------------------//

unsigned char OW_read_bit (void)
{
        unsigned char read_data;                       //reading a bit
        drive_OW_low();                               // Drive the bus low
        __delay_us(6);
                                 // delay 6 microsecond (us)
       
        drive_OW_high ();                             // Release the bus
        __delay_us(9);                                    // delay 9 microsecond (us)


        read_data = read_OW();                        //Read the status of OW_PIN
        __delay_us(55);                                  // delay 55 microsecond (us)

return read_data;
}

//----------------------------------------------------------------------------//
// Function:        void OW_write_byte (unsigned char write_data)
// PreCondition:    None
// Input:           Send byte to 1-wire slave device
// Output:          None
// Overview:        This function used to transmit a complete byte to slave device.
//
//----------------------------------------------------------------------------//
void OW_write_byte (unsigned char write_data)
{
        unsigned char i;
       
        for (i = 0; i < 8; i++)
        {
                OW_write_bit(write_data & 0x01);         //Sending LS-bit first
                write_data >>= 1;                        // shift the data byte for the next bit to send
        }       
}       

//----------------------------------------------------------------------------//
// Function:        unsigned char OW_read_byte (void)
// PreCondition:    None
// Input:           None
// Output:          Return the read byte from slave device
// Overview:        This function used to read a complete byte from the slave device.
//
//----------------------------------------------------------------------------//

unsigned char OW_read_byte (void)
{
        unsigned char i, result=0;
       
        for (i = 0; i < 8; i++)
        {
               
                result >>= 1;              // shift the result to get it ready for the next bit to receive
                if (OW_read_bit())
                result |= 0x80;            // if result is one, then set MS-bit
        }
        return result;                                       
}       

//======================== End of 1-Wire.c ===================================//

1wire.h

Código: [Seleccionar]
////////////////////////////////////////////////////////////////////////////////
// 1wire.h                                                                    //
////////////////////////////////////////////////////////////////////////////////

#ifndef _1wire_H
#define _1wire_H

//==============================  Includes  ==================================//
//#include <p18f4580.h>

//============================= Prototypes ===================================//

void drive_OW_low (void);
void drive_OW_high (void);
unsigned char read__OW (void);
void OW_write_bit (unsigned char write_data);
unsigned char OW_read_bit (void);
unsigned char OW_reset_pulse(void);
void OW_write_byte (unsigned char write_data);
unsigned char OW_read_byte (void);

#endif

//=============================  End of 1wire.h  =============================//

config.h

Código: [Seleccionar]
////////////////////////////////////////////////////////////////////////////////
// Config.h                                                                    //
////////////////////////////////////////////////////////////////////////////////
#include <p24FJ64GB002.h>

#ifndef _Config_H
#define _Config_H

//========================= Generic Definitions ==============================//

#define        HIGH        1
#define        LOW         0
#define        OUTPUT      0
#define        INPUT       1
#define        SET         1
#define        CLEAR       0

//======================== 1-Wire Port Pin Definition ========================//
// This Configuration is required to make any PIC MicroController
// I/O pin as Open drain to drive 1-wire.
//============================================================================//

#define OW_OPEN_DRAIN            _ODB7
#define OW_PIN_DIRECTION         _TRISB7
#define OW_WRITE_PIN             _LATB7    //fOR pic 24F LATB.RB7
#define OW_READ_PIN              _RB7


#endif

//============================= End of Config.h  =============================//

Muchs gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ds18b20
« Respuesta #1 en: 15 de Abril de 2015, 22:16:07 »
Lo que me parece raro es que no llegue a 0V como bien decis.

El DS18B20 tiene tambien una entrada Open Colector, asi que no deberia molestarte para nada el tenerlo o no, ya que este solo puede pullear la entrada/salida a 0V.

El reset parece estar bien, solo que le cambiaste un delay por uno de 10s creo, pero seguro que fue para debuggearlo, lo unico que se me ocurre es que no estes configurando bien el pic.


Es correcto poner _LATB7 y no LATBbits.LATB7 ?
Eso es la unica duda que tengo ya que siempre me maneje de la ultima forma, asi tambien para los demas.

EDIT:

#define OW_OPEN_DRAIN            _ODB7
#define OW_OPEN_DRAIN            _ODCB7

Parece que te falto una letra
« Última modificación: 15 de Abril de 2015, 22:23:03 por KILLERJC »

Desconectado danifiguerola

  • PIC10
  • *
  • Mensajes: 24
Re: ds18b20
« Respuesta #2 en: 16 de Abril de 2015, 03:56:59 »
Hola KILLERJC

Primero gracias por la respuesta  :).

El tema del _LATB7 en principio está bien, se puede poner así o como tu indicas. Igualmente lo he cambiado por lo que me indicabas y tampoco he conseguido ponerlo a 0V

Por lo del _ODB7, creo que ya está bien así. El compilador no me reconoce _ODCB7. Estoy usando MPLAB X IDE con XC16.

No se, estoy perdido. No le veo explicación a no ser que el sensor esté dañado, cosa que me sorprende ya que como dije es nuevo y la primera vez que lo uso  :(


Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ds18b20
« Respuesta #3 en: 16 de Abril de 2015, 04:41:42 »
A me parecio raro por que vi por internet esto:

#define ENABLE_RB7_OPENDRAIN() _ODCB7 = 1
#define DISABLE_RB7_OPENDRAIN() _ODCB7 = 0

Pero en el registro de ese PIC es ODB7 ... Asi que eso elimina esta opcion. Por lo que el PIC esta bien y queda el sensor...

Estas usando una alimentacion externa o lo alimentas con la misma linea de datos al sensor?
« Última modificación: 16 de Abril de 2015, 05:01:28 por KILLERJC »

Desconectado danifiguerola

  • PIC10
  • *
  • Mensajes: 24
Re: ds18b20
« Respuesta #4 en: 16 de Abril de 2015, 05:16:51 »
Hola de nuevo.

Entiendo lo que dices pero si pongo _ODCB7 o ODCBbits.ODCB7 el compliador no me los reconoce (me indica que no están definidos).

He mirado el archivo include p24fj64gb002.h (el pic que utilizo) y me salen definidos como _ODB7 y ODCBbits.ODB7 (sin la C). A lo mejor dependiendo del pic o lenguaje de programación (en mi caso XC16) varian las definiciones.
Igualmente he cambiado el _ODB7 por ODCBbits.ODB7 y tampoco funciona.

Por lo del debugger. Estoy usando el Microstick II con MPLAB X. Lo he mirado y si, se me setea el bit del registro ODCB (bit 7). Cuando el bit 7 (RB7) del registro LATB se pone a "0" el bit7 del PORTB sigue estando a "1" (que es realmente lo que pasa, no consigo bajarlo a "0").

He repasado las conexiones y si no se me escapa nada están correctas. Empiezo a sospechar seriamente de los sensores... aunque por otra parte me extraña  :shock:

Estoy usando alimentación externa (pin 1 a tierra, pin 2 a pic y alimentación a través de resistencia 4,7K y pin 3 a 5V)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ds18b20
« Respuesta #5 en: 16 de Abril de 2015, 05:30:22 »
Sinceramente ami tambien me extraña y mas que 2 vengan fallados al mismo tiempo.

Realmente no se me ocurre otra cosa, PIC bien seteado, caminos y resistencia de pull-up bien. No queda otra que el sensor, lamento no poder ser mas de ayuda.

Desconectado danifiguerola

  • PIC10
  • *
  • Mensajes: 24
Re: ds18b20
« Respuesta #6 en: 16 de Abril de 2015, 05:47:43 »
Si, no lo entiendo  :(

Muy agradecido por la ayuda!!!  :)

Desconectado Tisco

  • PIC16
  • ***
  • Mensajes: 108
Re: ds18b20
« Respuesta #7 en: 16 de Abril de 2015, 08:05:34 »
Por qué no pruebas a quitar el uC de la ecuación?

Conecta el sensor y la resistencia de pull-up, debería de haber 5V en la patilla DQ del sensor.

Después conecta la patilla DQ a masa, debería de haber 0V en DQ y 5V en el pin Vcc del sensor.

Si estos pasos funcionan, el sensor está bien y el problema está en la configuración del uC.

Si la tensión de alimentación cae a 0V cuando conectes DQ a masa, entonces el sensor está mal (hay algún cortocircuito).

Saludos!

Desconectado danifiguerola

  • PIC10
  • *
  • Mensajes: 24
Re: ds18b20
« Respuesta #8 en: 16 de Abril de 2015, 09:33:06 »
Ei. Solucionado. 

Tenia el sensor mal conectado... :oops: :oops: :oops: :oops: :oops: :cry: :cry: :cry: :cry:

Que error más tonto...

Gracias por el tiempo y las indicaciones!!!

Ahora parece que la comunicación con el sensor ya funciona, lo que no es la conversión de la temperatura.

Voy a pelearme un poco con el programa.

Muchas gracias de nuevo a todos  :) :)


 

anything