[SOLVED]ATMEGA328 doesn't behave like Arduino

I etched a circuit board for a thermostat project. I wrote the code and prototyped it with an UNO. It works great using the Arduino. But when I transfer the code to the circuit I constructed, the reading of the sensor is way off. The board circuit is wired exactly like the UNO diagram, but without the 16U2. The only difference is the MCU is a 328, NOT a 328P. As far as I have read, this shouldn't make any difference.

I have checked, double checked, and triple checked the board wiring. All is right. The code running on the Arduino yields correct temperatures. But the same code running on the MCU yields a temperature reading 15-20 degrees below what it should be. Is there a difference between the 328 and 328P that could cause this that I am unaware of? Has anyone else built an MCU based circuit that showed differences from the Arduino?

EDIT: BTW, I loaded the chip with the UNO bootloader. Could this have an effect for some reason?

Show us your schematic, your PCB layout and a picture of the final board.

InPhase277:
The only difference is the MCU is a 328, NOT a 328P. As far as I have read, this shouldn't make any difference.

More or less... The "P" letter stays for "PicoPower", and it indicates that the chip is using the newer core from Atmel that optimize the power consumption of the chip by letting the user to shut down the peripherals that are not used, so that you can obtain very low levels of power consumptions when in sleep.
The core itself is a little bit different and you should not use code compiled for an Atmega328P on an Atmega328 and viceversa. You should create a new board into the boards.txt specifing that the MCU is an Atmega328 so that the compilter can compile for the proper micro.

However, the differences in temperature could be caused by some errors in the circuit, so please publish the schematic.

It is possible to write the bootloader of the Arduino Uno (for a ATmega328p) into a ATmega328 and making the Arduino IDE think that a ATmega328p is connected when uploading a sketch. I have that, and had no problems with it.

What kind of temperature sensor do you use ?

The signature of the chip isn't provided by the bootloader but the chip itself.
You can instruct avrdude to flash a firmware compiled for a microcontroller on another MCU by altering the "-p" param used to specify the chip but this is not the way to do the things.

The way is: create a new board; compile for the different MCU; flash the right firmware on the right chip.
328 != 328P

As far I know it will not make any difference if you run the same code in 328 or 328p. The error must be crept in due to the circuit only.

They have different cores.

If you use digitalWrite to light on/off a LED, you won't find any difference. Moreover, in most of the situations you wan't find any relevant differences using the Arduino sketches.

But if you try to use specific code that makes use of the sleep capabilities of the "P" on a "non-P" you'll find why I'm telling you that they are different :wink:
Moreover, I could be wrong but it seems to me that on the "non-P" chip there is not fuse bit to disable the BOD circuit.

Leo, if you have hard data about differences in behavior between the 328 and 328, please let us know specifically!
Several people have poured over the datasheets and not found anything except the inability to turn off BOD. They certainly do NOT have "different cores" in the usual definition of "core" (there are actually several different AVR varieties, with differences in the size of interrupt vectors, presence of MUL or JMP instructions, and so on. But the 328 and 328p appear identical.)
There have been suggestions that the 328s are merely 328p chips that failed low-power specifications at the factory. :slight_smile:

The version of the compiler shipped with Arduino doesn't even support the ATmega328, and I'm pretty sure that the newer compilers never produce binaries that differ between 328p and 328 compilations.

The signature of the chip isn't provided by the bootloader but the chip itself.

And while the first paragraph is full of "I think" and such, I can say with absolute certainty that the Arduino 328x bootloaders provide a hardwired chip signature, and DO NOT get it from the chip itself.

I etched a circuit board for a thermostat project. I wrote the code and prototyped it with an UNO. It works great using the Arduino. But when I transfer the code to the circuit I constructed, the reading of the sensor is way off. The board circuit is wired exactly like the UNO diagram, but without the 16U2. The only difference is the MCU is a 328, NOT a 328P. As far as I have read, this shouldn't make any difference.

What ! You DARE to try to get us back to the original topic???!!!

You're right; it shouldn't make any difference. How are you doing with:

Show us your schematic, your PCB layout and a picture of the final board.

Does your board have a DIP packaged 328? (Can you swap chips with your Uno and see whether the behavior follows the chip, or follows the board?)

@westfw:
I don't know if the actual 328 chips are just 328P with failed PicoPower cores, but I agree (I confirmed that myself) that in normal use there are no apparent differences between 328 and 328P.
(wanna make a test for me? use the PRR register in a sketch. What does happen if you upload to a 328 "non-P" that code?)

Holy Cow! I figured I would wait a few days and work on some other stuff and I might get a couple of responses! You guys are quick!

However, I have solved the problem, sorry for the late response. I knew it couldn't be electrical because I have poured over the board many times. And I knew it wasn't likely to be a difference between the 328 and 328P. So, while working on another project, I realized I had changed some code sections between the Arduino prototype and the final PCB. Something like this:

float milliVolts = average * (5000 / 1024);

Can you see the problem? Well I sure didn't for a long time! A couple of decimal points apparently go a LONG way! I changed it to this:

 float milliVolts = average * (5000.0 / 1024.0);

and voila! It works perfectly. I'm not entirely sure about why that is, but the important thing is that it works! Thanks to all that replied!

You declared your variable as a floating point integer, This requires a decimal point and the compiler doesn't just add it for you.
Some variable types will "auto-complete" and add things like decimal points but in this case it doesn't.

InPhase277:
I knew it couldn't be electrical because I have poured over the board many times.

What did you pour over the board? Most liquids will cause electrical problems.

fungus:
What did you pour over the board? Most liquids will cause electrical problems.

Hi Oh! Will you be taking that on the road :stuck_out_tongue: