Trouble with DS18B20 with Atmega 32A

Go To Last Post
27 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello folks,

 

I am using DS18B20 with Atmega 32A, I have downloaded a library for atmega 8 @16MHz and modified it for use with atmega 32A @8MHz. The library works fine with atmega 8 but does not work with atmega 32 A. Please help..

 

This is the code portion where I read and display the temperature on a 16x2 LCD.--

 

void Measure()
{
    
    while(1)
    {
        if(status_1)// sensor buffer ready
        {
            status_1=0; // clear buffer for new data
            counts = ReadAndAvg();
            rd=(5.0/1024.0)*counts;
            sprintf(lcd_buffer, "Counts: %4d",counts);
            lcd_gotoxy(0,0);
            lcd_puts(lcd_buffer);
        }
            
        if(status_2) // buffer full
        
        {    
            status_2=0; // refresh buffer for new data
            //t = Get_Temp();    
            sprintf(lcd_buffer,"TEMP:");
            lcd_gotoxy(0,1);
            lcd_puts(lcd_buffer);
            //t=(float)(4.8828*read_adc(tmp)/10.0);
            t = ds18b20_gettemp();//read
            //sprintf(lcd_buffer," %04d Deg",t);
            sprintf(lcd_buffer," %03.2f Deg",t);
            lcd_gotoxy(5,1);
            lcd_puts(lcd_buffer);        
                    
        }
        
                
        if(Get_Key_Status(DN))
        {
            //Scroll Key is pressed
            //Check that it was not pressed previously
            if(!Get_PrevKey_Status(DN))
            {
                PREV_KEYS=KEYS;
                lcd_clrscr();
                break;
                
            }
        }
        PREV_KEYS=KEYS;
    }
    
    
}

 

 

 

This is the library :

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#include "ds18b20.h"

/*
 * ds18b20 init
 */
uint8_t ds18b20_reset() {
    uint8_t i;

    //low for 480us
    DS18B20_PORT &= ~ (1<<DS18B20_DQ); //low
    DS18B20_DDR |= (1<<DS18B20_DQ); //output
    _delay_us(480);

    //release line and wait for 60uS
    DS18B20_DDR &= ~(1<<DS18B20_DQ); //input
    _delay_us(60);

    //get value and wait 420us
    i = (DS18B20_PIN & (1<<DS18B20_DQ));
    _delay_us(420);

    //return the read value, 0=ok, 1=error
    return i;
}

/*
 * write one bit
 */
void ds18b20_writebit(uint8_t bit){
    //low for 1uS
    DS18B20_PORT &= ~ (1<<DS18B20_DQ); //low
    DS18B20_DDR |= (1<<DS18B20_DQ); //output
    _delay_us(1);

    //if we want to write 1, release the line (if not will keep low)
    if(bit)
        DS18B20_DDR &= ~(1<<DS18B20_DQ); //input

    //wait 60uS and release the line
    _delay_us(60);
    DS18B20_DDR &= ~(1<<DS18B20_DQ); //input
}

/*
 * read one bit
 */
uint8_t ds18b20_readbit(void){
    uint8_t bit=0;

    //low for 1uS
    DS18B20_PORT &= ~ (1<<DS18B20_DQ); //low
    DS18B20_DDR |= (1<<DS18B20_DQ); //output
    _delay_us(1);

    //release line and wait for 14uS
    DS18B20_DDR &= ~(1<<DS18B20_DQ); //input
    _delay_us(14);

    //read the value
    if(DS18B20_PIN & (1<<DS18B20_DQ))
        bit=1;

    //wait 45uS and return read value
    _delay_us(45);
    return bit;
}

/*
 * write one byte
 */
void ds18b20_writebyte(uint8_t byte){
    uint8_t i=8;
    while(i--){
        ds18b20_writebit(byte&1);
        byte >>= 1;
    }
}

/*
 * read one byte
 */
uint8_t ds18b20_readbyte(void){
    uint8_t i=8, n=0;
    while(i--){
        n >>= 1;
        n |= (ds18b20_readbit()<<7);
    }
    return n;
}

/*
 * get temperature
 */
double ds18b20_gettemp() {
    uint8_t temperature_l;
    uint8_t temperature_h;
    double retd = 0;

    #if DS18B20_STOPINTERRUPTONREAD == 1
    cli();
    #endif

    ds18b20_reset(); //reset
    ds18b20_writebyte(DS18B20_CMD_SKIPROM); //skip ROM
    ds18b20_writebyte(DS18B20_CMD_CONVERTTEMP); //start temperature conversion

    while(!ds18b20_readbit()); //wait until conversion is complete

    ds18b20_reset(); //reset
    ds18b20_writebyte(DS18B20_CMD_SKIPROM); //skip ROM
    ds18b20_writebyte(DS18B20_CMD_RSCRATCHPAD); //read scratchpad

    //read 2 byte from scratchpad
    temperature_l = ds18b20_readbyte();
    temperature_h = ds18b20_readbyte();

    #if DS18B20_STOPINTERRUPTONREAD == 1
    sei();
    #endif

    //convert the 12 bit value obtained
    retd = ( ( temperature_h << 8 ) + temperature_l ) * 0.0625;

    return retd;
}

 

 

