Atmega328pb

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

help to do a project with an atmega328pb and max665 thermocouple sensor interacting with an lcd display

javier

Last Edited: Wed. Jul 17, 2019 - 03:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Step one is to be able to program the 328PB controller

without attaching anything to it, other than perhaps an

LED (with a current-limiting resistor).  Once you can

load code and blink the LED, you are well on your way.

 

Step two could be learning to write to the display.  There

are already-written libraries available for common displays

so you might want to search for these instead of writing

your own code from scratch. Otherwise, search for the

datasheet of the display to find out how to write to it.

 

Step three is to learn to read data from the sensor. Again

there are probably libraries you can just use for this if you

aren't trying to write the code yourself. You'll need to know

what protocol the sensor uses. Maybe it's SPI or I2C (TWI).

The sensor's datasheet will tell you.

 

Step four is to combine everything into one project where

you read from the sensor and then output the values to

the display.

 

If you get stuck during any of these steps you can ask

specific questions showing schematics and code and some

one here can likely help.

 

--Mike

 

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

Have you taken a look at any of the many AVR tutorials on this and other sites?  Try going through a few of them to get ideas for creating your project code.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

javi0810 wrote:
max665 thermocouple sensor

Are you sure that is the correct part number?  Details are important.

 

Jim

 

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

share.robinhood.com/jamesc3274
stack gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

When I tried searching earlier I hit some threads back at Freaks about a "6675". Wonder if it's really that (in which case those threads would be relevant reading too).

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

it was my mistake it is a max6665 thermocouple sensor, I have to interface with an lcd keypad shield through SPI, using the ATmega328pb microcontroller. I write the following code, but I am not getting in the display the reading from the thermocouple, can someone please help me

Code:

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define MOSI 3
#define SCK 5
#define SS 2

#define LCD_DPRT PORTD
#define    LCD_DDDR DDRD
#define LCD_DPIN PIND
#define LCD_CPRT  PORTB
#define LCD_CDDR  DDRB
#define LCD_CPIN  PINB
#define LCD_RS        0
#define LCD_RW      4
#define LCD_EN        1

void lcdComrnand( unsigned char cmnd )
{
    LCD_DPRT = cmnd & 0xF0;
    LCD_CPRT &= ~(1<<LCD_RS);
    LCD_CPRT &= ~ (1<<LCD_RW);
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    _delay_ms(100);
    LCD_DPRT = cmnd<<4;
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    _delay_ms(100);
}
void lcdData( unsigned char data )
{
    LCD_DPRT = data & 0xF0;
    LCD_CPRT |= (1<<LCD_RS);
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    LCD_DPRT = (LCD_DPRT & 0x0F) | (data<<4);
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    _delay_ms(100);
}
void lcd_init()
{
    LCD_DDDR = 0xFF;
    LCD_CDDR = 0x03;
    LCD_CPRT &=~(1<<LCD_EN);
    lcdComrnand(0x33);
    lcdComrnand(0x32);
    lcdComrnand(0x28);
    lcdComrnand(0x0E);
    lcdComrnand(0x01);
    _delay_ms(2000);
    lcdComrnand(0x06);    
}
void lcd_gotoxy(unsigned char x, unsigned char y)
{
    unsigned char firstCharAdr[] ={0x81, 0xC0, }; 
    lcdComrnand(firstCharAdr[ y-1] + x - 1);
    _delay_ms(100);
}
void lcd_print( char *str )
{
    unsigned char i = 0;
    while (str[ i] !=0)
    {
        lcdData (str[ i] ) ;
        i++ ;
    }
}
void dataRead( unsigned int )
{
    unsigned int j = SPDR0;
    j<<8;
    j|=SPDR0;
}
//**************************************************************************
int main()

    
    DDRB = (1<<MOSI)|(1<<SCK)|(1<<SS);
    DDRD = 0xFF;
    SPCR0 = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    
    
        PORTB &=~(1<<SS);
        SPDR0 = 'j';
        while(!(SPSR0 &(1<<SPIF)));
        PORTD = SPDR0;
        PORTB |= (1<<SS);
    
    lcd_init();
    lcd_gotoxy(1,1);
    lcd_print("%d, j");
    
    
    while(1);
    return 0;

}

javier

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

did you manage to put "hello world"  on the display?

and you do know that ms = miliseconds and not micro seconds right?

there are a number of delays in your write routines that are massive, wonder if they are needed and if you not have taken the wrong delay time.

in combination with a wrong clock speed that might be visually killing.

you have set the fuses to match the selected clock input?

for instance you state you have a 16mHz clock source somewhere. but if you actually run at internal RC with default fuses times are 16x longer, so a 100ms delay will become 1,6 seconds a 2 second delay will become 32.........

And for the impatient programmer expecting things to happen with the blink of an eye that is a massive "help my thingy does not work"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
void dataRead( unsigned int )
{
    unsigned int j = SPDR0;
    j<<8;
    j|=SPDR0;
}

Umm I don't think so for many reasons.

 

Presumably this was supposed to look something like:

uint8_t SPI_transfer(uint8_t byte) {
    SPDR = byte;
    while(!(SPSR0 & (1 << SPIF)));
    return SPDR;
}

uint16_t dataRead(void)
{
    uint16_t j;
    j = SPI_transfer(0xFF) << 8;
    j |= SPI_transfer(0xFF);
}

Of course, for this to be useful you then have to call it somewhere. At present all you have is:

    lcd_print("%d, j");

which appears to be printing some variable called 'j' and yet I don't see where that is either defined or assigned? (it will have nothing to do with the local 'j' in your uncalled dataRead( ) function.

 

BTW in the above I have introduced an SPI_transfer() function  - this recognizes the fact that every time you use SPI you both send and receive a byte. Sometimes the value of the byte you send does not matter but, as master, you still have to send it to make the SPI system "clock". In the example code I am sending a dummy 0xFF value each time simply to persuade the device to actually return the high and low bytes I'm interested in. (does it really return high then low rather than low then high??).

 

Just this small bit of your code I have looked at suggests to me that you don't yet have a grasp of even the fundamentals of C programming (like returning values from functions) so I would spend a few weeks just learning C basics before trying to apply that to an actual AVR application.

 

PS even this:

void lcd_print( char *str )
{
    unsigned char i = 0;
    while (str[ i] !=0)
    {
        lcdData (str[ i] ) ;
        i++ ;
    }
}

could be better - there's no need for 'i' in this:

void lcd_print( char *str )
{
    while (*str)
    {
        lcdData (*str++) ;
    }
}

EDIT: actually I just noticed another thing. Your program structure is essentially:

int main()
{
    lcd_init();

    lcd_print("%d, j");

    while(1);
}

Surely you don't want it to just make one reading at power on then stop? Surely you want a structure more like:

int main()
{
    uint16_t j;

    lcd_init();

    while(1) {
        j = dataRead();
        lcd_print("%d, j");
    }
}

so that it attempts to read and print over and over again.

 

(obviously I left out a whole bunch of other init stuff - you need that back as well).

 

Oh hold on. I just realised you used:

        lcd_print("%d, j");

My eyesight must be failing - even THAT is wrong. If this lcd_print() function is something like printf() with variadic parameters then I imagine you mean:

        lcd_print("%d", j);

but if it isn't then you need to convert the value into a string first using a function such as sprintf():

char buf[30];
...
        sprintf(buf, "%d", j);
        lcd_print(buf);

As I say there are just so many fundamental C errors in the code that I think you need to take a step back and learn C first before trying to do anything with it like reading thermocouples.

Last Edited: Fri. Jul 19, 2019 - 09:25 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After work very hard to fix my code to get my project done, I did some improvement to my code, but I am not getting the temperature on the display still. Any ideas what am I missing on this code.

 

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