And this is the header file:

 

#ifndef DS18B20_H_
#define DS18B20_H_

#include <avr/io.h>

//setup connection
#define DS18B20_PORT PORTC
#define DS18B20_DDR DDRC
#define DS18B20_PIN PINC
#define DS18B20_DQ    0

//commands
#define DS18B20_CMD_CONVERTTEMP 0x44
#define DS18B20_CMD_RSCRATCHPAD 0xbe
#define DS18B20_CMD_WSCRATCHPAD 0x4e
#define DS18B20_CMD_CPYSCRATCHPAD 0x48
#define DS18B20_CMD_RECEEPROM 0xb8
#define DS18B20_CMD_RPWRSUPPLY 0xb4
#define DS18B20_CMD_SEARCHROM 0xf0
#define DS18B20_CMD_READROM 0x33
#define DS18B20_CMD_MATCHROM 0x55
#define DS18B20_CMD_SKIPROM 0xcc
#define DS18B20_CMD_ALARMSEARCH 0xec

//stop any interrupt on read
#define DS18B20_STOPINTERRUPTONREAD 1

//functions
extern double ds18b20_gettemp();

#endif

Abhishek

Last Edited: Wed. Dec 19, 2018 - 11:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you proven that your mega32 is actually running at 8MHz? Try flashing a led to confirm the delays are correct. Onceyou’ve proven that, then we can look at other potential problems.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Abhishek_Sarma252 wrote:
I have downloaded a library for atmega 8 @16MHz

Abhishek_Sarma252 wrote:
The library works fine with atmega 8

On the M8 does it work at 8MHz or 16MHz?

 

Abhishek_Sarma252 wrote:
modified it for use with atmega 32A @8MHz

What mods did you do?

 

As Kartman asked, how have you proven your M32 is running at 8MHz, please post fuse settings.

Your using the delay functions, these need to know what speed the cpu is running at with F_CPU defined with the speed before the include delay line.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Wed. Dec 19, 2018 - 02:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes the microcontroller is running @ 8MHz.

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Jim,

 

I have included #define F_CPU 8000000UL in the library file (.c) but still the problem is there.

 

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Again, how have you proven that the mega32 is running at 8MHz? Show us evidence. Otherwise you could be mislead by a bad procedure.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The #define does NOT set the CPU speed, it's simply a mechanism for you to convey what you believe the speed to be to the code. But if you get your assumption wrong then the code will be wrong.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Abhishek_Sarma252 wrote:
I have included #define F_CPU 8000000UL in the library file (.c) but still the problem is there.

 

The define must proceed the include like this:

 

#include <avr/io.h>
#define F_CPU 8000000ul
#include <util/delay.h>
#include <avr/interrupt.h>

#include "ds18b20.h"

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The fuse bit setting:

 

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still not concrete proof. Using delay(), have you written code to flash a led and confirmed it flashes at the correct speed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Those fuse settings say to use the internal 8MHz RC, BOD 2.7, ISP and JTAG enabled.

 

I have not looked it up, but your not trying to use the port where the jtag is enabled are you, we have seen that before....

And the VCC is 3.3v to 5v ???

 

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please ZIP up your AS7 project and attach the ZIP.

 

It is very important to get the F_CPU  correct for each C file.  Fuse values: 8MHz RC fuse will be fine.   Using PC0 pin should be fine.

 

It is much easier for a reader to just build a project and even run it on similar hardware.

I do not feel like reconstructing your project from the snippets you have posted.   

 

As a general rule Arduino Uno target board is the most popular target if you want readers to build and debug your project.

However,  mega32 was quite popular in dev boards.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi David, good morning !

 

I made some changes to my project, but nothing seems to be working. I have zipped up the whole project and also included the Proteus simulation file. Kindly have a look.

 

Attachment(s): 

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With proteus you have virtual test instruments you can use to verify the timing. Have you tried these?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your project has many design "features"

1.   it is wise to use C files for a C project.  It avoids name-mangling issues.

2.   include H files

3.   add C files as separate compilation units to your project

4.   add F_CPU to the Symbols in your project properties.

5.   do not enable peripheral interrupts without ISR()

6.   do not call external functions from within an ISR().   Just set a flag.

7.   DS18B20 takes a very long time to do the temperature conversion.

8.   it is convenient to "start" the conversion.    And not come back until you know it will be ready.

9.   in practice this could mean once a second:  reading the previous result,  starting the next.

10.  you appear to have stitched a Codevision Codewizard initialisation with several GCC files.

11.  you have altered the way that ds18b20 macros are used without understanding e.g. with C_CLEARBIT()

 

I suggest that you design a simple project first.   e.g. read once a second.   display on LCD.

Add the extra functionality later.

 

No,  I have not looked at your recent attachment.

 

David.

Last Edited: Mon. Dec 24, 2018 - 02:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi David,

 

I have simplified the things in my recent attachment. Kindly view it and revert.

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is a lot simpler project.

 

I have made some corrections to your project.   Look in the C file