#define LCD_DPRT PORTD
#define    LCD_DDDR DDRD
#define LCD_DPIN PIND
#define LCD_CPRT  PORTB
#define LCD_CDDR  DDRB
#define LCD_CPIN  PINB
#define LCD_RS        0
#define LCD_RW      2
#define LCD_EN        1
#define MOSI 3
#define MISO 4
#define SCK 5
#define SS 2
void lcdComrnand( unsigned char cmnd )
{
    LCD_DPRT = (LCD_DPRT & 0x0F)|(cmnd & 0xF0);
    LCD_CPRT &= ~(1<<LCD_RS);
    LCD_CPRT &= ~ (1<<LCD_RW);
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    _delay_ms(100);
    LCD_DPRT = (LCD_DPRT & 0x0F)|cmnd<<4;
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    _delay_ms(100);
}

void lcdData( unsigned char data )
{
    LCD_DPRT = data & 0xF0;
    LCD_CPRT |= (1<<LCD_RS);
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    LCD_DPRT = (LCD_DPRT & 0x0F) | (data<<4);
    LCD_CPRT |= (1<<LCD_EN);
    _delay_ms(1);
    LCD_CPRT &= ~(1<<LCD_EN);
    _delay_ms(100);
}

void lcd_init()
{
    LCD_DDDR = 0xF0;
    LCD_CDDR = 0x03;
    LCD_CPRT &=~(1<<LCD_EN);
    lcdComrnand(0x33);
    lcdComrnand(0x32);
    lcdComrnand(0x28);
    lcdComrnand(0x0E);
    lcdComrnand(0x01);
    _delay_ms(2000);
    lcdComrnand(0x06);    
}
void lcd_gotoxy(unsigned char x, unsigned char y)
{
    unsigned char firstCharAdr[] ={0x81, 0xC0, 0x94, 0xD4}; 
    lcdComrnand(firstCharAdr[ y-1] + x - 1);
    _delay_ms(100);
}
void lcd_print( char *str )
{
    unsigned char i = 0;
    while (str[ i] !=0)
    {
        lcdData (str[ i] ) ;
        i++ ;
    }
}

char dataWrite(char cData)
{
        DDRB = (1<<MOSI)|(1<<SCK)|(1<<SS);
        DDRB = ~(1<<MISO);
        SPCR0 = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPHA)|(1<<CPOL);
    
            PORTB &=~(1<<SS);
            SPDR0 = cData;
            SPDR0 = cData << 8;
            SPDR0 |= SPDR0;
            while(!(SPSR0 & (1<<SPIF)));
            PORTD = SPDR0;
            PORTB |= (1<<SS);

}

//**************************************************************************
int main()
{
    lcd_init();
    lcd_gotoxy(1,1);
    lcd_print("Temperature");
    lcd_gotoxy(1,2);
    lcd_print(dataWrite(PORTD));
    while(1);
    return 0;
}

javier

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

After work very hard to fix my code to get my project done, I did some improvement to my code,

The description you provide is very lacking...does the display work AT ALL?  Can you get it to say "hello" ...why do you overlook stating what is working?

We can not tell what is happening...you could even have bad wiring.  Getting the display functioning is step one, before trying to show other items that themselves need to be up & running.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

The display is working, I print hello, and did others test to see if the code for the display is right, and it seems to work perfectly, after that I attached a max6675 thermocouple and add the code  to get the temperature and print it in the display, but I am not able to do it. 

javier

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

Ok, that is good to know (you should state this earlier!)--so now we can concentrate on whether the readings are simply not coming in, or whether reading are being rcvd, but not being formatted properly such that they will show on the display

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

Your code makes little sense. At one stage you use lcd_print("Temperature") which suggests the function takes char * and yet later you call lcd_print() but passing a parameter of dataWrite() which is a function that has a char not char *  return and what's more the function itself does not even contain a return statement anyway?

 

Suggest you stop to think about the design of this before rushing to implementation.