And added a second project to show how to use multiple source files.

 

Note that Project Properties defaults to "Active Configuration".    It is always wise to put settings in "All Configurations"

 

Please let me know if you have understood my comments.    Especially the reason for separate C compilation.

Life is simpler when all your C and H files are in the same directory.    But it is not difficult to specify another directory to search.

 

Which country do you live in?

 

David.

Attachment(s): 

Last Edited: Wed. Dec 26, 2018 - 10:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi David, Good day :)

 

I am from India. Let me see the modifications that you have done and understand those. I am very grateful to you for sparing the time to check my code. I really appreciate.

 

--Abhishek

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi David. I have looked through the changes that you have made and also the comments. I have certain points to put:

 

1. What is the need of separate C file, i.e. ds18b20_thermo.c and ds18b20_thermo_kbv.c.

2. How ".kbv corrected your PORTB"?

3. Even now I am not able to read the temperature and display it on the 16x2 LCD.

 

Kindly help me 

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have described the differences between the two files.

//.kbv Linker: tick use vprintf library for f-p printf
//.kbv Linker: add libprintf_flt to libraries

//.kbv corrected your DS18B20_PIN define
//'kbv changed your ds18b20_gettemp() function
 
//.kbv please ignore my _LCD_DEFINITIONS_FILE symbol.   My lcd wiring is different to yours. 

This built your project successfully.   I ran it with a real DS18B20 on PB0 with an 8MHz mega32.   Using your files.

 

You have to tell AS7 to use the f-p version of printf().

The DS18B20_PIN define must be PINB and not PORTB

My Sensor uses parasite power.    Hence the different sequence for gettemp()

 

However,  the most important advice is in the other project:

//.kbv add C files to project
//.kbv C Compiler: set search path for H files in Project Properties
//.kbv C Compiler: Symbols.  add F_CPU

This uses the lcd.? and ds18b20.? files from your directory (as links)

It shows you how to add C files to your project.  And configure Project Properties.

 

I would expect both of those projects to build and run correctly.    I note that you are using PORTC for the LCD.    PORTC is used by JTAG (in a virgin chip).

Did you see "Hello" on the LCD?

 

My LCD was on PORTD.    The project uses my defines if _LCD_DEFINITIONS_FILE is defined in Project Symbols.    Your ZIP has the mis-spelled ___LCD_DEFINITIONS_FILE symbol.   So it does not use my defines.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi David,

 

Thanks for explaining me the modifications and differences.

I have the following points to mention:

1. I am using ATmega 32A PU running @ 8MHz (internal RC osc).

2. I am able to see "Hello" on the LCD, which is connected to Port C.

3. I am using floating point version of printf() and temperature is showing 0.00

4. My sensor uses Vcc not parasitic power. I have a pull up of 4.7K to DQ pin.

5. I am simulating the code on proteus (as found in the attachment shared with you).

6. I am seeing that when I start the simulation, pin PB0 stays at low, there is no pulsing of pin toggling. Hence, I am not getting any temp data.

Do, I need to make any modification in the code. If so, kindly help.

 

-Abhishek

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would expect the ZIP that I posted will work for you on real hardware.

You just need to connect your LCD to PORTC and the DS18B20 to PB0

You do not need to make any edits.

 

It is good that your LCD is working.   The printf() is working too.

Your DS18B20 should work with regular power or with parasitic power.

I have only tested with parasitic power.

You can change the #if in ds18b20.c

 

I do not own a Proteus licence.    I have not even looked at your Proteus files.

I know that Proteus can simulate an LCD ok.    I doubt if it can simulate a DS18B20.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

I doubt if it can simulate a DS18B20.

 

Actually it can, there's even an example project with a mega16 reading one and displaying it. And you can see the source code, written for AVR-GCC.

 

@OP

Why don't you look at the example within Proteus.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is fascinating. What Serial Number does it return? How does it cope with multiple OneWIRE devices?
.
Proteus has always intrigued me. It just seems easier (and cheaper) to run code on real hardware.
It seems an excellent tool for University students.
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

What Serial Number does it return? How does it cope with multiple OneWIRE devices? .

 

In the device properties you can set a value (6 hex digits?) for the ROM serial number. Don't know about multiple devices.

 

 

david.prentice wrote:

Proteus has always intrigued me. It just seems easier (and cheaper) to run code on real hardware. It seems an excellent tool for University students. . David.

 

Same here which is why I have the eval version installed. My other job sees me away from the office with lots of time to kill between shows; time which I often think could be usefully used on development work. Hence my interest in a hardware-free development system.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi David,

 

The code actually worked on real hardware. A big thumbs down to Proteus !!! It actually wasted a lot of my time.

And big thanks to you David. I really appreciate

 

-Abhishek

Abhishek

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not have a Proteus licence.
I do not know what arrangements your University has with LabCenter regarding student licences.
.
Brian says that the Proteus Simulation should work. I suggest that you try the examples and check your Proteus project files. Perhaps you configure the simulated temperature. If so, choose an unlikely temperature like 12.34C or 43.21C
.
However the most important lesson is to understand how to add C files to an AS7 project from #20.
.
David.